[vlc-commits] substext: store multiple region info in updater
Francois Cartegnie
git at videolan.org
Tue Jan 10 15:49:45 CET 2017
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | 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] );
More information about the vlc-commits
mailing list