PR #25184 opened by Marti2203
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25184
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25184.patch

Follow-up to #25179: this crash was found and reported by the review of that PR 
(it predates the PR and is unrelated to it).

`filter_frame()` selected the aligned or unaligned 16x16 SAD from the alignment 
of the current frame (`in->data[0]`), but the first source of every SAD call is 
the reference (previous) frame. With frames of different alignment, e.g. crop 
with frame-dependent offsets, the aligned x86 SAD reads the reference frame 
unaligned and crashes:

```
ffmpeg -f lavfi -i 
"testsrc2=size=320x240:rate=10:duration=2,crop=304:224:x='6*sin(t*5)':y='5*cos(t*4)'"
 -vf deshake -f null -
```

(SIGSEGV on an x86 asm build; `search=less` and a user-defined box crash the 
same way.)

The fix checks the alignment of the reference frame. Block offsets keep the 
alignment, since `rx` is required to be a multiple of 16 and the box is aligned 
to 16. As the aligned and unaligned SAD return the same sums, the output is 
otherwise unchanged; it matches a build without x86 asm.

The second commit adds `fate-filter-deshake-crop`, which crashes without the 
fix on x86 (asm) and gives the same output with and without asm. It is placed 
away from the `fate-filter-deshake` test added in #25179.

🤖 Generated with [Claude Code](https://claude.com/claude-code)



From 6166c9bd9e2a9fa213a5347166b4d207c630d65b Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Sun, 18 Oct 2026 19:21:40 +0800
Subject: [PATCH 1/2] avfilter/vf_deshake: select the SAD function from the
 reference frame

The first source of every SAD call is the reference (previous) frame, but
the aligned SAD variant was selected from the current frame's alignment.
When the two frames have different alignment, e.g. after crop with
frame-dependent offsets, the aligned x86 SAD read the reference frame
unaligned and crashed:

  ffmpeg -f lavfi -i 
"testsrc2=size=320x240:rate=10:duration=2,crop=304:224:x='6*sin(t*5)':y='5*cos(t*4)'"
 -vf deshake -f null -

Check the alignment of the reference frame instead.

Reported-by: Forgejo_Fairy (review of #25179)
Signed-off-by: Martin Mirchev <[email protected]>
---
 libavfilter/vf_deshake.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index afd0989e05..a134f7abc8 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -466,6 +466,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(link->format);
     const int chroma_width  = AV_CEIL_RSHIFT(link->w, desc->log2_chroma_w);
     const int chroma_height = AV_CEIL_RSHIFT(link->h, desc->log2_chroma_h);
+    const uint8_t *ref;
     int aligned;
     float transform_zoom;
 
@@ -476,7 +477,9 @@ static int filter_frame(AVFilterLink *link, AVFrame *in)
     }
     av_frame_copy_props(out, in);
 
-    aligned = !((intptr_t)in->data[0] & 15 | in->linesize[0] & 15);
+    /* The first SAD source is the reference (previous) frame. */
+    ref = deshake->ref ? deshake->ref->data[0] : in->data[0];
+    aligned = !((intptr_t)ref & 15 | in->linesize[0] & 15);
     deshake->sad = av_pixelutils_get_sad_fn(4, 4, aligned, deshake); // 16x16, 
2nd source unaligned
     if (!deshake->sad) {
         ret = AVERROR(EINVAL);
-- 
2.54.0


From 50c877d92cbe318e62dcec32ddce9abb186300ff Mon Sep 17 00:00:00 2001
From: Martin Mirchev <[email protected]>
Date: Sun, 18 Oct 2026 19:21:40 +0800
Subject: [PATCH 2/2] fate/filter-video: add a deshake test with crop offsets

Feed deshake frames whose data pointers have different alignment, which
crashed on x86 before the SAD function was selected from the reference
frame.

Signed-off-by: Martin Mirchev <[email protected]>
---
 tests/fate/filter-video.mak        |  5 +++++
 tests/ref/fate/filter-deshake-crop | 25 +++++++++++++++++++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 tests/ref/fate/filter-deshake-crop

diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak
index 4a065ec032..b1f41318c5 100644
--- a/tests/fate/filter-video.mak
+++ b/tests/fate/filter-video.mak
@@ -477,6 +477,11 @@ FATE_FILTER-$(call FILTERFRAMECRC, TESTSRC2 CHROMASHIFT) 
+= fate-filter-chromash
 fate-filter-chromashift-smear: CMD = framecrc -lavfi 
testsrc2=r=5:d=1,chromashift=cbh=-1:cbv=1:crh=2:crv=-2:edge=smear -pix_fmt 
yuv420p
 fate-filter-chromashift-wrap:  CMD = framecrc -lavfi 
testsrc2=r=5:d=1,chromashift=cbh=-1:cbv=1:crh=2:crv=-2:edge=wrap  -pix_fmt 
yuv420p
 
+# Frames whose data pointers have different alignment, as produced by crop
+# with frame-dependent offsets, as deshake input.
+FATE_FILTER-$(call FILTERFRAMECRC, TESTSRC2 CROP DESHAKE) += 
fate-filter-deshake-crop
+fate-filter-deshake-crop: CMD = framecrc -auto_conversion_filters -flags 
bitexact -lavfi 
"testsrc2=s=320x240:r=10:d=2,crop=304:224:x=6*sin(t*5):y=5*cos(t*4),deshake" 
-pix_fmt yuv420p
+
 FATE_FILTER-$(call FILTERFRAMECRC, TESTSRC2 FPS DECIMATE) += 
fate-filter-decimate
 fate-filter-decimate: CMD = framecrc -lavfi 
testsrc2=r=24:d=10,fps=60,decimate=5,decimate=4,decimate=3 -pix_fmt yuv420p
 
diff --git a/tests/ref/fate/filter-deshake-crop 
b/tests/ref/fate/filter-deshake-crop
new file mode 100644
index 0000000000..cd2d141ed4
--- /dev/null
+++ b/tests/ref/fate/filter-deshake-crop
@@ -0,0 +1,25 @@
+#tb 0: 1/10
+#media_type 0: video
+#codec_id 0: rawvideo
+#dimensions 0: 304x224
+#sar 0: 1/1
+0,          0,          0,        1,   102144, 0x06f6df24
+0,          1,          1,        1,   102144, 0xe671b115
+0,          2,          2,        1,   102144, 0x698c3556
+0,          3,          3,        1,   102144, 0x384709b2
+0,          4,          4,        1,   102144, 0xf1b64929
+0,          5,          5,        1,   102144, 0x0a815666
+0,          6,          6,        1,   102144, 0x10d5f633
+0,          7,          7,        1,   102144, 0x8c3b3aa0
+0,          8,          8,        1,   102144, 0xdef47f83
+0,          9,          9,        1,   102144, 0x71370953
+0,         10,         10,        1,   102144, 0x7fd01b43
+0,         11,         11,        1,   102144, 0x405ae32e
+0,         12,         12,        1,   102144, 0xea6aa17d
+0,         13,         13,        1,   102144, 0x2be301e3
+0,         14,         14,        1,   102144, 0x6deccf35
+0,         15,         15,        1,   102144, 0x23ff508c
+0,         16,         16,        1,   102144, 0x9d62dd61
+0,         17,         17,        1,   102144, 0xf80ce778
+0,         18,         18,        1,   102144, 0x49bc5078
+0,         19,         19,        1,   102144, 0xc151d318
-- 
2.54.0

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

Reply via email to