[FFmpeg-devel] [PATCH 1/4] checkasm/sw_rgb: add rgb24toyv12 tests
Ramiro Polla
ramiro.polla at gmail.com
Wed Aug 28 23:43:00 EEST 2024
NOTE: currently the tests for rgb24toyv12 fail for x86 since the c and
mmxext implementations differ (the mmxext version averages four
rgb pixels before performing the chroma calculations).
---
tests/checkasm/sw_rgb.c | 89 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 89 insertions(+)
diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c
index f278454d3d..ff84ddf5ef 100644
--- a/tests/checkasm/sw_rgb.c
+++ b/tests/checkasm/sw_rgb.c
@@ -114,6 +114,92 @@ static void check_uyvy_to_422p(void)
}
}
+#define NUM_LINES 5
+#define MAX_LINE_SIZE 1920
+#define BUFSIZE (NUM_LINES * MAX_LINE_SIZE)
+
+static int cmp_off_by_n(const uint8_t *ref, const uint8_t *test, size_t n, int accuracy)
+{
+ for (size_t i = 0; i < n; i++) {
+ if (abs(ref[i] - test[i]) > accuracy)
+ return 1;
+ }
+ return 0;
+}
+
+static void check_rgb24toyv12(struct SwsContext *ctx)
+{
+ static const int input_sizes[] = {16, 128, 512, MAX_LINE_SIZE, -MAX_LINE_SIZE};
+
+ LOCAL_ALIGNED_32(uint8_t, src, [BUFSIZE * 3]);
+ LOCAL_ALIGNED_32(uint8_t, buf_y_0, [BUFSIZE]);
+ LOCAL_ALIGNED_32(uint8_t, buf_y_1, [BUFSIZE]);
+ LOCAL_ALIGNED_32(uint8_t, buf_u_0, [BUFSIZE / 4]);
+ LOCAL_ALIGNED_32(uint8_t, buf_u_1, [BUFSIZE / 4]);
+ LOCAL_ALIGNED_32(uint8_t, buf_v_0, [BUFSIZE / 4]);
+ LOCAL_ALIGNED_32(uint8_t, buf_v_1, [BUFSIZE / 4]);
+
+ declare_func(void, const uint8_t *src, uint8_t *ydst, uint8_t *udst,
+ uint8_t *vdst, int width, int height, int lumStride,
+ int chromStride, int srcStride, int32_t *rgb2yuv);
+
+ randomize_buffers(src, BUFSIZE * 3);
+
+ for (int isi = 0; isi < FF_ARRAY_ELEMS(input_sizes); isi++) {
+ int input_size = input_sizes[isi];
+ int negstride = input_size < 0;
+ const char *negstride_str = negstride ? "_negstride" : "";
+ int width = FFABS(input_size);
+ int linesize = width + 32;
+ /* calculate height based on specified width to use the entire buffer. */
+ int height = (BUFSIZE / linesize) & ~1;
+ uint8_t *src0 = src;
+ uint8_t *src1 = src;
+ uint8_t *dst_y_0 = buf_y_0;
+ uint8_t *dst_y_1 = buf_y_1;
+ uint8_t *dst_u_0 = buf_u_0;
+ uint8_t *dst_u_1 = buf_u_1;
+ uint8_t *dst_v_0 = buf_v_0;
+ uint8_t *dst_v_1 = buf_v_1;
+
+ if (negstride) {
+ src0 += (height - 1) * (linesize * 3);
+ src1 += (height - 1) * (linesize * 3);
+ dst_y_0 += (height - 1) * linesize;
+ dst_y_1 += (height - 1) * linesize;
+ dst_u_0 += ((height / 2) - 1) * (linesize / 2);
+ dst_u_1 += ((height / 2) - 1) * (linesize / 2);
+ dst_v_0 += ((height / 2) - 1) * (linesize / 2);
+ dst_v_1 += ((height / 2) - 1) * (linesize / 2);
+ linesize *= -1;
+ }
+
+ if (check_func(ff_rgb24toyv12, "rgb24toyv12_%d_%d%s", width, height, negstride_str)) {
+ memset(buf_y_0, 0xFF, BUFSIZE);
+ memset(buf_y_1, 0xFF, BUFSIZE);
+ memset(buf_u_0, 0xFF, BUFSIZE / 4);
+ memset(buf_u_1, 0xFF, BUFSIZE / 4);
+ memset(buf_v_0, 0xFF, BUFSIZE / 4);
+ memset(buf_v_1, 0xFF, BUFSIZE / 4);
+
+ call_ref(src0, dst_y_0, dst_u_0, dst_v_0, width, height,
+ linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
+ call_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
+ linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
+ if (cmp_off_by_n(buf_y_0, buf_y_1, BUFSIZE, 1) ||
+ cmp_off_by_n(buf_u_0, buf_u_1, BUFSIZE / 4, 1) ||
+ cmp_off_by_n(buf_v_0, buf_v_1, BUFSIZE / 4, 1))
+ fail();
+ bench_new(src1, dst_y_1, dst_u_1, dst_v_1, width, height,
+ linesize, linesize / 2, linesize * 3, ctx->input_rgb2yuv_table);
+ }
+ }
+}
+
+#undef NUM_LINES
+#undef MAX_LINE_SIZE
+#undef BUFSIZE
+
static void check_interleave_bytes(void)
{
LOCAL_ALIGNED_16(uint8_t, src0_buf, [MAX_STRIDE*MAX_HEIGHT+1]);
@@ -327,5 +413,8 @@ void checkasm_check_sw_rgb(void)
check_rgb_to_uv(ctx);
report("rgb_to_uv");
+ check_rgb24toyv12(ctx);
+ report("rgb24toyv12");
+
sws_freeContext(ctx);
}
--
2.30.2
More information about the ffmpeg-devel
mailing list