[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