diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index c84dd82e7d..2fd3f19fcb 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -42,6 +42,7 @@ typedef struct ListEntry { char name[1024]; int64_t duration; // segment duration in AV_TIME_BASE units + int discont; struct ListEntry *next; } ListEntry; @@ -76,6 +77,8 @@ typedef struct HLSContext { char *iv; // Set by a private option. int iv_len; + int recovered; + char *key_basename; AVDictionary *enc_opts; @@ -214,7 +217,8 @@ static int hls_mux_init(AVFormatContext *s) 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)); @@ -223,6 +227,7 @@ static int append_entry(HLSContext *hls, int64_t duration, const char *name) av_strlcpy(en->name, name, sizeof(en->name)); + en->discont = discont; en->duration = duration; en->next = NULL; @@ -289,6 +294,10 @@ static int hls_window(AVFormatContext *s, int last) sequence); for (en = hls->list; en; en = en->next) { + if (en->discont) { + avio_printf(out, "#EXT-X-DISCONTINUITY\n"); + } + if (hls->encrypt) { char *key_url; @@ -383,7 +392,7 @@ static int hls_recover(AVFormatContext *s) char line[1024]; AVIOContext *io; const char *ptr; - int ret, is_segment = 0; + int ret, is_segment = 0, is_discont = 0; int64_t duration = 0; 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)) { is_segment = 1; duration = atof(ptr) * AV_TIME_BASE; + } else if (av_strstart(line, "#EXT-X-DISCONTINUITY", NULL)) { + is_discont = 1; } else if (av_strstart(line, "#", NULL)) { continue; } else if (line[0]) { if (is_segment) { - append_entry(hls, duration, av_basename(line)); + append_entry(hls, duration, av_basename(line), is_discont); is_segment = 0; + is_discont = 0; } } } + hls->recovered = 1; + return 0; } @@ -539,7 +553,8 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hls->duration = pts - hls->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) return ret; @@ -574,7 +589,7 @@ static int hls_write_trailer(struct AVFormatContext *s) ff_format_io_close(s, &oc->pb); avformat_free_context(oc); 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); free_entries(hls);