PR #25363 opened by Forgejo_Fairy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25363 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25363.patch
Seeking after probing a small DASH fragment can duplicate the selected segment. Probing may reach EOF and set `is_restart_needed`; `dash_seek()` resets the selected sequence number and read offsets but retains this flag. At the next segment EOF, `read_data()` consequently skips advancing the sequence number and the same segment is opened again. Clear the pending restart before reopening the component. Clearing it before reopening also preserves a new restart legitimately requested while probing the selected segment. A generated 15-second Opus input produces 751 packets without seeking and 1,001 with `-ss 0` before this fix. The duplicated packets have backward timestamps, which FFmpeg adjusts to one-tick increments when writing MP4. With the fix, seek-to-zero packet timestamps and payload hashes match the no-seek baseline exactly. Validation: - Added portable generated-media FATE tests `fate-dash-seek-zero` and `fate-dash-seek-reference`, sharing an expected packet-checksum/timestamp reference. The seek test fails with 14 duplicate MP2 packets before the fix; both pass with 42 packets afterward. - Verified that Opus seeks to 0, 5, 7, 10, and 14 seconds no longer duplicate 250 packets or produce non-monotonic DTS warnings. - Verified the fix with generated H.264/Opus DASH input as well. - Reproduced the underlying bug on master and release/9.0, 8.1, 8.0, 7.1, 6.1, 5.1, and 4.4. The patch itself was tested on master on Linux ARM64. - No additional FATE sample upload is needed. Fixes #25247. >From 2e3196a7089e099bb6e768740218ac3d2e55edd4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 22 Oct 2026 16:42:29 +0000 Subject: [PATCH] avformat/dashdec: clear pending segment restart when seeking Probing a small fragment can reach EOF and set is_restart_needed before a seek. dash_seek selects a new segment but leaves this flag set, so read_data does not advance cur_seq_no at the next EOF. The selected segment is then opened a second time. Clear the pending restart along with the other segment read state before reopening the component. Do this before probing the new segment, which may legitimately set the flag again. Add generated MP2 DASH tests comparing seek-to-zero and sequential packet checksums and timestamps. The seek test emits 14 duplicate packets without the reset; both tests produce the same 42 packets with it. Fixes #25247 Assisted-by: Fairy --- libavformat/dashdec.c | 1 + tests/fate/dashenc.mak | 13 ++++++++++ tests/ref/fate/dash-seek-zero | 47 +++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) create mode 100644 tests/ref/fate/dash-seek-zero diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 8b0fb0361d8..654c0535db8 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -2516,6 +2516,7 @@ set_seq_num: pls->cur_timestamp = 0; pls->cur_seg_offset = 0; pls->init_sec_buf_read_offset = 0; + pls->is_restart_needed = 0; ret = dry_run ? 0 : reopen_demux_for_component(s, pls); return ret; diff --git a/tests/fate/dashenc.mak b/tests/fate/dashenc.mak index a1c00e74021..0f1cca3341c 100644 --- a/tests/fate/dashenc.mak +++ b/tests/fate/dashenc.mak @@ -43,5 +43,18 @@ fate-dash-big-init: tests/data/dash_big_init.mpd fate-dash-big-init: CLEANFILES = tests/data/dash_big_init.mpd tests/data/dash_big_init.m3u8 tests/data/dash_big_init.mp4 tests/data/dash_big_init_*.m4s fate-dash-big-init: CMD = framecrc -i $(TARGET_PATH)/tests/data/dash_big_init.mpd -map 0:a:99 -c copy +tests/data/dash_seek.mpd: TAG = GEN +tests/data/dash_seek.mpd: ffmpeg$(PROGSSUF)$(EXESUF) | tests/data + $(M)$(TARGET_EXEC) $(TARGET_PATH)/$< -nostdin -loglevel error \ + -f lavfi -i "sine=sample_rate=16000:duration=3" \ + -c:a mp2fixed -b:a 8k -bitexact -f dash -seg_duration 1 \ + -init_seg_name dash_seek_init.mp4 -media_seg_name 'dash_seek_$$Number$$.m4s' $(TARGET_PATH)/$@ + +FATE_DASHENC_LAVFI-$(call ALLYES, SINE_FILTER ARESAMPLE_FILTER LAVFI_INDEV PCM_S16LE_DECODER MP2FIXED_ENCODER DASH_MUXER MP4_MUXER DASH_DEMUXER MOV_DEMUXER MP3_DECODER FILE_PROTOCOL FRAMECRC_MUXER PIPE_PROTOCOL) += fate-dash-seek-zero fate-dash-seek-reference +fate-dash-seek-zero fate-dash-seek-reference: tests/data/dash_seek.mpd +fate-dash-seek-zero: CMD = framecrc -ss 0 -i $(TARGET_PATH)/tests/data/dash_seek.mpd -c copy +fate-dash-seek-reference: CMD = framecrc -i $(TARGET_PATH)/tests/data/dash_seek.mpd -c copy +fate-dash-seek-reference: REF = $(SRC_PATH)/tests/ref/fate/dash-seek-zero + FATE_FFMPEG += $(FATE_DASHENC_LAVFI-yes) fate-dashenc: $(FATE_DASHENC_LAVFI-yes) diff --git a/tests/ref/fate/dash-seek-zero b/tests/ref/fate/dash-seek-zero new file mode 100644 index 00000000000..c2190258fd4 --- /dev/null +++ b/tests/ref/fate/dash-seek-zero @@ -0,0 +1,47 @@ +#tb 0: 1/16000 +#media_type 0: audio +#codec_id 0: mp3 +#sample_rate 0: 16000 +#channel_layout_name 0: mono +0, 0, 0, 1152, 72, 0x76b21f9b +0, 1152, 1152, 1152, 72, 0x9e131900 +0, 2304, 2304, 1152, 72, 0xaa621ba7 +0, 3456, 3456, 1152, 72, 0x76ab1842 +0, 4608, 4608, 1152, 72, 0xcc1f1c52 +0, 5760, 5760, 1152, 72, 0xd1991af3 +0, 6912, 6912, 1152, 72, 0x88301bf2 +0, 8064, 8064, 1152, 72, 0x9e8f1bb3 +0, 9216, 9216, 1152, 72, 0xc2911b4d +0, 10368, 10368, 1152, 72, 0xd44d1b0b +0, 11520, 11520, 1152, 72, 0x5d3f1906 +0, 12672, 12672, 1152, 72, 0xc5cb1bae +0, 13824, 13824, 1152, 72, 0x60fa18f9 +0, 14976, 14976, 1152, 72, 0xb0e01be3 +0, 16128, 16128, 1152, 72, 0x4ccf1a2b +0, 17280, 17280, 1152, 72, 0x96ba1b53 +0, 18432, 18432, 1152, 72, 0xc8db1a81 +0, 19584, 19584, 1152, 72, 0xb5161cc4 +0, 20736, 20736, 1152, 72, 0x166a16a6 +0, 21888, 21888, 1152, 72, 0xd6631b63 +0, 23040, 23040, 1152, 72, 0x8a9019e5 +0, 24192, 24192, 1152, 72, 0xb9851c35 +0, 25344, 25344, 1152, 72, 0x81d51936 +0, 26496, 26496, 1152, 72, 0xd0671c45 +0, 27648, 27648, 1152, 72, 0x9ce119d9 +0, 28800, 28800, 1152, 72, 0xbde81b9f +0, 29952, 29952, 1152, 72, 0x9e131900 +0, 31104, 31104, 1152, 72, 0xaa621ba7 +0, 32256, 32256, 1152, 72, 0x76ab1842 +0, 33408, 33408, 1152, 72, 0xcc1f1c52 +0, 34560, 34560, 1152, 72, 0xd1991af3 +0, 35712, 35712, 1152, 72, 0x88301bf2 +0, 36864, 36864, 1152, 72, 0x9e8f1bb3 +0, 38016, 38016, 1152, 72, 0xc2911b4d +0, 39168, 39168, 1152, 72, 0xd44d1b0b +0, 40320, 40320, 1152, 72, 0x5d3f1906 +0, 41472, 41472, 1152, 72, 0xc5cb1bae +0, 42624, 42624, 1152, 72, 0x60fa18f9 +0, 43776, 43776, 1152, 72, 0xb0e01be3 +0, 44928, 44928, 1152, 72, 0x4ccf1a2b +0, 46080, 46080, 1152, 72, 0x96ba1b53 +0, 47232, 47232, 1152, 72, 0x832d1ae9 -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
