| 
				
				
					
				
				
				 | 
			
			 | 
			@@ -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); | 
		
		
	
	
		
			
				| 
				
					
				
				
				
				 | 
			
			 | 
			
  |