PR #24503 opened by jiangjie URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24503 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24503.patch
Use moof-relative addressing when global sidx shifts fragmented data, and add regression coverage for empty_moov and delay_moov. The bug is caused by an invalid fragment offset after writing a global sidx atom. With global_sidx, FFmpeg writes the fragmented MP4 first and inserts the global sidx in a second pass. This insertion shifts every moof and mdat atom forward in the file. However, the tfhd.base_data_offset fields were already serialized using the original absolute moof offsets and are not updated after the shift. As a result, the demuxer calculates sample positions from stale offsets. It reads bytes from the trun metadata area instead of the corresponding mdat payload. For H.264, those metadata bytes are interpreted as NAL-unit length fields, producing errors such as: Invalid NAL unit size Error splitting the input into NAL units The issue is exposed by combinations such as: global_sidx + frag_keyframe + empty_moov global_sidx + frag_keyframe + delay_moov Using default_base_moof or omit_tfhd_offset avoids the problem because fragment addressing no longer depends on the stale absolute base_data_offset. The fix makes FFmpeg use default-base-is-moof automatically when global_sidx is enabled for fragmented output. >From 211e3183cafe33497fa561ce16c36aaad37781e4 Mon Sep 17 00:00:00 2001 From: jiangjie <[email protected]> Date: Tue, 15 Sep 2026 19:14:18 +0800 Subject: [PATCH] avformat/movenc: fix global sidx fragment offsets Use moof-relative addressing when global sidx shifts fragmented data, and add regression coverage for empty_moov and delay_moov. Fixes issue #24438. --- libavformat/movenc.c | 7 +++++++ tests/fate/mov.mak | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index ecc6544bad..a64d54adc6 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -8273,6 +8273,13 @@ static int mov_init(AVFormatContext *s) mov->flags |= FF_MOV_FLAG_FRAGMENT | FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_DEFAULT_BASE_MOOF | FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS; + /* global_sidx is inserted in a second pass, shifting all fragments. Use + * moof-relative addressing so that tfhd offsets remain valid after that + * shift. */ + if (mov->flags & FF_MOV_FLAG_GLOBAL_SIDX && + mov->flags & FF_MOV_FLAG_FRAGMENT) + mov->flags |= FF_MOV_FLAG_DEFAULT_BASE_MOOF; + if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV && s->flags & AVFMT_FLAG_AUTO_BSF) { av_log(s, AV_LOG_VERBOSE, "Empty MOOV enabled; disabling automatic bitstream filtering\n"); s->flags &= ~AVFMT_FLAG_AUTO_BSF; diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 3c0ac3ec13..dc3f62806c 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -322,6 +322,21 @@ fate-mov-vfr: CMD = md5 -filter_complex testsrc=size=2x2:duration=1,setpts=N*N:s fate-mov-vfr: CMP = oneline fate-mov-vfr: REF = 1558b4a9398d8635783c93f84eb5a60d +# Verify that inserting a global sidx does not invalidate fragment offsets. +FATE_MOV_FFMPEG-$(call ALLYES, LAVFI_INDEV TESTSRC_FILTER MPEG4_ENCODER \ + MP4_MUXER MOV_DEMUXER NULL_MUXER FILE_PROTOCOL) \ + += fate-mov-global-sidx fate-mov-global-sidx-delay-moov +fate-mov-global-sidx: CMP = null +fate-mov-global-sidx: CMD = run_with_temp \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error -f lavfi -i testsrc=size=32x24:rate=25 \ + -frames:v 3 -c:v mpeg4 -movflags +global_sidx+frag_keyframe+empty_moov -f mp4 -y" \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error -f null - -i" mp4 +fate-mov-global-sidx-delay-moov: CMP = null +fate-mov-global-sidx-delay-moov: CMD = run_with_temp \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error -f lavfi -i testsrc=size=32x24:rate=25 \ + -frames:v 3 -c:v mpeg4 -movflags +global_sidx+frag_keyframe+delay_moov -f mp4 -y" \ + "$(FFMPEG) -nostdin -hide_banner -loglevel error -f null - -i" mp4 + FATE_MOV_FFMPEG_FFPROBE-$(call ALLYES, COLOR_FILTER SETPTS_FILTER MPEG4_ENCODER \ MOV_MUXER MOV_DEMUXER FILE_PROTOCOL) \ += fate-mov-vfr-bframes-derived-duration -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
