[vlc-commits] ttml: use native time spec (fix #18056)

Francois Cartegnie git at videolan.org
Thu Mar 2 13:04:48 CET 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Mar  2 13:01:36 2017 +0100| [ac50e7acfb38563d58341d8cc8e8d31d3bdf8de1] | committer: Francois Cartegnie

ttml: use native time spec (fix #18056)

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ac50e7acfb38563d58341d8cc8e8d31d3bdf8de1
---

 modules/codec/ttml/substtml.c |  35 ++++++-------
 modules/codec/ttml/ttml.c     | 116 +++++++++++++++++++++---------------------
 modules/codec/ttml/ttml.h     |  75 ++++++++++++++++++++++++---
 modules/demux/ttml.c          |  79 +++++++++++++++-------------
 4 files changed, 187 insertions(+), 118 deletions(-)

diff --git a/modules/codec/ttml/substtml.c b/modules/codec/ttml/substtml.c
index f41729c..d4cca23 100644
--- a/modules/codec/ttml/substtml.c
+++ b/modules/codec/ttml/substtml.c
@@ -671,10 +671,10 @@ static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_tt
 static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t *p_node,
                                          ttml_region_t *p_region,
                                          const ttml_style_t *p_upper_set_styles,
-                                         int64_t i_playbacktime )
+                                         tt_time_t playbacktime )
 {
-    if( i_playbacktime != -1 &&
-       !tt_timings_Contains( &p_node->timings, i_playbacktime ) )
+    if( tt_time_Valid( &playbacktime ) &&
+       !tt_timings_Contains( &p_node->timings, &playbacktime ) )
         return;
 
     const char *psz_regionid = (const char *)
@@ -707,8 +707,8 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
         else if( !tt_node_NameCompare( ((const tt_node_t *)p_child)->psz_node_name, "set" ) )
         {
             const tt_node_t *p_set = (const tt_node_t *)p_child;
-            if( i_playbacktime == -1 ||
-                tt_timings_Contains( &p_set->timings, i_playbacktime ) )
+            if( !tt_time_Valid( &playbacktime ) ||
+                tt_timings_Contains( &p_set->timings, &playbacktime ) )
             {
                 if( p_set_styles != NULL || (p_set_styles = ttml_style_New()) )
                 {
@@ -724,7 +724,7 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
         else
         {
             ConvertNodesToRegionContent( p_ctx, (const tt_node_t *) p_child,
-                                         p_region, p_set_styles, i_playbacktime );
+                                         p_region, p_set_styles, playbacktime );
         }
     }
 
@@ -762,7 +762,7 @@ static tt_node_t *ParseTTML( decoder_t *p_dec, const uint8_t *p_buffer, size_t i
     return p_rootnode;
 }
 
-static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, int64_t i_playbacktime )
+static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, tt_time_t playbacktime )
 {
     ttml_region_t*  p_regions = NULL;
     ttml_region_t** pp_region_last = &p_regions;
@@ -775,7 +775,7 @@ static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, int64_t i_playback
             ttml_context_t context;
             context.p_rootnode = p_rootnode;
             vlc_dictionary_init( &context.regions, 1 );
-            ConvertNodesToRegionContent( &context, p_bodynode, NULL, NULL, i_playbacktime );
+            ConvertNodesToRegionContent( &context, p_bodynode, NULL, NULL, playbacktime );
 
             for( int i = 0; i < context.regions.i_size; ++i )
             {
@@ -801,15 +801,16 @@ static ttml_region_t *GenerateRegions( tt_node_t *p_rootnode, int64_t i_playback
 
 static int ParseBlock( decoder_t *p_dec, const block_t *p_block )
 {
-    int64_t *p_timings_array = NULL;
+    tt_time_t *p_timings_array = NULL;
     size_t   i_timings_count = 0;
 
     /* We Only support absolute timings */
     tt_timings_t temporal_extent;
     temporal_extent.i_type = TT_TIMINGS_PARALLEL;
-    temporal_extent.i_begin = 0;
-    temporal_extent.i_end = -1;
-    temporal_extent.i_dur = -1;
+    tt_time_Init( &temporal_extent.begin );
+    tt_time_Init( &temporal_extent.end );
+    tt_time_Init( &temporal_extent.dur );
+    temporal_extent.begin.base = 0;
 
     if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
         return VLCDEC_SUCCESS;
@@ -830,25 +831,25 @@ static int ParseBlock( decoder_t *p_dec, const block_t *p_block )
 
 #ifdef TTML_DEBUG
     for( size_t i=0; i<i_timings_count; i++ )
-        printf("%ld ", p_timings_array[i]);
+        printf("%ld ", tt_time_Convert( &p_timings_array[i] ) );
     printf("\n");
 #endif
 
     for( size_t i=0; i+1 < i_timings_count; i++ )
     {
         /* We Only support absolute timings (2) */
-        if( p_timings_array[i] + VLC_TS_0 < p_block->i_dts )
+        if( tt_time_Convert( &p_timings_array[i] ) + VLC_TS_0 < p_block->i_dts )
             continue;
 
-        if( p_timings_array[i] + VLC_TS_0 > p_block->i_dts + p_block->i_length )
+        if( tt_time_Convert( &p_timings_array[i] ) + VLC_TS_0 > p_block->i_dts + p_block->i_length )
             break;
 
         subpicture_t *p_spu = NULL;
         ttml_region_t *p_regions = GenerateRegions( p_rootnode, p_timings_array[i] );
         if( p_regions && ( p_spu = decoder_NewSubpictureText( p_dec ) ) )
         {
-            p_spu->i_start    = VLC_TS_0 + p_timings_array[i];
-            p_spu->i_stop     = VLC_TS_0 + p_timings_array[i+1] - 1;
+            p_spu->i_start    = VLC_TS_0 + tt_time_Convert( &p_timings_array[i] );
+            p_spu->i_stop     = VLC_TS_0 + tt_time_Convert( &p_timings_array[i+1] ) - 1;
             p_spu->b_ephemer  = true;
             p_spu->b_absolute = false;
 
diff --git a/modules/codec/ttml/ttml.c b/modules/codec/ttml/ttml.c
index 1874530..582cdb2 100644
--- a/modules/codec/ttml/ttml.c
+++ b/modules/codec/ttml/ttml.c
@@ -77,8 +77,9 @@ static inline bool tt_ScanReset( unsigned *a, unsigned *b, unsigned *c, unsigned
     return false;
 }
 
-static int64_t tt_ParseTime( const char *s )
+static tt_time_t tt_ParseTime( const char *s )
 {
+    tt_time_t t = {-1, 0};
     unsigned h1 = 0, m1 = 0, s1 = 0, d1 = 0;
 
     if( sscanf( s, "%u:%u:%u%*[,.]%u", &h1, &m1, &s1, &d1 ) == 4 ||
@@ -89,21 +90,21 @@ static int64_t tt_ParseTime( const char *s )
                          tt_ScanReset( &h1, &m1, &s1, &d1 )      ||
         sscanf( s, "%us",                        &s1      ) == 1 )
     {
-        return ( (int64_t)h1 * 3600 * 1000 +
-                 (int64_t)m1 * 60 * 1000 +
-                 (int64_t)s1 * 1000 +
-                 (int64_t)d1 ) * 1000;
+        t.base = h1 * 3600 + m1 * 60 + s1;
+        t.frames = d1;
     }
 
-    return -1;
+    return t;
 }
 
-bool tt_timings_Contains( const tt_timings_t *p_range, int64_t i_time )
+bool tt_timings_Contains( const tt_timings_t *p_range, const tt_time_t *time )
 {
-    if( p_range->i_end != -1 && p_range->i_end <= i_time )
+    if( tt_time_Valid( &p_range->end ) &&
+        tt_time_Compare( &p_range->end, time ) <= 0 )
         return false;
 
-    if( p_range->i_begin != -1 && p_range->i_begin > i_time )
+    if( tt_time_Valid( &p_range->begin ) &&
+        tt_time_Compare( &p_range->begin, time ) > 0 )
         return false;
 
     return true;
@@ -178,9 +179,9 @@ tt_node_t * tt_node_New( xml_reader_t* reader, tt_node_t* p_parent, const char*
         return NULL;
     }
     vlc_dictionary_init( &p_node->attr_dict, 0 );
-    p_node->timings.i_begin = -1;
-    p_node->timings.i_end = -1;
-    p_node->timings.i_dur = -1;
+    tt_time_Init( &p_node->timings.begin );
+    tt_time_Init( &p_node->timings.end );
+    tt_time_Init( &p_node->timings.dur );
     p_node->p_parent = p_parent;
     if( p_parent )
         tt_node_ParentAddChild( p_parent, (tt_basenode_t *) p_node );
@@ -196,11 +197,11 @@ tt_node_t * tt_node_New( xml_reader_t* reader, tt_node_t* p_parent, const char*
             vlc_dictionary_insert( &p_node->attr_dict, psz_key, psz_val );
 
             if( !strcasecmp( psz_key, "begin" ) )
-                p_node->timings.i_begin = tt_ParseTime( psz_val );
+                p_node->timings.begin = tt_ParseTime( psz_val );
             else if( ! strcasecmp( psz_key, "end" ) )
-                p_node->timings.i_end = tt_ParseTime( psz_val );
+                p_node->timings.end = tt_ParseTime( psz_val );
             else if( ! strcasecmp( psz_key, "dur" ) )
-                p_node->timings.i_dur = tt_ParseTime( psz_val );
+                p_node->timings.dur = tt_ParseTime( psz_val );
             else if( ! strcasecmp( psz_key, "timeContainer" ) )
                 p_node->timings.i_type = strcmp( psz_val, "seq" ) ? TT_TIMINGS_PARALLEL
                                                                   : TT_TIMINGS_SEQUENTIAL;
@@ -332,46 +333,46 @@ int tt_nodes_Read( xml_reader_t *p_reader, tt_node_t *p_root_node )
 static int tt_bsearch_searchkey_Compare( const void *key, const void *other )
 {
     struct tt_searchkey *p_key = (struct tt_searchkey *) key;
-    int64_t i_time = *((int64_t *) other);
-    p_key->p_last = (int64_t *) other;
-    return ( p_key->i_time >= i_time ) ? p_key->i_time - i_time : -1;
+    tt_time_t time = *((tt_time_t *) other);
+    p_key->p_last = (tt_time_t *) other;
+    return tt_time_Compare( &p_key->time, &time );
 }
 
-size_t tt_timings_FindLowerIndex( const int64_t *p_times, size_t i_times, int64_t i_time, bool *pb_found )
+size_t tt_timings_FindLowerIndex( const tt_time_t *p_times, size_t i_times, tt_time_t time, bool *pb_found )
 {
     size_t i_index = 0;
     if( p_times )
     {
         struct tt_searchkey key;
-        key.i_time = i_time;
+        key.time = time;
         key.p_last = NULL;
 
-        int64_t *lookup = bsearch( &key, p_times, i_times,
-                                   sizeof(int64_t), tt_bsearch_searchkey_Compare );
+        tt_time_t *lookup = bsearch( &key, p_times, i_times,
+                                     sizeof(tt_time_t), tt_bsearch_searchkey_Compare );
         if( lookup )
             key.p_last = lookup;
         *pb_found = !!lookup;
 
         /* Compute index from last visited */
         i_index = (key.p_last - p_times);
-        if( p_times[i_index] < i_time )
+        if( tt_time_Compare( &p_times[i_index], &time ) < 0 )
             i_index++;
     }
     else *pb_found = false;
     return i_index;
 }
 
-static void tt_bsearch_Insert( int64_t **pp_times, size_t *pi_times, int64_t i_time )
+static void tt_bsearch_Insert( tt_time_t **pp_times, size_t *pi_times, tt_time_t time )
 {
     bool b_exists;
-    size_t i_index = tt_timings_FindLowerIndex( *pp_times, *pi_times, i_time, &b_exists );
+    size_t i_index = tt_timings_FindLowerIndex( *pp_times, *pi_times, time, &b_exists );
     if( b_exists )
         return;
 
-    if( SIZE_MAX / sizeof(int64_t) < (*pi_times + 1) )
+    if( SIZE_MAX / sizeof(tt_time_t) < (*pi_times + 1) )
         return;
 
-    int64_t *p_array = realloc( *pp_times, (*pi_times + 1) * sizeof(int64_t) );
+    tt_time_t *p_array = realloc( *pp_times, (*pi_times + 1) * sizeof(tt_time_t) );
     if( !p_array )
         return;
     *pp_times = p_array;
@@ -380,10 +381,10 @@ static void tt_bsearch_Insert( int64_t **pp_times, size_t *pi_times, int64_t i_t
     {
         memmove( &p_array[i_index + 1],
                  &p_array[i_index],
-                 (*pi_times - i_index) * sizeof(int64_t) );
+                 (*pi_times - i_index) * sizeof(tt_time_t) );
     }
 
-    p_array[i_index] = i_time;
+    p_array[i_index] = time;
     *pi_times += 1;
 }
 
@@ -391,58 +392,59 @@ static void tt_bsearch_Insert( int64_t **pp_times, size_t *pi_times, int64_t i_t
 /* Timings storage */
 static void tt_timings_MergeParallel( const tt_timings_t *p_ref, tt_timings_t *p_local )
 {
-    if( p_local->i_begin != -1 )
-        p_local->i_begin += p_ref->i_begin;
+    if( tt_time_Valid( &p_local->begin ) )
+        p_local->begin = tt_time_Add( p_local->begin, p_ref->begin );
     else
-        p_local->i_begin = p_ref->i_begin;
+        p_local->begin = p_ref->begin;
 
-    if( p_local->i_end != -1 )
+    if( tt_time_Valid( &p_local->end ) )
     {
-        p_local->i_end += p_ref->i_begin;
+        p_local->end = tt_time_Add( p_local->end, p_ref->begin );
     }
-    else if( p_local->i_dur != -1 && p_local->i_begin != -1 )
+    else if( tt_time_Valid( &p_local->dur ) && tt_time_Valid( &p_local->begin ) )
     {
-        p_local->i_end = p_local->i_begin + p_local->i_dur;
+        p_local->end = tt_time_Add( p_local->begin, p_local->dur );
     }
-    else p_local->i_end = p_ref->i_end;
+    else p_local->end = p_ref->end;
 
     /* Enforce contained duration */
-    if( p_ref->i_end != -1 && p_local->i_end > p_ref->i_end )
-        p_local->i_end = p_ref->i_end;
+
+    if( tt_time_Valid( &p_ref->end ) && tt_time_Compare( &p_local->end, &p_ref->end ) > 0 )
+        p_local->end = p_ref->end;
 
     /* Just for consistency */
-    if( p_local->i_begin != -1 && p_local->i_end != -1 )
-        p_local->i_dur = p_local->i_end - p_local->i_begin;
+    if( tt_time_Valid( &p_local->begin ) && tt_time_Valid( &p_local->end ) )
+        p_local->dur = tt_time_Sub( p_local->end, p_local->begin );
 }
 
 static void tt_timings_MergeSequential( const tt_timings_t *p_restrict,
                                        const tt_timings_t *p_prevref, tt_timings_t *p_local )
 {
-    if( p_local->i_begin != -1 )
-        p_local->i_begin += p_prevref->i_end;
+    if( tt_time_Valid( &p_local->begin ) )
+        p_local->begin = tt_time_Add( p_local->begin, p_prevref->end );
     else
-        p_local->i_begin = p_prevref->i_end;
+        p_local->begin = p_prevref->end;
 
-    if( p_local->i_end != -1 )
+    if( tt_time_Valid( &p_local->end ) )
     {
-        p_local->i_end += p_prevref->i_end;
+        p_local->end = tt_time_Add( p_local->end, p_prevref->end );
     }
-    else if( p_local->i_dur != -1 && p_local->i_begin != -1 )
+    else if( tt_time_Valid( &p_local->dur ) && tt_time_Valid( &p_local->begin ) )
     {
-        p_local->i_end = p_local->i_begin + p_local->i_dur;
+        p_local->end = tt_time_Add( p_local->begin, p_local->dur );
     }
 
     /* Enforce contained duration */
-    if( p_restrict->i_end != -1 && p_local->i_end > p_restrict->i_end )
-        p_local->i_end = p_restrict->i_end;
+    if( tt_time_Valid( &p_restrict->end ) && tt_time_Compare( &p_local->end, &p_restrict->end ) > 0 )
+        p_local->end = p_restrict->end;
 
     /* Just for consistency */
-    if( p_local->i_begin != -1 && p_local->i_end != -1 )
-        p_local->i_dur = p_local->i_end - p_local->i_begin;
+    if( tt_time_Valid( &p_local->begin ) && tt_time_Valid( &p_local->end ) )
+        p_local->dur = tt_time_Sub( p_local->end, p_local->begin );
 }
 
 void tt_timings_Resolve( tt_basenode_t *p_child, const tt_timings_t *p_container_timings,
-                         int64_t **pp_array, size_t *pi_count )
+                         tt_time_t **pp_array, size_t *pi_count )
 {
     const tt_node_t *p_prevnode = NULL;
     for(  ; p_child; p_child = p_child->p_next )
@@ -464,11 +466,11 @@ void tt_timings_Resolve( tt_basenode_t *p_child, const tt_timings_t *p_container
             tt_timings_MergeParallel( p_container_timings, &p_childnode->timings );
         }
 
-        if( p_childnode->timings.i_begin != -1 )
-            tt_bsearch_Insert( pp_array, pi_count, p_childnode->timings.i_begin );
+        if( tt_time_Valid( &p_childnode->timings.begin ) )
+            tt_bsearch_Insert( pp_array, pi_count, p_childnode->timings.begin );
 
-        if( p_childnode->timings.i_end != -1 )
-            tt_bsearch_Insert( pp_array, pi_count, p_childnode->timings.i_end );
+        if( tt_time_Valid( &p_childnode->timings.end ) )
+            tt_bsearch_Insert( pp_array, pi_count, p_childnode->timings.end );
 
         p_prevnode = p_childnode;
 
diff --git a/modules/codec/ttml/ttml.h b/modules/codec/ttml/ttml.h
index f842d2e..c2dc4dc 100644
--- a/modules/codec/ttml/ttml.h
+++ b/modules/codec/ttml/ttml.h
@@ -31,18 +31,27 @@ enum
     TT_TIMINGS_SEQUENTIAL,
 };
 
+#define TT_FRAME_RATE 30
+
+typedef struct
+{
+    time_t base;
+    unsigned frames;
+    //unsigned ticks;
+} tt_time_t;
+
 typedef struct
 {
     uint8_t i_type;
-    int64_t i_begin;
-    int64_t i_end;
-    int64_t i_dur;
+    tt_time_t begin;
+    tt_time_t end;
+    tt_time_t dur;
 } tt_timings_t;
 
 struct tt_searchkey
 {
-    int64_t i_time;
-    int64_t *p_last;
+    tt_time_t time;
+    tt_time_t *p_last;
 };
 
 enum
@@ -87,10 +96,60 @@ bool tt_node_HasChild( const tt_node_t *p_node );
 int tt_nodes_Read( xml_reader_t *p_reader, tt_node_t *p_root_node );
 
 void tt_timings_Resolve( tt_basenode_t *p_child, const tt_timings_t *p_container_timings,
-                         int64_t **pp_array, size_t *pi_count );
-bool tt_timings_Contains( const tt_timings_t *p_range, int64_t i_time );
-size_t tt_timings_FindLowerIndex( const int64_t *p_times, size_t i_times, int64_t i_time, bool *pb_found );
+                         tt_time_t **pp_array, size_t *pi_count );
+bool tt_timings_Contains( const tt_timings_t *p_range, const tt_time_t * );
+size_t tt_timings_FindLowerIndex( const tt_time_t *p_times, size_t i_times, tt_time_t time, bool *pb_found );
 
+static inline void tt_time_Init( tt_time_t *t )
+{
+    t->base = -1;
+    t->frames = 0;
+}
 
+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;
+    return t;
+}
 
+static inline bool tt_time_Valid( const tt_time_t *t )
+{
+    return t->base != -1;
+}
 
+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;
+}
+
+static inline mtime_t tt_time_Compare( const tt_time_t *t1, const tt_time_t *t2 )
+{
+    return tt_time_Convert( t1 ) - tt_time_Convert( t2 );
+}
+
+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.frames = t1.frames % TT_FRAME_RATE;
+    return t1;
+}
+
+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.frames += diff * TT_FRAME_RATE;
+    }
+    t1.frames -= t2.frames;
+    t1.base -= t2.base;
+    return t1;
+}
diff --git a/modules/demux/ttml.c b/modules/demux/ttml.c
index d99653b..2019586 100644
--- a/modules/demux/ttml.c
+++ b/modules/demux/ttml.c
@@ -60,26 +60,24 @@ struct demux_sys_t
     */
     struct
     {
-        int64_t *p_array;
+        tt_time_t *p_array;
         size_t   i_count;
         size_t   i_current;
     } times;
 };
 
-static char *tt_genTiming( int64_t i_time )
+static char *tt_genTiming( tt_time_t t )
 {
-    if( i_time < 0 )
-        i_time = 0;
+    if( !tt_time_Valid( &t ) )
+        t.base = 0;
 
-    unsigned f = (i_time % CLOCK_FREQ) / 10000;
-    i_time /= CLOCK_FREQ;
-    unsigned h = i_time / 3600;
-    unsigned m = i_time % 3600 / 60;
-    unsigned s = i_time % 60;
+    unsigned h = t.base / 3600;
+    unsigned m = t.base % 3600 / 60;
+    unsigned s = t.base % 60;
 
     char *psz;
-    if( asprintf( &psz, "%2.2u:%2.2u:%2.2u.%2.2u",
-                        h, m, s, f ) < 0 )
+    if( asprintf( &psz, "%2.2u:%2.2u:%2.2u.%u",
+                        h, m, s, t.frames ) < 0 )
         psz = NULL;
 
     return psz;
@@ -124,16 +122,16 @@ static void tt_node_AttributesToText( struct vlc_memstream *p_stream, const tt_n
 
     if( b_timed_node )
     {
-        if( p_node->timings.i_begin != -1 )
+        if( tt_time_Valid( &p_node->timings.begin ) )
         {
-            char *psz = tt_genTiming( p_node->timings.i_begin );
+            char *psz = tt_genTiming( p_node->timings.begin );
             vlc_memstream_printf( p_stream, " begin=\"%s\"", psz );
             free( psz );
         }
 
-        if( p_node->timings.i_end != -1 )
+        if( tt_time_Valid( &p_node->timings.end ) )
         {
-            char *psz = tt_genTiming( p_node->timings.i_end );
+            char *psz = tt_genTiming( p_node->timings.end );
             vlc_memstream_printf( p_stream, " end=\"%s\"", psz );
             free( psz );
         }
@@ -141,14 +139,14 @@ static void tt_node_AttributesToText( struct vlc_memstream *p_stream, const tt_n
 }
 
 static void tt_node_ToText( struct vlc_memstream *p_stream, const tt_basenode_t *p_basenode,
-                            int64_t i_playbacktime )
+                            const tt_time_t *playbacktime )
 {
     if( p_basenode->i_type == TT_NODE_TYPE_ELEMENT )
     {
         const tt_node_t *p_node = (const tt_node_t *) p_basenode;
 
-        if( i_playbacktime != -1 &&
-           !tt_timings_Contains( &p_node->timings, i_playbacktime ) )
+        if( tt_time_Valid( playbacktime ) &&
+           !tt_timings_Contains( &p_node->timings, playbacktime ) )
             return;
 
         vlc_memstream_putc( p_stream, '<' );
@@ -162,14 +160,14 @@ static void tt_node_ToText( struct vlc_memstream *p_stream, const tt_basenode_t
 
 #ifdef TTML_DEMUX_DEBUG
             vlc_memstream_printf( p_stream, "<!-- starts %ld ends %ld -->",
-                                  p_node->timings.i_begin,
-                                  p_node->timings.i_end );
+                                  tt_time_Convert( &p_node->timings.begin ),
+                                  tt_time_Convert( &p_node->timings.end ) );
 #endif
 
             for( const tt_basenode_t *p_child = p_node->p_child;
                                    p_child; p_child = p_child->p_next )
             {
-                tt_node_ToText( p_stream, p_child, i_playbacktime );
+                tt_node_ToText( p_stream, p_child, playbacktime );
             }
 
             vlc_memstream_printf( p_stream, "</%s>", p_node->psz_node_name );
@@ -204,8 +202,9 @@ static int Control( demux_t* p_demux, int i_query, va_list args )
             i64 = (int64_t)va_arg( args, int64_t );
             if( p_sys->times.i_count )
             {
+                tt_time_t t = tt_time_Create( i64 - VLC_TS_0 );
                 size_t i_index = tt_timings_FindLowerIndex( p_sys->times.p_array,
-                                                            p_sys->times.i_count, i64, &b );
+                                                            p_sys->times.i_count, t, &b );
                 p_sys->times.i_current = i_index;
                 p_sys->b_first_time = true;
                 return VLC_SUCCESS;
@@ -220,8 +219,9 @@ static int Control( demux_t* p_demux, int i_query, va_list args )
             pi64 = (int64_t*)va_arg( args, int64_t * );
             if( p_sys->times.i_count )
             {
-                *pi64 = p_sys->times.p_array[p_sys->times.i_count - 1] -
-                        p_sys->temporal_extent.i_begin;
+                tt_time_t t = tt_time_Sub( p_sys->times.p_array[p_sys->times.i_count - 1],
+                                           p_sys->temporal_extent.begin );
+                *pi64 = tt_time_Convert( &t );
                 return VLC_SUCCESS;
             }
             break;
@@ -233,8 +233,8 @@ static int Control( demux_t* p_demux, int i_query, va_list args )
             }
             else if( p_sys->times.i_count > 0 )
             {
-                *pf = (double) p_sys->i_next_demux_time /
-                      (p_sys->times.p_array[p_sys->times.i_count - 1] + 0.5);
+                i64 = tt_time_Convert( &p_sys->times.p_array[p_sys->times.i_count - 1] );
+                *pf = (double) p_sys->i_next_demux_time / (i64 + 0.5);
             }
             else
             {
@@ -245,9 +245,10 @@ static int Control( demux_t* p_demux, int i_query, va_list args )
             f = (double)va_arg( args, double );
             if( p_sys->times.i_count )
             {
-                i64 = f * p_sys->times.p_array[p_sys->times.i_count - 1];
+                i64 = f * tt_time_Convert( &p_sys->times.p_array[p_sys->times.i_count - 1] );
+                tt_time_t t = tt_time_Create( i64 );
                 size_t i_index = tt_timings_FindLowerIndex( p_sys->times.p_array,
-                                                            p_sys->times.i_count, i64, &b );
+                                                            p_sys->times.i_count, t, &b );
                 p_sys->times.i_current = i_index;
                 p_sys->b_first_time = true;
                 return VLC_SUCCESS;
@@ -319,10 +320,12 @@ static int Demux( demux_t* p_demux )
 
     /* Last one must be an end time */
     while( p_sys->times.i_current + 1 < p_sys->times.i_count &&
-           p_sys->times.p_array[p_sys->times.i_current] <= p_sys->i_next_demux_time )
+           tt_time_Convert( &p_sys->times.p_array[p_sys->times.i_current] ) <= p_sys->i_next_demux_time )
     {
-        const int64_t i_playbacktime = p_sys->times.p_array[p_sys->times.i_current];
-        const int64_t i_playbackendtime = p_sys->times.p_array[p_sys->times.i_current + 1] - 1;
+        const int64_t i_playbacktime =
+                tt_time_Convert( &p_sys->times.p_array[p_sys->times.i_current] );
+        const int64_t i_playbackendtime =
+                tt_time_Convert( &p_sys->times.p_array[p_sys->times.i_current + 1] ) - 1;
 
         if ( !p_sys->b_slave && p_sys->b_first_time )
         {
@@ -335,7 +338,8 @@ static int Demux( demux_t* p_demux )
         if( vlc_memstream_open( &stream ) )
             return VLC_DEMUXER_EGENERIC;
 
-        tt_node_ToText( &stream, (tt_basenode_t *) p_sys->p_rootnode, i_playbacktime );
+        tt_node_ToText( &stream, (tt_basenode_t *) p_sys->p_rootnode,
+                        &p_sys->times.p_array[p_sys->times.i_current] );
 
         if( vlc_memstream_close( &stream ) == VLC_SUCCESS )
         {
@@ -396,9 +400,10 @@ int OpenDemux( vlc_object_t* p_this )
 
     p_sys->b_first_time = true;
     p_sys->temporal_extent.i_type = TT_TIMINGS_PARALLEL;
-    p_sys->temporal_extent.i_begin = 0;
-    p_sys->temporal_extent.i_end = -1;
-    p_sys->temporal_extent.i_dur = -1;
+    tt_time_Init( &p_sys->temporal_extent.begin );
+    tt_time_Init( &p_sys->temporal_extent.end );
+    tt_time_Init( &p_sys->temporal_extent.dur );
+    p_sys->temporal_extent.begin.base = 0;
 
     p_sys->p_xml = xml_Create( p_demux );
     if( !p_sys->p_xml )
@@ -425,7 +430,9 @@ int OpenDemux( vlc_object_t* p_this )
         if( vlc_memstream_open( &stream ) )
             goto error;
 
-        tt_node_ToText( &stream, (tt_basenode_t*)p_sys->p_rootnode, -1 );
+        tt_time_t t;
+        tt_time_Init( &t );
+        tt_node_ToText( &stream, (tt_basenode_t*)p_sys->p_rootnode, &t /* invalid */ );
 
         vlc_memstream_putc( &stream, '\0' );
 



More information about the vlc-commits mailing list