avformat/hls: Sync starting segment across variants on live streams

This will avoid a large time difference between variants in the most
common case.
pull/228/head
Anssi Hannula 8 years ago
parent 9cb30f7a88
commit 4d85069e5d
  1. 25
      libavformat/hls.c

@ -1520,6 +1520,7 @@ static int hls_read_header(AVFormatContext *s)
void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb;
HLSContext *c = s->priv_data; HLSContext *c = s->priv_data;
int ret = 0, i, j, stream_offset = 0; int ret = 0, i, j, stream_offset = 0;
int highest_cur_seq_no = 0;
c->ctx = s; c->ctx = s;
c->interrupt_callback = &s->interrupt_callback; c->interrupt_callback = &s->interrupt_callback;
@ -1594,6 +1595,17 @@ static int hls_read_header(AVFormatContext *s)
add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group); add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group);
} }
/* Select the starting segments */
for (i = 0; i < c->n_playlists; i++) {
struct playlist *pls = c->playlists[i];
if (pls->n_segments == 0)
continue;
pls->cur_seq_no = select_cur_seq_no(c, pls);
highest_cur_seq_no = FFMAX(highest_cur_seq_no, pls->cur_seq_no);
}
/* Open the demuxer for each playlist */ /* Open the demuxer for each playlist */
for (i = 0; i < c->n_playlists; i++) { for (i = 0; i < c->n_playlists; i++) {
struct playlist *pls = c->playlists[i]; struct playlist *pls = c->playlists[i];
@ -1610,7 +1622,18 @@ static int hls_read_header(AVFormatContext *s)
pls->index = i; pls->index = i;
pls->needed = 1; pls->needed = 1;
pls->parent = s; pls->parent = s;
pls->cur_seq_no = select_cur_seq_no(c, pls);
/*
* If this is a live stream and this playlist looks like it is one segment
* behind, try to sync it up so that every substream starts at the same
* time position (so e.g. avformat_find_stream_info() will see packets from
* all active streams within the first few seconds). This is not very generic,
* though, as the sequence numbers are technically independent.
*/
if (!pls->finished && pls->cur_seq_no == highest_cur_seq_no - 1 &&
highest_cur_seq_no < pls->start_seq_no + pls->n_segments) {
pls->cur_seq_no = highest_cur_seq_no;
}
pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE); pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
if (!pls->read_buffer){ if (!pls->read_buffer){

Loading…
Cancel
Save