This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit 848753352d4050d486ffdb523ab86bc08dc5f813
Author:     Niklas Haas <[email protected]>
AuthorDate: Thu Jun 18 13:24:39 2026 +0200
Commit:     Niklas Haas <[email protected]>
CommitDate: Tue Jun 23 11:48:13 2026 +0000

    swscale/ops_dispatch: substantially refactor subpass compilation
    
    Instead of a loop with fixed structure, this function now recursively calls
    itself as many times as needed to satisfy all criteria.
    
    This is absolutely needed for the upcoming refactor which will allow for
    also splitting apart ops lists as needed to e.g. handle partially subsampled
    ops lists, which may need a complex sequence of filtering and merge steps
    to be fully satisfied.
    
    This does modify the way in which subpasses are compiled slightly, in that
    each new subpass first tried again un-split, rather than a single split
    resulting in all subsequent passes being split as well. This is mostly a
    benign change, though it might matter one day.
    
    Sponsored-by: Sovereign Tech Fund
    Signed-off-by: Niklas Haas <[email protected]>
---
 libswscale/ops_dispatch.c | 87 ++++++++++++++++++++++++++---------------------
 1 file changed, 49 insertions(+), 38 deletions(-)

diff --git a/libswscale/ops_dispatch.c b/libswscale/ops_dispatch.c
index f17f40ebab..efb00233e6 100644
--- a/libswscale/ops_dispatch.c
+++ b/libswscale/ops_dispatch.c
@@ -30,6 +30,12 @@
 #include "ops_dispatch.h"
 #include "swscale_internal.h"
 
+#define RET(x)                                                                 
\
+    do {                                                                       
\
+        if ((ret = (x)) < 0)                                                   
\
+            goto fail;                                                         
\
+    } while (0)
+
 typedef struct SwsOpPass {
     SwsCompiledOp comp;
     SwsOpExec exec_base;
@@ -663,6 +669,44 @@ fail:
     return ret;
 }
 
+/* Takes over ownership of *pops, even on failure */
+static int compile_subpass(const CompileArgs *args, SwsOpList **pops,
+                           SwsPass *input, SwsPass **output)
+{
+    SwsContext *ctx = args->graph->ctx;
+    SwsOpList *ops  = *pops;
+    SwsOpList *rest = NULL;
+    SwsPass *tmp = NULL;
+    *pops = NULL;
+
+    int ret = compile_single(args, ops, input, output);
+    if (ret != AVERROR(ENOTSUP))
+        goto fail; /* either success or a hard error */
+
+    /* Find any unresolved filter */
+    for (int idx = 1; idx < ops->num_ops - 1; idx++) {
+        const SwsOp *op = &ops->ops[idx];
+        if (op->op == SWS_OP_FILTER_H || op->op == SWS_OP_FILTER_V) {
+            RET(ff_sws_op_list_split_at(ops, &rest, idx));
+            /* Serial split: feed first pass into second */
+            RET(compile_subpass(args, &ops,  input, &tmp));
+            RET(compile_subpass(args, &rest, tmp, output));
+            return 0;
+        }
+    }
+
+    /* If we didn't find any more operations to eliminate, then this ops list
+     * is simply unsupported by any of the available backends */
+    av_log(ctx, AV_LOG_WARNING, "No backend found for operations:\n");
+    ff_sws_op_list_print(ctx, AV_LOG_WARNING, AV_LOG_TRACE, ops);
+    ret = AVERROR(ENOTSUP);
+
+fail:
+    ff_sws_op_list_free(&ops);
+    ff_sws_op_list_free(&rest);
+    return ret;
+}
+
 int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend,
                         SwsOpList **pops, int flags, SwsPass *input,
                         SwsPass **output)
@@ -700,48 +744,15 @@ int ff_sws_compile_pass(SwsGraph *graph, const 
SwsOpBackend *backend,
         .flags   = flags,
     };
 
-    ret = compile_single(&args, ops, input, output);
-    if (ret != AVERROR(ENOTSUP))
+    ret = compile_subpass(&args, &ops, input, output);
+    if (ret < 0)
         goto out;
 
-    av_log(ctx, AV_LOG_DEBUG, "Retrying with separated filter passes.\n");
-    SwsPass *prev = input;
-    bool first = true;
-    while (ops) {
-        SwsOpList *rest;
-        ret = ff_sws_op_list_subpass(ops, &rest);
-        if (ret < 0)
-            goto out;
-
-        if (first && !rest) {
-            /* No point in compiling an unsplit pass again */
-            ret = AVERROR(ENOTSUP);
-            goto out;
-        }
-
-        ret = compile_single(&args, ops, prev, &prev);
-        if (ret < 0) {
-            ff_sws_op_list_free(&rest);
-            goto out;
-        }
-
-        ff_sws_op_list_free(&ops);
-        first = false;
-        ops = rest;
-    }
-
-    if (output) {
-        /* Return last subpass successfully compiled */
-        av_log(ctx, AV_LOG_VERBOSE, "Using %d separate passes.\n",
-               graph->num_passes - passes_orig);
-        *output = prev;
-    }
+    const int num_passes = graph->num_passes - passes_orig;
+    if (num_passes > 1)
+        av_log(ctx, AV_LOG_VERBOSE, "Using %d separate passes.\n", num_passes);
 
 out:
-    if (ret == AVERROR(ENOTSUP)) {
-        av_log(ctx, AV_LOG_WARNING, "No backend found for operations:\n");
-        ff_sws_op_list_print(ctx, AV_LOG_WARNING, AV_LOG_TRACE, ops);
-    }
     if (ret < 0)
         ff_sws_graph_rollback(graph, passes_orig);
     ff_sws_op_list_free(&ops);

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to