PR #24908 opened by Timo Rothenpieler (BtbN) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24908 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24908.patch
Fixes an over-read of one line, and adds testcases to checkasm what would have caught this. Fixes: #YWH-PGM45796-1 >From 05a7bf45a852396437e94371c0e947a7ea9d6ad1 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler <[email protected]> Date: Tue, 6 Oct 2026 21:14:50 +0200 Subject: [PATCH 1/2] swscale/aarch64: fix uyvy/yuyv to yuv420p with a height of 1 For yuv420 output, interleaved_yuv_to_planar processes two source lines per iteration and keeps the pair count, height >> 1, in w5. Both the fast and the slow path test that counter only at the bottom of the loop, so a height of 1 starts with w5 == 0: the body runs once, reading a second source line and writing a second luma line that don't exist, then w5 wraps to -1 and the loop runs far past the buffers. A height of 1 is reached with 1-line frames, and also when swscale slice-threads a conversion and the last slice is a single line. Skip the pair loop when there are no full line pairs and go straight to the existing odd-last-line handling. The fast-path tail code reads the tail width from w9, which is otherwise only set at the loop head, so set it there too. uyvytoyuv422 and yuyvtoyuv422 do not pair lines and are not affected. Fixes: #YWH-PGM45796-1 Reported-by: jpraveenrao Assisted-by: Claude Opus 5.5 --- libswscale/aarch64/rgb2rgb_neon.S | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libswscale/aarch64/rgb2rgb_neon.S b/libswscale/aarch64/rgb2rgb_neon.S index ba2f904879..76a9e07774 100644 --- a/libswscale/aarch64/rgb2rgb_neon.S +++ b/libswscale/aarch64/rgb2rgb_neon.S @@ -884,6 +884,9 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 b.eq 6f +.ifc \dst_fmt, yuv420 + cbz w5, 30f // height==1: no full line pairs, handle the lone line only +.endif 1: // fast path - the width is at least 32 and w14, w4, #~31 // w14 is the main loop counter and w9, w4, #31 // w9 holds the remaining width, 0 to 31 @@ -898,7 +901,9 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 b.ne 1b .ifc \dst_fmt, yuv420 // handle the last line in case the height is odd +30: cbz w17, 3f + and w9, w4, #31 // tail width, needed by the shift-back below and w14, w4, #~31 4: fastpath_iteration \src_fmt, \dst_fmt, 0, 1 @@ -916,6 +921,9 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 6: // slow path - width is at most 31 and w9, w4, #31 +.ifc \dst_fmt, yuv420 + cbz w5, 60f // height==1: no full line pairs, handle the lone line only +.endif cbz w9, 9f // even part empty (orig width 0 or 1) 7: subs w9, w9, #2 @@ -928,6 +936,7 @@ function ff_\src_fmt\()to\dst_fmt\()_neon, export=1 b.ne 6b .ifc \dst_fmt, yuv420 +60: cbz w17, 8f and w9, w4, #31 .ifc \src_fmt, uyvy -- 2.52.0 >From 4b97ed51dff93104a80c3dc12b2c9f4e4c2e8651 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler <[email protected]> Date: Tue, 6 Oct 2026 21:22:09 +0200 Subject: [PATCH 2/2] tests/checkasm/sw_rgb: test uyvytoyuv420 and yuyvtoyuv420 Only the yuv422 variants of the interleaved-to-planar converters were tested, so the yuv420 variants had no coverage at all. The existing helper works for 4:2:0 output as is, since it compares whole destination buffers. Also add single-line sizes covering the slow path, the fast path, and the fast path with a tail, which would have caught the height-1 overrun fixed in the previous commit. Assisted-by: Claude Opus 5.5 --- tests/checkasm/sw_rgb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/checkasm/sw_rgb.c b/tests/checkasm/sw_rgb.c index 7bf5d8e175..723f810411 100644 --- a/tests/checkasm/sw_rgb.c +++ b/tests/checkasm/sw_rgb.c @@ -40,7 +40,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}, - {1,1}, {1,4}, {3,8}, {13,16}, {21,9}, {63,7}, {127,5} + {1,1}, {1,4}, {3,8}, {13,16}, {21,9}, {63,7}, {127,5}, + {13,1}, {32,1}, {66,1} }; #define MAX_STRIDE 128 @@ -964,6 +965,10 @@ void checkasm_check_sw_rgb(void) report("uyvytoyuv422"); check_interleaved_to_planar(yuyvtoyuv422, "yuyvtoyuv422", 2); report("yuyvtoyuv422"); + check_interleaved_to_planar(uyvytoyuv420, "uyvytoyuv420", 1); + report("uyvytoyuv420"); + check_interleaved_to_planar(yuyvtoyuv420, "yuyvtoyuv420", 2); + report("yuyvtoyuv420"); check_interleave_bytes(); report("interleave_bytes"); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
