From 7fc7aaf265eb64eb745af91b407ddab54af89105 Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Fri, 5 Jun 2026 21:15:57 +0200 Subject: [PATCH] swscale/graph: prefer ops backend for floating point formats These have horrible support in legacy swscale; in particular, they break the pixel range (limited vs full) when converting to yuva444p, resulting in SSIM errors like: uyva 96x96 -> grayf32le 96x96, SSIM={Y=0.997654 U=1.000000 V=1.000000 A=1.000000} loss=1.876414e-03 loss 1.876414e-03 is worse by 1.864254e-03, expected loss 1.215935e-05 (The ops-based backend gets a 100% bit-exact roundtrip here) Signed-off-by: Niklas Haas --- libswscale/graph.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/libswscale/graph.c b/libswscale/graph.c index 83e6787a01..f12c493c49 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -659,6 +659,15 @@ static int add_ops_convert_pass(SwsGraph *graph, const SwsFormat *src, #endif } +static bool prefer_ops_backend(SwsContext *ctx, const SwsFormat *src, const SwsFormat *dst) +{ + if (ctx->flags & SWS_UNSTABLE) + return true; + if (isFloat(src->format) || isFloat(dst->format)) + return true; /* ops backend has better support for float formats */ + return false; /* default to legacy for stability reasons */ +} + static int add_convert_pass(SwsGraph *graph, const SwsFormat *src, const SwsFormat *dst, SwsPass *input, SwsPass **output) @@ -666,13 +675,11 @@ static int add_convert_pass(SwsGraph *graph, const SwsFormat *src, SwsContext *ctx = graph->ctx; int ret; - if (ctx->flags & SWS_UNSTABLE) { - /* Prefer unstable ops backend over legacy backend */ + if (prefer_ops_backend(ctx, src, dst)) { ret = add_ops_convert_pass(graph, src, dst, input, output); if (ret == AVERROR(ENOTSUP)) ret = add_legacy_sws_pass(graph, src, dst, input, output); } else { - /* Prefer legacy backend for stability reasons */ ret = add_legacy_sws_pass(graph, src, dst, input, output); if (ret == AVERROR(ENOTSUP)) ret = add_ops_convert_pass(graph, src, dst, input, output);