[FFmpeg-devel] [PATCH] avformat/hls allow playback when some variant streams are unavailable
Tim Hunt
tnhunt at gmail.com
Thu Apr 13 18:14:46 EEST 2017
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 <tnhunt at 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
>
More information about the ffmpeg-devel
mailing list