swscale/ops_chain: simplify ff_sws_compile_op_tables() with int index

Instead of this needlessly complicated dance of allocating on-stack copies
of SwsOpList only to iterate with AVERROR(EAGAIN).

This was originally thought to be useful for compiling multiple ops at once,
but even that can be solved in easier ways.

Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-03-27 19:29:01 +01:00
parent f6a2d41fe2
commit 3f39783337
4 changed files with 20 additions and 35 deletions
+6 -12
View File
@@ -66,20 +66,14 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
av_assert0(ops->num_ops > 0);
const SwsPixelType read_type = ops->ops[0].type;
/* Make on-stack copy of `ops` to iterate over */
SwsOpList rest = *ops;
do {
for (int i = 0; i < ops->num_ops; i++) {
ret = ff_sws_op_compile_tables(ctx, tables, FF_ARRAY_ELEMS(tables),
&rest, SWS_BLOCK_SIZE, chain);
} while (ret == AVERROR(EAGAIN));
if (ret < 0) {
ff_sws_op_chain_free(chain);
if (rest.num_ops < ops->num_ops) {
av_log(ctx, AV_LOG_TRACE, "Uncompiled remainder:\n");
ff_sws_op_list_print(ctx, AV_LOG_TRACE, AV_LOG_TRACE, &rest);
ops, i, SWS_BLOCK_SIZE, chain);
if (ret < 0) {
av_log(ctx, AV_LOG_TRACE, "Failed to compile op %d\n", i);
ff_sws_op_chain_free(chain);
return ret;
}
return ret;
}
*out = (SwsCompiledOp) {
+4 -7
View File
@@ -201,13 +201,13 @@ static int op_match(const SwsOp *op, const SwsOpEntry *entry)
}
int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[],
int num_tables, SwsOpList *ops, const int block_size,
SwsOpChain *chain)
int num_tables, SwsOpList *ops, int ops_index,
const int block_size, SwsOpChain *chain)
{
const SwsOp *op = &ops->ops[ops_index];
const unsigned cpu_flags = av_get_cpu_flags();
const SwsOpEntry *best = NULL;
const SwsOpTable *best_table = NULL;
const SwsOp *op = &ops->ops[0];
int ret, best_score = 0;
SwsImplParams params = {
@@ -258,10 +258,7 @@ int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[],
chain->cpu_flags |= best_table->cpu_flags;
chain->over_read = FFMAX(chain->over_read, res.over_read);
chain->over_write = FFMAX(chain->over_write, res.over_write);
ops->ops++;
ops->num_ops--;
return ops->num_ops ? AVERROR(EAGAIN) : 0;
return 0;
}
#define q2pixel(type, q) ((q).den ? (type) (q).num / (q).den : 0)
+3 -3
View File
@@ -166,10 +166,10 @@ struct SwsOpTable {
* "Compile" a single op by looking it up in a list of fixed size op tables.
* See `op_match` in `ops_chain.c` for details on how the matching works.
*
* Returns 0, AVERROR(EAGAIN), or a negative error code.
* Returns 0 or a negative error code.
*/
int ff_sws_op_compile_tables(SwsContext *ctx, const SwsOpTable *const tables[],
int num_tables, SwsOpList *ops, const int block_size,
SwsOpChain *chain);
int num_tables, SwsOpList *ops, int ops_index,
const int block_size, SwsOpChain *chain);
#endif
+7 -13
View File
@@ -983,11 +983,9 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
.block_size = 2 * FFMIN(mmsize, 32) / ff_sws_op_list_max_size(ops),
};
/* Make on-stack copy of `ops` to iterate over */
SwsOpList rest = *ops;
do {
for (int i = 0; i < ops->num_ops; i++) {
int op_block_size = out->block_size;
SwsOp *op = &rest.ops[0];
SwsOp *op = &ops->ops[i];
if (op_is_type_invariant(op)) {
if (op->op == SWS_OP_CLEAR)
@@ -997,16 +995,12 @@ static int compile(SwsContext *ctx, SwsOpList *ops, SwsCompiledOp *out)
}
ret = ff_sws_op_compile_tables(ctx, tables, FF_ARRAY_ELEMS(tables),
&rest, op_block_size, chain);
} while (ret == AVERROR(EAGAIN));
if (ret < 0) {
ff_sws_op_chain_free(chain);
if (rest.num_ops < ops->num_ops) {
av_log(ctx, AV_LOG_TRACE, "Uncompiled remainder:\n");
ff_sws_op_list_print(ctx, AV_LOG_TRACE, AV_LOG_TRACE, &rest);
ops, i, op_block_size, chain);
if (ret < 0) {
av_log(ctx, AV_LOG_TRACE, "Failed to compile op %d\n", i);
ff_sws_op_chain_free(chain);
return ret;
}
return ret;
}
#define ASSIGN_PROCESS_FUNC(NAME) \