The follow cmd output corrupted file before the patch: ffmpeg -f lavfi -i color=blue,trim=duration=0.04 \ -f lavfi -i anullsrc,atrim=duration=2 \ -movflags +empty_moov+hybrid_fragmented \ -frag_duration 1000000 \ -frag_interleave 1 \ output.mp4 1. first_track is the first track with track->entry != 0. As in the command above, video track (track index 0) has a single frame. When flush the second fragment, first_track is 1, the audio track. 2. write_moof = i == first_track, so write_moof is false for i = 0. 3. When mov->frag_interleave != 0, mov->mdat_buf != NULL, because it contains audio data. So avio_write is called before write_moof, that is, the data write before moof, and mov_finish_fragment executed with wrong mdat_start. 4. With normal fmp4 output, the error isn't obvious. With hybrid_fragmented, ffplay output.mp4 shows a lot of error messages.
Unified · Split
| @@ -6509,9 +6509,9 @@ static int mov_flush_fragment(AVFormatContext *s, int force) · 6508 unmodified lines | ||
| 6509 | 6509 | int buf_size, write_moof = 1, moof_tracks = -1; |
| 6510 | 6510 | uint8_t *buf; |
| 6511 | 6511 | |
| 6512 | + if (!track->entry) | |
| 6513 | + continue; | |
| 6512 | 6514 | if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) { |
| 6513 | − if (!track->entry) | |
| 6514 | − continue; | |
| 6515 | 6515 | mdat_size = avio_tell(track->mdat_buf); |
| 6516 | 6516 | moof_tracks = i; |
| 6517 | 6517 | } else { |
| @@ -84,6 +84,11 @@ fate-mov-ibi-elst-starts-b: CMD = framemd5 -flags +bitexact -i $(TARGET_SAMPLES) · 83 unmodified lines | ||
| 84 | 84 | # Makes sure that we handle overlapping framgments |
| 85 | 85 | fate-mov-frag-overlap: CMD = framemd5 -i $(TARGET_SAMPLES)/mov/frag_overlap.mp4 |
| 86 | 86 | |
| 87 | +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 -f mp4 | |
| 88 | +fate-mov-mp4-frag-flush: CMP = oneline | |
| 89 | +fate-mov-mp4-frag-flush: REF = a10c0e2e2dfc120f31ca5e59e0e4392a | |
| 90 | +FATE_MOV-$(call ALLYES, LAVFI_INDEV, COLOR_FILTER, FORMAT_FILTER, TRIM_FILTER, ANULL_FILTER, AFORMAT_FILTER, ATRIM_FILTER, PNG_ENCODER, PCM_S16LE_ENCODER, MOV_MUXER) += fate-mov-mp4-frag-flush | |
| 91 | + | |
| 87 | 92 | # Makes sure that we pick the right frames according to edit list when there is no keyframe with PTS < edit list start. |
| 88 | 93 | # For example, when video starts on a B-frame, and edit list starts on that B-frame too. |
| 89 | 94 | # GOP structure : B B I in presentation order. |