summaryrefslogtreecommitdiff
path: root/libavformat/mux.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2016-08-12 21:28:08 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2016-09-11 23:17:31 +0200
commitcb114ed464069ac83f05a4ebdfe992e8f1549815 (patch)
tree380e2c4845b1f7ddf4d35d4d26670373a2d3cfa5 /libavformat/mux.c
parent09317e3e06d7126337c2311ecf8bb7762369c110 (diff)
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.c39
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;