[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