PR #23510 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23510 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23510.patch
The stride was not enough to cover the input width ... >From 1219fef95e8e1ac6a2debdcd823d9d30bc447d3a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 15 Jun 2026 19:00:00 +0200 Subject: [PATCH 1/3] checkasm/sw_rgb: fix too small source stride in uyvytoyuv422 test The planes table stored a source stride smaller than the 2*width bytes a packed UYVY line occupies (e.g. width 12 with stride 12), and the correct stride for width 128 would be 256, which does not even fit the uint8_t field. The test passed only because the oversized source buffer absorbed the resulting out-of-bounds reads. Derive srcStride from the width (2*width) instead of storing it, so each line is passed its true size. Signed-off-by: Michael Niedermayer <[email protected]> --- tests/checkasm/sw_rgb.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c index a38e1d68f5..7a3049ddd1 100644 --- a/tests/checkasm/sw_rgb.c +++ b/tests/checkasm/sw_rgb.c @@ -38,8 +38,8 @@ } while (0) static const uint8_t width[] = {12, 16, 20, 32, 36, 128}; -static const struct {uint8_t w, h, s;} planes[] = { - {12,16,12}, {16,16,16}, {20,23,25}, {32,18,48}, {8,128,16}, {128,128,128} +static const struct {uint8_t w, h;} planes[] = { + {12,16}, {16,16}, {20,23}, {32,18}, {8,128}, {128,128} }; #define MAX_STRIDE 128 @@ -93,6 +93,9 @@ static void check_uyvy_to_422p(void) if (check_func(uyvytoyuv422, "uyvytoyuv422")) { for (i = 0; i < 6; i ++) { + int w = planes[i].w, h = planes[i].h; + int srcStride = 2 * w; + memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT); memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT); memset(dst_u_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT); @@ -100,17 +103,17 @@ static void check_uyvy_to_422p(void) memset(dst_v_0, 0, (MAX_STRIDE/2) * MAX_HEIGHT); memset(dst_v_1, 0, (MAX_STRIDE/2) * MAX_HEIGHT); - call_ref(dst_y_0, dst_u_0, dst_v_0, src0, planes[i].w, planes[i].h, - MAX_STRIDE, MAX_STRIDE / 2, planes[i].s); - call_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[i].w, planes[i].h, - MAX_STRIDE, MAX_STRIDE / 2, planes[i].s); + call_ref(dst_y_0, dst_u_0, dst_v_0, src0, w, h, + MAX_STRIDE, MAX_STRIDE / 2, srcStride); + call_new(dst_y_1, dst_u_1, dst_v_1, src1, w, h, + MAX_STRIDE, MAX_STRIDE / 2, srcStride); if (memcmp(dst_y_0, dst_y_1, MAX_STRIDE * MAX_HEIGHT) || memcmp(dst_u_0, dst_u_1, (MAX_STRIDE/2) * MAX_HEIGHT) || memcmp(dst_v_0, dst_v_1, (MAX_STRIDE/2) * MAX_HEIGHT)) fail(); } bench_new(dst_y_1, dst_u_1, dst_v_1, src1, planes[5].w, planes[5].h, - MAX_STRIDE, MAX_STRIDE / 2, planes[5].s); + MAX_STRIDE, MAX_STRIDE / 2, 2 * planes[5].w); } } -- 2.52.0 >From 9e2693b21f3e6f1e9b0285c9efeb7e22c542a15e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 15 Jun 2026 19:00:26 +0200 Subject: [PATCH 2/3] checkasm/sw_rgb: test uyvytoyuv422 with odd widths The SIMD uyvytoyuv422 implementations only handled even widths correctly. Add odd width and 1x1 entries so the trailing column handling is exercised against the C reference. An odd width reads one source byte more than 2*width, the V sample at src[2w], so the stride is extended by one for odd widths. Signed-off-by: Michael Niedermayer <[email protected]> --- tests/checkasm/sw_rgb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c index 7a3049ddd1..53bde765db 100644 --- a/tests/checkasm/sw_rgb.c +++ b/tests/checkasm/sw_rgb.c @@ -39,7 +39,8 @@ static const uint8_t width[] = {12, 16, 20, 32, 36, 128}; static const struct {uint8_t w, h;} planes[] = { - {12,16}, {16,16}, {20,23}, {32,18}, {8,128}, {128,128} + {12,16}, {16,16}, {20,23}, {32,18}, {8,128}, {128,128}, + {1,1}, {1,4}, {3,8}, {13,16}, {21,9}, {63,7}, {127,5} }; #define MAX_STRIDE 128 @@ -92,9 +93,9 @@ static void check_uyvy_to_422p(void) memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT * 2); if (check_func(uyvytoyuv422, "uyvytoyuv422")) { - for (i = 0; i < 6; i ++) { + for (i = 0; i < FF_ARRAY_ELEMS(planes); i ++) { int w = planes[i].w, h = planes[i].h; - int srcStride = 2 * w; + int srcStride = 2 * w + (w & 1); // UYVY odd width reads V at src[2w] memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT); memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT); -- 2.52.0 >From 8c94b3869c0fcabb194f7dbab3b36ade9d9fa2b0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Mon, 15 Jun 2026 22:12:41 +0200 Subject: [PATCH 3/3] checkasm/sw_rgb: also test yuyvtoyuv422 yuyvtoyuv422 reads the trailing odd V sample at src[2w+1], one byte further than uyvytoyuv422, so the number of extra source bytes an odd width needs is passed in per format (1 for UYVY, 2 for YUYV) and added to the stride. uyvytoyuv420 and yuyvtoyuv420 are intentionally not added: their x86 mmxext chroma averaging uses PAVGB rounding and so is not bit-exact with the C reference, which truncates, so they cannot be verified this way. Signed-off-by: Michael Niedermayer <[email protected]> --- tests/checkasm/sw_rgb.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c index 53bde765db..7bf5d8e175 100644 --- a/tests/checkasm/sw_rgb.c +++ b/tests/checkasm/sw_rgb.c @@ -72,7 +72,7 @@ static void check_shuffle_bytes(void * func, const char * report) } } -static void check_uyvy_to_422p(void) +static void check_interleaved_to_planar(void *func, const char *report, int odd_tail) { int i; @@ -92,10 +92,10 @@ static void check_uyvy_to_422p(void) randomize_buffers(src0, MAX_STRIDE * MAX_HEIGHT * 2); memcpy(src1, src0, MAX_STRIDE * MAX_HEIGHT * 2); - if (check_func(uyvytoyuv422, "uyvytoyuv422")) { + if (check_func(func, "%s", report)) { for (i = 0; i < FF_ARRAY_ELEMS(planes); i ++) { int w = planes[i].w, h = planes[i].h; - int srcStride = 2 * w + (w & 1); // UYVY odd width reads V at src[2w] + int srcStride = 2 * w + (w & 1 ? odd_tail : 0); memset(dst_y_0, 0, MAX_STRIDE * MAX_HEIGHT); memset(dst_y_1, 0, MAX_STRIDE * MAX_HEIGHT); @@ -960,8 +960,10 @@ void checkasm_check_sw_rgb(void) } report("rgb24tobgr32"); - check_uyvy_to_422p(); + check_interleaved_to_planar(uyvytoyuv422, "uyvytoyuv422", 1); report("uyvytoyuv422"); + check_interleaved_to_planar(yuyvtoyuv422, "yuyvtoyuv422", 2); + report("yuyvtoyuv422"); check_interleave_bytes(); report("interleave_bytes"); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
