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

Steve Lhomme robux4 at ycbcr.xyz
Thu Nov 21 15:14:03 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 |  7 ++++---
 modules/stream_out/sdi/SDIStream.hpp |  2 +-
 modules/stream_out/transcode/video.c | 13 ++++++++-----
 modules/video_chroma/chain.c         |  8 ++++----
 modules/video_filter/canvas.c        |  2 +-
 modules/video_filter/edgedetection.c |  2 +-
 src/misc/filter_chain.c              |  8 +++++++-
 src/video_output/display.c           |  2 +-
 src/video_output/video_output.c      | 11 +++++++----
 11 files changed, 40 insertions(+), 23 deletions(-)

diff --git a/include/vlc_filter.h b/include/vlc_filter.h
index a26083323ae..54833538cc1 100644
--- a/include/vlc_filter.h
+++ b/include/vlc_filter.h
@@ -366,9 +366,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 f378d447f8b..df9189aeb89 100644
--- a/modules/stream_out/mosaic_bridge.c
+++ b/modules/stream_out/mosaic_bridge.c
@@ -575,7 +575,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 2b736f976ff..bc835a65966 100644
--- a/modules/stream_out/sdi/SDIStream.cpp
+++ b/modules/stream_out/sdi/SDIStream.cpp
@@ -503,7 +503,7 @@ static const struct filter_video_callbacks transcode_filter_video_cbs =
     transcode_video_filter_buffer_new, NULL,
 };
 
-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;
@@ -513,7 +513,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)
     {
@@ -547,7 +547,8 @@ 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,
+                                            picture_GetVideoContext(p_pic));
         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 b65e199ae09..b0f507d8a4b 100644
--- a/modules/stream_out/sdi/SDIStream.hpp
+++ b/modules/stream_out/sdi/SDIStream.hpp
@@ -168,7 +168,7 @@ namespace sdi_sout
             static void VideoDecCallback_queue_cc( decoder_t *, block_t *,
                                                    const decoder_cc_desc_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 *);
             void Output(picture_t *);
             void QueueCC(block_t *);
             filter_chain_t *p_filters_chain;
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index f58652725f5..944acf81cb7 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -99,7 +99,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_enc_in );
 
     int chain_works = filter_chain_AppendConverter( test_chain, p_enc_in );
     filter_chain_Delete( test_chain );
@@ -241,6 +241,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 )
 {
@@ -287,7 +288,7 @@ 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;
@@ -308,6 +309,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 )
 {
@@ -319,7 +321,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 )
@@ -338,7 +340,7 @@ static int transcode_video_filters_init( sout_stream_t *p_stream,
     }
 
     /* 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;
 
@@ -349,7 +351,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 );
@@ -554,6 +556,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,
+                                                 picture_GetVideoContext(p_pic),
                                                  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 f812729cac3..dbfb7a6d980 100644
--- a/modules/video_chroma/chain.c
+++ b/modules/video_chroma/chain.c
@@ -378,7 +378,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 ||
@@ -418,7 +418,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;
 }
@@ -429,7 +429,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)
     {
@@ -467,7 +467,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 5ae294d672d..80010eecc17 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 2f158dac0e2..935189122f1 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 b1f097c170b..450987bb47a 100644
--- a/src/misc/filter_chain.c
+++ b/src/misc/filter_chain.c
@@ -174,6 +174,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 );
@@ -181,7 +183,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 );
@@ -189,6 +192,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 2407acf367f..ef7c751a98b 100644
--- a/src/video_output/display.c
+++ b/src/video_output/display.c
@@ -339,7 +339,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 e72483d1b1e..8e3bd6454a9 100644
--- a/src/video_output/video_output.c
+++ b/src/video_output/video_output.c
@@ -814,6 +814,7 @@ 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;
 
@@ -823,7 +824,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_target, 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");
@@ -853,8 +854,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);
         }
     }
 
@@ -996,7 +997,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