Commit 31ba826726 for ffmpeg
commit 31ba826726fd0d1547f2c22e041848d1d7f3f860
Author: Jun Zhao <barryjzhao@tencent.com>
Date: Wed Oct 28 11:06:10 2026 +0800
swscale/tests: cover chroma range conversion with FATE references
Print intermediate chroma results for both range directions at
8/9/10/12/14/16 bits, including neutral and nearby values. Test both
planes with the C and available native implementations, and keep
expected values in tests/ref/fate/sws-range-convert.
Based on the test implementation from Forgejo_Fairy in PR #25549.
Signed-off-by: Jun Zhao <barryjzhao@tencent.com>
diff --git a/libswscale/Makefile b/libswscale/Makefile
index 7db08ef966..9c49d6d709 100644
--- a/libswscale/Makefile
+++ b/libswscale/Makefile
@@ -51,6 +51,7 @@ SHLIBOBJS-$(HAVE_GNU_WINDRES) += swscaleres.o
TESTPROGS = colorspace \
floatimg_cmp \
pixdesc_query \
+ range_convert \
swscale \
unscaled_threaded \
diff --git a/libswscale/tests/.gitignore b/libswscale/tests/.gitignore
index 081b75f02e..b358351617 100644
--- a/libswscale/tests/.gitignore
+++ b/libswscale/tests/.gitignore
@@ -1,6 +1,7 @@
/colorspace
/floatimg_cmp
/pixdesc_query
+/range_convert
/rational64
/swscale
/sws_ops
diff --git a/libswscale/tests/range_convert.c b/libswscale/tests/range_convert.c
new file mode 100644
index 0000000000..2794c42fe5
--- /dev/null
+++ b/libswscale/tests/range_convert.c
@@ -0,0 +1,94 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+
+#include "libavutil/common.h"
+#include "libavutil/cpu.h"
+#include "libavutil/mem_internal.h"
+#include "libavutil/pixdesc.h"
+#include "libswscale/swscale_internal.h"
+
+int main(void)
+{
+ static const enum AVPixelFormat formats[] = {
+ AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV444P9,
+ AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV444P12,
+ AV_PIX_FMT_YUV444P14, AV_PIX_FMT_YUV444P16,
+ };
+ const int cpu_flags = av_get_cpu_flags();
+ SwsContext *sws = sws_alloc_context();
+ SwsInternal *c;
+
+ if (!sws)
+ return 1;
+ c = sws_internal(sws);
+
+ for (int native = 0; native < 2; native++) {
+ av_force_cpu_flags(native ? cpu_flags : 0);
+ for (int p = 0; p < FF_ARRAY_ELEMS(formats); p++) {
+ const int depth = av_pix_fmt_desc_get(formats[p])->comp[0].depth;
+ const int shift = (depth <= 14 ? 15 : 19) - depth;
+ const int center = 128 << (depth - 8);
+ const int samples[] = {
+ 0, 16 << (depth - 8), center - 1, center,
+ center + 1, 235 << (depth - 8), 240 << (depth - 8),
+ (1 << depth) - 1,
+ };
+ DECLARE_ALIGNED(32, int16_t, u16)[16];
+ DECLARE_ALIGNED(32, int16_t, v16)[16];
+ DECLARE_ALIGNED(32, int32_t, u32)[16];
+ DECLARE_ALIGNED(32, int32_t, v32)[16];
+
+ sws->src_format = sws->dst_format = formats[p];
+ c->dstBpc = depth;
+ for (int from = 0; from < 2; from++) {
+ sws->src_range = from;
+ sws->dst_range = !from;
+ ff_sws_init_range_convert(c);
+ for (int i = 0; i < 16; i++) {
+ const int u = samples[i % 8] << shift;
+ const int v = samples[7 - i % 8] << shift;
+ if (depth == 16) {
+ u32[i] = u;
+ v32[i] = v;
+ } else {
+ u16[i] = u;
+ v16[i] = v;
+ }
+ }
+ c->chrConvertRange(depth == 16 ? (int16_t *) u32 : u16,
+ depth == 16 ? (int16_t *) v32 : v16, 16,
+ c->chrConvertRange_coeff,
+ c->chrConvertRange_offset);
+ printf("%s %2d-bit %s U:", native ? "native" : "c ",
+ depth, from ? "full-to-limited" : "limited-to-full");
+ for (int i = 0; i < 8; i++)
+ printf(" %d", depth == 16 ? u32[i] : u16[i]);
+ printf(" V:");
+ for (int i = 0; i < 8; i++)
+ printf(" %d", depth == 16 ? v32[i] : v16[i]);
+ printf("\n");
+ }
+ }
+ }
+
+ av_force_cpu_flags(cpu_flags);
+ sws_freeContext(sws);
+ return 0;
+}
diff --git a/tests/fate/libswscale.mak b/tests/fate/libswscale.mak
index 802ac72a03..97a410bc62 100644
--- a/tests/fate/libswscale.mak
+++ b/tests/fate/libswscale.mak
@@ -1,3 +1,7 @@
+FATE_LIBSWSCALE += fate-sws-range-convert
+fate-sws-range-convert: libswscale/tests/range_convert$(EXESUF)
+fate-sws-range-convert: CMD = run libswscale/tests/range_convert$(EXESUF)
+
FATE_LIBSWSCALE += fate-sws-unscaled-threaded
fate-sws-unscaled-threaded: libswscale/tests/unscaled_threaded$(EXESUF)
fate-sws-unscaled-threaded: CMD = run libswscale/tests/unscaled_threaded$(EXESUF)
diff --git a/tests/ref/fate/sws-range-convert b/tests/ref/fate/sws-range-convert
new file mode 100644
index 0000000000..171d85451e
--- /dev/null
+++ b/tests/ref/fate/sws-range-convert
@@ -0,0 +1,24 @@
+c 8-bit limited-to-full U: -2268 64 16238 16384 16530 31976 32705 32767 V: 32767 32705 31976 16530 16384 16238 64 -2268
+c 8-bit full-to-limited U: 1991 3790 16272 16384 16496 28416 28978 30665 V: 30665 28978 28416 16496 16384 16272 3790 1991
+c 9-bit limited-to-full U: -2304 32 16311 16384 16457 32006 32736 32767 V: 32767 32736 32006 16457 16384 16311 32 -2304
+c 9-bit full-to-limited U: 2019 3815 16328 16384 16440 28392 28953 30693 V: 30693 28953 28392 16440 16384 16328 3815 2019
+c 10-bit limited-to-full U: -2323 15 16347 16384 16421 32022 32753 32767 V: 32767 32753 32022 16421 16384 16347 15 -2323
+c 10-bit full-to-limited U: 2034 3828 16356 16384 16412 28380 28940 30706 V: 30706 28940 28380 16412 16384 16356 3828 2034
+c 12-bit limited-to-full U: -2336 4 16375 16384 16393 32033 32764 32767 V: 32767 32764 32033 16393 16384 16375 4 -2336
+c 12-bit full-to-limited U: 2044 3837 16377 16384 16391 28371 28932 30717 V: 30717 28932 28371 16391 16384 16377 3837 2044
+c 14-bit limited-to-full U: -2339 1 16382 16384 16386 32035 32767 32767 V: 32767 32767 32035 16386 16384 16382 1 -2339
+c 14-bit full-to-limited U: 2047 3839 16382 16384 16386 28369 28929 30719 V: 30719 28929 28369 16386 16384 16382 3839 2047
+c 16-bit limited-to-full U: -37445 4 262135 262144 262153 512582 524284 524287 V: 524287 524284 512582 262153 262144 262135 4 -37445
+c 16-bit full-to-limited U: 32764 61437 262137 262144 262151 453891 462852 491517 V: 491517 462852 453891 262151 262144 262137 61437 32764
+native 8-bit limited-to-full U: -2268 64 16238 16384 16530 31976 32705 32767 V: 32767 32705 31976 16530 16384 16238 64 -2268
+native 8-bit full-to-limited U: 1991 3790 16272 16384 16496 28416 28978 30665 V: 30665 28978 28416 16496 16384 16272 3790 1991
+native 9-bit limited-to-full U: -2304 32 16311 16384 16457 32006 32736 32767 V: 32767 32736 32006 16457 16384 16311 32 -2304
+native 9-bit full-to-limited U: 2019 3815 16328 16384 16440 28392 28953 30693 V: 30693 28953 28392 16440 16384 16328 3815 2019
+native 10-bit limited-to-full U: -2323 15 16347 16384 16421 32022 32753 32767 V: 32767 32753 32022 16421 16384 16347 15 -2323
+native 10-bit full-to-limited U: 2034 3828 16356 16384 16412 28380 28940 30706 V: 30706 28940 28380 16412 16384 16356 3828 2034
+native 12-bit limited-to-full U: -2336 4 16375 16384 16393 32033 32764 32767 V: 32767 32764 32033 16393 16384 16375 4 -2336
+native 12-bit full-to-limited U: 2044 3837 16377 16384 16391 28371 28932 30717 V: 30717 28932 28371 16391 16384 16377 3837 2044
+native 14-bit limited-to-full U: -2339 1 16382 16384 16386 32035 32767 32767 V: 32767 32767 32035 16386 16384 16382 1 -2339
+native 14-bit full-to-limited U: 2047 3839 16382 16384 16386 28369 28929 30719 V: 30719 28929 28369 16386 16384 16382 3839 2047
+native 16-bit limited-to-full U: -37445 4 262135 262144 262153 512582 524284 524287 V: 524287 524284 512582 262153 262144 262135 4 -37445
+native 16-bit full-to-limited U: 32764 61437 262137 262144 262151 453891 462852 491517 V: 491517 462852 453891 262151 262144 262137 61437 32764