hls: Add a discontinuity marker on recover

It seems to improve the compatibility with the js demuxers.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
Luca Barbato 2018-02-16 16:09:25 +01:00
parent 2d6b3f3a9d
commit aeaa108baf
1 changed files with 20 additions and 5 deletions

View File

@ -42,6 +42,7 @@
typedef struct ListEntry { typedef struct ListEntry {
char name[1024]; char name[1024];
int64_t duration; // segment duration in AV_TIME_BASE units int64_t duration; // segment duration in AV_TIME_BASE units
int discont;
struct ListEntry *next; struct ListEntry *next;
} ListEntry; } ListEntry;
@ -76,6 +77,8 @@ typedef struct HLSContext {
char *iv; // Set by a private option. char *iv; // Set by a private option.
int iv_len; int iv_len;
int recovered;
char *key_basename; char *key_basename;
AVDictionary *enc_opts; AVDictionary *enc_opts;
@ -214,7 +217,8 @@ static int hls_mux_init(AVFormatContext *s)
return 0; return 0;
} }
static int append_entry(HLSContext *hls, int64_t duration, const char *name) static int append_entry(HLSContext *hls, int64_t duration, const char *name,
int discont)
{ {
ListEntry *en = av_malloc(sizeof(*en)); ListEntry *en = av_malloc(sizeof(*en));
@ -223,6 +227,7 @@ static int append_entry(HLSContext *hls, int64_t duration, const char *name)
av_strlcpy(en->name, name, sizeof(en->name)); av_strlcpy(en->name, name, sizeof(en->name));
en->discont = discont;
en->duration = duration; en->duration = duration;
en->next = NULL; en->next = NULL;
@ -289,6 +294,10 @@ static int hls_window(AVFormatContext *s, int last)
sequence); sequence);
for (en = hls->list; en; en = en->next) { for (en = hls->list; en; en = en->next) {
if (en->discont) {
avio_printf(out, "#EXT-X-DISCONTINUITY\n");
}
if (hls->encrypt) { if (hls->encrypt) {
char *key_url; char *key_url;
@ -383,7 +392,7 @@ static int hls_recover(AVFormatContext *s)
char line[1024]; char line[1024];
AVIOContext *io; AVIOContext *io;
const char *ptr; const char *ptr;
int ret, is_segment = 0; int ret, is_segment = 0, is_discont = 0;
int64_t duration = 0; int64_t duration = 0;
ret = s->io_open(s, &io, s->filename, AVIO_FLAG_READ, NULL); ret = s->io_open(s, &io, s->filename, AVIO_FLAG_READ, NULL);
@ -410,16 +419,21 @@ static int hls_recover(AVFormatContext *s)
} else if (av_strstart(line, "#EXTINF:", &ptr)) { } else if (av_strstart(line, "#EXTINF:", &ptr)) {
is_segment = 1; is_segment = 1;
duration = atof(ptr) * AV_TIME_BASE; duration = atof(ptr) * AV_TIME_BASE;
} else if (av_strstart(line, "#EXT-X-DISCONTINUITY", NULL)) {
is_discont = 1;
} else if (av_strstart(line, "#", NULL)) { } else if (av_strstart(line, "#", NULL)) {
continue; continue;
} else if (line[0]) { } else if (line[0]) {
if (is_segment) { if (is_segment) {
append_entry(hls, duration, av_basename(line)); append_entry(hls, duration, av_basename(line), is_discont);
is_segment = 0; is_segment = 0;
is_discont = 0;
} }
} }
} }
hls->recovered = 1;
return 0; return 0;
} }
@ -539,7 +553,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
hls->duration = pts - hls->end_pts; hls->duration = pts - hls->end_pts;
if (can_split && pts - hls->start_pts >= end_pts) { if (can_split && pts - hls->start_pts >= end_pts) {
ret = append_entry(hls, hls->duration, av_basename(hls->avf->filename)); ret = append_entry(hls, hls->duration, av_basename(hls->avf->filename), hls->recovered);
hls->recovered = 0;
if (ret) if (ret)
return ret; return ret;
@ -574,7 +589,7 @@ static int hls_write_trailer(struct AVFormatContext *s)
ff_format_io_close(s, &oc->pb); ff_format_io_close(s, &oc->pb);
avformat_free_context(oc); avformat_free_context(oc);
av_free(hls->basename); av_free(hls->basename);
append_entry(hls, hls->duration, av_basename(hls->avf->filename)); append_entry(hls, hls->duration, av_basename(hls->avf->filename), 0);
hls_window(s, 1); hls_window(s, 1);
free_entries(hls); free_entries(hls);