[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