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 <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-06-05 22:37:18 +02:00
committed by Ramiro Polla
co-authored by Ramiro Polla
parent 016cee7a02
commit 7fc7aaf265
+10 -3
View File
@@ -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);