From 9d64f236292ba28018dd9afd2d57f8f944b33f81 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Aug 2012 01:00:05 +0200 Subject: [PATCH] hls: Respect the different stream time bases when comparing dts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also adjust the streams timestamps according to their start timestamp when comparing. This helps getting correctly interleaved packets if one stream lacks timestamps (such as a plain ADTS stream when the other variants are full mpegts) when the others have timestamps that don't start from zero. This probably doesn't work properly if such a stream is temporarily disabled (via the discard flags) and then reenabled, and such streams are hard to correctly sync against the other streams as well - but this works better than before at least. The segment number restriction makes sure all variants advance roughly at the same pace as well. Signed-off-by: Martin Storsjö --- libavformat/hls.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 86cf9741da..d69a3809e4 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -644,11 +644,28 @@ start: /* Check if this stream still is on an earlier segment number, or * has the packet with the lowest dts */ if (var->pkt.data) { - if (minvariant < 0 || - var->cur_seq_no < c->variants[minvariant]->cur_seq_no || - (var->cur_seq_no == c->variants[minvariant]->cur_seq_no && - var->pkt.dts < c->variants[minvariant]->pkt.dts)) + struct variant *minvar = c->variants[minvariant]; + if (minvariant < 0 || var->cur_seq_no < minvar->cur_seq_no) { minvariant = i; + } else if (var->cur_seq_no == minvar->cur_seq_no) { + int64_t dts = var->pkt.dts; + int64_t mindts = minvar->pkt.dts; + AVStream *st = var->ctx->streams[var->pkt.stream_index]; + AVStream *minst = minvar->ctx->streams[minvar->pkt.stream_index]; + + if (dts == AV_NOPTS_VALUE) { + minvariant = i; + } else if (mindts != AV_NOPTS_VALUE) { + if (st->start_time != AV_NOPTS_VALUE) + dts -= st->start_time; + if (minst->start_time != AV_NOPTS_VALUE) + mindts -= minst->start_time; + + if (av_compare_ts(dts, st->time_base, + mindts, minst->time_base) < 0) + minvariant = i; + } + } } } if (c->end_of_segment) {