[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