PR #24929 opened by Timo Rothenpieler (BtbN)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24929
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24929.patch

Backport of fix from #24908


>From 059de27b682ba39343bb27b4fe020aac885ddf30 Mon Sep 17 00:00:00 2001
From: Timo Rothenpieler <[email protected]>
Date: Wed, 7 Oct 2026 02:25:56 +0200
Subject: [PATCH] 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
(cherry picked from commit 5f9b4882166651da0515bbd0b074e71137545717)
---
 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

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to