[vlc-commits] [Git][videolan/vlc][master] 2 commits: chroma: chain: let AppendChromaChain override the target format
Steve Lhomme (@robUx4)
gitlab at videolan.org
Thu Apr 23 05:26:44 UTC 2026
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
d9352dd6 by Thomas Guillem at 2026-04-23T05:10:52+00:00
chroma: chain: let AppendChromaChain override the target format
This will allow using a resize+chroma filter as the last converter.
No functional changes. last_fmt will be used in the next commit.
- - - - -
c7470a3b by Thomas Guillem at 2026-04-23T05:10:52+00:00
chroma: chain: handle chroma+resize via the probe path
BuildChromaResize only tried 2-step pipelines, so multi step conversions
like VAAPI_420 -> I420 -> RV24 couldn't work.
Go through BuildChromaChain instead, and pass fmt_out as the last
converter's target so swscale can do chroma+resize at once.
If that is not possible (if a hw->cpu download filter can't resize),
retry with a normal chroma chain and append resize-only converter.
Fixes #29795
- - - - -
1 changed file:
- modules/video_chroma/chain.c
Changes:
=====================================
modules/video_chroma/chain.c
=====================================
@@ -57,12 +57,10 @@ static void Flush ( filter_t * );
static int ChainMouse ( filter_t *p_filter, vlc_mouse_t *p_mouse, const vlc_mouse_t *p_old );
static int BuildTransformChain( filter_t *p_filter );
-static int BuildChromaResize( filter_t * );
static int BuildChromaChain( filter_t *p_filter );
static int BuildFilterChain( filter_t *p_filter );
static int CreateChain( filter_t *p_filter, const es_format_t *p_fmt_mid );
-static int CreateResizeChromaChain( filter_t *p_filter, const es_format_t *p_fmt_mid );
static void EsFormatMergeSize( es_format_t *p_dst,
const es_format_t *p_base,
const es_format_t *p_size );
@@ -167,13 +165,9 @@ static int Activate( filter_t *p_filter, int (*pf_build)(filter_t *) )
static int ActivateConverter( filter_t *p_filter )
{
const bool b_chroma = !video_format_IsSameChroma( &p_filter->fmt_in.video, &p_filter->fmt_out.video);
- const bool b_resize = p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ||
- p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height;
-
- const bool b_chroma_resize = b_chroma && b_resize;
const bool b_transform = p_filter->fmt_in.video.orientation != p_filter->fmt_out.video.orientation;
- if( !b_chroma && !b_chroma_resize && !b_transform)
+ if( !b_chroma && !b_transform )
return VLC_EGENERIC;
if( var_Type( vlc_object_parent(p_filter), "chain-level" ) != 0 )
@@ -181,7 +175,6 @@ static int ActivateConverter( filter_t *p_filter )
var_Create( p_filter, "chain-level", VLC_VAR_INTEGER );
int ret = Activate( p_filter, b_transform ? BuildTransformChain :
- b_chroma_resize ? BuildChromaResize :
BuildChromaChain );
var_Destroy( p_filter, "chain-level" );
@@ -256,41 +249,25 @@ static int BuildTransformChain( filter_t *p_filter )
return i_ret;
}
-static int BuildChromaResize( filter_t *p_filter )
-{
- es_format_t fmt_mid;
- int i_ret;
-
- /* Lets try resizing and then doing the chroma conversion */
- msg_Dbg( p_filter, "Trying to build resize+chroma" );
- EsFormatMergeSize( &fmt_mid, &p_filter->fmt_in, &p_filter->fmt_out );
- i_ret = CreateResizeChromaChain( p_filter, &fmt_mid );
- es_format_Clean( &fmt_mid );
-
- if( i_ret == VLC_SUCCESS )
- return VLC_SUCCESS;
-
- /* Lets try it the other way around (chroma and then resize) */
- msg_Dbg( p_filter, "Trying to build chroma+resize" );
- EsFormatMergeSize( &fmt_mid, &p_filter->fmt_out, &p_filter->fmt_in );
- i_ret = CreateChain( p_filter, &fmt_mid );
- es_format_Clean( &fmt_mid );
- if( i_ret == VLC_SUCCESS )
- return VLC_SUCCESS;
-
- return VLC_EGENERIC;
-}
-
static int AppendChromaChain( filter_t *p_filter, const vlc_fourcc_t *chromas,
- size_t chroma_count )
+ size_t chroma_count, const es_format_t *last_fmt )
{
filter_sys_t *p_sys = p_filter->p_sys;
es_format_t fmt_mid;
for( size_t i = 0; i < chroma_count; ++i )
{
- es_format_Copy( &fmt_mid, &p_filter->fmt_in );
- fmt_mid.i_codec = fmt_mid.video.i_chroma = chromas[i];
+
+ if( i == chroma_count - 1 && last_fmt != NULL )
+ {
+ assert( last_fmt->i_codec == chromas[i] );
+ es_format_Copy( &fmt_mid, last_fmt );
+ }
+ else
+ {
+ es_format_Copy( &fmt_mid, &p_filter->fmt_in );
+ fmt_mid.i_codec = fmt_mid.video.i_chroma = chromas[i];
+ }
int i_ret = filter_chain_AppendConverter( p_sys->p_chain, &fmt_mid );
es_format_Clean( &fmt_mid );
@@ -306,6 +283,9 @@ static int BuildChromaChain( filter_t *p_filter )
filter_sys_t *p_sys = p_filter->p_sys;
int i_ret = VLC_EGENERIC;
+ const bool resize = p_filter->fmt_in.video.i_width != p_filter->fmt_out.video.i_width ||
+ p_filter->fmt_in.video.i_height != p_filter->fmt_out.video.i_height;
+
size_t res_count;
struct vlc_chroma_conv_result *results =
vlc_chroma_conv_Probe( p_filter->fmt_in.video.i_chroma,
@@ -332,7 +312,23 @@ static int BuildChromaChain( filter_t *p_filter )
filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in, p_filter->vctx_in,
&p_filter->fmt_out );
- i_ret = AppendChromaChain( p_filter, &res->chain[1], res->chain_count - 1);
+ /* Try the one-pass chain: the last converter handles chroma+resize. */
+ i_ret = AppendChromaChain( p_filter, &res->chain[1], res->chain_count - 1,
+ &p_filter->fmt_out );
+ if( i_ret != VLC_SUCCESS && resize )
+ {
+ msg_Warn( p_filter, "one-pass chain failed, trying chroma chain, "
+ "then resize");
+ filter_chain_Reset( p_sys->p_chain, &p_filter->fmt_in,
+ p_filter->vctx_in, &p_filter->fmt_out );
+
+ i_ret = AppendChromaChain( p_filter, &res->chain[1],
+ res->chain_count - 1, NULL );
+ if( i_ret == VLC_SUCCESS )
+ i_ret = filter_chain_AppendConverter( p_sys->p_chain,
+ &p_filter->fmt_out );
+ }
+
if( i_ret == VLC_SUCCESS )
{
p_filter->vctx_out = filter_chain_GetVideoCtxOut( p_sys->p_chain );
@@ -415,7 +411,7 @@ static int BuildFilterChain( filter_t *p_filter )
&p_filter->fmt_out );
i_ret = AppendChromaChain( p_filter, &res->chain[1],
- res->chain_count - 1 );
+ res->chain_count - 1, NULL );
if( i_ret != VLC_SUCCESS )
continue;
@@ -468,40 +464,6 @@ error:
return VLC_EGENERIC;
}
-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->vctx_in, &p_filter->fmt_out );
-
- int i_ret = filter_chain_AppendConverter( p_sys->p_chain, p_fmt_mid );
- if( i_ret != VLC_SUCCESS )
- return i_ret;
-
- if( p_filter->b_allow_fmt_out_change )
- {
- /* XXX: Update i_sar_num/i_sar_den from last converter. Cf.
- * p_filter->b_allow_fmt_out_change comment in video_chroma/swscale.c.
- * */
-
- es_format_t fmt_out;
- es_format_Copy( &fmt_out,
- filter_chain_GetFmtOut( p_sys->p_chain ) );
- fmt_out.video.i_chroma = p_filter->fmt_out.video.i_chroma;
-
- i_ret = filter_chain_AppendConverter( p_sys->p_chain, &fmt_out );
- es_format_Clean( &fmt_out );
- }
- else
- i_ret = filter_chain_AppendConverter( p_sys->p_chain, &p_filter->fmt_out );
-
- if( i_ret != VLC_SUCCESS )
- filter_chain_Clear( p_sys->p_chain );
- else
- p_filter->vctx_out = filter_chain_GetVideoCtxOut( p_sys->p_chain );
-
- return i_ret;
-}
-
static void EsFormatMergeSize( es_format_t *p_dst,
const es_format_t *p_base,
const es_format_t *p_size )
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bd7d103792c37f6a9883b40d099f008672e2ea39...c7470a3b703552b395d3b53eec75d813a591f330
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/bd7d103792c37f6a9883b40d099f008672e2ea39...c7470a3b703552b395d3b53eec75d813a591f330
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list