vlc | branch: master | Francois Cartegnie <[email protected]> | Mon Jan 9 14:15:15 2017 +0100| [596292128ec25c923a99f30b4fa33b81e0b32f5b] | committer: Francois Cartegnie
substext: store multiple region info in updater > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=596292128ec25c923a99f30b4fa33b81e0b32f5b --- modules/codec/cc.c | 7 +- modules/codec/scte18.c | 4 +- modules/codec/subsdec.c | 4 +- modules/codec/substext.h | 188 +++++++++++++++++++++++++++++------------- modules/codec/substx3g.c | 4 +- modules/codec/ttml/substtml.c | 51 ++++++++++-- modules/codec/zvbi.c | 18 ++-- 7 files changed, 189 insertions(+), 87 deletions(-) diff --git a/modules/codec/cc.c b/modules/codec/cc.c index d78bb3b..3e8ef7b 100644 --- a/modules/codec/cc.c +++ b/modules/codec/cc.c @@ -434,10 +434,9 @@ static subpicture_t *Subtitle( decoder_t *p_dec, text_segment_t *p_segments, mti /* The "leavetext" alignment is a special mode where the subpicture region itself gets aligned, but the text inside it does not */ - p_spu_sys->align = SUBPICTURE_ALIGN_LEAVETEXT; - p_spu_sys->p_segments = p_segments; - p_spu_sys->noregionbg = true; - p_spu_sys->gridmode = true; + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_LEAVETEXT; + p_spu_sys->region.p_segments = p_segments; + p_spu_sys->region.flags = UPDT_REGION_IGNORE_BACKGROUND | UPDT_REGION_USES_GRID_COORDINATES; /* Set style defaults (will be added to segments if none set) */ p_spu_sys->p_default_style->i_style_flags |= STYLE_MONOSPACED; if( p_dec->p_sys->b_opaque ) diff --git a/modules/codec/scte18.c b/modules/codec/scte18.c index 884639f..79954a8 100644 --- a/modules/codec/scte18.c +++ b/modules/codec/scte18.c @@ -196,7 +196,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) p_spu->b_ephemer = true; p_spu->b_absolute = false; - p_spu_sys->align = SUBPICTURE_ALIGN_TOP; + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_TOP; p_spu_sys->p_default_style->i_style_flags = STYLE_BOLD | STYLE_BACKGROUND; p_spu_sys->p_default_style->i_features |= STYLE_HAS_FLAGS; p_spu_sys->p_default_style->i_background_color = 0x000000; @@ -205,7 +205,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) p_spu_sys->p_default_style->i_font_color = 0xFF0000; p_spu_sys->p_default_style->i_features |= STYLE_HAS_FONT_COLOR; - p_spu_sys->p_segments = text_segment_New( p_cea->psz_alert_text ); + p_spu_sys->region.p_segments = text_segment_New( p_cea->psz_alert_text ); } msg_Info( p_dec, "Received %s", p_cea->psz_alert_text ); scte18_cea_Free( p_cea ); diff --git a/modules/codec/subsdec.c b/modules/codec/subsdec.c index 7aaec5d..f75a152 100644 --- a/modules/codec/subsdec.c +++ b/modules/codec/subsdec.c @@ -459,8 +459,8 @@ static subpicture_t *ParseText( decoder_t *p_dec, block_t *p_block ) subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys; - p_spu_sys->align = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align; - p_spu_sys->p_segments = ParseSubtitles( &p_spu_sys->align, psz_subtitle ); + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align; + p_spu_sys->region.p_segments = ParseSubtitles( &p_spu_sys->region.inner_align, psz_subtitle ); free( psz_subtitle ); diff --git a/modules/codec/substext.h b/modules/codec/substext.h index 2fea88f..ceeea20 100644 --- a/modules/codec/substext.h +++ b/modules/codec/substext.h @@ -24,23 +24,71 @@ #include <vlc_strings.h> #include <vlc_text_style.h> -struct subpicture_updater_sys_t { +typedef struct subpicture_updater_sys_region_t subpicture_updater_sys_region_t; + +enum subpicture_updater_sys_region_flags_e +{ + UPDT_REGION_ORIGIN_X_IS_PERCENTILE = 1 << 0, + UPDT_REGION_ORIGIN_Y_IS_PERCENTILE = 1 << 1, + UPDT_REGION_EXTENT_X_IS_PERCENTILE = 1 << 2, + UPDT_REGION_EXTENT_Y_IS_PERCENTILE = 1 << 3, + UPDT_REGION_IGNORE_BACKGROUND = 1 << 4, + UPDT_REGION_USES_GRID_COORDINATES = 1 << 5, + UPDT_REGION_FIX_DONE = 1 << 31, +}; + +struct subpicture_updater_sys_region_t +{ + struct + { + int x; + int y; + } origin, extent; + /* store above percentile meanings as modifier flags */ + int flags; /* subpicture_updater_sys_region_flags_e */ + int align; /* alignment of the region itself */ + int inner_align; /* alignment of content inside the region */ + text_style_t *p_region_style; text_segment_t *p_segments; + subpicture_updater_sys_region_t *p_next; +}; - int align; - int x; - int y; +struct subpicture_updater_sys_t { - bool is_fixed; - int fixed_width; - int fixed_height; - bool noregionbg; - bool gridmode; + /* a min of one region */ + subpicture_updater_sys_region_t region; /* styling */ text_style_t *p_default_style; /* decoder (full or partial) defaults */ }; +static inline void SubpictureUpdaterSysRegionClean(subpicture_updater_sys_region_t *p_updtregion) +{ + text_segment_ChainDelete( p_updtregion->p_segments ); + text_style_Delete( p_updtregion->p_region_style ); +} + +static inline void SubpictureUpdaterSysRegionInit(subpicture_updater_sys_region_t *p_updtregion) +{ + memset(p_updtregion, 0, sizeof(*p_updtregion)); +} + +static inline subpicture_updater_sys_region_t *SubpictureUpdaterSysRegionNew( ) +{ + subpicture_updater_sys_region_t *p_region = malloc(sizeof(*p_region)); + if(p_region) + SubpictureUpdaterSysRegionInit(p_region); + return p_region; +} + +static inline void SubpictureUpdaterSysRegionAdd(subpicture_updater_sys_region_t *p_prev, + subpicture_updater_sys_region_t *p_new) +{ + subpicture_updater_sys_region_t **pp_next = &p_prev->p_next; + for(; *pp_next; pp_next = &(*pp_next)->p_next); + *pp_next = p_new; +} + static int SubpictureTextValidate(subpicture_t *subpic, bool has_src_changed, const video_format_t *fmt_src, bool has_dst_changed, const video_format_t *fmt_dst, @@ -51,16 +99,21 @@ static int SubpictureTextValidate(subpicture_t *subpic, if (!has_src_changed && !has_dst_changed) return VLC_SUCCESS; - if (!sys->is_fixed && subpic->b_absolute && subpic->p_region && - subpic->i_original_picture_width > 0 && - subpic->i_original_picture_height > 0) { - sys->is_fixed = true; - sys->x = subpic->p_region->i_x; - sys->y = subpic->p_region->i_y; - sys->fixed_width = subpic->i_original_picture_width; - sys->fixed_height = subpic->i_original_picture_height; + subpicture_updater_sys_region_t *p_updtregion = &sys->region; + + if (!(p_updtregion->flags & UPDT_REGION_FIX_DONE) && + subpic->b_absolute && subpic->p_region && + subpic->i_original_picture_width > 0 && + subpic->i_original_picture_height > 0) + { + p_updtregion->flags |= UPDT_REGION_FIX_DONE; + p_updtregion->origin.x = subpic->p_region->i_x; + p_updtregion->origin.y = subpic->p_region->i_y; + p_updtregion->extent.x = subpic->i_original_picture_width; + p_updtregion->extent.y = subpic->i_original_picture_height; } + return VLC_EGENERIC; } @@ -83,58 +136,74 @@ static void SubpictureTextUpdate(subpicture_t *subpic, fmt.i_sar_num = 1; fmt.i_sar_den = 1; - subpicture_region_t *r = subpic->p_region = subpicture_region_New(&fmt); - if (!r) - return; + subpicture_region_t **pp_last_region = &subpic->p_region; - r->p_text = text_segment_Copy( sys->p_segments ); - r->i_align = sys->align; - r->b_noregionbg = sys->noregionbg; - r->b_gridmode = sys->gridmode; - if (!sys->is_fixed) { - const float margin_ratio = 0.04; - const int margin_h = margin_ratio * fmt_dst->i_visible_width; - const int margin_v = margin_ratio * fmt_dst->i_visible_height; - - r->i_x = 0; - if (r->i_align & SUBPICTURE_ALIGN_LEFT) - r->i_x += margin_h + fmt_dst->i_x_offset; - else if (r->i_align & SUBPICTURE_ALIGN_RIGHT) - r->i_x += margin_h + fmt_dst->i_width - (fmt_dst->i_visible_width + fmt_dst->i_x_offset); - - r->i_y = 0; - if (r->i_align & SUBPICTURE_ALIGN_TOP ) - r->i_y += margin_v + fmt_dst->i_y_offset; - else if (r->i_align & SUBPICTURE_ALIGN_BOTTOM ) - r->i_y += margin_v + fmt_dst->i_height - (fmt_dst->i_visible_height + fmt_dst->i_y_offset); - } else { - /* FIXME it doesn't adapt on crop settings changes */ - r->i_x = sys->x * fmt_dst->i_width / sys->fixed_width; - r->i_y = sys->y * fmt_dst->i_height / sys->fixed_height; - } - - /* Add missing default style, if any, to all segments */ - for ( text_segment_t* p_segment = r->p_text; p_segment; p_segment = p_segment->p_next ) + for( subpicture_updater_sys_region_t *p_updtregion = &sys->region; + p_updtregion; p_updtregion = p_updtregion->p_next ) { - /* Add decoder defaults */ - if( p_segment->style ) - text_style_Merge( p_segment->style, sys->p_default_style, false ); - else - p_segment->style = text_style_Duplicate( sys->p_default_style ); - /* Update all segments font sizes in pixels, *** metric used by renderers *** */ - /* We only do this when a fixed font size isn't set */ - if( p_segment->style && p_segment->style->f_font_relsize && !p_segment->style->i_font_size ) + subpicture_region_t *r = *pp_last_region = subpicture_region_New(&fmt); + if (!r) + return; + pp_last_region = &r->p_next; + + r->p_text = text_segment_Copy( p_updtregion->p_segments ); + r->i_align = p_updtregion->inner_align | p_updtregion->align; /* we do not support text align by itself */ + r->b_noregionbg = p_updtregion->flags & UPDT_REGION_IGNORE_BACKGROUND; + r->b_gridmode = p_updtregion->flags & UPDT_REGION_USES_GRID_COORDINATES; + if (!(p_updtregion->flags & UPDT_REGION_FIX_DONE)) + { + const float margin_ratio = 0.04; + const int margin_h = margin_ratio * fmt_dst->i_visible_width; + const int margin_v = margin_ratio * fmt_dst->i_visible_height; + + r->i_x = 0; + if (r->i_align & SUBPICTURE_ALIGN_LEFT) + r->i_x += margin_h + fmt_dst->i_x_offset; + else if (r->i_align & SUBPICTURE_ALIGN_RIGHT) + r->i_x += margin_h + fmt_dst->i_width - (fmt_dst->i_visible_width + fmt_dst->i_x_offset); + + r->i_y = 0; + if (r->i_align & SUBPICTURE_ALIGN_TOP ) + r->i_y += margin_v + fmt_dst->i_y_offset; + else if (r->i_align & SUBPICTURE_ALIGN_BOTTOM ) + r->i_y += margin_v + fmt_dst->i_height - (fmt_dst->i_visible_height + fmt_dst->i_y_offset); + } else { + /* FIXME it doesn't adapt on crop settings changes */ + r->i_x = p_updtregion->origin.x * fmt_dst->i_width / p_updtregion->extent.x; + r->i_y = p_updtregion->origin.y * fmt_dst->i_height / p_updtregion->extent.y; + } + + /* Add missing default style, if any, to all segments */ + for ( text_segment_t* p_segment = r->p_text; p_segment; p_segment = p_segment->p_next ) { - p_segment->style->i_font_size = p_segment->style->f_font_relsize * - subpic->i_original_picture_height / 100; + /* Add decoder defaults */ + if( p_segment->style ) + text_style_Merge( p_segment->style, sys->p_default_style, false ); + else + p_segment->style = text_style_Duplicate( sys->p_default_style ); + /* Update all segments font sizes in pixels, *** metric used by renderers *** */ + /* We only do this when a fixed font size isn't set */ + if( p_segment->style && p_segment->style->f_font_relsize && !p_segment->style->i_font_size ) + { + p_segment->style->i_font_size = p_segment->style->f_font_relsize * + subpic->i_original_picture_height / 100; + } } + } } static void SubpictureTextDestroy(subpicture_t *subpic) { subpicture_updater_sys_t *sys = subpic->updater.p_sys; - text_segment_ChainDelete( sys->p_segments ); + SubpictureUpdaterSysRegionClean( &sys->region ); + subpicture_updater_sys_region_t *p_region = sys->region.p_next; + while( p_region ) + { + subpicture_updater_sys_region_t *p_next = p_region->p_next; + SubpictureUpdaterSysRegionClean( p_region ); + p_region = p_next; + } text_style_Delete( sys->p_default_style ); free(sys); } @@ -148,6 +217,7 @@ static inline subpicture_t *decoder_NewSubpictureText(decoder_t *decoder) .pf_destroy = SubpictureTextDestroy, .p_sys = sys, }; + SubpictureUpdaterSysRegionInit( &sys->region ); sys->p_default_style = text_style_Create( STYLE_NO_DEFAULTS ); if(unlikely(!sys->p_default_style)) { diff --git a/modules/codec/substx3g.c b/modules/codec/substx3g.c index 1563231..cb7243a 100644 --- a/modules/codec/substx3g.c +++ b/modules/codec/substx3g.c @@ -435,7 +435,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) p_spu->b_ephemer = (p_block->i_length == 0); p_spu->b_absolute = false; - p_spu_sys->align = SUBPICTURE_ALIGN_BOTTOM; + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_BOTTOM; FontSizeConvert( p_dec->fmt_in.subs.p_style, p_spu_sys->p_default_style ); @@ -454,7 +454,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) p_cur = p_cur->p_next; } - p_spu_sys->p_segments = p_text_segments; + p_spu_sys->region.p_segments = p_text_segments; block_Release( p_block ); diff --git a/modules/codec/ttml/substtml.c b/modules/codec/ttml/substtml.c index e880b27..19680fb 100644 --- a/modules/codec/ttml/substtml.c +++ b/modules/codec/ttml/substtml.c @@ -630,7 +630,12 @@ static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block ) /* Create the subpicture unit */ p_spu = decoder_NewSubpictureText( p_dec ); if( !p_spu ) + { + text_segment_ChainDelete( p_segments ); + if( p_ttml_style ) + ttml_style_Delete( p_ttml_style ); return NULL; + } p_spu->i_start = p_block->i_pts; p_spu->i_stop = p_block->i_pts + p_block->i_length; @@ -642,19 +647,47 @@ static subpicture_t *ParseBlock( decoder_t *p_dec, const block_t *p_block ) /* Broken stuff. See comments */ if( p_ttml_style ) { - p_spu_sys->x = ( p_ttml_style->i_margin_h ) ? p_ttml_style->i_margin_h - : p_ttml_style->i_margin_percent_h; + if( p_ttml_style->i_margin_percent_h ) + { + p_spu_sys->region.origin.x = p_ttml_style->i_margin_percent_h; + p_spu_sys->region.flags |= UPDT_REGION_ORIGIN_X_IS_PERCENTILE; + } + else + { + p_spu_sys->region.origin.x = p_ttml_style->i_margin_h; + } + + if( p_ttml_style->i_margin_percent_v ) + { + p_spu_sys->region.origin.y = p_ttml_style->i_margin_percent_v; + p_spu_sys->region.flags |= UPDT_REGION_ORIGIN_Y_IS_PERCENTILE; + } + else + { + p_spu_sys->region.origin.y = p_ttml_style->i_margin_v; + } - p_spu_sys->y = ( p_ttml_style->i_margin_v ) ? p_ttml_style->i_margin_v - : p_ttml_style->i_margin_percent_v; + if( p_ttml_style->i_align & SUBPICTURE_ALIGN_LEFT ) + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_LEFT; + else if( p_ttml_style->i_align & SUBPICTURE_ALIGN_LEFT ) + p_spu_sys->region.inner_align = SUBPICTURE_ALIGN_RIGHT; - p_spu_sys->align |= p_ttml_style->i_align; + /* broken legacy align var (can't handle center...) */ + if( (p_ttml_style->i_align & SUBPICTURE_ALIGN_MASK) == 0 && + (p_sys->i_align & SUBPICTURE_ALIGN_MASK) != 0 ) + { + p_spu_sys->region.align = p_sys->i_align; + } + else + { + if( p_ttml_style->i_align & SUBPICTURE_ALIGN_TOP ) + p_spu_sys->region.align = SUBPICTURE_ALIGN_TOP; + else + p_spu_sys->region.align = SUBPICTURE_ALIGN_BOTTOM; + } } - if( (p_spu_sys->align & SUBPICTURE_ALIGN_MASK) == 0 ) - p_spu_sys->align = SUBPICTURE_ALIGN_BOTTOM | p_sys->i_align; - - p_spu_sys->p_segments = p_segments; + p_spu_sys->region.p_segments = p_segments; } if( p_ttml_style ) diff --git a/modules/codec/zvbi.c b/modules/codec/zvbi.c index 1004fd1..ff3de7f 100644 --- a/modules/codec/zvbi.c +++ b/modules/codec/zvbi.c @@ -395,7 +395,7 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) if( !p_spu ) goto error; subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys; - p_spu_sys->p_segments = text_segment_New(""); + p_spu_sys->region.p_segments = text_segment_New(""); p_sys->b_update = true; p_sys->i_last_page = i_wanted_page; @@ -452,20 +452,20 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block ) offset++; subpicture_updater_sys_t *p_spu_sys = p_spu->updater.p_sys; - p_spu_sys->p_segments = text_segment_New( &p_text[offset] ); - if( p_spu_sys->p_segments && b_opaque ) + p_spu_sys->region.p_segments = text_segment_New( &p_text[offset] ); + if( p_spu_sys->region.p_segments && b_opaque ) { - p_spu_sys->p_segments->style = text_style_Create( STYLE_NO_DEFAULTS ); - if( p_spu_sys->p_segments->style ) + p_spu_sys->region.p_segments->style = text_style_Create( STYLE_NO_DEFAULTS ); + if( p_spu_sys->region.p_segments->style ) { /* Set text background */ - p_spu_sys->p_segments->style->i_style_flags = STYLE_BACKGROUND; - p_spu_sys->p_segments->style->i_features |= STYLE_HAS_FLAGS; + p_spu_sys->region.p_segments->style->i_style_flags = STYLE_BACKGROUND; + p_spu_sys->region.p_segments->style->i_features |= STYLE_HAS_FLAGS; } } - p_spu_sys->align = i_align; - p_spu_sys->noregionbg = true; + p_spu_sys->region.inner_align = i_align; + p_spu_sys->region.flags = UPDT_REGION_IGNORE_BACKGROUND; #ifdef ZVBI_DEBUG msg_Info( p_dec, "page %x-%x(%d)\n\"%s\"", p_page.pgno, p_page.subno, i_total, &p_text[offset] ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
