[vlc-devel] [PATCH 10/12] video_filter:deinterlace: use a callback to call do the rendering on a field

Steve Lhomme robux4 at videolabs.io
Tue Jun 27 16:11:12 CEST 2017


--
replaces https://patches.videolan.org/patch/17111/
- fixed field swapping when using history
---
 modules/video_filter/deinterlace/deinterlace.c | 112 +++++++------------------
 modules/video_filter/deinterlace/deinterlace.h |  14 +---
 2 files changed, 32 insertions(+), 94 deletions(-)

diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
index b793fc482d..93efabb8b5 100644
--- a/modules/video_filter/deinterlace/deinterlace.c
+++ b/modules/video_filter/deinterlace/deinterlace.c
@@ -158,29 +158,29 @@ static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
 
     if( !strcmp( mode, "discard" ) )
     {
-        p_sys->i_mode = DEINTERLACE_DISCARD;
+        p_sys->pf_render_pic = RenderDiscard;
         p_sys->b_single_field = true;
         p_sys->b_half_height = true;
     }
     else if( !strcmp( mode, "bob" ) || !strcmp( mode, "progressive-scan" ) )
     {
-        p_sys->i_mode = DEINTERLACE_BOB;
+        p_sys->pf_render_pic = RenderBob;
         p_sys->b_double_rate = true;
     }
     else if( !strcmp( mode, "linear" ) )
     {
-        p_sys->i_mode = DEINTERLACE_LINEAR;
+        p_sys->pf_render_pic = RenderLinear;
         p_sys->b_double_rate = true;
     }
     else if( !strcmp( mode, "mean" ) )
     {
-        p_sys->i_mode = DEINTERLACE_MEAN;
+        p_sys->pf_render_pic = RenderMean;
         p_sys->b_single_field = true;
         p_sys->b_half_height = true;
     }
     else if( !strcmp( mode, "blend" ) )
     {
-        p_sys->i_mode = DEINTERLACE_BLEND;
+        p_sys->pf_render_pic = RenderBlend;
         p_sys->b_single_field = true;
     }
     else if( pack )
@@ -191,13 +191,13 @@ static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
     }
     else if( !strcmp( mode, "yadif" ) )
     {
-        p_sys->i_mode = DEINTERLACE_YADIF;
+        p_sys->pf_render_pic = RenderYadif;
         p_sys->b_single_field = true;
         p_sys->b_use_frame_history = true;
     }
     else if( !strcmp( mode, "yadif2x" ) )
     {
-        p_sys->i_mode = DEINTERLACE_YADIF2X;
+        p_sys->pf_render_pic = RenderYadif;
         p_sys->b_double_rate = true;
         p_sys->b_use_frame_history = true;
     }
@@ -209,18 +209,18 @@ static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
     }
     else if( !strcmp( mode, "x" ) )
     {
-        p_sys->i_mode = DEINTERLACE_X;
+        p_sys->pf_render_pic = RenderX;
         p_sys->b_single_field = true;
     }
     else if( !strcmp( mode, "phosphor" ) )
     {
-        p_sys->i_mode = DEINTERLACE_PHOSPHOR;
+        p_sys->pf_render_pic = RenderPhosphor;
         p_sys->b_double_rate = true;
         p_sys->b_use_frame_history = true;
     }
     else if( !strcmp( mode, "ivtc" ) )
     {
-        p_sys->i_mode = DEINTERLACE_IVTC;
+        p_sys->pf_render_pic = RenderIVTC;
         p_sys->b_single_field = true;
         p_sys->b_use_frame_history = true;
     }
@@ -430,78 +430,24 @@ picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
     assert( i_nb_fields > 2  ||  p_dst[2] == NULL );
 
     /* Render */
-    switch( p_sys->i_mode )
+    if ( p_sys->b_single_field )
     {
-        case DEINTERLACE_DISCARD:
-            RenderDiscard( p_filter, p_dst[0], p_pic, 0, 0 );
-            break;
-
-        case DEINTERLACE_BOB:
-            RenderBob( p_filter, p_dst[0], p_pic, 0,
-                       !b_top_field_first );
-            if( p_dst[1] )
-                RenderBob( p_filter, p_dst[1], p_pic, 1,
-                           b_top_field_first );
-            if( p_dst[2] )
-                RenderBob( p_filter, p_dst[2], p_pic, 2,
-                           !b_top_field_first );
-            break;;
-
-        case DEINTERLACE_LINEAR:
-            RenderLinear( p_filter, p_dst[0], p_pic, 0,
-                          !b_top_field_first );
-            if( p_dst[1] )
-                RenderLinear( p_filter, p_dst[1], p_pic, 1,
-                              b_top_field_first );
-            if( p_dst[2] )
-                RenderLinear( p_filter, p_dst[2], p_pic, 2,
-                              !b_top_field_first );
-            break;
-
-        case DEINTERLACE_MEAN:
-            RenderMean( p_filter, p_dst[0], p_pic, 0, 0 );
-            break;
-
-        case DEINTERLACE_BLEND:
-            RenderBlend( p_filter, p_dst[0], p_pic, 0, 0 );
-            break;
-
-        case DEINTERLACE_X:
-            RenderX( p_filter, p_dst[0], p_pic, 0, 0 );
-            break;
-
-        case DEINTERLACE_YADIF:
-            if( RenderYadif( p_filter, p_dst[0], p_pic, 0, 0 ) )
-                goto drop;
-            break;
-
-        case DEINTERLACE_YADIF2X:
-            if( RenderYadif( p_filter, p_dst[0], p_pic, 0, !b_top_field_first ) )
-                goto drop;
-            if( p_dst[1] )
-                RenderYadif( p_filter, p_dst[1], p_pic, 1, b_top_field_first );
-            if( p_dst[2] )
-                RenderYadif( p_filter, p_dst[2], p_pic, 2, !b_top_field_first );
-            break;
-
-        case DEINTERLACE_PHOSPHOR:
-            if( RenderPhosphor( p_filter, p_dst[0], p_pic, 0,
-                                !b_top_field_first ) )
-                goto drop;
-            if( p_dst[1] )
-                RenderPhosphor( p_filter, p_dst[1], p_pic, 1,
-                                b_top_field_first );
-            if( p_dst[2] )
-                RenderPhosphor( p_filter, p_dst[2], p_pic, 2,
-                                !b_top_field_first );
-            break;
-
-        case DEINTERLACE_IVTC:
-            /* Note: RenderIVTC will automatically drop the duplicate frames
-                     produced by IVTC. This is part of normal operation. */
-            if( RenderIVTC( p_filter, p_dst[0], p_pic, 0, 0 ) )
-                goto drop;
-            break;
+        if ( p_sys->pf_render_pic( p_filter, p_dst[0], p_pic, 0, 0 ) )
+            goto drop;
+    }
+    else
+    {
+        /* Note: RenderIVTC will automatically drop the duplicate frames
+                 produced by IVTC. This is part of normal operation. */
+        if ( p_sys->pf_render_pic( p_filter, p_dst[0], p_pic,
+                                   0, !b_top_field_first ) )
+            goto drop;
+        if ( p_dst[1] )
+            p_sys->pf_render_pic( p_filter, p_dst[1], p_pic,
+                                  1, b_top_field_first );
+        if ( p_dst[2] )
+            p_sys->pf_render_pic( p_filter, p_dst[1], p_pic,
+                                  2, !b_top_field_first );
     }
 
     /* Set output timestamps, if the algorithm didn't request CUSTOM_PTS
@@ -647,7 +593,6 @@ notsupp:
                        p_filter->p_cfg );
     char *psz_mode = var_InheritString( p_filter, FILTER_CFG_PREFIX "mode" );
     SetFilterMethod( p_filter, psz_mode, packed );
-    free( psz_mode );
 
     for( int i = 0; i < METADATA_SIZE; i++ )
     {
@@ -716,7 +661,7 @@ notsupp:
     GetOutputFormat( p_filter, &fmt, &p_filter->fmt_in.video );
 
     /* */
-    if( p_sys->i_mode == DEINTERLACE_PHOSPHOR )
+    if( !strcmp( psz_mode, "phosphor" ) )
     {
         int i_c420 = var_GetInteger( p_filter,
                                      FILTER_CFG_PREFIX "phosphor-chroma" );
@@ -754,6 +699,7 @@ notsupp:
                         VLC_CODEC_J422 : VLC_CODEC_I422;
         }
     }
+    free( psz_mode );
 
     if( !p_filter->b_allow_fmt_out_change &&
         ( fmt.i_chroma != p_filter->fmt_in.video.i_chroma ||
diff --git a/modules/video_filter/deinterlace/deinterlace.h b/modules/video_filter/deinterlace/deinterlace.h
index 3059f09f2a..e3ded7a944 100644
--- a/modules/video_filter/deinterlace/deinterlace.h
+++ b/modules/video_filter/deinterlace/deinterlace.h
@@ -61,15 +61,6 @@ static const char *const mode_list_text[] = {
  * Data structures
  *****************************************************************************/
 
-/**
- * Available deinterlace algorithms.
- * @see SetFilterMethod()
- */
-typedef enum { DEINTERLACE_DISCARD, DEINTERLACE_MEAN,    DEINTERLACE_BLEND,
-               DEINTERLACE_BOB,     DEINTERLACE_LINEAR,  DEINTERLACE_X,
-               DEINTERLACE_YADIF,   DEINTERLACE_YADIF2X, DEINTERLACE_PHOSPHOR,
-               DEINTERLACE_IVTC } deinterlace_mode;
-
 #define METADATA_SIZE (3)
 /**
  * Metadata history structure, used for framerate doublers.
@@ -91,8 +82,6 @@ struct filter_sys_t
 {
     const vlc_chroma_description_t *chroma;
 
-    uint8_t  i_mode;              /**< Deinterlace mode */
-
     /* Algorithm behaviour flags */
     bool b_double_rate;       /**< Shall we double the framerate? */
     bool b_half_height;       /**< Shall be divide the height by 2 */
@@ -106,6 +95,9 @@ struct filter_sys_t
     void (*pf_end_merge) ( void );
 #endif
 
+    int (*pf_render_pic)(filter_t *p_filter, picture_t *p_dst, picture_t *p_pic,
+                         int order, int i_field);
+
     /**
      * Metadata history (PTS, nb_fields, TFF). Used for framerate doublers.
      * @see metadata_history_t
-- 
2.12.1



More information about the vlc-devel mailing list