vlc | branch: master | Francois Cartegnie <[email protected]> | 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 ) _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
