[vlc-commits] codec: substtml: handle set node

Francois Cartegnie git at videolan.org
Tue Feb 14 17:51:01 CET 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Feb 14 15:12:54 2017 +0100| [1eafa71b46312b575df60b2cc4e4c8e23bb254f8] | committer: Francois Cartegnie

codec: substtml: handle set node

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

 modules/codec/ttml/substtml.c | 89 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 76 insertions(+), 13 deletions(-)

diff --git a/modules/codec/ttml/substtml.c b/modules/codec/ttml/substtml.c
index c244e20..f78bd4a 100644
--- a/modules/codec/ttml/substtml.c
+++ b/modules/codec/ttml/substtml.c
@@ -113,6 +113,37 @@ static void ttml_region_Delete( ttml_region_t *p_region )
     free( p_region );
 }
 
+static ttml_style_t * ttml_style_Duplicate( const ttml_style_t *p_src )
+{
+    ttml_style_t *p_dup = ttml_style_New( );
+    if( p_dup )
+    {
+        *p_dup = *p_src;
+        p_dup->font_style = text_style_Duplicate( p_src->font_style );
+    }
+    return p_dup;
+}
+
+static void ttml_style_Merge( const ttml_style_t *p_src, ttml_style_t *p_dst )
+{
+    if( p_src && p_dst )
+    {
+        if( p_src->font_style )
+        {
+            if( p_dst->font_style )
+                text_style_Merge( p_dst->font_style, p_src->font_style, true );
+            else
+                p_dst->font_style = text_style_Duplicate( p_src->font_style );
+        }
+
+        if( p_src->b_direction_set )
+        {
+            p_dst->b_direction_set = true;
+            p_dst->i_direction = p_src->i_direction;
+        }
+    }
+}
+
 static ttml_region_t *ttml_region_New( )
 {
     ttml_region_t *p_ttml_region = calloc( 1, sizeof( ttml_region_t ) );
@@ -410,6 +441,18 @@ static void DictMergeWithRegionID( ttml_context_t *p_ctx, const char *psz_id,
     }
 }
 
+static void DictToTTMLStyle( const vlc_dictionary_t *p_dict, ttml_style_t *p_ttml_style )
+{
+    for( int i = 0; i < p_dict->i_size; ++i )
+    {
+        for ( vlc_dictionary_entry_t* p_entry = p_dict->p_entries[i];
+              p_entry != NULL; p_entry = p_entry->p_next )
+        {
+            FillTTMLStyle( p_entry->psz_key, p_entry->p_value, p_ttml_style );
+        }
+    }
+}
+
 static ttml_style_t * InheritTTMLStyles( ttml_context_t *p_ctx, tt_node_t *p_node )
 {
     assert( p_node );
@@ -435,14 +478,7 @@ static ttml_style_t * InheritTTMLStyles( ttml_context_t *p_ctx, tt_node_t *p_nod
 
     if( merged.i_size && merged.p_entries[0] && (p_ttml_style = ttml_style_New()) )
     {
-        for( int i = 0; i < merged.i_size; ++i )
-        {
-            for ( vlc_dictionary_entry_t* p_entry = merged.p_entries[i];
-                  p_entry != NULL; p_entry = p_entry->p_next )
-            {
-                FillTTMLStyle( p_entry->psz_key, p_entry->p_value, p_ttml_style );
-            }
-        }
+        DictToTTMLStyle( &merged, p_ttml_style );
     }
 
     vlc_dictionary_clear( &merged, NULL, NULL );
@@ -576,7 +612,7 @@ static void AppendLineBreakToRegion( ttml_region_t *p_region )
 }
 
 static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_ttnode,
-                                ttml_region_t *p_region )
+                                const ttml_style_t *p_set_styles, ttml_region_t *p_region )
 {
     text_segment_t *p_segment;
 
@@ -589,6 +625,9 @@ static void AppendTextToRegion( ttml_context_t *p_ctx, const tt_textnode_t *p_tt
         ttml_style_t *s = InheritTTMLStyles( p_ctx, p_ttnode->p_parent );
         if( s )
         {
+            if( p_set_styles )
+                ttml_style_Merge( p_set_styles, s );
+
             p_segment->style = s->font_style;
             s->font_style = NULL;
 
@@ -606,7 +645,9 @@ 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, int64_t i_playbacktime )
+                                         ttml_region_t *p_region,
+                                         const ttml_style_t *p_upper_set_styles,
+                                         int64_t i_playbacktime )
 {
     if( i_playbacktime != -1 &&
        !tt_timings_Contains( &p_node->timings, i_playbacktime ) )
@@ -626,12 +667,31 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
         AppendLineBreakToRegion( p_region );
     }
 
+    /* Styles from <set> element */
+    ttml_style_t *p_set_styles = (p_upper_set_styles)
+                               ? ttml_style_Duplicate( p_upper_set_styles )
+                               : NULL;
+
     for( const tt_basenode_t *p_child = p_node->p_child;
                               p_child; p_child = p_child->p_next )
     {
         if( p_child->i_type == TT_NODE_TYPE_TEXT )
         {
-            AppendTextToRegion( p_ctx, (const tt_textnode_t *) p_child, p_region );
+            AppendTextToRegion( p_ctx, (const tt_textnode_t *) p_child,
+                                p_set_styles, p_region );
+        }
+        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( p_set_styles != NULL || (p_set_styles = ttml_style_New()) )
+                {
+                    /* Merge with or create a local set of styles to apply to following childs */
+                    DictToTTMLStyle( &p_set->attr_dict, p_set_styles );
+                }
+            }
         }
         else if( !tt_node_NameCompare( ((const tt_node_t *)p_child)->psz_node_name, "br" ) )
         {
@@ -640,9 +700,12 @@ static void ConvertNodesToRegionContent( ttml_context_t *p_ctx, const tt_node_t
         else
         {
             ConvertNodesToRegionContent( p_ctx, (const tt_node_t *) p_child,
-                                         p_region, i_playbacktime );
+                                         p_region, p_set_styles, i_playbacktime );
         }
     }
+
+    if( p_set_styles )
+        ttml_style_Delete( p_set_styles );
 }
 
 static tt_node_t *ParseTTML( decoder_t *p_dec, const uint8_t *p_buffer, size_t i_buffer )
@@ -688,7 +751,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, i_playbacktime );
+            ConvertNodesToRegionContent( &context, p_bodynode, NULL, NULL, i_playbacktime );
 
             for( int i = 0; i < context.regions.i_size; ++i )
             {



More information about the vlc-commits mailing list