My last patch was slightly convoluted and really dumb. I suspect it impacts on a couple of checks for variants[0]->playlists[0]->finished and the problem will be when a non live stream has two variants using EXT-X-ENDLIST and the first stream in the playlist is down? Not sure how to approach this, will look into it more later.
--- libavformat/hls.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index bac53a4..26b8751 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -1611,7 +1611,7 @@ static int hls_read_header(AVFormatContext *s) void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; HLSContext *c = s->priv_data; int ret = 0, i; - int highest_cur_seq_no = 0; + int highest_cur_seq_no = 0, found_segments; c->ctx = s; c->interrupt_callback = &s->interrupt_callback; @@ -1652,14 +1652,20 @@ static int hls_read_header(AVFormatContext *s) /* If the playlist only contained playlists (Master Playlist), * parse each individual playlist. */ if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) { + found_segments = -1; + for (i = 0; i < c->n_playlists; i++) { struct playlist *pls = c->playlists[i]; - if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) - goto fail; + if (parse_playlist(c, pls->url, pls, NULL) == 0 && pls->n_segments > 0) + found_segments = 1; } - } - if (c->variants[0]->playlists[0]->n_segments == 0) { + if(found_segments == -1) { + av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); + ret = AVERROR_EOF; + goto fail; + } + } else if (c->variants[0]->playlists[0]->n_segments == 0) { av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); ret = AVERROR_EOF; goto fail; @@ -1805,7 +1811,6 @@ static int hls_read_header(AVFormatContext *s) } update_noheader_flag(s); - return 0; fail: hls_close(s); -- 2.7.4 On Thu, Apr 13, 2017 at 12:43 AM, Tim Hunt <tnh...@gmail.com> wrote: > addresses ticket #2617 > > The test url given in the bug report is now working and has been playing > for a couple of hours. > > http://amd.cdn.turner.com/adultswim/big/streams/playlists/toonami.m3u8 > > --- > libavformat/hls.c | 26 ++++++++++++++++++++------ > 1 file changed, 20 insertions(+), 6 deletions(-) > > diff --git a/libavformat/hls.c b/libavformat/hls.c > index bac53a4..87e0c71 100644 > --- a/libavformat/hls.c > +++ b/libavformat/hls.c > @@ -1610,8 +1610,8 @@ static int hls_read_header(AVFormatContext *s) > { > void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb; > HLSContext *c = s->priv_data; > - int ret = 0, i; > - int highest_cur_seq_no = 0; > + int ret = 0, i, j; > + int highest_cur_seq_no = 0, found_segments; > > c->ctx = s; > c->interrupt_callback = &s->interrupt_callback; > @@ -1655,11 +1655,26 @@ static int hls_read_header(AVFormatContext *s) > for (i = 0; i < c->n_playlists; i++) { > struct playlist *pls = c->playlists[i]; > if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) > - goto fail; > + continue; > } > - } > > - if (c->variants[0]->playlists[0]->n_segments == 0) { > + found_segments = -1; > + for(i = 0; i < c->n_variants && found_segments == -1; i++) { > + struct variant *var = c->variants[i]; > + for(j = 0; j < var->n_playlists; j++) { > + if(var->playlists[j]->n_segments > 0) { > + found_segments = 1; > + break; > + } > + } > + } > + > + if(found_segments == -1) { > + av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); > + ret = AVERROR_EOF; > + goto fail; > + } > + } else if (c->variants[0]->playlists[0]->n_segments == 0) { > av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); > ret = AVERROR_EOF; > goto fail; > @@ -1805,7 +1820,6 @@ static int hls_read_header(AVFormatContext *s) > } > > update_noheader_flag(s); > - > return 0; > fail: > hls_close(s); > -- > 2.7.4 > _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel