diff options
author | Martin Storsjö <martin@martin.st> | 2016-04-20 23:10:37 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2016-05-18 10:37:03 +0300 |
commit | e1eb0fc960163402bbb4e630185790488f7d28ed (patch) | |
tree | 6e27920fd573abb1428ccd0b6fa4e74ab9603165 /libavformat/movenc.c | |
parent | fd4957d9c67996e7d218fd36b4168c9cb85f9ea7 (diff) | |
download | ffmpeg-e1eb0fc960163402bbb4e630185790488f7d28ed.tar.gz |
movenc: Use packets in interleaving queues for the duration at the end of fragments
As long as caller only writes packets using av_interleaved_write_frame
with no manual flushing, this should allow us to always have accurate
durations at the end of fragments, since there should be at least
one queued packet in each stream (except for the stream where the
current packet is being written, but if the muxer itself does the
cutting of fragments, it also has info about the next packet for that
stream).
Signed-off-by: Martin Storsjö <martin@martin.st>
Diffstat (limited to 'libavformat/movenc.c')
-rw-r--r-- | libavformat/movenc.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/libavformat/movenc.c b/libavformat/movenc.c index d8022dcd5c..ae754e13e3 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3188,6 +3188,25 @@ static int mov_flush_fragment(AVFormatContext *s, int force) if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) return 0; + // Try to fill in the duration of the last packet in each stream + // from queued packets in the interleave queues. If the flushing + // of fragments was triggered automatically by an AVPacket, we + // already have reliable info for the end of that track, but other + // tracks may need to be filled in. + for (i = 0; i < s->nb_streams; i++) { + MOVTrack *track = &mov->tracks[i]; + if (!track->end_reliable) { + AVPacket *next = ff_interleaved_peek(s, i); + if (next) { + track->track_duration = next->dts - track->start_dts; + if (next->pts != AV_NOPTS_VALUE) + track->end_pts = next->pts; + else + track->end_pts = next->dts; + } + } + } + for (i = 0; i < mov->nb_streams; i++) { MOVTrack *track = &mov->tracks[i]; if (track->entry <= 1) @@ -3267,6 +3286,7 @@ static int mov_flush_fragment(AVFormatContext *s, int force) mov->tracks[i].track_duration - mov->tracks[i].cluster[0].dts; mov->tracks[i].entry = 0; + mov->tracks[i].end_reliable = 0; } avio_flush(s->pb); return 0; @@ -3346,6 +3366,7 @@ static int mov_flush_fragment(AVFormatContext *s, int force) track->frag_start += duration; track->entry = 0; track->entries_flushed = 0; + track->end_reliable = 0; if (!mov->frag_interleave) { if (!track->mdat_buf) continue; @@ -3650,6 +3671,7 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) trk->end_pts = pkt->pts; else trk->end_pts = pkt->dts; + trk->end_reliable = 1; mov_auto_flush_fragment(s, 0); } } |