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

Steve Lhomme robux4 at videolabs.io
Fri Jun 30 14:20:02 CEST 2017


--
replaces https://patches.videolan.org/patch/17111/
- fixed field swapping when using history
replaces https://patches.videolan.org/patch/17126/
- no b_single_field anymore it was the opposite of b_double_rate
---
 modules/video_filter/deinterlace/deinterlace.c | 106 +++++++------------------
 modules/video_filter/deinterlace/deinterlace.h |  17 ++--
 2 files changed, 35 insertions(+), 88 deletions(-)

diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
index 741c1831f1..aff138dc33 100644
--- a/modules/video_filter/deinterlace/deinterlace.c
+++ b/modules/video_filter/deinterlace/deinterlace.c
@@ -157,27 +157,27 @@ 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_single_pic = RenderDiscard;
         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_ordered = RenderBob;
         p_sys->b_double_rate = true;
     }
     else if( !strcmp( mode, "linear" ) )
     {
-        p_sys->i_mode = DEINTERLACE_LINEAR;
+        p_sys->pf_render_ordered = RenderLinear;
         p_sys->b_double_rate = true;
     }
     else if( !strcmp( mode, "mean" ) )
     {
-        p_sys->i_mode = DEINTERLACE_MEAN;
+        p_sys->pf_render_single_pic = RenderMean;
         p_sys->b_half_height = true;
     }
     else if( !strcmp( mode, "blend" ) )
     {
-        p_sys->i_mode = DEINTERLACE_BLEND;
+        p_sys->pf_render_single_pic = RenderBlend;
     }
     else if( pack )
     {
@@ -187,12 +187,12 @@ 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_single_pic = RenderYadifSingle;
         p_sys->b_use_frame_history = true;
     }
     else if( !strcmp( mode, "yadif2x" ) )
     {
-        p_sys->i_mode = DEINTERLACE_YADIF2X;
+        p_sys->pf_render_ordered = RenderYadif;
         p_sys->b_double_rate = true;
         p_sys->b_use_frame_history = true;
     }
@@ -204,17 +204,17 @@ 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_single_pic = RenderX;
     }
     else if( !strcmp( mode, "phosphor" ) )
     {
-        p_sys->i_mode = DEINTERLACE_PHOSPHOR;
+        p_sys->pf_render_ordered = 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_single_pic = RenderIVTC;
         p_sys->b_use_frame_history = true;
     }
     else
@@ -423,72 +423,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_double_rate )
     {
-        case DEINTERLACE_DISCARD:
-            RenderDiscard( p_filter, p_dst[0], p_pic );
-            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 );
-            break;
-
-        case DEINTERLACE_BLEND:
-            RenderBlend( p_filter, p_dst[0], p_pic );
-            break;
-
-        case DEINTERLACE_X:
-            RenderX( p_filter, p_dst[0], p_pic );
-            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 ) )
-                goto drop;
-            break;
+        if ( p_sys->pf_render_single_pic( p_filter, p_dst[0], p_pic ) )
+            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_ordered( p_filter, p_dst[0], p_pic,
+                                       0, !b_top_field_first ) )
+            goto drop;
+        if ( p_dst[1] )
+            p_sys->pf_render_ordered( p_filter, p_dst[1], p_pic,
+                                      1, b_top_field_first );
+        if ( p_dst[2] )
+            p_sys->pf_render_ordered( p_filter, p_dst[1], p_pic,
+                                      2, !b_top_field_first );
     }
 
     /* Set output timestamps, if the algorithm didn't request CUSTOM_PTS
@@ -634,7 +586,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++ )
     {
@@ -703,7 +654,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" );
@@ -741,6 +692,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 00fddb74ec..d750863d49 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 */
@@ -105,6 +94,12 @@ struct filter_sys_t
     void (*pf_end_merge) ( void );
 #endif
 
+    union {
+        int (*pf_render_ordered)(filter_t *, picture_t *p_dst, picture_t *p_pic,
+                                 int order, int i_field);
+        int (*pf_render_single_pic)(filter_t *, picture_t *p_dst, picture_t *p_pic);
+    };
+
     /**
      * 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