This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 0c1a1ee12e09b8eb9e085d66486da47e9829edc1 Author: Niklas Haas <[email protected]> AuthorDate: Tue May 5 20:11:25 2026 +0200 Commit: Niklas Haas <[email protected]> CommitDate: Sun May 17 10:41:34 2026 +0000 swscale/ops_optimizer: don't push scale past truncating conversions In an op list like: [ u8 +XXX] SWS_OP_READ : 1 elem(s) planar >> 3 [ u8 .XXX] SWS_OP_FILTER_V : 256 -> 320 bilinear (2 taps) [f32 .XXX] SWS_OP_SCALE : * 65535 [f32 +XXX] SWS_OP_CONVERT : f32 -> u16 [u16 zXXX] SWS_OP_SWAP_BYTES [u16 zzzX] SWS_OP_SWIZZLE : 0003 [u16 zzz+] SWS_OP_CLEAR : {_ _ _ 65535} [u16 XXXX] SWS_OP_WRITE : 4 elem(s) packed >> 0 The current version of the code would happily push the SWS_OP_SCALE past the truncating conversion, leading to degenerate loss of information. (In this case, the result was quite extreme) Affects quality across a wide range of formats, e.g.: rgb24 16x16 -> rgb48be 16x32: [ u8 +++X] SWS_OP_READ : 3 elem(s) packed >> 0 min: {0 0 0 _}, max: {255 255 255 _} [ u8 ...X] SWS_OP_FILTER_V : 16 -> 32 bilinear (2 taps) min: {0 0 0 _}, max: {255 255 255 _} + [f32 ...X] SWS_OP_SCALE : * 257 + min: {0 0 0 _}, max: {65535 65535 65535 _} [f32 +++X] SWS_OP_CONVERT : f32 -> u16 - min: {0 0 0 _}, max: {255 255 255 _} - [u16 +++X] SWS_OP_SCALE : * 257 min: {0 0 0 _}, max: {65535 65535 65535 _} [u16 zzzX] SWS_OP_SWAP_BYTES min: {0 0 0 _}, max: {65535 65535 65535 _} [u16 XXXX] SWS_OP_WRITE : 3 elem(s) packed >> 0 (X = unused, z = byteswapped, + = exact, 0 = zero) Signed-off-by: Niklas Haas <[email protected]> --- libswscale/ops_optimizer.c | 15 +++++++++++++-- tests/ref/fate/sws-ops-list | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/libswscale/ops_optimizer.c b/libswscale/ops_optimizer.c index c7972e471f..619c6cf42b 100644 --- a/libswscale/ops_optimizer.c +++ b/libswscale/ops_optimizer.c @@ -337,6 +337,16 @@ static bool extract_swizzle(SwsLinearOp *op, SwsComps prev, SwsSwizzleOp *out_sw return true; } +static int op_result_is_exact(const SwsOp *op) +{ + for (int i = 0; i < 4; i++) { + if (SWS_OP_NEEDED(op, i) && !(op->comps.flags[i] & SWS_COMP_EXACT)) + return false; + } + + return true; +} + int ff_sws_op_list_optimize(SwsOpList *ops) { int ret; @@ -769,9 +779,10 @@ retry: } case SWS_OP_SCALE: - /* Scaling by integer before conversion to int */ + /* Exact integer multiplication */ if (op->scale.factor.den == 1 && next->op == SWS_OP_CONVERT && - ff_sws_pixel_type_is_int(next->convert.to)) + ff_sws_pixel_type_is_int(next->convert.to) && + op_result_is_exact(op)) { op->type = next->convert.to; FFSWAP(SwsOp, *op, *next); diff --git a/tests/ref/fate/sws-ops-list b/tests/ref/fate/sws-ops-list index 533b5e178e..705b26e5cc 100644 --- a/tests/ref/fate/sws-ops-list +++ b/tests/ref/fate/sws-ops-list @@ -1 +1 @@ -8481a9658f6f61c8f7a72edc2ba42b5b +09abbf1916b75341a4f9a643c8afb97f _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
