swscale/ops_dispatch: make ff_sws_ops_compile() output optional

Allows the uops macro generation code to not actually compile any passes.
More generally, this could be used to e.g. test if an op list is supported by
a backend without actually creating the passes.

The `bool first` change is needed because the `input == prev` check no longer
works if we don't actually compiled any passes.

Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-04-24 02:00:48 +02:00
parent 420b1bf368
commit 76dc83d9be
2 changed files with 22 additions and 12 deletions
+14 -7
View File
@@ -481,6 +481,8 @@ static int compile(SwsGraph *graph, const SwsOpBackend *backend,
int ret = ff_sws_ops_compile(ctx, backend, ops, &p->comp);
if (ret < 0)
goto fail;
else if (!output)
goto fail; /* nothing to do, just return */
const SwsCompiledOp *comp = &p->comp;
const SwsFormat *dst = &ops->dst;
@@ -591,7 +593,8 @@ int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend,
/* Check if the whole operation graph is an end-to-end no-op */
if (ff_sws_op_list_is_noop(ops)) {
*output = input;
if (output)
*output = input;
goto out;
}
@@ -618,32 +621,36 @@ int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend,
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 (prev == input && !rest) {
if (first && !rest) {
/* No point in compiling an unsplit pass again */
ret = AVERROR(ENOTSUP);
goto out;
}
ret = compile(graph, backend, ops, prev, &prev);
ret = compile(graph, backend, ops, prev, output ? &prev : NULL);
if (ret < 0) {
ff_sws_op_list_free(&rest);
goto out;
}
ff_sws_op_list_free(&ops);
first = false;
ops = rest;
}
/* Return last subpass successfully compiled */
av_log(ctx, AV_LOG_VERBOSE, "Using %d separate passes.\n",
graph->num_passes - passes_orig);
*output = prev;
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;
}
out:
if (ret == AVERROR(ENOTSUP)) {
+8 -5
View File
@@ -160,13 +160,16 @@ int ff_sws_ops_compile(SwsContext *ctx, const SwsOpBackend *backend,
/**
* Resolves an operation list to a graph pass. The first and last operations
* must be a read/write respectively. `flags` is a list of SwsOpCompileFlags.
* must be a read/write respectively.
*
* @param backend Force the use of a specific backend (Optional)
*
* Takes over ownership of `ops` and sets it to NULL, even on failure.
*
* Note: `ops` may be modified by this function.
* @param ops Operations to compile. Ownership passes to this function, and
* will be set to NULL, even on failure.
* @param flags Set of SwsOpCompileFlags
* @param input The input for the compiled passes. (Optional)
* @param output The resulting final output pass will be stored here. If NULL,
* no output passes are created, and any compiled functions are
* instead immediately freed.
*/
int ff_sws_compile_pass(SwsGraph *graph, const SwsOpBackend *backend,
SwsOpList **ops, int flags, SwsPass *input,