diff --git a/libavformat/movenc.c b/libavformat/movenc.c index e949c54f04..42c8771496 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -8437,6 +8437,20 @@ static int mov_write_header(AVFormatContext *s) avio_wb32(pb, 8); // placeholder for extended size field (64 bit) ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free"); mov->mdat_pos = avio_tell(pb); + // The free/wide header that later will be converted into an + // mdat, covering the initial moov and all the fragments. + avio_wb32(pb, 0); + ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free"); + // Write an ftyp atom, hidden in a free/wide. This is neither + // exposed while the file is written, as fragmented, nor when the + // file is finalized into non-fragmented form. However, this allows + // accessing a pristine, sequential ftyp+moov init segment, even + // after the file is finalized. It also allows dumping the whole + // contents of the mdat box, to get the fragmented form of the + // file. + if ((ret = mov_write_identification(pb, s)) < 0) + return ret; + update_size(pb, mov->mdat_pos); } } else if (mov->mode != MODE_AVIF) { if (mov->flags & FF_MOV_FLAG_FASTSTART) @@ -8598,7 +8612,7 @@ static void mov_write_mdat_size(AVFormatContext *s) avio_seek(pb, mov->mdat_pos, SEEK_SET); avio_wb32(pb, mov->mdat_size + 8); if (mov->flags & FF_MOV_FLAG_HYBRID_FRAGMENTED) - ffio_wfourcc(pb, "mdat"); // overwrite the original moov into a mdat + ffio_wfourcc(pb, "mdat"); // overwrite the original free/wide into a mdat } else { /* overwrite 'wide' placeholder atom */ avio_seek(pb, mov->mdat_pos - 8, SEEK_SET); diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index eb666c5865..1f2f589beb 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -92,7 +92,7 @@ fate-mov-frag-overlap: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/frag_overlap.mp4 fate-mov-mp4-frag-flush: CMD = md5 -f lavfi -i color=blue,format=rgb24,trim=duration=0.04 -f lavfi -i anullsrc,aformat=s16,atrim=duration=2 -c:v png -c:a pcm_s16le -movflags +empty_moov+hybrid_fragmented -frag_duration 1000000 -frag_interleave 1 -bitexact -f mp4 fate-mov-mp4-frag-flush: CMP = oneline -fate-mov-mp4-frag-flush: REF = a1ac687d15552505f3c01a43285f32d0 +fate-mov-mp4-frag-flush: REF = 48d833e4773f7542f65dadb446f8bf61 FATE_MOV_FFMPEG-$(call ALLYES, LAVFI_INDEV COLOR_FILTER FORMAT_FILTER TRIM_FILTER \ ANULLSRC_FILTER AFORMAT_FILTER ATRIM_FILTER \ WRAPPED_AVFRAME_DECODER PCM_S16LE_DECODER PCM_S16BE_DECODER \ diff --git a/tests/ref/lavf/mov_hybrid_frag b/tests/ref/lavf/mov_hybrid_frag index 64f4e9085e..13cad9505a 100644 --- a/tests/ref/lavf/mov_hybrid_frag +++ b/tests/ref/lavf/mov_hybrid_frag @@ -1,3 +1,3 @@ -7f79311fa73287c093aa029f58b71476 *tests/data/lavf/lavf.mov_hybrid_frag -358436 tests/data/lavf/lavf.mov_hybrid_frag +b79a7ecf125aef1f97c8e9b7df7066a0 *tests/data/lavf/lavf.mov_hybrid_frag +358464 tests/data/lavf/lavf.mov_hybrid_frag tests/data/lavf/lavf.mov_hybrid_frag CRC=0xbb2b949b