PR #25648 opened by Forgejo_Fairy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25648 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25648.patch
The AVX512ICL unpacker consumes 24 pixels per iteration but stores 32 luma samples and 16 samples per chroma plane. The caller's 12-pixel rounding and reservation can let the last iteration overwrite the next row, or adjacent planes and the allocation end for strideless input. This causes the corruption reported in #25577. Round the accelerated span to whole 24-pixel iterations and reserve at least eight luma samples for the overstores. Skip empty spans because the SIMD loops execute at least once. The existing scalar tail replaces all extra stores. This implements the approach suggested by Dmytro Sinitsyn in the report. Add a generated 48×4 strideless round-trip FATE test with its expected output in tests/ref/fate/v210-strideless. It requires no external sample and fails before this fix under Ice Lake emulation. Validation: - Both reported 1920×1080 failure modes reproduced for three frames under Intel SDE Ice Lake emulation and matched the C reference after the fix. - Verified the regression boundary: f30b4c2f47ab passes and 6af453ca389c fails. - New FATE test, fate-v210, fate-checkasm-v210dec, and v210/v210-10 variants of vsynth1 and vsynth3 pass under emulation. - A separate guard-buffer harness passed all widths 1–8192 with aligned and unaligned dispatch for C, SSSE3, AVX, AVX2 and emulated AVX512ICL. The harness is preserved on fairy/issue25577-tooling. Native AVX512ICL performance was not measured. No release backports are included. From 1ce9e81158430b3f8b0913cb63960d8d4c75733f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 31 Oct 2026 11:42:31 +0000 Subject: [PATCH] avcodec/v210dec: keep SIMD stores within the decoded row The AVX512ICL unpacker consumes 24 pixels per iteration and stores 32 luma and 16 samples of each chroma plane. Rounding the accelerated span to 12 pixels and reserving 12 pixels can therefore overwrite the next row, or the next plane and allocation end for strideless input. Use whole 24-pixel iterations and reserve at least eight luma samples for the overstores. Skip the unpacker for an empty span, since the SIMD loops execute at least once. The scalar tail replaces all extra stores. Add a generated strideless round-trip FATE test which fails with the AVX512ICL decoder before this change and matches the C decoder afterward. Fixes: 6af453ca389c56cb113876628cb173577faa9464 Reported-by: Dmytro Sinitsyn (Davis) Suggested-by: Dmytro Sinitsyn (Davis) Assisted-by: Fairy --- libavcodec/v210dec.c | 7 +++++-- tests/fate/vcodec.mak | 4 ++++ tests/ref/fate/v210-strideless | 8 ++++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 tests/ref/fate/v210-strideless diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index 63337941fd9..6cfb7349d7e 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -61,9 +61,12 @@ static void decode_row(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t * void (*unpack_frame)(const uint32_t *src, uint16_t *y, uint16_t *u, uint16_t *v, int width)) { uint32_t val; - int w = (FFMAX(0, width - 12) / 12) * 12; + /* The widest unpacker processes 24 pixels and writes 8 extra luma + * samples (4 chroma samples). Leave room for those stores within the row. */ + int w = (FFMAX(0, width - 8) / 24) * 24; - unpack_frame(src, y, u, v, w); + if (w) + unpack_frame(src, y, u, v, w); y += w; u += w >> 1; diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak index a5abace91fc..62e35f1c12d 100644 --- a/tests/fate/vcodec.mak +++ b/tests/fate/vcodec.mak @@ -470,6 +470,10 @@ FATE_VCODEC_SCALE-$(call ENCDEC, R210, AVI) += r210 FATE_VCODEC_SCALE-$(call ENCDEC, V210, AVI) += v210 v210-10 fate-vsynth%-v210-10: ENCOPTS = -pix_fmt yuv422p10 +FATE_FFMPEG-$(call TRANSCODE, V210, AVI, LAVFI_INDEV WRAPPED_AVFRAME_DECODER TESTSRC2_FILTER FORMAT_FILTER) += fate-v210-strideless +fate-v210-strideless: CMD = transcode lavfi "testsrc2=size=48x4:rate=1,format=yuv422p10le" avi \ + "-c:v v210 -frames:v 1" "-pix_fmt yuv422p10le" "" "" "-custom_stride -1 -threads 1" + FATE_VCODEC_SCALE-$(call ENCDEC, RAWVIDEO, AVI) += v308 fate-vsynth%-v308: ENCOPTS = -pix_fmt vyu444 -sws_flags neighbor+bitexact fate-vsynth%-v308: DECOPTS = -sws_flags neighbor+bitexact diff --git a/tests/ref/fate/v210-strideless b/tests/ref/fate/v210-strideless new file mode 100644 index 00000000000..4222fd341bd --- /dev/null +++ b/tests/ref/fate/v210-strideless @@ -0,0 +1,8 @@ +8d5042aab12f215c7f338ec9efe7447b *tests/data/fate/v210-strideless.avi +6264 tests/data/fate/v210-strideless.avi +#tb 0: 1/1 +#media_type 0: video +#codec_id 0: rawvideo +#dimensions 0: 48x4 +#sar 0: 1/1 +0, 0, 0, 1, 768, 0x709abefc -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
