[vlc-devel] [PATCH 16/25] deinterlace: one function pointer per frame
Victorien Le Couviour--Tuffet
victorien.lecouviour.tuffet at gmail.com
Tue Apr 14 12:40:27 CEST 2020
Instead of per feature line merging functions, have per CPU feature
frame deinterlacing implementations.
This prepares for having assembly seperate files of deinterlacing
methods, in the next commits.
---
modules/video_filter/deinterlace/algo_basic.c | 400 +++++++++++++-----
modules/video_filter/deinterlace/algo_basic.h | 12 +-
modules/video_filter/deinterlace/algo_ivtc.c | 6 +
modules/video_filter/deinterlace/algo_ivtc.h | 2 +-
.../video_filter/deinterlace/algo_phosphor.c | 12 +-
.../video_filter/deinterlace/algo_phosphor.h | 4 +-
modules/video_filter/deinterlace/algo_x.c | 8 +-
modules/video_filter/deinterlace/algo_x.h | 2 +-
modules/video_filter/deinterlace/algo_yadif.c | 31 +-
modules/video_filter/deinterlace/algo_yadif.h | 5 +-
.../video_filter/deinterlace/deinterlace.c | 37 +-
.../video_filter/deinterlace/deinterlace.h | 5 +
12 files changed, 370 insertions(+), 154 deletions(-)
diff --git a/modules/video_filter/deinterlace/algo_basic.c b/modules/video_filter/deinterlace/algo_basic.c
index 1d652d634b..2ef7698c31 100644
--- a/modules/video_filter/deinterlace/algo_basic.c
+++ b/modules/video_filter/deinterlace/algo_basic.c
@@ -32,17 +32,17 @@
#include <vlc_common.h>
#include <vlc_picture.h>
#include <vlc_filter.h>
-
-#include "merge.h"
-#include "deinterlace.h" /* definition of p_sys, needed for Merge() */
-
+#include <vlc_cpu.h>
+#include "deinterlace.h"
#include "algo_basic.h"
+#include "merge.h"
/*****************************************************************************
* RenderDiscard: only keep TOP or BOTTOM field, discard the other.
*****************************************************************************/
-int RenderDiscard( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
+static int RenderDiscard( filter_t *p_filter,
+ picture_t *p_outpic, picture_t *p_pic )
{
VLC_UNUSED(p_filter);
int i_plane;
@@ -69,12 +69,19 @@ int RenderDiscard( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
return VLC_SUCCESS;
}
+single_pic_renderer_t DiscardRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderDiscard;
+}
+
/*****************************************************************************
* RenderBob: renders a BOB picture - simple copy
*****************************************************************************/
-int RenderBob( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic,
- int order, int i_field )
+static int RenderBob( filter_t *p_filter,
+ picture_t *p_outpic, picture_t *p_pic,
+ int order, int i_field )
{
VLC_UNUSED(p_filter);
VLC_UNUSED(order);
@@ -125,132 +132,305 @@ int RenderBob( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic,
return VLC_SUCCESS;
}
+ordered_renderer_t BobRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderBob;
+}
+
/*****************************************************************************
* RenderLinear: BOB with linear interpolation
*****************************************************************************/
-int RenderLinear( filter_t *p_filter,
- picture_t *p_outpic, picture_t *p_pic, int order, int i_field )
-{
- VLC_UNUSED(order);
- int i_plane;
-
- filter_sys_t *p_sys = p_filter->p_sys;
-
- /* Copy image and skip lines */
- for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
- {
- uint8_t *p_in, *p_out_end, *p_out;
-
- p_in = p_pic->p[i_plane].p_pixels;
- p_out = p_outpic->p[i_plane].p_pixels;
- p_out_end = p_out + p_outpic->p[i_plane].i_pitch
- * p_outpic->p[i_plane].i_visible_lines;
-
- /* For BOTTOM field we need to add the first line */
- if( i_field == 1 )
- {
- memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
- p_in += p_pic->p[i_plane].i_pitch;
- p_out += p_outpic->p[i_plane].i_pitch;
- }
-
- p_out_end -= 2 * p_outpic->p[i_plane].i_pitch;
-
- for( ; p_out < p_out_end ; )
- {
- memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
-
- p_out += p_outpic->p[i_plane].i_pitch;
-
- Merge( p_out, p_in, p_in + 2 * p_pic->p[i_plane].i_pitch,
- p_pic->p[i_plane].i_pitch );
+#define RENDER_LINEAR(merge, bpc, feature) \
+static int RenderLinear##bpc##Bit_##feature( filter_t *p_filter, \
+ picture_t *p_outpic, \
+ picture_t *p_pic, \
+ int order, int i_field ) \
+{ \
+ VLC_UNUSED(p_filter); VLC_UNUSED(order); \
+ int i_plane; \
+ \
+ /* Copy image and skip lines */ \
+ for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) \
+ { \
+ uint8_t *p_in, *p_out_end, *p_out; \
+ \
+ p_in = p_pic->p[i_plane].p_pixels; \
+ p_out = p_outpic->p[i_plane].p_pixels; \
+ p_out_end = p_out + p_outpic->p[i_plane].i_pitch \
+ * p_outpic->p[i_plane].i_visible_lines; \
+ \
+ /* For BOTTOM field we need to add the first line */ \
+ if( i_field == 1 ) \
+ { \
+ memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); \
+ p_in += p_pic->p[i_plane].i_pitch; \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ } \
+ \
+ p_out_end -= 2 * p_outpic->p[i_plane].i_pitch; \
+ \
+ for( ; p_out < p_out_end ; ) \
+ { \
+ memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); \
+ \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ \
+ ptrdiff_t stride = p_pic->p[i_plane].i_pitch; \
+ merge( p_out, p_in, p_in + 2 * stride, stride); \
+ \
+ p_in += 2 * p_pic->p[i_plane].i_pitch; \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ } \
+ \
+ memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); \
+ \
+ /* For TOP field we need to add the last line */ \
+ if( i_field == 0 ) \
+ { \
+ p_in += p_pic->p[i_plane].i_pitch; \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); \
+ } \
+ } \
+ return VLC_SUCCESS; \
+}
- p_in += 2 * p_pic->p[i_plane].i_pitch;
- p_out += p_outpic->p[i_plane].i_pitch;
- }
+#define RENDER_LINEAR_SIMD(bpc, feature) \
+ RENDER_LINEAR(Merge##bpc##Bit##feature, bpc, feature)
+#define RENDER_LINEAR_ARM(bpc, feature) \
+ RENDER_LINEAR(merge##bpc##_##feature, bpc, feature)
- memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
+RENDER_LINEAR(Merge8BitGeneric, 8, c)
+RENDER_LINEAR(Merge16BitGeneric, 16, c)
+#if defined(CAN_COMPILE_SSE2)
+RENDER_LINEAR_SIMD(8, SSE2)
+RENDER_LINEAR_SIMD(16, SSE2)
+#endif
+#if defined(CAN_COMPILE_ARM)
+RENDER_LINEAR_ARM(8, arm_neon)
+RENDER_LINEAR_ARM(16, arm_neon)
+RENDER_LINEAR_ARM(8, armv6)
+RENDER_LINEAR_ARM(16, armv6)
+#endif
+#if defined(CAN_COMPILE_SVE)
+RENDER_LINEAR_ARM(8, arm_sve)
+RENDER_LINEAR_ARM(16, arm_sve)
+#endif
+#if defined(CAN_COMPULE_ARM64)
+RENDER_LINEAR_ARM(8, arm64_neon)
+RENDER_LINEAR_ARM(16, arm64_neon)
+#endif
- /* For TOP field we need to add the last line */
- if( i_field == 0 )
- {
- p_in += p_pic->p[i_plane].i_pitch;
- p_out += p_outpic->p[i_plane].i_pitch;
- memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
- }
- }
- return VLC_SUCCESS;
+ordered_renderer_t LinearRenderer(unsigned pixel_size)
+{
+#if defined(CAN_COMPILE_SSE2)
+ if (vlc_CPU_SSE2())
+ return pixel_size & 1 ? RenderLinear8Bit_SSE2 : RenderLinear16Bit_SSE2;
+ else
+#endif
+#if defined(CAN_COMPILE_ARM)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderLinear8Bit_arm_neon : RenderLinear16Bit_arm_neon;
+ else
+ if (vlc_CPU_ARMv6())
+ return pixel_size & 1 ? RenderLinear8Bit_armv6 : RenderLinear16Bit_armv6;
+ else
+#endif
+#if defined(CAN_COMPILE_SVE)
+ if (vlc_CPU_ARM_SVE())
+ return pixel_size & 1 ? RenderLinear8Bit_arm_sve : RenderLinear16Bit_arm_sve;
+ else
+#endif
+#if defined(CAN_COMPULE_ARM64)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderLinear8Bit_arm64_neon : RenderLinear16Bit_arm64_neon;
+ else
+#endif
+ return pixel_size & 1 ? RenderLinear8Bit_c : RenderLinear16Bit_c;
}
/*****************************************************************************
* RenderMean: Half-resolution blender
*****************************************************************************/
-int RenderMean( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
-{
- int i_plane;
-
- filter_sys_t *p_sys = p_filter->p_sys;
-
- /* Copy image and skip lines */
- for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
- {
- uint8_t *p_in, *p_out_end, *p_out;
-
- p_in = p_pic->p[i_plane].p_pixels;
+#define RENDER_MEAN(merge, bpc, feature) \
+static int RenderMean##bpc##Bit_##feature( filter_t *p_filter, \
+ picture_t *p_outpic, \
+ picture_t *p_pic ) \
+{ \
+ VLC_UNUSED(p_filter); \
+ int i_plane; \
+ \
+ /* Copy image and skip lines */ \
+ for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) \
+ { \
+ uint8_t *p_in, *p_out_end, *p_out; \
+ \
+ p_in = p_pic->p[i_plane].p_pixels; \
+ \
+ p_out = p_outpic->p[i_plane].p_pixels; \
+ p_out_end = p_out + p_outpic->p[i_plane].i_pitch \
+ * p_outpic->p[i_plane].i_visible_lines; \
+ \
+ /* All lines: mean value */ \
+ for( ; p_out < p_out_end ; ) \
+ { \
+ merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, \
+ p_pic->p[i_plane].i_pitch ); \
+ \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ p_in += 2 * p_pic->p[i_plane].i_pitch; \
+ } \
+ } \
+ return VLC_SUCCESS; \
+}
- p_out = p_outpic->p[i_plane].p_pixels;
- p_out_end = p_out + p_outpic->p[i_plane].i_pitch
- * p_outpic->p[i_plane].i_visible_lines;
+#define RENDER_MEAN_SIMD(bpc, feature) \
+ RENDER_MEAN(Merge##bpc##Bit##feature, bpc, feature)
+#define RENDER_MEAN_ARM(bpc, feature) \
+ RENDER_MEAN(merge##bpc##_##feature, bpc, feature)
- /* All lines: mean value */
- for( ; p_out < p_out_end ; )
- {
- Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
- p_pic->p[i_plane].i_pitch );
+RENDER_MEAN(Merge8BitGeneric, 8, c)
+RENDER_MEAN(Merge16BitGeneric, 16, c)
+#if defined(CAN_COMPILE_SSE2)
+RENDER_MEAN_SIMD(8, SSE2)
+RENDER_MEAN_SIMD(16, SSE2)
+#endif
+#if defined(CAN_COMPILE_ARM)
+RENDER_MEAN_ARM(8, arm_neon)
+RENDER_MEAN_ARM(16, arm_neon)
+RENDER_MEAN_ARM(8, armv6)
+RENDER_MEAN_ARM(16, armv6)
+#endif
+#if defined(CAN_COMPILE_SVE)
+RENDER_MEAN_ARM(8, arm_sve)
+RENDER_MEAN_ARM(16, arm_sve)
+#endif
+#if defined(CAN_COMPULE_ARM64)
+RENDER_MEAN_ARM(8, arm64_neon)
+RENDER_MEAN_ARM(16, arm64_neon)
+#endif
- p_out += p_outpic->p[i_plane].i_pitch;
- p_in += 2 * p_pic->p[i_plane].i_pitch;
- }
- }
- return VLC_SUCCESS;
+single_pic_renderer_t MeanRenderer(unsigned pixel_size)
+{
+#if defined(CAN_COMPILE_SSE2)
+ if (vlc_CPU_SSE2())
+ return pixel_size & 1 ? RenderMean8Bit_SSE2 : RenderMean16Bit_SSE2;
+ else
+#endif
+#if defined(CAN_COMPILE_ARM)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderMean8Bit_arm_neon : RenderMean16Bit_arm_neon;
+ else
+ if (vlc_CPU_ARMv6())
+ return pixel_size & 1 ? RenderMean8Bit_armv6 : RenderMean16Bit_armv6;
+ else
+#endif
+#if defined(CAN_COMPILE_SVE)
+ if (vlc_CPU_ARM_SVE())
+ return pixel_size & 1 ? RenderMean8Bit_arm_sve : RenderMean16Bit_arm_sve;
+ else
+#endif
+#if defined(CAN_COMPULE_ARM64)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderMean8Bit_arm64_neon : RenderMean16Bit_arm64_neon;
+ else
+#endif
+ return pixel_size & 1 ? RenderMean8Bit_c : RenderMean16Bit_c;
}
/*****************************************************************************
* RenderBlend: Full-resolution blender
*****************************************************************************/
-int RenderBlend( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
-{
- int i_plane;
-
- filter_sys_t *p_sys = p_filter->p_sys;
-
- /* Copy image and skip lines */
- for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ )
- {
- uint8_t *p_in, *p_out_end, *p_out;
-
- p_in = p_pic->p[i_plane].p_pixels;
-
- p_out = p_outpic->p[i_plane].p_pixels;
- p_out_end = p_out + p_outpic->p[i_plane].i_pitch
- * p_outpic->p[i_plane].i_visible_lines;
+#define RENDER_BLEND(merge, bpc, feature) \
+static int RenderBlend##bpc##Bit_##feature( filter_t *p_filter, \
+ picture_t *p_outpic, \
+ picture_t *p_pic ) \
+{ \
+ VLC_UNUSED(p_filter); \
+ int i_plane; \
+ \
+ /* Copy image and skip lines */ \
+ for( i_plane = 0 ; i_plane < p_pic->i_planes ; i_plane++ ) \
+ { \
+ uint8_t *p_in, *p_out_end, *p_out; \
+ \
+ p_in = p_pic->p[i_plane].p_pixels; \
+ \
+ p_out = p_outpic->p[i_plane].p_pixels; \
+ p_out_end = p_out + p_outpic->p[i_plane].i_pitch \
+ * p_outpic->p[i_plane].i_visible_lines; \
+ \
+ /* First line: simple copy */ \
+ memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch ); \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ \
+ /* Remaining lines: mean value */ \
+ for( ; p_out < p_out_end ; ) \
+ { \
+ merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch, \
+ p_pic->p[i_plane].i_pitch ); \
+ \
+ p_out += p_outpic->p[i_plane].i_pitch; \
+ p_in += p_pic->p[i_plane].i_pitch; \
+ } \
+ } \
+ return VLC_SUCCESS; \
+}
- /* First line: simple copy */
- memcpy( p_out, p_in, p_pic->p[i_plane].i_pitch );
- p_out += p_outpic->p[i_plane].i_pitch;
+#define RENDER_BLEND_SIMD(bpc, feature) \
+ RENDER_BLEND(Merge##bpc##Bit##feature, bpc, feature)
+#define RENDER_BLEND_ARM(bpc, feature) \
+ RENDER_BLEND(merge##bpc##_##feature, bpc, feature)
- /* Remaining lines: mean value */
- for( ; p_out < p_out_end ; )
- {
- Merge( p_out, p_in, p_in + p_pic->p[i_plane].i_pitch,
- p_pic->p[i_plane].i_pitch );
+RENDER_BLEND(Merge8BitGeneric, 8, c)
+RENDER_BLEND(Merge16BitGeneric, 16, c)
+#if defined(CAN_COMPILE_SSE2)
+RENDER_BLEND_SIMD(8, SSE2)
+RENDER_BLEND_SIMD(16, SSE2)
+#endif
+#if defined(CAN_COMPILE_ARM)
+RENDER_BLEND_ARM(8, arm_neon)
+RENDER_BLEND_ARM(16, arm_neon)
+RENDER_BLEND_ARM(8, armv6)
+RENDER_BLEND_ARM(16, armv6)
+#endif
+#if defined(CAN_COMPILE_SVE)
+RENDER_BLEND_ARM(8, arm_sve)
+RENDER_BLEND_ARM(16, arm_sve)
+#endif
+#if defined(CAN_COMPULE_ARM64)
+RENDER_BLEND_ARM(8, arm64_neon)
+RENDER_BLEND_ARM(16, arm64_neon)
+#endif
- p_out += p_outpic->p[i_plane].i_pitch;
- p_in += p_pic->p[i_plane].i_pitch;
- }
- }
- return VLC_SUCCESS;
+single_pic_renderer_t BlendRenderer(unsigned pixel_size)
+{
+#if defined(CAN_COMPILE_SSE2)
+ if (vlc_CPU_SSE2())
+ return pixel_size & 1 ? RenderBlend8Bit_SSE2 : RenderBlend16Bit_SSE2;
+ else
+#endif
+#if defined(CAN_COMPILE_ARM)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderBlend8Bit_arm_neon : RenderBlend16Bit_arm_neon;
+ else
+ if (vlc_CPU_ARMv6())
+ return pixel_size & 1 ? RenderBlend8Bit_armv6 : RenderBlend16Bit_armv6;
+ else
+#endif
+#if defined(CAN_COMPILE_SVE)
+ if (vlc_CPU_ARM_SVE())
+ return pixel_size & 1 ? RenderBlend8Bit_arm_sve : RenderBlend16Bit_arm_sve;
+ else
+#endif
+#if defined(CAN_COMPULE_ARM64)
+ if (vlc_CPU_ARM_NEON())
+ return pixel_size & 1 ? RenderBlend8Bit_arm64_neon : RenderBlend16Bit_arm64_neon;
+ else
+#endif
+ return pixel_size & 1 ? RenderBlend8Bit_c : RenderBlend16Bit_c;
}
diff --git a/modules/video_filter/deinterlace/algo_basic.h b/modules/video_filter/deinterlace/algo_basic.h
index 1f25563ab8..d6dce2a4e8 100644
--- a/modules/video_filter/deinterlace/algo_basic.h
+++ b/modules/video_filter/deinterlace/algo_basic.h
@@ -48,7 +48,7 @@ struct picture_t;
* @see RenderBob()
* @see Deinterlace()
*/
-int RenderDiscard( filter_t *, picture_t *p_outpic, picture_t *p_pic );
+single_pic_renderer_t DiscardRenderer(unsigned pixel_size);
/**
* RenderBob: basic framerate doubler.
@@ -63,8 +63,7 @@ int RenderDiscard( filter_t *, picture_t *p_outpic, picture_t *p_pic );
* @see RenderLinear()
* @see Deinterlace()
*/
-int RenderBob( filter_t *,
- picture_t *p_outpic, picture_t *p_pic, int order, int i_field );
+ordered_renderer_t BobRenderer(unsigned pixel_size);
/**
* RenderLinear: Bob with linear interpolation.
@@ -78,8 +77,7 @@ int RenderBob( filter_t *,
* @see RenderBob()
* @see Deinterlace()
*/
-int RenderLinear( filter_t *p_filter,
- picture_t *p_outpic, picture_t *p_pic, int order, int i_field );
+ordered_renderer_t LinearRenderer(unsigned pixel_size);
/**
* RenderMean: half-resolution blender.
@@ -93,7 +91,7 @@ int RenderLinear( filter_t *p_filter,
* @param p_pic Input frame. Must exist.
* @see Deinterlace()
*/
-int RenderMean( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic );
+single_pic_renderer_t MeanRenderer(unsigned pixel_size);
/**
* RenderBlend: full-resolution blender.
@@ -108,6 +106,6 @@ int RenderMean( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic );
* @param p_pic Input frame. Must exist.
* @see Deinterlace()
*/
-int RenderBlend( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic );
+single_pic_renderer_t BlendRenderer(unsigned pixel_size);
#endif
diff --git a/modules/video_filter/deinterlace/algo_ivtc.c b/modules/video_filter/deinterlace/algo_ivtc.c
index 2e6d09b69d..242d8c01cb 100644
--- a/modules/video_filter/deinterlace/algo_ivtc.c
+++ b/modules/video_filter/deinterlace/algo_ivtc.c
@@ -1570,6 +1570,12 @@ int RenderIVTC( filter_t *p_filter, picture_t *p_dst, picture_t *p_pic )
}
}
+single_pic_renderer_t IVTCRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderIVTC;
+}
+
/* See function doc in header. */
void IVTCClearState( filter_t *p_filter )
{
diff --git a/modules/video_filter/deinterlace/algo_ivtc.h b/modules/video_filter/deinterlace/algo_ivtc.h
index f032d7e21b..5f04669927 100644
--- a/modules/video_filter/deinterlace/algo_ivtc.h
+++ b/modules/video_filter/deinterlace/algo_ivtc.h
@@ -138,7 +138,7 @@ typedef struct
* @see CalculateInterlaceScore()
* @see EstimateNumBlocksWithMotion()
*/
-int RenderIVTC( filter_t *p_filter, picture_t *p_dst, picture_t *p_pic );
+single_pic_renderer_t IVTCRenderer(unsigned pixel_size);
/**
* Clears the inverse telecine subsystem state.
diff --git a/modules/video_filter/deinterlace/algo_phosphor.c b/modules/video_filter/deinterlace/algo_phosphor.c
index 289eed783b..71f631e0d5 100644
--- a/modules/video_filter/deinterlace/algo_phosphor.c
+++ b/modules/video_filter/deinterlace/algo_phosphor.c
@@ -276,9 +276,9 @@ static void DarkenFieldMMX( picture_t *p_dst,
*****************************************************************************/
/* See header for function doc. */
-int RenderPhosphor( filter_t *p_filter,
- picture_t *p_dst, picture_t *p_pic,
- int i_order, int i_field )
+static int RenderPhosphor( filter_t *p_filter,
+ picture_t *p_dst, picture_t *p_pic,
+ int i_order, int i_field )
{
VLC_UNUSED(p_pic);
assert( p_filter != NULL );
@@ -370,3 +370,9 @@ int RenderPhosphor( filter_t *p_filter,
}
return VLC_SUCCESS;
}
+
+ordered_renderer_t PhosphorRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderPhosphor;
+}
diff --git a/modules/video_filter/deinterlace/algo_phosphor.h b/modules/video_filter/deinterlace/algo_phosphor.h
index 3cc5aaca46..6cae0e2cad 100644
--- a/modules/video_filter/deinterlace/algo_phosphor.h
+++ b/modules/video_filter/deinterlace/algo_phosphor.h
@@ -99,9 +99,7 @@ typedef struct
* @see RenderLinear()
* @see Deinterlace()
*/
-int RenderPhosphor( filter_t *p_filter,
- picture_t *p_dst, picture_t *p_pic,
- int i_order, int i_field );
+ordered_renderer_t PhosphorRenderer(unsigned pixel_size);
/*****************************************************************************
* Extra documentation
diff --git a/modules/video_filter/deinterlace/algo_x.c b/modules/video_filter/deinterlace/algo_x.c
index 411351d1cd..205f5e8286 100644
--- a/modules/video_filter/deinterlace/algo_x.c
+++ b/modules/video_filter/deinterlace/algo_x.c
@@ -511,7 +511,7 @@ static inline void XDeintBand8x8MMXEXT( uint8_t *dst, int i_dst,
* Public functions
*****************************************************************************/
-int RenderX( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
+static int RenderX( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
{
VLC_UNUSED(p_filter);
int i_plane;
@@ -571,3 +571,9 @@ int RenderX( filter_t *p_filter, picture_t *p_outpic, picture_t *p_pic )
#endif
return VLC_SUCCESS;
}
+
+single_pic_renderer_t XRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderX;
+}
diff --git a/modules/video_filter/deinterlace/algo_x.h b/modules/video_filter/deinterlace/algo_x.h
index dd70cbd732..4e6bd6b323 100644
--- a/modules/video_filter/deinterlace/algo_x.h
+++ b/modules/video_filter/deinterlace/algo_x.h
@@ -49,6 +49,6 @@ struct picture_t;
* @param[out] p_outpic Output frame. Must be allocated by caller.
* @see Deinterlace()
*/
-int RenderX( filter_t *, picture_t *p_outpic, picture_t *p_pic );
+single_pic_renderer_t XRenderer(unsigned pixel_size);
#endif
diff --git a/modules/video_filter/deinterlace/algo_yadif.c b/modules/video_filter/deinterlace/algo_yadif.c
index 6fdecf53a5..fe1bf427cb 100644
--- a/modules/video_filter/deinterlace/algo_yadif.c
+++ b/modules/video_filter/deinterlace/algo_yadif.c
@@ -46,13 +46,8 @@
Necessary preprocessor macros are defined in common.h. */
#include "yadif.h"
-int RenderYadifSingle( filter_t *p_filter, picture_t *p_dst, picture_t *p_src )
-{
- return RenderYadif( p_filter, p_dst, p_src, 0, 0 );
-}
-
-int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
- int i_order, int i_field )
+static int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
+ int i_order, int i_field )
{
VLC_UNUSED(p_src);
@@ -184,8 +179,9 @@ int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
as set by Open() or SetFilterMethod(). It is always 0. */
/* FIXME not good as it does not use i_order/i_field */
- RenderX( p_filter, p_dst, p_next );
- return VLC_SUCCESS;
+ const vlc_chroma_description_t *chroma =
+ vlc_fourcc_GetChromaDescription( p_filter->fmt_in.video.i_chroma );
+ return XRenderer( chroma->pixel_size )( p_filter, p_dst, p_next );
}
else
{
@@ -194,3 +190,20 @@ int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
return VLC_EGENERIC;
}
}
+
+static int RenderYadifSingle( filter_t *p_filter, picture_t *p_dst, picture_t *p_src )
+{
+ return RenderYadif( p_filter, p_dst, p_src, 0, 0 );
+}
+
+ordered_renderer_t YadifRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderYadif;
+}
+
+single_pic_renderer_t YadifSingleRenderer(unsigned pixel_size)
+{
+ VLC_UNUSED(pixel_size);
+ return RenderYadifSingle;
+}
diff --git a/modules/video_filter/deinterlace/algo_yadif.h b/modules/video_filter/deinterlace/algo_yadif.h
index 483ca48f67..09cecf7eed 100644
--- a/modules/video_filter/deinterlace/algo_yadif.h
+++ b/modules/video_filter/deinterlace/algo_yadif.h
@@ -82,12 +82,11 @@ struct picture_t;
* @retval VLC_EGENERIC Frame dropped; only occurs at the second frame after start.
* @see Deinterlace()
*/
-int RenderYadif( filter_t *p_filter, picture_t *p_dst, picture_t *p_src,
- int i_order, int i_field );
+ordered_renderer_t YadifRenderer(unsigned pixel_size);
/**
* Same as RenderYadif() but with no temporal references
*/
-int RenderYadifSingle( filter_t *p_filter, picture_t *p_dst, picture_t *p_src );
+single_pic_renderer_t YadifSingleRenderer(unsigned pixel_size);
#endif
diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
index 9d33d434a9..8469a6ac8e 100644
--- a/modules/video_filter/deinterlace/deinterlace.c
+++ b/modules/video_filter/deinterlace/deinterlace.c
@@ -340,36 +340,35 @@ struct filter_mode_t
{
const char *psz_mode;
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);
+ ordered_renderer_t (*pf_ordered_renderer)( unsigned pixel_size );
+ single_pic_renderer_t (*pf_single_pic_renderer)( unsigned pixel_size );
};
deinterlace_algo settings;
bool can_pack; /**< can handle packed pixel */
bool b_high_bit_depth; /**< can handle high bit depth */
};
static struct filter_mode_t filter_mode [] = {
- { "discard", .pf_render_single_pic = RenderDiscard,
+ { "discard", .pf_single_pic_renderer = DiscardRenderer,
{ false, false, false, true }, true, true },
- { "bob", .pf_render_ordered = RenderBob,
+ { "bob", .pf_ordered_renderer = BobRenderer,
{ true, false, false, false }, true, true },
- { "progressive-scan", .pf_render_ordered = RenderBob,
+ { "progressive-scan", .pf_ordered_renderer = BobRenderer,
{ true, false, false, false }, true, true },
- { "linear", .pf_render_ordered = RenderLinear,
+ { "linear", .pf_ordered_renderer = LinearRenderer,
{ true, false, false, false }, true, true },
- { "mean", .pf_render_single_pic = RenderMean,
+ { "mean", .pf_single_pic_renderer = MeanRenderer,
{ false, false, false, true }, true, true },
- { "blend", .pf_render_single_pic = RenderBlend,
+ { "blend", .pf_single_pic_renderer = BlendRenderer,
{ false, false, false, false }, true, true },
- { "yadif", .pf_render_single_pic = RenderYadifSingle,
+ { "yadif", .pf_single_pic_renderer = YadifSingleRenderer,
{ false, true, false, false }, false, true },
- { "yadif2x", .pf_render_ordered = RenderYadif,
+ { "yadif2x", .pf_ordered_renderer = YadifRenderer,
{ true, true, false, false }, false, true },
- { "x", .pf_render_single_pic = RenderX,
+ { "x", .pf_single_pic_renderer = XRenderer,
{ false, false, false, false }, false, false },
- { "phosphor", .pf_render_ordered = RenderPhosphor,
+ { "phosphor", .pf_ordered_renderer = PhosphorRenderer,
{ true, true, false, false }, false, false },
- { "ivtc", .pf_render_single_pic = RenderIVTC,
+ { "ivtc", .pf_single_pic_renderer = IVTCRenderer,
{ false, true, true, false }, false, false },
};
@@ -407,10 +406,16 @@ static void SetFilterMethod( filter_t *p_filter, const char *mode, bool pack )
SetFilterMethod( p_filter, "blend", pack );
return;
}
-
msg_Dbg( p_filter, "using %s deinterlace method", mode );
+
+ const vlc_fourcc_t fourcc = p_filter->fmt_in.video.i_chroma;
+ const vlc_chroma_description_t *chroma =
+ vlc_fourcc_GetChromaDescription( fourcc );
+ assert( chroma->pixel_size < 2 );
+
p_sys->context.settings = filter_mode[i].settings;
- p_sys->context.pf_render_ordered = filter_mode[i].pf_render_ordered;
+ p_sys->context.pf_render_ordered =
+ filter_mode[i].pf_ordered_renderer( chroma->pixel_size );
return;
}
}
diff --git a/modules/video_filter/deinterlace/deinterlace.h b/modules/video_filter/deinterlace/deinterlace.h
index 959cd6ae96..8d2342d02f 100644
--- a/modules/video_filter/deinterlace/deinterlace.h
+++ b/modules/video_filter/deinterlace/deinterlace.h
@@ -33,8 +33,13 @@ struct picture_t;
struct vlc_object_t;
#include <vlc_common.h>
+#include <vlc_fourcc.h>
#include <vlc_mouse.h>
+typedef int (*single_pic_renderer_t)(filter_t *, picture_t *, picture_t *);
+typedef int (*ordered_renderer_t)(filter_t *, picture_t *, picture_t *,
+ int order, int field);
+
/* Local algorithm headers */
#include "algo_basic.h"
#include "algo_x.h"
--
2.24.1
More information about the vlc-devel
mailing list