fix for ext-discontinuity
This commit is contained in:
parent
5511102b0c
commit
7ad49b423e
|
@ -66,7 +66,9 @@ enum KeyType {
|
|||
};
|
||||
|
||||
struct segment {
|
||||
int64_t previous_duration;
|
||||
int64_t duration;
|
||||
int64_t start_time;
|
||||
int64_t url_offset;
|
||||
int64_t size;
|
||||
char *url;
|
||||
|
@ -716,7 +718,7 @@ static int parse_playlist(HLSContext *c, const char *url,
|
|||
struct playlist *pls, AVIOContext *in)
|
||||
{
|
||||
int ret = 0, is_segment = 0, is_variant = 0;
|
||||
int64_t duration = 0;
|
||||
int64_t duration = 0, previous_duration1 = 0, previous_duration = 0, total_duration = 0;
|
||||
enum KeyType key_type = KEY_NONE;
|
||||
uint8_t iv[16] = "";
|
||||
int has_iv = 0;
|
||||
|
@ -874,6 +876,8 @@ static int parse_playlist(HLSContext *c, const char *url,
|
|||
} else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
|
||||
if (pls)
|
||||
pls->finished = 1;
|
||||
} else if (av_strstart(line, "#EXT-X-DISCONTINUITY", &ptr)) {
|
||||
previous_duration = previous_duration1;
|
||||
} else if (av_strstart(line, "#EXTINF:", &ptr)) {
|
||||
is_segment = 1;
|
||||
duration = atof(ptr) * AV_TIME_BASE;
|
||||
|
@ -903,6 +907,14 @@ static int parse_playlist(HLSContext *c, const char *url,
|
|||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
previous_duration1 += duration;
|
||||
seg->previous_duration = previous_duration;
|
||||
seg->start_time = total_duration;
|
||||
total_duration += duration;
|
||||
seg->duration = duration;
|
||||
seg->key_type = key_type;
|
||||
|
||||
if (has_iv) {
|
||||
memcpy(seg->iv, iv, sizeof(iv));
|
||||
} else {
|
||||
|
@ -949,8 +961,9 @@ static int parse_playlist(HLSContext *c, const char *url,
|
|||
" set to default value to 1ms.\n", seg->url);
|
||||
duration = 0.001 * AV_TIME_BASE;
|
||||
}
|
||||
seg->duration = duration;
|
||||
seg->key_type = key_type;
|
||||
// seg->duration = duration;
|
||||
// seg->key_type = key_type;
|
||||
|
||||
dynarray_add(&pls->segments, &pls->n_segments, seg);
|
||||
is_segment = 0;
|
||||
|
||||
|
@ -2257,6 +2270,29 @@ static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||
ist->time_base,
|
||||
AV_TIME_BASE_Q);
|
||||
|
||||
if (c->playlists[minplaylist]->finished) {
|
||||
struct playlist *pls = c->playlists[minplaylist];
|
||||
int seq_no = pls->cur_seq_no - pls->start_seq_no;
|
||||
if (seq_no < pls->n_segments && s->streams[pkt->stream_index]) {
|
||||
struct segment *seg = pls->segments[seq_no];
|
||||
int64_t pred = av_rescale_q(seg->previous_duration,
|
||||
AV_TIME_BASE_Q,
|
||||
s->streams[pkt->stream_index]->time_base);
|
||||
int64_t max_ts = av_rescale_q(seg->start_time + seg->duration,
|
||||
AV_TIME_BASE_Q,
|
||||
s->streams[pkt->stream_index]->time_base);
|
||||
/* EXTINF duration is not precise enough */
|
||||
max_ts += 2 * AV_TIME_BASE;
|
||||
if (s->start_time > 0) {
|
||||
max_ts += av_rescale_q(s->start_time,
|
||||
AV_TIME_BASE_Q,
|
||||
s->streams[pkt->stream_index]->time_base);
|
||||
}
|
||||
if (pkt->dts != AV_NOPTS_VALUE && pkt->dts + pred < max_ts) pkt->dts += pred;
|
||||
if (pkt->pts != AV_NOPTS_VALUE && pkt->pts + pred < max_ts) pkt->pts += pred;
|
||||
}
|
||||
}
|
||||
|
||||
/* There may be more situations where this would be useful, but this at least
|
||||
* handles newly probed codecs properly (i.e. request_probe by mpegts). */
|
||||
if (ist->codecpar->codec_id != st->codecpar->codec_id) {
|
||||
|
|
Loading…
Reference in New Issue