[vlc-devel] [PATCH 22/34] filter_chain: keep the input video context on Reset

Steve Lhomme robux4 at ycbcr.xyz
Fri Nov 8 15:40:26 CET 2019


It will be passed to the first filter when it's created.

It is only set when calling filter_chain_Reset() and no filter has been added yet.

We should not be using the filter chain unless filter_chain_Reset() has been called.
---
 include/vlc_filter.h                 |  6 +++++-
 modules/stream_out/mosaic_bridge.c   |  2 +-
 modules/stream_out/sdi/SDIStream.cpp |  6 +++---
 modules/stream_out/sdi/SDIStream.hpp |  2 +-
 modules/stream_out/transcode/video.c | 16 +++++++++++-----
 modules/video_chroma/chain.c         |  8 ++++----
 modules/video_filter/canvas.c        |  2 +-
 modules/video_filter/edgedetection.c |  2 +-
 src/misc/filter_chain.c              | 10 +++++++++-
 src/video_output/display.c           |  2 +-
 src/video_output/video_output.c      | 13 +++++++++----
 11 files changed, 46 insertions(+), 23 deletions(-)

diff --git a/include/vlc_filter.h b/include/vlc_filter.h
index efa43197cd8..d3ec4665e30 100644
--- a/include/vlc_filter.h
+++ b/include/vlc_filter.h
@@ -357,9 +357,13 @@ VLC_API void filter_chain_Delete( filter_chain_t * );
  *
  * \param p_chain pointer to filter chain
  * \param p_fmt_in new fmt_in params
+ * \paramt vctx_in new input video context
  * \param p_fmt_out new fmt_out params
  */
-VLC_API void filter_chain_Reset( filter_chain_t *, const es_format_t *, const es_format_t * );
+VLC_API void filter_chain_Reset( filter_chain_t *p_chain,
+                                 const es_format_t *p_fmt_in,
+                                 vlc_video_context *vctx_in,
+                                 const es_format_t *p_fmt_out );
 
 /**
  * Remove all existing filters
diff --git a/modules/stream_out/mosaic_bridge.c b/modules/stream_out/mosaic_bridge.c
index a97ba4f386f..b0b9106d2a4 100644
--- a/modules/stream_out/mosaic_bridge.c
+++ b/modules/stream_out/mosaic_bridge.c
@@ -598,7 +598,7 @@ static int video_update_format_decoder( decoder_t *p_dec, vlc_video_context *vct
                 fmt.video.i_chroma = p_sys->i_chroma;
                 vctx = NULL; // CPU chroma, no video context
             }
-            filter_chain_Reset( p_sys->p_vf2, &fmt, &fmt );
+            filter_chain_Reset( p_sys->p_vf2, &fmt, vctx, &fmt );
             es_format_Clean( &fmt );
             filter_chain_AppendFromString( p_sys->p_vf2, psz_chain );
             free( psz_chain );
diff --git a/modules/stream_out/sdi/SDIStream.cpp b/modules/stream_out/sdi/SDIStream.cpp
index abcdc79c3d6..a61239c2bb3 100644
--- a/modules/stream_out/sdi/SDIStream.cpp
+++ b/modules/stream_out/sdi/SDIStream.cpp
@@ -541,7 +541,7 @@ static const struct filter_video_callbacks transcode_filter_video_cbs =
     transcode_video_filter_buffer_new,
 };
 
-filter_chain_t * VideoDecodedStream::VideoFilterCreate(const es_format_t *p_srcfmt)
+filter_chain_t * VideoDecodedStream::VideoFilterCreate(const es_format_t *p_srcfmt, vlc_video_context *vctx)
 {
     filter_chain_t *p_chain;
     filter_owner_t owner;
@@ -551,7 +551,7 @@ filter_chain_t * VideoDecodedStream::VideoFilterCreate(const es_format_t *p_srcf
     p_chain = filter_chain_NewVideo(p_stream, false, &owner);
     if(!p_chain)
         return NULL;
-    filter_chain_Reset(p_chain, p_srcfmt, &requestedoutput);
+    filter_chain_Reset(p_chain, p_srcfmt, vctx, &requestedoutput);
 
     if(p_srcfmt->video.i_chroma != requestedoutput.video.i_chroma)
     {
@@ -585,7 +585,7 @@ void VideoDecodedStream::Output(picture_t *p_pic)
 
         if(p_filters_chain)
             filter_chain_Delete(p_filters_chain);
-        p_filters_chain = VideoFilterCreate(&p_owner->last_fmt_update);
+        p_filters_chain = VideoFilterCreate(&p_owner->last_fmt_update, p_owner->last_fmt_vctx);
         if(!p_filters_chain)
         {
             picture_Release(p_pic);
diff --git a/modules/stream_out/sdi/SDIStream.hpp b/modules/stream_out/sdi/SDIStream.hpp
index 03c3f57db12..1eb624e12ae 100644
--- a/modules/stream_out/sdi/SDIStream.hpp
+++ b/modules/stream_out/sdi/SDIStream.hpp
@@ -170,7 +170,7 @@ namespace sdi_sout
                                                    const decoder_cc_desc_t * );
             static vlc_decoder_device * VideoDecCallback_get_device(decoder_t *);
             static int VideoDecCallback_update_format(decoder_t *, vlc_video_context *);
-            filter_chain_t * VideoFilterCreate(const es_format_t *);
+            filter_chain_t * VideoFilterCreate(const es_format_t *, vlc_video_context *);
             virtual void ReleaseDecoder();
             void Output(picture_t *);
             void QueueCC(block_t *);
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index 9f5a7941ef8..68a342a816c 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -109,7 +109,7 @@ static int video_update_format_decoder( decoder_t *p_dec, vlc_video_context *vct
     msg_Dbg( p_obj, "Checking if filter chain %4.4s -> %4.4s is possible",
                  (char *)&p_dec->fmt_out.i_codec, (char*)&p_enc_in->i_codec );
     test_chain = filter_chain_NewVideo( p_obj, false, NULL );
-    filter_chain_Reset( test_chain, &p_dec->fmt_out, &p_dec->fmt_out );
+    filter_chain_Reset( test_chain, &p_dec->fmt_out, vctx, &p_dec->fmt_out );
 
     int chain_works = filter_chain_AppendConverter( test_chain, p_enc_in );
     filter_chain_Delete( test_chain );
@@ -252,6 +252,7 @@ static const struct filter_video_callbacks transcode_filter_video_cbs =
 static int transcode_video_set_conversions( sout_stream_t *p_stream,
                                             sout_stream_id_sys_t *id,
                                             const es_format_t **pp_src,
+                                            vlc_video_context **pp_src_vctx,
                                             const es_format_t *p_dst,
                                             bool b_reorient )
 {
@@ -298,12 +299,13 @@ static int transcode_video_set_conversions( sout_stream_t *p_stream,
         *pp_chain = filter_chain_NewVideo( p_stream, step == STEP_NONSTATIC, &owner );
         if( !*pp_chain )
             return VLC_EGENERIC;
-        filter_chain_Reset( *pp_chain, *pp_src, p_tmpdst );
+        filter_chain_Reset( *pp_chain, *pp_src, *pp_src_vctx, p_tmpdst );
 
         if( filter_chain_AppendConverter( *pp_chain, p_tmpdst ) != VLC_SUCCESS )
             return VLC_EGENERIC;
 
         *pp_src = filter_chain_GetFmtOut( *pp_chain );
+        *pp_src_vctx = filter_chain_GetVideoCtxOut( *pp_chain );
         debug_format( p_stream, *pp_src );
     }
 
@@ -319,6 +321,7 @@ static int transcode_video_filters_init( sout_stream_t *p_stream,
                                          const sout_filters_config_t *p_cfg,
                                          bool b_master_sync,
                                          const es_format_t *p_src,
+                                         vlc_video_context *src_ctx,
                                          const es_format_t *p_dst,
                                          sout_stream_id_sys_t *id )
 {
@@ -330,7 +333,7 @@ static int transcode_video_filters_init( sout_stream_t *p_stream,
     id->p_f_chain = filter_chain_NewVideo( p_stream, false, &owner );
     if( !id->p_f_chain )
         return VLC_EGENERIC;
-    filter_chain_Reset( id->p_f_chain, p_src, p_src );
+    filter_chain_Reset( id->p_f_chain, p_src, src_ctx, p_src );
 
     /* Deinterlace */
     if( p_cfg->video.psz_deinterlace != NULL )
@@ -340,16 +343,18 @@ static int transcode_video_filters_init( sout_stream_t *p_stream,
                                    p_cfg->video.p_deinterlace_cfg,
                                    p_src );
         p_src = filter_chain_GetFmtOut( id->p_f_chain );
+        src_ctx = filter_chain_GetVideoCtxOut( id->p_f_chain );
     }
 
     if( b_master_sync )
     {
         filter_chain_AppendFilter( id->p_f_chain, "fps", NULL, p_dst );
         p_src = filter_chain_GetFmtOut( id->p_f_chain );
+        src_ctx = filter_chain_GetVideoCtxOut( id->p_f_chain );
     }
 
     /* Chroma and other conversions */
-    if( transcode_video_set_conversions( p_stream, id, &p_src, p_dst,
+    if( transcode_video_set_conversions( p_stream, id, &p_src, &src_ctx, p_dst,
                                          p_cfg->video.b_reorient ) != VLC_SUCCESS )
         return VLC_EGENERIC;
 
@@ -360,7 +365,7 @@ static int transcode_video_filters_init( sout_stream_t *p_stream,
         id->p_uf_chain = filter_chain_NewVideo( p_stream, true, &owner );
         if(!id->p_uf_chain)
             return VLC_EGENERIC;
-        filter_chain_Reset( id->p_uf_chain, p_src, p_dst );
+        filter_chain_Reset( id->p_uf_chain, p_src, src_ctx, p_dst );
         filter_chain_AppendFromString( id->p_uf_chain, p_cfg->psz_filters );
         p_src = filter_chain_GetFmtOut( id->p_uf_chain );
         debug_format( p_stream, p_src );
@@ -567,6 +572,7 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
                                                   id->p_filterscfg,
                                                  (id->p_enccfg->video.fps.num > 0),
                                                  &tmpfmt,
+                                                 p_pic->vctx,
                                                  transcode_encoder_format_in( id->encoder ),
                                                  id ) != VLC_SUCCESS )
                     goto error;
diff --git a/modules/video_chroma/chain.c b/modules/video_chroma/chain.c
index ab523397a2e..6620d779d8a 100644
--- a/modules/video_chroma/chain.c
+++ b/modules/video_chroma/chain.c
@@ -371,7 +371,7 @@ static int BuildFilterChain( filter_t *p_filter )
     const vlc_fourcc_t *pi_allowed_chromas = get_allowed_chromas( p_filter );
     for( int i = 0; pi_allowed_chromas[i]; i++ )
     {
-        filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
+        filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_out );
 
         const vlc_fourcc_t i_chroma = pi_allowed_chromas[i];
         if( i_chroma == p_filter->fmt_in.i_codec ||
@@ -411,7 +411,7 @@ static int BuildFilterChain( filter_t *p_filter )
         es_format_Clean( &fmt_mid );
     }
     if( i_ret != VLC_SUCCESS )
-        filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
+        filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_out );
 
     return i_ret;
 }
@@ -422,7 +422,7 @@ static int BuildFilterChain( filter_t *p_filter )
 static int CreateChain( filter_t *p_filter, const es_format_t *p_fmt_mid )
 {
     filter_sys_t *p_sys = p_filter->p_sys;
-    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
+    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_out );
 
     if( p_filter->fmt_in.video.orientation != p_fmt_mid->video.orientation)
     {
@@ -460,7 +460,7 @@ error:
 static int CreateResizeChromaChain( filter_t *p_filter, const es_format_t *p_fmt_mid )
 {
     filter_sys_t *p_sys = p_filter->p_sys;
-    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &p_filter->fmt_out );
+    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_out );
 
     int i_ret = filter_chain_AppendConverter( p_sys->p_chain, p_fmt_mid );
     if( i_ret != VLC_SUCCESS )
diff --git a/modules/video_filter/canvas.c b/modules/video_filter/canvas.c
index 5fcf9b43b2d..6d183bad43e 100644
--- a/modules/video_filter/canvas.c
+++ b/modules/video_filter/canvas.c
@@ -333,7 +333,7 @@ static int Activate( vlc_object_t *p_this )
     fmt.video.i_width = p_filter->fmt_in.video.i_width * fmt.video.i_visible_width / p_filter->fmt_in.video.i_visible_width;
     fmt.video.i_height = p_filter->fmt_in.video.i_height * fmt.video.i_visible_height / p_filter->fmt_in.video.i_visible_height;
 
-    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, &fmt );
+    filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in, &fmt );
     /* Append scaling module */
     if ( filter_chain_AppendConverter( p_sys->p_chain, NULL ) )
     {
diff --git a/modules/video_filter/edgedetection.c b/modules/video_filter/edgedetection.c
index e9ed9c7380c..20149af9fa2 100644
--- a/modules/video_filter/edgedetection.c
+++ b/modules/video_filter/edgedetection.c
@@ -105,7 +105,7 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
     /* Clear filter chain */
-    filter_chain_Reset( sys, &p_filter->fmt_in, &p_filter->fmt_in);
+    filter_chain_Reset( sys, &p_filter->fmt_in, p_filter->vctx_in, &p_filter->fmt_in);
     /* Add adjust filter to turn frame black-and-white */
     i_ret = filter_chain_AppendFromString( sys, "adjust{saturation=0}" );
     if ( i_ret == -1 )
diff --git a/src/misc/filter_chain.c b/src/misc/filter_chain.c
index dbe978b1e8b..be6cd53d2ac 100644
--- a/src/misc/filter_chain.c
+++ b/src/misc/filter_chain.c
@@ -51,6 +51,7 @@ struct filter_chain_t
     chained_filter_t *first, *last; /**< List of filters */
 
     es_format_t fmt_in; /**< Chain input format (constant) */
+    vlc_video_context *vctx_in; /**< Chain input video context (set on Reset) */
     es_format_t fmt_out; /**< Chain output format (constant) */
     bool b_allow_fmt_out_change; /**< Each filter can change the output */
     const char *filter_cap; /**< Filter modules capability */
@@ -77,6 +78,7 @@ static filter_chain_t *filter_chain_NewInner( vlc_object_t *obj,
     chain->first = NULL;
     chain->last = NULL;
     es_format_Init( &chain->fmt_in, cat, 0 );
+    chain->vctx_in = NULL;
     es_format_Init( &chain->fmt_out, cat, 0 );
     chain->b_allow_fmt_out_change = fmt_out_change;
     chain->filter_cap = cap;
@@ -163,6 +165,8 @@ void filter_chain_Delete( filter_chain_t *p_chain )
     filter_chain_Clear( p_chain );
 
     es_format_Clean( &p_chain->fmt_in );
+    if ( p_chain->vctx_in )
+        vlc_video_context_Release( p_chain->vctx_in );
     es_format_Clean( &p_chain->fmt_out );
 
     free( p_chain );
@@ -170,7 +174,8 @@ void filter_chain_Delete( filter_chain_t *p_chain )
 /**
  * Filter chain reinitialisation
  */
-void filter_chain_Reset( filter_chain_t *p_chain, const es_format_t *p_fmt_in,
+void filter_chain_Reset( filter_chain_t *p_chain,
+                         const es_format_t *p_fmt_in, vlc_video_context *vctx_in,
                          const es_format_t *p_fmt_out )
 {
     filter_chain_Clear( p_chain );
@@ -178,6 +183,9 @@ void filter_chain_Reset( filter_chain_t *p_chain, const es_format_t *p_fmt_in,
     assert(p_fmt_in != NULL);
     es_format_Clean( &p_chain->fmt_in );
     es_format_Copy( &p_chain->fmt_in, p_fmt_in );
+    if ( p_chain->vctx_in )
+        vlc_video_context_Release( p_chain->vctx_in );
+    p_chain->vctx_in = vctx_in ? vlc_video_context_Hold(vctx_in) : NULL;
 
     assert(p_fmt_out != NULL);
     es_format_Clean( &p_chain->fmt_out );
diff --git a/src/video_output/display.c b/src/video_output/display.c
index b8e0d2b6929..3b5394f79e4 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -338,7 +338,7 @@ static int VoutDisplayCreateRender(vout_display_t *vd)
 
         es_format_InitFromVideo(&dst, i == 0 ? &v_dst : &v_dst_cmp);
 
-        filter_chain_Reset(osys->converters, &src, &dst);
+        filter_chain_Reset(osys->converters, &src, osys->src_vctx, &dst);
         ret = filter_chain_AppendConverter(osys->converters, &dst);
         es_format_Clean(&dst);
         if (ret == 0)
diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c
index 7aa3c38d658..7919680188c 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -814,8 +814,10 @@ static void ThreadChangeFilters(vout_thread_t *vout,
 
     es_format_t fmt_target;
     es_format_InitFromVideo(&fmt_target, source ? source : &vout->p->filter.src_fmt);
+    vlc_video_context *vctx_target   = source ? src_vctx : vout->p->filter.src_vctx;
 
     const es_format_t *p_fmt_current = &fmt_target;
+    vlc_video_context *vctx_current = vctx_target;
 
     for (int a = 0; a < 2; a++) {
         vlc_array_t    *array = a == 0 ? &array_static :
@@ -823,7 +825,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
         filter_chain_t *chain = a == 0 ? vout->p->filter.chain_static :
                                          vout->p->filter.chain_interactive;
 
-        filter_chain_Reset(chain, p_fmt_current, p_fmt_current);
+        filter_chain_Reset(chain, p_fmt_current, vctx_current, p_fmt_current);
         for (size_t i = 0; i < vlc_array_count(array); i++) {
             vout_filter_t *e = vlc_array_item_at_index(array, i);
             msg_Dbg(vout, "Adding '%s' as %s", e->name, a == 0 ? "static" : "interactive");
@@ -843,6 +845,7 @@ static void ThreadChangeFilters(vout_thread_t *vout,
         if (!filter_chain_IsEmpty(chain))
         {
             p_fmt_current = filter_chain_GetFmtOut(chain);
+            vctx_current = filter_chain_GetVideoCtxOut(chain);
         }
         vlc_array_clear(array);
     }
@@ -853,8 +856,8 @@ static void ThreadChangeFilters(vout_thread_t *vout,
                                          &fmt_target) != 0) {
             msg_Err(vout, "Failed to compensate for the format changes, removing all filters");
             ThreadDelAllFilterCallbacks(vout);
-            filter_chain_Reset(vout->p->filter.chain_static,      &fmt_target, &fmt_target);
-            filter_chain_Reset(vout->p->filter.chain_interactive, &fmt_target, &fmt_target);
+            filter_chain_Reset(vout->p->filter.chain_static,      &fmt_target, vctx_target, &fmt_target);
+            filter_chain_Reset(vout->p->filter.chain_interactive, &fmt_target, vctx_target, &fmt_target);
         }
     }
 
@@ -981,7 +984,9 @@ static picture_t *ConvertRGB32AndBlend(vout_thread_t *vout, picture_t *pic,
     dst.video.i_chroma = VLC_CODEC_RGB32;
     video_format_FixRgb(&dst.video);
 
-    filter_chain_Reset(filterc, &src, &dst);
+    filter_chain_Reset(filterc, &src,
+                       NULL /* TODO output video context of blender */,
+                       &dst);
 
     if (filter_chain_AppendConverter(filterc, &dst) != 0)
     {
-- 
2.17.1



More information about the vlc-devel mailing list