[vlc-commits] codec: webvtt: parent everything to video pseudo node

Francois Cartegnie git at videolan.org
Mon Oct 30 13:42:38 CET 2017


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Oct 30 10:32:14 2017 +0100| [4d9fea5eea0f6bb098045a38801d8755518f1525] | committer: Francois Cartegnie

codec: webvtt: parent everything to video pseudo node

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

 modules/codec/webvtt/subsvtt.c | 186 +++++++++++++++++++++++------------------
 1 file changed, 104 insertions(+), 82 deletions(-)

diff --git a/modules/codec/webvtt/subsvtt.c b/modules/codec/webvtt/subsvtt.c
index 92d7884405..7dc6153750 100644
--- a/modules/codec/webvtt/subsvtt.c
+++ b/modules/codec/webvtt/subsvtt.c
@@ -83,6 +83,7 @@ enum webvtt_node_type_e
     NODE_TEXT,
     NODE_CUE,
     NODE_REGION,
+    NODE_VIDEO,
 };
 
 #define WEBVTT_NODE_BASE_MEMBERS \
@@ -129,6 +130,12 @@ typedef struct
     webvtt_dom_node_t *p_child;
 } webvtt_dom_tag_t;
 
+typedef struct
+{
+    WEBVTT_NODE_BASE_MEMBERS
+    webvtt_dom_node_t *p_child;
+} webvtt_dom_video_t;
+
 struct webvtt_dom_node_t
 {
     WEBVTT_NODE_BASE_MEMBERS
@@ -136,8 +143,7 @@ struct webvtt_dom_node_t
 
 struct decoder_sys_t
 {
-    webvtt_region_t *p_regions;
-    webvtt_dom_cue_t *p_regionless_cues;
+    webvtt_dom_video_t *p_root;
 };
 
 #define ATOM_iden VLC_FOURCC('i', 'd', 'e', 'n')
@@ -333,6 +339,12 @@ static void webvtt_domnode_ChainDelete( webvtt_dom_node_t *p_node );
 static void webvtt_dom_cue_Delete( webvtt_dom_cue_t *p_cue );
 static void webvtt_region_Delete( webvtt_region_t *p_region );
 
+static void webvtt_dom_video_Delete( webvtt_dom_video_t *p_node )
+{
+    webvtt_domnode_ChainDelete( p_node->p_child );
+    free( p_node );
+}
+
 static void webvtt_dom_text_Delete( webvtt_dom_text_t *p_node )
 {
     free( p_node->psz_text );
@@ -372,11 +384,21 @@ static void webvtt_domnode_ChainDelete( webvtt_dom_node_t *p_node )
             webvtt_dom_cue_Delete( (webvtt_dom_cue_t *) p_node );
         else if( p_node->type == NODE_REGION )
             webvtt_region_Delete( (webvtt_region_t *) p_node );
+        else if( p_node->type == NODE_VIDEO )
+            webvtt_dom_video_Delete( (webvtt_dom_video_t *) p_node );
 
         p_node = p_next;
     }
 }
 
+static webvtt_dom_video_t * webvtt_dom_video_New( void )
+{
+    webvtt_dom_video_t *p_node = calloc( 1, sizeof(*p_node) );
+    if( p_node )
+        p_node->type = NODE_VIDEO;
+    return p_node;
+}
+
 static webvtt_dom_text_t * webvtt_dom_text_New( webvtt_dom_node_t *p_parent )
 {
     webvtt_dom_text_t *p_node = calloc( 1, sizeof(*p_node) );
@@ -607,7 +629,6 @@ static void ClearCuesByTime( webvtt_dom_node_t **pp_next, mtime_t i_time )
         webvtt_dom_node_t *p_node = *pp_next;
         if( p_node )
         {
-            assert( p_node->type == NODE_CUE );
             if( p_node->type == NODE_CUE )
             {
                 webvtt_dom_cue_t *p_cue = (webvtt_dom_cue_t *)p_node;
@@ -696,11 +717,17 @@ static webvtt_region_t * webvtt_region_New( void )
 static webvtt_region_t * webvtt_region_GetByID( decoder_sys_t *p_sys,
                                                 const char *psz_id )
 {
-    for( webvtt_region_t *p_region = p_sys->p_regions; p_region && psz_id;
-                          p_region = (webvtt_region_t *) p_region->p_next )
+    if( !psz_id )
+        return NULL;
+    for( webvtt_dom_node_t *p_node = p_sys->p_root->p_child;
+                            p_node; p_node = p_node->p_next )
     {
-        if( !strcmp( psz_id, p_region->psz_id ) )
-            return p_region;
+        if( p_node->type == NODE_REGION )
+        {
+            webvtt_region_t *p_region = (webvtt_region_t *) p_node;
+            if( p_region->psz_id && !strcmp( psz_id, p_region->psz_id ) )
+                return p_region;
+        }
     }
     return NULL;
 }
@@ -796,19 +823,6 @@ static webvtt_dom_node_t * CreateDomNodes( const char *psz_text, unsigned *pi_li
     return p_head;
 }
 
-static void ExpireCues( decoder_t *p_dec, mtime_t i_time )
-{
-    decoder_sys_t *p_sys = p_dec->p_sys;
-    for( webvtt_region_t *p_vttregion = p_sys->p_regions; p_vttregion;
-                          p_vttregion = (webvtt_region_t *) p_vttregion->p_next )
-    {
-        assert( p_vttregion->type == NODE_REGION );
-        ClearCuesByTime( &p_vttregion->p_child, i_time );
-    }
-
-    ClearCuesByTime( (webvtt_dom_node_t **) &p_sys->p_regionless_cues, i_time );
-}
-
 static void ProcessCue( decoder_t *p_dec, const char *psz, webvtt_dom_cue_t *p_cue )
 {
     VLC_UNUSED(p_dec);
@@ -991,67 +1005,70 @@ static void RenderRegions( decoder_t *p_dec, mtime_t i_start, mtime_t i_stop )
     subpicture_t *p_spu = NULL;
     subpicture_updater_sys_region_t *p_updtregion = NULL;
 
-    for( const webvtt_region_t *p_vttregion = p_dec->p_sys->p_regions; p_vttregion;
-                                p_vttregion = (const webvtt_region_t *) p_vttregion->p_next )
+    for( const webvtt_dom_node_t *p_node = p_dec->p_sys->p_root->p_child;
+                                  p_node; p_node = p_node->p_next )
     {
-        /* Variables */
-        struct render_variables_s v;
-        v.p_region = p_vttregion;
-        v.i_left_offset = p_vttregion->anchor_x * p_vttregion->f_width;
-        v.i_left = p_vttregion->viewport_anchor_x - v.i_left_offset;
-        v.i_top_offset = p_vttregion->anchor_y * p_vttregion->i_lines_max_scroll *
-                         WEBVTT_DEFAULT_LINE_HEIGHT_VH / 100.0;
-        v.i_top = p_vttregion->viewport_anchor_y - v.i_top_offset;
-        /* !Variables */
-
-        text_segment_t *p_segments =
-                ConvertCuesToSegments( p_dec, i_start, i_stop, &v,
-                                      (const webvtt_dom_cue_t *)p_vttregion->p_child );
-        if( !p_segments )
-            continue;
-
-        CreateSpuOrNewUpdaterRegion( p_dec, &p_spu, &p_updtregion );
-        if( !p_spu || !p_updtregion )
+        if( p_node->type == NODE_REGION )
         {
-            text_segment_ChainDelete( p_segments );
-            continue;
-        }
-
-        p_updtregion->align = SUBPICTURE_ALIGN_TOP|SUBPICTURE_ALIGN_LEFT;
-        p_updtregion->origin.x = v.i_left;
-        p_updtregion->origin.y = v.i_top;
-        p_updtregion->extent.x = p_vttregion->f_width;
+            const webvtt_region_t *p_vttregion = (const webvtt_region_t *) p_node;
+            /* Variables */
+            struct render_variables_s v;
+            v.p_region = p_vttregion;
+            v.i_left_offset = p_vttregion->anchor_x * p_vttregion->f_width;
+            v.i_left = p_vttregion->viewport_anchor_x - v.i_left_offset;
+            v.i_top_offset = p_vttregion->anchor_y * p_vttregion->i_lines_max_scroll *
+                             WEBVTT_DEFAULT_LINE_HEIGHT_VH / 100.0;
+            v.i_top = p_vttregion->viewport_anchor_y - v.i_top_offset;
+            /* !Variables */
+
+            text_segment_t *p_segments =
+                    ConvertCuesToSegments( p_dec, i_start, i_stop, &v,
+                                          (const webvtt_dom_cue_t *)p_vttregion->p_child );
+            if( !p_segments )
+                continue;
 
-        p_updtregion->flags = UPDT_REGION_ORIGIN_X_IS_RATIO|UPDT_REGION_ORIGIN_Y_IS_RATIO
-                            | UPDT_REGION_EXTENT_X_IS_RATIO;
-        p_updtregion->p_segments = p_segments;
-    }
+            CreateSpuOrNewUpdaterRegion( p_dec, &p_spu, &p_updtregion );
+            if( !p_spu || !p_updtregion )
+            {
+                text_segment_ChainDelete( p_segments );
+                continue;
+            }
 
-    for( const webvtt_dom_cue_t *p_cue = p_dec->p_sys->p_regionless_cues; p_cue;
-                                 p_cue = (const webvtt_dom_cue_t *) p_cue->p_next )
-    {
-        /* Variables */
-        struct render_variables_s v;
-        v.p_region = NULL;
-        v.i_left_offset = 0.0;
-        v.i_left = 0.0;
-        v.i_top_offset = 0.0;
-        v.i_top = 0.0;
-        /* !Variables */
-
-        text_segment_t *p_segments = ConvertCuesToSegments( p_dec, i_start, i_stop, &v, p_cue );
-        if( !p_segments )
-            continue;
+            p_updtregion->align = SUBPICTURE_ALIGN_TOP|SUBPICTURE_ALIGN_LEFT;
+            p_updtregion->origin.x = v.i_left;
+            p_updtregion->origin.y = v.i_top;
+            p_updtregion->extent.x = p_vttregion->f_width;
 
-        CreateSpuOrNewUpdaterRegion( p_dec, &p_spu, &p_updtregion );
-        if( !p_spu || !p_updtregion )
-        {
-            text_segment_ChainDelete( p_segments );
-            continue;
+            p_updtregion->flags = UPDT_REGION_ORIGIN_X_IS_RATIO|UPDT_REGION_ORIGIN_Y_IS_RATIO
+                                | UPDT_REGION_EXTENT_X_IS_RATIO;
+            p_updtregion->p_segments = p_segments;
         }
+        else if( p_node->type == NODE_CUE ) /* regionless cues */
+        {
+            const webvtt_dom_cue_t *p_cue = (const webvtt_dom_cue_t *) p_node;
+            /* Variables */
+            struct render_variables_s v;
+            v.p_region = NULL;
+            v.i_left_offset = 0.0;
+            v.i_left = 0.0;
+            v.i_top_offset = 0.0;
+            v.i_top = 0.0;
+            /* !Variables */
+
+            text_segment_t *p_segments = ConvertCuesToSegments( p_dec, i_start, i_stop, &v, p_cue );
+            if( !p_segments )
+                continue;
+
+            CreateSpuOrNewUpdaterRegion( p_dec, &p_spu, &p_updtregion );
+            if( !p_spu || !p_updtregion )
+            {
+                text_segment_ChainDelete( p_segments );
+                continue;
+            }
 
-        p_updtregion->align = SUBPICTURE_ALIGN_BOTTOM;
-        p_updtregion->p_segments = p_segments;
+            p_updtregion->align = SUBPICTURE_ALIGN_BOTTOM;
+            p_updtregion->p_segments = p_segments;
+        }
     }
 
     if( p_spu )
@@ -1118,7 +1135,8 @@ static int ProcessISOBMFF( decoder_t *p_dec,
             }
             else
             {
-                webvtt_domnode_AppendLast( &p_dec->p_sys->p_regionless_cues, p_cue );
+                webvtt_domnode_AppendLast( &p_dec->p_sys->p_root->p_child, p_cue );
+                p_cue->p_parent = (webvtt_dom_node_t *) p_dec->p_sys->p_root;
             }
         }
     }
@@ -1144,7 +1162,8 @@ static void ParserHeaderHandler( void *priv, enum webvtt_header_line_e s,
         {
             if( ctx->p_region->psz_id )
             {
-                webvtt_domnode_AppendLast( &p_sys->p_regions, ctx->p_region );
+                webvtt_domnode_AppendLast( &p_sys->p_root->p_child, ctx->p_region );
+                ctx->p_region->p_parent = (webvtt_dom_node_t *) p_sys->p_root;
                 msg_Dbg( p_dec, "added new region %s", ctx->p_region->psz_id );
             }
             /* incomplete region decl (no id at least) */
@@ -1203,9 +1222,9 @@ static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
         return VLCDEC_SUCCESS;
 
     if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
-        ExpireCues( p_dec, INT64_MAX );
+        ClearCuesByTime( &p_dec->p_sys->p_root->p_child, INT64_MAX );
     else
-        ExpireCues( p_dec, p_block->i_dts );
+        ClearCuesByTime( &p_dec->p_sys->p_root->p_child, p_block->i_dts );
 
     ProcessISOBMFF( p_dec, p_block->p_buffer, p_block->i_buffer,
                     p_block->i_pts, p_block->i_pts + p_block->i_length );
@@ -1224,8 +1243,7 @@ void CloseDecoder( vlc_object_t *p_this )
     decoder_t *p_dec = (decoder_t *)p_this;
     decoder_sys_t *p_sys = p_dec->p_sys;
 
-    webvtt_domnode_ChainDelete( (webvtt_dom_node_t *) p_sys->p_regions );
-    webvtt_domnode_ChainDelete( (webvtt_dom_node_t *) p_sys->p_regionless_cues );
+    webvtt_domnode_ChainDelete( (webvtt_dom_node_t *) p_sys->p_root );
 
     free( p_sys );
 }
@@ -1246,8 +1264,12 @@ int OpenDecoder( vlc_object_t *p_this )
     if( unlikely( p_sys == NULL ) )
         return VLC_ENOMEM;
 
-    p_sys->p_regions = NULL;
-    p_sys->p_regionless_cues = NULL;
+    p_sys->p_root = webvtt_dom_video_New();
+    if( !p_sys->p_root )
+    {
+        free( p_sys );
+        return VLC_ENOMEM;
+    }
 
     p_dec->pf_decode = DecodeBlock;
 



More information about the vlc-commits mailing list