aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Liu <lq@chinaffmpeg.org>2019-09-03 09:55:17 +0800
committerSteven Liu <lq@chinaffmpeg.org>2019-11-13 16:40:09 +0800
commit4e0860e36305c768c3d97b41d38122e59a18da87 (patch)
tree6f291d692cae8c552ea795918e2ffec09a639ee1
parentcc61466058ef1689f98067a81d5d4706dac7544a (diff)
downloadffmpeg-4e0860e36305c768c3d97b41d38122e59a18da87.tar.gz
avformat/hls: continue to play enabled playlist when have failed playlist
fix ticket: 7811 Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
-rw-r--r--libavformat/hls.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/libavformat/hls.c b/libavformat/hls.c
index 17a75e20cd..8dc0e4e385 100644
--- a/libavformat/hls.c
+++ b/libavformat/hls.c
@@ -116,6 +116,7 @@ struct playlist {
int n_segments;
struct segment **segments;
int needed;
+ int broken;
int cur_seq_no;
int64_t cur_seg_offset;
int64_t last_load_time;
@@ -1815,15 +1816,21 @@ static int hls_read_header(AVFormatContext *s)
if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
for (i = 0; i < c->n_playlists; i++) {
struct playlist *pls = c->playlists[i];
- if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0)
+ if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0) {
+ av_log(s, AV_LOG_WARNING, "parse_playlist error %s [%s]\n", av_err2str(ret), pls->url);
+ pls->broken = 1;
+ if (c->n_playlists > 1)
+ continue;
goto fail;
+ }
}
}
- if (c->variants[0]->playlists[0]->n_segments == 0) {
- av_log(s, AV_LOG_WARNING, "Empty segment\n");
- ret = AVERROR_EOF;
- goto fail;
+ for (i = 0; i < c->n_variants; i++) {
+ if (c->variants[i]->playlists[0]->n_segments == 0) {
+ av_log(s, AV_LOG_WARNING, "Empty segment [%s]\n", c->variants[i]->playlists[0]->url);
+ c->variants[i]->playlists[0]->broken = 1;
+ }
}
/* If this isn't a live stream, calculate the total duration of the
@@ -1994,6 +2001,9 @@ static int recheck_discard_flags(AVFormatContext *s, int first)
cur_needed = playlist_needed(c->playlists[i]);
+ if (pls->broken) {
+ continue;
+ }
if (cur_needed && !pls->needed) {
pls->needed = 1;
changed = 1;