diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2016-08-12 21:28:08 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2016-09-11 23:17:31 +0200 |
commit | cb114ed464069ac83f05a4ebdfe992e8f1549815 (patch) | |
tree | 380e2c4845b1f7ddf4d35d4d26670373a2d3cfa5 /libavformat/mux.c | |
parent | 09317e3e06d7126337c2311ecf8bb7762369c110 (diff) | |
download | ffmpeg-cb114ed464069ac83f05a4ebdfe992e8f1549815.tar.gz |
avformat/mux: implement AVFMT_FLAG_SHORTEST
This will allow fixing several bugs with the -shortest option
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r-- | libavformat/mux.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/libavformat/mux.c b/libavformat/mux.c index a427f4659b..176af59f13 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1032,6 +1032,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, int stream_count = 0; int noninterleaved_count = 0; int i, ret; + int eof = flush; if (pkt) { if ((ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts)) < 0) @@ -1084,6 +1085,44 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, } } + if (s->internal->packet_buffer && + eof && + (s->flags & AVFMT_FLAG_SHORTEST) && + s->internal->shortest_end == AV_NOPTS_VALUE) { + AVPacket *top_pkt = &s->internal->packet_buffer->pkt; + + s->internal->shortest_end = av_rescale_q(top_pkt->dts, + s->streams[top_pkt->stream_index]->time_base, + AV_TIME_BASE_Q); + } + + if (s->internal->shortest_end != AV_NOPTS_VALUE) { + while (s->internal->packet_buffer) { + AVPacket *top_pkt = &s->internal->packet_buffer->pkt; + AVStream *st; + int64_t top_dts = av_rescale_q(top_pkt->dts, + s->streams[top_pkt->stream_index]->time_base, + AV_TIME_BASE_Q); + + if (s->internal->shortest_end + 1 >= top_dts) + break; + + pktl = s->internal->packet_buffer; + st = s->streams[pktl->pkt.stream_index]; + + s->internal->packet_buffer = pktl->next; + if (!s->internal->packet_buffer) + s->internal->packet_buffer_end = NULL; + + if (st->last_in_packet_buffer == pktl) + st->last_in_packet_buffer = NULL; + + av_packet_unref(&pktl->pkt); + av_freep(&pktl); + flush = 0; + } + } + if (stream_count && flush) { AVStream *st; pktl = s->internal->packet_buffer; |