[vlc-commits] ttml: fix bnf timing parsing
Francois Cartegnie
git at videolan.org
Thu Mar 2 20:01:02 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Mar 2 19:57:15 2017 +0100| [989bc9d662bc982613b3264e6ecf192687ba6a52] | committer: Francois Cartegnie
ttml: fix bnf timing parsing
"this is left as an exercise for the reader"
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=989bc9d662bc982613b3264e6ecf192687ba6a52
---
modules/codec/ttml/ttml.c | 62 ++++++++++++++++++++++++++++++++++++++---------
modules/codec/ttml/ttml.h | 12 ++++-----
modules/demux/ttml.c | 31 ++++++++++++++++++++----
3 files changed, 83 insertions(+), 22 deletions(-)
diff --git a/modules/codec/ttml/ttml.c b/modules/codec/ttml/ttml.c
index 582cdb2..cb9b4b6 100644
--- a/modules/codec/ttml/ttml.c
+++ b/modules/codec/ttml/ttml.c
@@ -25,6 +25,7 @@
#include <vlc_plugin.h>
#include <vlc_xml.h>
#include <vlc_strings.h>
+#include <vlc_charset.h>
#include <assert.h>
#include <stdlib.h>
@@ -71,9 +72,10 @@ bool tt_node_HasChild( const tt_node_t *p_node )
return p_node->p_child;
}
-static inline bool tt_ScanReset( unsigned *a, unsigned *b, unsigned *c, unsigned *d )
+static inline bool tt_ScanReset( unsigned *a, unsigned *b, unsigned *c,
+ char *d, unsigned *e )
{
- *a = *b = *c = *d = 0;
+ *a = *b = *c = *d = *e = 0;
return false;
}
@@ -81,17 +83,55 @@ static tt_time_t tt_ParseTime( const char *s )
{
tt_time_t t = {-1, 0};
unsigned h1 = 0, m1 = 0, s1 = 0, d1 = 0;
+ char c = 0;
- if( sscanf( s, "%u:%u:%u%*[,.]%u", &h1, &m1, &s1, &d1 ) == 4 ||
- tt_ScanReset( &h1, &m1, &s1, &d1 ) ||
- sscanf( s, "%u:%u:%u", &h1, &m1, &s1 ) == 3 ||
- tt_ScanReset( &h1, &m1, &s1, &d1 ) ||
- sscanf( s, "%u.%us", &s1, &d1 ) == 2 ||
- tt_ScanReset( &h1, &m1, &s1, &d1 ) ||
- sscanf( s, "%us", &s1 ) == 1 )
+ /* Clock time */
+ if( sscanf( s, "%u:%u:%u%c%u", &h1, &m1, &s1, &c, &d1 ) == 5 ||
+ tt_ScanReset( &h1, &m1, &s1, &c, &d1 ) ||
+ sscanf( s, "%u:%u:%u", &h1, &m1, &s1 ) == 3 ||
+ tt_ScanReset( &h1, &m1, &s1, &c, &d1 ) )
{
- t.base = h1 * 3600 + m1 * 60 + s1;
- t.frames = d1;
+ t.base = CLOCK_FREQ * (h1 * 3600 + m1 * 60 + s1);
+ if( c == '.' && d1 > 0 )
+ {
+ unsigned i_den = 1;
+ for( const char *p = strchr( s, '.' ) + 1; *p; p++ )
+ i_den *= 10;
+ t.base += CLOCK_FREQ * d1 / i_den;
+ }
+ else if( c == ':' )
+ {
+ t.frames = d1;
+ }
+ }
+ else /* Offset Time */
+ {
+ char *psz_end = (char *) s;
+ double v = us_strtod( s, &psz_end );
+ if( psz_end != s && *psz_end )
+ {
+ if( *psz_end == 'm' )
+ {
+ if( *(psz_end + 1) == 's' )
+ t.base = 1000 * v;
+ else
+ t.base = CLOCK_FREQ * 60 * v;
+ }
+ else if( *psz_end == 's' )
+ {
+ t.base = CLOCK_FREQ * v;
+ }
+ else if( *psz_end == 'h' )
+ {
+ t.base = CLOCK_FREQ * v * 3600;
+ }
+ else if( *psz_end == 'f' )
+ {
+ t.base = 0;
+ t.frames = v;
+ }
+ //else if( *psz_end == 't' );
+ }
}
return t;
diff --git a/modules/codec/ttml/ttml.h b/modules/codec/ttml/ttml.h
index c2dc4dc..94263ed 100644
--- a/modules/codec/ttml/ttml.h
+++ b/modules/codec/ttml/ttml.h
@@ -35,7 +35,7 @@ enum
typedef struct
{
- time_t base;
+ int64_t base;
unsigned frames;
//unsigned ticks;
} tt_time_t;
@@ -109,8 +109,8 @@ static inline void tt_time_Init( tt_time_t *t )
static inline tt_time_t tt_time_Create( mtime_t i )
{
tt_time_t t;
- t.base = i / CLOCK_FREQ;
- t.frames = (i % CLOCK_FREQ) * TT_FRAME_RATE / CLOCK_FREQ;
+ t.base = i;
+ t.frames = 0;
return t;
}
@@ -124,7 +124,7 @@ static inline mtime_t tt_time_Convert( const tt_time_t *t )
if( !tt_time_Valid( t ) )
return -1;
else
- return CLOCK_FREQ * t->base + CLOCK_FREQ * t->frames / TT_FRAME_RATE;
+ return t->base + CLOCK_FREQ * t->frames / TT_FRAME_RATE;
}
static inline mtime_t tt_time_Compare( const tt_time_t *t1, const tt_time_t *t2 )
@@ -136,7 +136,7 @@ static inline tt_time_t tt_time_Add( tt_time_t t1, tt_time_t t2 )
{
t1.base += t2.base;
t1.frames += t2.frames;
- t1.base += t1.frames / TT_FRAME_RATE;
+ t1.base += CLOCK_FREQ * ( t1.frames / TT_FRAME_RATE );
t1.frames = t1.frames % TT_FRAME_RATE;
return t1;
}
@@ -146,7 +146,7 @@ static inline tt_time_t tt_time_Sub( tt_time_t t1, tt_time_t t2 )
if( t2.frames > t1.frames )
{
unsigned diff = 1 + (t2.frames - t1.frames) / TT_FRAME_RATE;
- t1.base -= diff;
+ t1.base -= diff * CLOCK_FREQ;
t1.frames += diff * TT_FRAME_RATE;
}
t1.frames -= t2.frames;
diff --git a/modules/demux/ttml.c b/modules/demux/ttml.c
index 2019586..f51569b 100644
--- a/modules/demux/ttml.c
+++ b/modules/demux/ttml.c
@@ -70,17 +70,38 @@ static char *tt_genTiming( tt_time_t t )
{
if( !tt_time_Valid( &t ) )
t.base = 0;
-
+ unsigned f = t.base % CLOCK_FREQ;
+ t.base /= CLOCK_FREQ;
unsigned h = t.base / 3600;
unsigned m = t.base % 3600 / 60;
unsigned s = t.base % 60;
+ int i_ret;
char *psz;
- if( asprintf( &psz, "%2.2u:%2.2u:%2.2u.%u",
- h, m, s, t.frames ) < 0 )
- psz = NULL;
+ if( f )
+ {
+ const char *lz = "000000";
+ const char *psz_lz = &lz[6];
+ /* add leading zeroes */
+ for( unsigned i=10*f; i<CLOCK_FREQ; i *= 10 )
+ psz_lz--;
+ /* strip trailing zeroes */
+ for( ; f > 0 && (f % 10) == 0; f /= 10 );
+ i_ret = asprintf( &psz, "%02u:%02u:%02u.%s%u",
+ h, m, s, psz_lz, f );
+ }
+ else if( t.frames )
+ {
+ i_ret = asprintf( &psz, "%02u:%02u:%02u:%s%u",
+ h, m, s, t.frames < 10 ? "0" : "", t.frames );
+ }
+ else
+ {
+ i_ret = asprintf( &psz, "%02u:%02u:%02u",
+ h, m, s );
+ }
- return psz;
+ return i_ret < 0 ? NULL : psz;
}
static void tt_node_AttributesToText( struct vlc_memstream *p_stream, const tt_node_t* p_node )
More information about the vlc-commits
mailing list