[vlc-devel] [PATCH v1 08/33] deinterlace: add a filter callback using the video sink
Steve Lhomme
robux4 at ycbcr.xyz
Fri Sep 25 16:46:44 CEST 2020
It's sending pictures with vlc_video_sink_PutPicture() rather than attaching
pictures to each other with vlc_picture_chain_AppendChain().
The old DoDeinterlacing() still works the same.
---
modules/hw/d3d11/d3d11_deinterlace.c | 11 ++++
modules/hw/d3d9/dxva2_deinterlace.c | 7 +++
modules/video_filter/deinterlace/common.c | 63 ++++++++++++++++---
modules/video_filter/deinterlace/common.h | 6 ++
.../video_filter/deinterlace/deinterlace.c | 7 +++
5 files changed, 86 insertions(+), 8 deletions(-)
diff --git a/modules/hw/d3d11/d3d11_deinterlace.c b/modules/hw/d3d11/d3d11_deinterlace.c
index b2c8d99447a..333c4dfd498 100644
--- a/modules/hw/d3d11/d3d11_deinterlace.c
+++ b/modules/hw/d3d11/d3d11_deinterlace.c
@@ -174,6 +174,16 @@ static picture_t *Deinterlace(filter_t *p_filter, picture_t *p_pic)
return res;
}
+static int DeinterlaceInto(filter_t *p_filter, picture_t *p_pic, struct vlc_video_sink *sink)
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+
+ d3d11_device_lock( p_sys->d3d_dev );
+ int res = DoDeinterlacingInto( p_filter, &p_sys->context, p_pic, sink );
+ d3d11_device_unlock( p_sys->d3d_dev );
+ return res;
+}
+
static const struct filter_mode_t *GetFilterMode(const char *mode)
{
if ( mode == NULL || !strcmp( mode, "auto" ) )
@@ -351,6 +361,7 @@ int D3D11OpenDeinterlace(vlc_object_t *obj)
filter->fmt_out.video = out_fmt;
filter->vctx_out = vlc_video_context_Hold(filter->vctx_in);
filter->pf_video_filter = Deinterlace;
+ filter->pf_video_filter_into = DeinterlaceInto;
filter->pf_flush = Flush;
filter->p_sys = sys;
diff --git a/modules/hw/d3d9/dxva2_deinterlace.c b/modules/hw/d3d9/dxva2_deinterlace.c
index 7c0c4ec6920..cbc8398f821 100644
--- a/modules/hw/d3d9/dxva2_deinterlace.c
+++ b/modules/hw/d3d9/dxva2_deinterlace.c
@@ -268,6 +268,12 @@ static picture_t *Deinterlace(filter_t *p_filter, picture_t *p_pic)
return DoDeinterlacing( p_filter, &p_sys->context, p_pic );
}
+static int DeinterlaceInto(filter_t *p_filter, picture_t *p_pic, struct vlc_video_sink *sink)
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ return DoDeinterlacingInto( p_filter, &p_sys->context, p_pic, sink );
+}
+
static const struct filter_mode_t *GetFilterMode(const char *mode)
{
if ( mode == NULL || !strcmp( mode, "auto" ) )
@@ -502,6 +508,7 @@ int D3D9OpenDeinterlace(vlc_object_t *obj)
filter->fmt_out.video = out_fmt;
filter->vctx_out = vlc_video_context_Hold(filter->vctx_in);
filter->pf_video_filter = Deinterlace;
+ filter->pf_video_filter_into = DeinterlaceInto;
filter->pf_flush = Flush;
filter->p_sys = sys;
diff --git a/modules/video_filter/deinterlace/common.c b/modules/video_filter/deinterlace/common.c
index 94a6280e37e..955e88f1e2b 100644
--- a/modules/video_filter/deinterlace/common.c
+++ b/modules/video_filter/deinterlace/common.c
@@ -124,10 +124,10 @@ void GetDeinterlacingOutput( const struct deinterlace_ctx *p_context,
#define CUSTOM_PTS -1
-picture_t *DoDeinterlacing( filter_t *p_filter,
- struct deinterlace_ctx *p_context, picture_t *p_pic )
+static int Deinterlace( filter_t *p_filter,
+ struct deinterlace_ctx *p_context, picture_t *p_pic,
+ picture_t *p_dst[DEINTERLACE_DST_SIZE] )
{
- picture_t *p_dst[DEINTERLACE_DST_SIZE];
int i_double_rate_alloc_end;
/* Remember the frame offset that we should use for this frame.
The value in p_sys will be updated to reflect the correct value
@@ -142,7 +142,7 @@ picture_t *DoDeinterlacing( filter_t *p_filter,
if( p_dst[0] == NULL )
{
picture_Release( p_pic );
- return NULL;
+ return VLC_ENOMEM;
}
picture_CopyProperties( p_dst[0], p_pic );
@@ -236,7 +236,6 @@ picture_t *DoDeinterlacing( filter_t *p_filter,
p_dst[i] = AllocPicture( p_filter );
if( p_dst[i] )
{
- vlc_picture_chain_AppendChain( p_dst[i-1], p_dst[i] );
picture_CopyProperties( p_dst[i], p_pic );
}
else
@@ -341,7 +340,7 @@ picture_t *DoDeinterlacing( filter_t *p_filter,
}
picture_Release( p_pic );
- return p_dst[0];
+ return VLC_SUCCESS;
drop:
picture_Release( p_dst[0] );
@@ -352,8 +351,56 @@ drop:
}
#ifndef NDEBUG
picture_Release( p_pic );
- return NULL;
+ return VLC_EGENERIC;
#else
- return p_pic;
+ p_dst[0] = p_pic;
+ return VLC_SUCCESS;
#endif
}
+
+picture_t *DoDeinterlacing( filter_t *p_filter,
+ struct deinterlace_ctx *p_context, picture_t *p_pic )
+{
+ picture_t *p_dst[DEINTERLACE_DST_SIZE];
+ int res = Deinterlace(p_filter, p_context, p_pic, p_dst);
+ if (res != VLC_SUCCESS)
+ return NULL;
+ if (p_dst[0])
+ {
+ // attach pictures consecutively
+ for (size_t i=1; p_dst[i] != NULL && i<ARRAY_SIZE(p_dst); i++)
+ vlc_picture_chain_AppendChain( p_dst[i-1], p_dst[i] );
+ }
+ return p_dst[0];
+}
+
+int DoDeinterlacingInto( filter_t *p_filter, struct deinterlace_ctx *p_context,
+ picture_t *p_pic, struct vlc_video_sink *sink )
+{
+ picture_t *p_dst[DEINTERLACE_DST_SIZE];
+ int res = Deinterlace(p_filter, p_context, p_pic, p_dst);
+ if (res != VLC_SUCCESS)
+ return res;
+
+ // push picture(s) to the sink
+ for (size_t i=0; i<ARRAY_SIZE(p_dst); i++)
+ {
+ if (!p_dst[i])
+ break;
+ res = vlc_video_sink_PutPicture( sink, p_dst[i] );
+ if (unlikely(res != VLC_SUCCESS))
+ {
+ if (i == 0)
+ res = VLC_EGENERIC; // nothing was pushed
+ for (; i<ARRAY_SIZE(p_dst); i++)
+ {
+ if (p_dst[i])
+ {
+ msg_Err(p_filter, "dropping filtered picture %zu", i);
+ picture_Release( p_dst[i] );
+ }
+ }
+ }
+ }
+ return res;
+}
diff --git a/modules/video_filter/deinterlace/common.h b/modules/video_filter/deinterlace/common.h
index 144523647c2..ed989dd1a7d 100644
--- a/modules/video_filter/deinterlace/common.h
+++ b/modules/video_filter/deinterlace/common.h
@@ -117,6 +117,12 @@ void GetDeinterlacingOutput( const struct deinterlace_ctx *,
*/
picture_t *DoDeinterlacing( filter_t *, struct deinterlace_ctx *, picture_t * );
+/**
+ * @brief Do the deinterlacing of the picture using pf_render_ordered() or pf_render_single_pic() calls.
+ * @return VLC_SUCCESS if pictures we pushed to the sink.
+ */
+int DoDeinterlacingInto( filter_t *, struct deinterlace_ctx *, picture_t *, struct vlc_video_sink * );
+
/**
* @brief Flush the deinterlacer context
*/
diff --git a/modules/video_filter/deinterlace/deinterlace.c b/modules/video_filter/deinterlace/deinterlace.c
index 1676a07f8ca..46ecf303e20 100644
--- a/modules/video_filter/deinterlace/deinterlace.c
+++ b/modules/video_filter/deinterlace/deinterlace.c
@@ -452,6 +452,12 @@ picture_t *Deinterlace( filter_t *p_filter, picture_t *p_pic )
return DoDeinterlacing( p_filter, &p_sys->context, p_pic );
}
+static int DeinterlaceInto(filter_t *p_filter, picture_t *p_pic, struct vlc_video_sink *sink)
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+ return DoDeinterlacingInto( p_filter, &p_sys->context, p_pic, sink );
+}
+
/*****************************************************************************
* Flush
*****************************************************************************/
@@ -644,6 +650,7 @@ notsupp:
p_filter->fmt_out.video = fmt;
p_filter->fmt_out.i_codec = fmt.i_chroma;
p_filter->pf_video_filter = Deinterlace;
+ p_filter->pf_video_filter_into = DeinterlaceInto;
p_filter->pf_flush = Flush;
p_filter->pf_video_mouse = Mouse;
--
2.26.2
More information about the vlc-devel
mailing list