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]
