[vlc-devel] [PATCH v1 10/33] filter_chain: allow filtering into a sink with filter_chain_VideoFilterInto
Steve Lhomme
robux4 at ycbcr.xyz
Fri Sep 25 16:46:46 CEST 2020
Intermediate filters send their output to a local sink filling
---
include/vlc_filter.h | 12 ++++++++
src/libvlccore.sym | 1 +
src/misc/filter_chain.c | 67 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 80 insertions(+)
diff --git a/include/vlc_filter.h b/include/vlc_filter.h
index e660e8c6d18..f8f1d48a417 100644
--- a/include/vlc_filter.h
+++ b/include/vlc_filter.h
@@ -541,6 +541,18 @@ VLC_API vlc_video_context *filter_chain_GetVideoCtxOut(const filter_chain_t *cha
VLC_API picture_t *filter_chain_VideoFilter(filter_chain_t *chain,
picture_t *pic);
+/**
+ * Apply the filter chain to a video picture and send the results to the video sink.
+ *
+ * \param chain pointer to filter chain
+ * \param pic picture to apply filters to
+ * \param sink video sinking receiving the filtered picture(s)
+ * \return VLC_SUCCESS if pictures were sent to the sink
+ */
+VLC_API int filter_chain_VideoFilterInto(filter_chain_t *chain,
+ picture_t *pic,
+ struct vlc_video_sink *sink);
+
/**
* Flush a video filter chain.
*/
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index fec60a194cf..d7b93d5bc4a 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -120,6 +120,7 @@ filter_chain_Reset
filter_chain_Clear
filter_chain_SubFilter
filter_chain_VideoFilter
+filter_chain_VideoFilterInto
filter_chain_VideoFlush
filter_chain_ForEach
filter_ConfigureBlend
diff --git a/src/misc/filter_chain.c b/src/misc/filter_chain.c
index 176135bc0d2..3019d67e749 100644
--- a/src/misc/filter_chain.c
+++ b/src/misc/filter_chain.c
@@ -424,6 +424,13 @@ vlc_video_context *filter_chain_GetVideoCtxOut(const filter_chain_t *p_chain)
return p_chain->vctx_in;
}
+static int PushFilteredPic(struct vlc_video_sink *sink, picture_t *pic)
+{
+ vlc_picture_chain_t *p_chain = sink->sys;
+ vlc_picture_chain_Append(p_chain, pic);
+ return VLC_SUCCESS;
+}
+
static picture_t *FilterChainVideoFilter( chained_filter_t *f, picture_t *p_pic )
{
for( ; f != NULL; f = f->next )
@@ -464,6 +471,66 @@ picture_t *filter_chain_VideoFilter( filter_chain_t *p_chain, picture_t *p_pic )
return NULL;
}
+int filter_chain_VideoFilterInto(filter_chain_t *p_chain, picture_t *p_pic,
+ struct vlc_video_sink *sink)
+{
+ assert( p_pic != NULL ); // handle caching of pushed pictures on your side
+ int res = VLC_SUCCESS;
+ chained_filter_t *f = p_chain->first;
+ if (f == NULL)
+ res = vlc_video_sink_PutPicture( sink, p_pic );
+ else
+ {
+ vlc_picture_chain_t src_chain;
+ vlc_picture_chain_Init( &src_chain );
+ vlc_picture_chain_Append( &src_chain, p_pic );
+ for( ; f != NULL; f = f->next )
+ {
+ vlc_picture_chain_t filtered_chain;
+ vlc_picture_chain_Init( &filtered_chain );
+ struct vlc_video_sink fsink;
+ if (f->next)
+ fsink = (struct vlc_video_sink) { &filtered_chain, PushFilteredPic };
+ else
+ fsink = *sink;
+
+ filter_t *p_filter = &f->filter;
+ picture_t *front;
+ for (front = vlc_picture_chain_PopFront(&src_chain); front != NULL;
+ front = vlc_picture_chain_PopFront(&src_chain) )
+ {
+ if ( p_filter->pf_video_filter_into != NULL )
+ {
+ res = p_filter->pf_video_filter_into( p_filter, front, &fsink );
+ if (res != VLC_SUCCESS)
+ break;
+ }
+ else
+ {
+ assert(p_filter->pf_video_filter != NULL);
+ picture_t *filtered = p_filter->pf_video_filter( p_filter, front );
+ if (filtered != NULL)
+ {
+ vlc_picture_chain_t chained = picture_GetAndResetChain( filtered );
+ fsink.pf_push_picture(fsink.sys, filtered);
+ while ( !vlc_picture_chain_IsEmpty( &chained ) )
+ {
+ picture_t *next = vlc_picture_chain_PopFront( &chained );
+ fsink.pf_push_picture(fsink.sys, next);
+ }
+ }
+ }
+ }
+
+ // we have filtered pictures in filtered_chain, move them in src_chain
+ // for the next iteration
+ while ((front = vlc_picture_chain_PopFront( &filtered_chain )) != NULL)
+ vlc_picture_chain_Append(&src_chain, front);
+ }
+ }
+ return res;
+}
+
void filter_chain_VideoFlush( filter_chain_t *p_chain )
{
for( chained_filter_t *f = p_chain->first; f != NULL; f = f->next )
--
2.26.2
More information about the vlc-devel
mailing list