This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 1cc4c2b236d55feec158f04b20caa1aa0e2e1a50 Author: Niklas Haas <[email protected]> AuthorDate: Thu Dec 4 19:51:22 2025 +0100 Commit: Niklas Haas <[email protected]> CommitDate: Mon Dec 15 14:31:58 2025 +0000 swscale/ops_optimizer: rework ambiguous op_type_is_independent() The current usage is ambiguous between "affects each component equally" and "affects each component independently" - and arguably, the current behavior was a bug (since SWS_OP_DITHER should not commute with a SWIZZLE, at least from a bit-exactness PoV). However, when trying to define cleaner replacements for these concepts, I realized there are too many special cases; and given that we only have two use sites, I decided to just split them directly into "commute" functions for those particular usage cases. As an added benefit, this moves the commutation logic out of the already-long ff_sws_ops_list_optimize(). --- libswscale/ops_optimizer.c | 87 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index f173e1f78f..96d71ae108 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -31,20 +31,76 @@ return ret; \ } while (0) -/* Returns true for operations that are independent per channel. These can - * usually be commuted freely other such operations. */ -static bool op_type_is_independent(SwsOpType op) +/** + * Try to commute a clear op with the next operation. Makes any adjustments + * to the operations as needed, but does not perform the actual commutation. + * + * Returns whether successful. + */ +static bool op_commute_clear(SwsOp *op, SwsOp *next) { - switch (op) { - case SWS_OP_SWAP_BYTES: + av_assert1(op->op == SWS_OP_CLEAR); + switch (next->op) { + case SWS_OP_CONVERT: + op->type = next->convert.to; + /* fall through */ case SWS_OP_LSHIFT: case SWS_OP_RSHIFT: - case SWS_OP_CONVERT: case SWS_OP_DITHER: case SWS_OP_MIN: case SWS_OP_MAX: case SWS_OP_SCALE: + case SWS_OP_CLEAR: + case SWS_OP_READ: + case SWS_OP_SWIZZLE: + ff_sws_apply_op_q(next, op->c.q4); return true; + case SWS_OP_INVALID: + case SWS_OP_SWAP_BYTES: + case SWS_OP_WRITE: + case SWS_OP_LINEAR: + case SWS_OP_PACK: + case SWS_OP_UNPACK: + return false; + case SWS_OP_TYPE_NB: + break; + } + + av_unreachable("Invalid operation type!"); + return false; +} + + /** + * Try to commute a swizzle op with the next operation. Makes any adjustments + * to the operations as needed, but does not perform the actual commutation. + * + * Returns whether successful. + */ +static bool op_commute_swizzle(SwsOp *op, SwsOp *next) +{ + av_assert1(op->op == SWS_OP_SWIZZLE); + switch (next->op) { + case SWS_OP_CONVERT: + op->type = next->convert.to; + /* fall through */ + case SWS_OP_SWAP_BYTES: + case SWS_OP_LSHIFT: + case SWS_OP_RSHIFT: + case SWS_OP_DITHER: + case SWS_OP_SCALE: + return true; + + /* Operations with per-channel coefficients need to be un-swizzled */ + case SWS_OP_MIN: + case SWS_OP_MAX: { + const SwsConst c = next->c; + for (int i = 0; i < 4; i++) { + if (!next->comps.unused[i]) + next->c.q4[op->swizzle.in[i]] = c.q4[i]; + } + return true; + } + case SWS_OP_INVALID: case SWS_OP_READ: case SWS_OP_WRITE: @@ -523,12 +579,7 @@ retry: /* Prefer to clear as late as possible, to avoid doing * redundant work */ - if ((op_type_is_independent(next->op) && next->op != SWS_OP_SWAP_BYTES) || - next->op == SWS_OP_SWIZZLE) - { - if (next->op == SWS_OP_CONVERT) - op->type = next->convert.to; - ff_sws_apply_op_q(next, op->c.q4); + if (op_commute_clear(op, next)) { FFSWAP(SwsOp, *op, *next); goto retry; } @@ -562,17 +613,7 @@ retry: } /* Try to push swizzles with duplicates towards the output */ - if (has_duplicates && op_type_is_independent(next->op)) { - if (next->op == SWS_OP_CONVERT) - op->type = next->convert.to; - if (next->op == SWS_OP_MIN || next->op == SWS_OP_MAX) { - /* Un-swizzle the next operation */ - const SwsConst c = next->c; - for (int i = 0; i < 4; i++) { - if (!next->comps.unused[i]) - next->c.q4[op->swizzle.in[i]] = c.q4[i]; - } - } + if (has_duplicates && op_commute_swizzle(op, next)) { FFSWAP(SwsOp, *op, *next); goto retry; } _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
