[vlc-devel] [PATCH 2/2] [RFC] vlc_es: add a sub_chroma structure

Steve Lhomme robux4 at videolabs.io
Sat Apr 16 10:57:44 CEST 2016


Tis is needed to compare chroma that rely on surfaces that may not all
be the same for the same VLC chroma integer.
---
 include/vlc_es.h                | 46 +++++++++++++++++++++++++++++++++++++++++
 src/input/decoder.c             |  2 +-
 src/misc/es_format.c            |  2 +-
 src/misc/filter.c               | 11 +++++++++-
 src/video_output/display.c      | 11 ++++++++--
 src/video_output/video_output.c |  2 +-
 6 files changed, 68 insertions(+), 6 deletions(-)

diff --git a/include/vlc_es.h b/include/vlc_es.h
index cbd03e5..c15bc67 100644
--- a/include/vlc_es.h
+++ b/include/vlc_es.h
@@ -192,12 +192,16 @@ typedef enum video_transform_t
     TRANSFORM_ANTI_TRANSPOSE = ORIENT_ANTI_TRANSPOSED
 } video_transform_t;
 
+typedef struct sub_chroma  sub_chroma;
+
 /**
  * video format description
  */
 struct video_format_t
 {
     vlc_fourcc_t i_chroma;                               /**< picture chroma */
+    sub_chroma   *p_sub_chroma;            /**< data depending on the chroma */
+    size_t        i_sub_chroma_size;      /**< size of the sub chroma buffer */
 
     unsigned int i_width;                                 /**< picture width */
     unsigned int i_height;                               /**< picture height */
@@ -233,6 +237,8 @@ static inline void video_format_Init( video_format_t *p_src, vlc_fourcc_t i_chro
     p_src->i_chroma = i_chroma;
     p_src->i_sar_num = p_src->i_sar_den = 1;
     p_src->p_palette = NULL;
+    p_src->p_sub_chroma = NULL;
+    p_src->i_sub_chroma_size = 0;
 }
 
 /**
@@ -250,6 +256,17 @@ static inline int video_format_Copy( video_format_t *p_dst, const video_format_t
             return VLC_ENOMEM;
         memcpy( p_dst->p_palette, p_src->p_palette, sizeof( *p_dst->p_palette ) );
     }
+    if ( p_src->i_sub_chroma_size && p_src->p_sub_chroma != NULL )
+    {
+        p_dst->p_sub_chroma = (sub_chroma *) malloc( p_src->i_sub_chroma_size );
+        if( !p_dst->p_sub_chroma )
+        {
+            free( p_dst->p_palette );
+            return VLC_ENOMEM;
+        }
+        memcpy( p_dst->p_sub_chroma, p_src->p_sub_chroma, p_src->i_sub_chroma_size );
+        p_dst->i_sub_chroma_size = p_src->i_sub_chroma_size;
+    }
     return VLC_SUCCESS;
 }
 
@@ -259,10 +276,39 @@ static inline int video_format_Copy( video_format_t *p_dst, const video_format_t
  */
 static inline void video_format_Clean( video_format_t *p_src )
 {
+    free( p_src->p_sub_chroma );
     free( p_src->p_palette );
     memset( p_src, 0, sizeof( video_format_t ) );
 }
 
+static inline bool video_format_IsSimilarChroma( const video_format_t *f1, const video_format_t *f2 )
+{
+    return f1->i_chroma == f2->i_chroma && f1->i_sub_chroma_size == f2->i_sub_chroma_size &&
+         ( !f1->i_sub_chroma_size || !memcmp(f1->p_sub_chroma, f2->p_sub_chroma, f1->i_sub_chroma_size));
+}
+
+static inline int video_format_SetChroma( video_format_t *p_fmt, vlc_fourcc_t i_chroma,
+                                          const sub_chroma *p_sub_chroma, size_t i_sub_chroma_size )
+{
+    if ( p_fmt->i_chroma == i_chroma &&
+         p_fmt->i_sub_chroma_size == i_sub_chroma_size &&
+         ( !i_sub_chroma_size || !memcmp(p_fmt->p_sub_chroma, p_sub_chroma, i_sub_chroma_size)) )
+        return VLC_SUCCESS;
+    sub_chroma *p_schroma = NULL;
+    if ( i_sub_chroma_size != 0 )
+    {
+        p_schroma = (sub_chroma *)malloc( i_sub_chroma_size );
+        if ( unlikely( p_schroma == NULL ) )
+            return VLC_ENOMEM;
+        memcpy( p_schroma, p_sub_chroma, i_sub_chroma_size );
+    }
+    free( p_fmt->p_sub_chroma );
+    p_fmt->p_sub_chroma = p_schroma;
+    p_fmt->i_sub_chroma_size = i_sub_chroma_size;
+    p_fmt->i_chroma = i_chroma;
+    return VLC_SUCCESS;
+}
+
 /**
  * It will fill up a video_format_t using the given arguments.
  * Note that the video_format_t must already be initialized.
diff --git a/src/input/decoder.c b/src/input/decoder.c
index a1d7414..f9b0c53 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -325,7 +325,7 @@ static int vout_update_format( decoder_t *p_dec )
      || p_dec->fmt_out.video.i_visible_height != p_owner->fmt.video.i_visible_height
      || p_dec->fmt_out.video.i_x_offset != p_owner->fmt.video.i_x_offset
      || p_dec->fmt_out.video.i_y_offset != p_owner->fmt.video.i_y_offset
-     || p_dec->fmt_out.i_codec != p_owner->fmt.video.i_chroma
+     || !video_format_IsSimilarChroma( &p_dec->fmt_out.video, &p_owner->fmt.video )
      || (int64_t)p_dec->fmt_out.video.i_sar_num * p_owner->fmt.video.i_sar_den !=
         (int64_t)p_dec->fmt_out.video.i_sar_den * p_owner->fmt.video.i_sar_num ||
         p_dec->fmt_out.video.orientation != p_owner->fmt.video.orientation )
diff --git a/src/misc/es_format.c b/src/misc/es_format.c
index 0375767..7c8b0d6 100644
--- a/src/misc/es_format.c
+++ b/src/misc/es_format.c
@@ -381,7 +381,7 @@ void video_format_ApplyRotation( video_format_t *restrict out,
 bool video_format_IsSimilar( const video_format_t *f1,
                              const video_format_t *f2 )
 {
-    if( f1->i_chroma != f2->i_chroma )
+    if( !video_format_IsSimilarChroma( f1, f2 ) )
         return false;
 
     if( f1->i_width != f2->i_width || f1->i_height != f2->i_height ||
diff --git a/src/misc/filter.c b/src/misc/filter.c
index 36f1ba4..24b4f95 100644
--- a/src/misc/filter.c
+++ b/src/misc/filter.c
@@ -43,6 +43,15 @@ filter_t *filter_NewBlend( vlc_object_t *p_this,
 
     p_blend->fmt_out.i_codec        = 
     p_blend->fmt_out.video.i_chroma = p_dst_chroma->i_chroma;
+    if ( p_dst_chroma->i_sub_chroma_size != 0 )
+    {
+        p_blend->fmt_out.video.p_sub_chroma = malloc( p_dst_chroma->i_sub_chroma_size );
+        if ( p_blend->fmt_out.video.p_sub_chroma == NULL )
+            vlc_object_release( p_blend );
+        memcpy( p_blend->fmt_out.video.p_sub_chroma, p_dst_chroma->p_sub_chroma,
+                p_dst_chroma->i_sub_chroma_size );
+    }
+
     p_blend->fmt_out.video.i_rmask  = p_dst_chroma->i_rmask;
     p_blend->fmt_out.video.i_gmask  = p_dst_chroma->i_gmask;
     p_blend->fmt_out.video.i_bmask  = p_dst_chroma->i_bmask;
@@ -66,7 +75,7 @@ int filter_ConfigureBlend( filter_t *p_blend,
 {
     /* */
     if( p_blend->p_module &&
-        p_blend->fmt_in.video.i_chroma != p_src->i_chroma )
+        !video_format_IsSimilarChroma( &p_blend->fmt_in.video, p_src ) )
     {
         /* The chroma is not the same, we need to reload the blend module */
         module_unneed( p_blend, p_blend->p_module );
diff --git a/src/video_output/display.c b/src/video_output/display.c
index ecf661a..1a8df71 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -55,7 +55,7 @@ static picture_t *VideoBufferNew(filter_t *filter)
     vout_display_t *vd = filter->owner.sys;
     const video_format_t *fmt = &filter->fmt_out.video;
 
-    assert(vd->fmt.i_chroma == fmt->i_chroma &&
+    assert(video_format_IsSimilarChroma( &vd->fmt, fmt) &&
            vd->fmt.i_width  == fmt->i_width  &&
            vd->fmt.i_height == fmt->i_height);
 
@@ -432,10 +432,17 @@ static int VoutDisplayCreateRender(vout_display_t *vd)
         (v_src.i_chroma == VLC_CODEC_J440 && v_dst.i_chroma == VLC_CODEC_I440) ||
         (v_src.i_chroma == VLC_CODEC_J444 && v_dst.i_chroma == VLC_CODEC_I444))
         v_dst_cmp.i_chroma = v_src.i_chroma;
+    v_dst_cmp.p_sub_chroma = NULL; // for memcmp
+    v_src.p_sub_chroma = NULL;     // for memcmp
 
-    const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0;
+    const bool convert = memcmp(&v_src, &v_dst_cmp, sizeof(v_src)) != 0 ||
+            (vd->source.i_sub_chroma_size && memcmp( vd->source.p_sub_chroma,
+                                                     vd->fmt.p_sub_chroma,
+                                                     vd->source.i_sub_chroma_size ) != 0 );
     if (!convert)
         return 0;
+    v_src.p_sub_chroma = vd->source.p_sub_chroma;
+    v_dst_cmp.p_sub_chroma = vd->fmt.p_sub_chroma;
 
     msg_Dbg(vd, "A filter to adapt decoder %4.4s to display %4.4s is needed",
             (const char *)&v_src.i_chroma, (const char *)&v_dst.i_chroma);
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 7994bec..48c88c8 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -893,7 +893,7 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced)
         subpicture_chromas = NULL;
 
         if (vout->p->spu_blend &&
-            vout->p->spu_blend->fmt_out.video.i_chroma != fmt_spu.i_chroma) {
+            !video_format_IsSimilarChroma( &vout->p->spu_blend->fmt_out.video, &fmt_spu )) {
             filter_DeleteBlend(vout->p->spu_blend);
             vout->p->spu_blend = NULL;
             vout->p->spu_blend_chroma = 0;
-- 
2.7.0.windows.1



More information about the vlc-devel mailing list