tests/swscale: unref buffers before each iteration

Otherwise, we always pass frames that already have buffers allocated, which
breaks the no-op refcopy optimizations.

Testing with -p 0.1 -threads 16 -bench 10, on an AMD Ryzen 9 9950X3D:

 Before:
  Overall speedup=2.776x faster, min=0.133x max=629.496x
  yuv444p 1920x1080 -> yuv444p 1920x1080, flags=0x100000 dither=1
     time=9 us, ref=9 us, speedup=1.043x faster

 After:
  Overall speedup=2.721x faster, min=0.140x max=574.034x
  yuv444p 1920x1080 -> yuv444p 1920x1080, flags=0x100000 dither=1
    time=0 us, ref=28 us, speedup=516.504x faster

(The slowdown in the legacy swscale case is from swscale's lack of a no-op
refcopy optimizaton, plus the fact that it's now actually doing memory
work instead of a no-op / redundant memset)

Signed-off-by: Niklas Haas <git@haasn.dev>
This commit is contained in:
Niklas Haas
2026-02-22 19:47:58 +01:00
committed by Ramiro Polla
parent 271bacffec
commit 2589ce4a2c

View File

@@ -192,6 +192,18 @@ static float get_loss(const float ssim[4])
return 1.0 - sum;
}
static void unref_buffers(AVFrame *frame)
{
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) {
if (!frame->buf[i])
break;
av_buffer_unref(&frame->buf[i]);
}
memset(frame->data, 0, sizeof(frame->data));
memset(frame->linesize, 0, sizeof(frame->linesize));
}
static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode,
struct options opts, int64_t *out_time)
{
@@ -216,8 +228,10 @@ static int scale_legacy(AVFrame *dst, const AVFrame *src, struct mode mode,
goto error;
int64_t time = av_gettime_relative();
for (int i = 0; ret >= 0 && i < opts.iters; i++)
for (int i = 0; ret >= 0 && i < opts.iters; i++) {
unref_buffers(dst);
ret = sws_scale_frame(sws_legacy, dst, src);
}
*out_time = av_gettime_relative() - time;
error:
@@ -284,6 +298,7 @@ static int run_test(enum AVPixelFormat src_fmt, enum AVPixelFormat dst_fmt,
time = av_gettime_relative();
for (int i = 0; i < opts.iters; i++) {
unref_buffers(dst);
if (sws_scale_frame(sws[1], dst, src) < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed %s ---> %s\n",
av_get_pix_fmt_name(src->format), av_get_pix_fmt_name(dst->format));