|  |  | @@ -76,7 +76,7 @@ typedef struct OutputStream { | 
		
	
		
			
			|  |  |  | int nb_segments, segments_size, segment_index; | 
		
	
		
			
			|  |  |  | Segment **segments; | 
		
	
		
			
			|  |  |  | int64_t first_pts, start_pts, max_pts; | 
		
	
		
			
			|  |  |  | int64_t last_dts; | 
		
	
		
			
			|  |  |  | int64_t last_dts, last_pts; | 
		
	
		
			
			|  |  |  | int bit_rate; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | char codec_str[100]; | 
		
	
	
		
			
				|  |  | @@ -123,6 +123,7 @@ typedef struct DASHContext { | 
		
	
		
			
			|  |  |  | AVIOContext *m3u8_out; | 
		
	
		
			
			|  |  |  | int streaming; | 
		
	
		
			
			|  |  |  | int64_t timeout; | 
		
	
		
			
			|  |  |  | int index_correction; | 
		
	
		
			
			|  |  |  | } DASHContext; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | static struct codec_string { | 
		
	
	
		
			
				|  |  | @@ -1060,7 +1061,7 @@ static int dash_write_header(AVFormatContext *s) | 
		
	
		
			
			|  |  |  | static int add_segment(OutputStream *os, const char *file, | 
		
	
		
			
			|  |  |  | int64_t time, int duration, | 
		
	
		
			
			|  |  |  | int64_t start_pos, int64_t range_length, | 
		
	
		
			
			|  |  |  | int64_t index_length) | 
		
	
		
			
			|  |  |  | int64_t index_length, int next_exp_index) | 
		
	
		
			
			|  |  |  | { | 
		
	
		
			
			|  |  |  | int err; | 
		
	
		
			
			|  |  |  | Segment *seg; | 
		
	
	
		
			
				|  |  | @@ -1088,6 +1089,12 @@ static int add_segment(OutputStream *os, const char *file, | 
		
	
		
			
			|  |  |  | seg->index_length = index_length; | 
		
	
		
			
			|  |  |  | os->segments[os->nb_segments++] = seg; | 
		
	
		
			
			|  |  |  | os->segment_index++; | 
		
	
		
			
			|  |  |  | //correcting the segment index if it has fallen behind the expected value | 
		
	
		
			
			|  |  |  | if (os->segment_index < next_exp_index) { | 
		
	
		
			
			|  |  |  | av_log(NULL, AV_LOG_WARNING, "Correcting the segment index after file %s: current=%d corrected=%d\n", | 
		
	
		
			
			|  |  |  | file, os->segment_index, next_exp_index); | 
		
	
		
			
			|  |  |  | os->segment_index = next_exp_index; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | return 0; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | @@ -1177,10 +1184,22 @@ static int dash_flush(AVFormatContext *s, int final, int stream) | 
		
	
		
			
			|  |  |  | const char *proto = avio_find_protocol_name(s->url); | 
		
	
		
			
			|  |  |  | int use_rename = proto && !strcmp(proto, "file"); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | int cur_flush_segment_index = 0; | 
		
	
		
			
			|  |  |  | if (stream >= 0) | 
		
	
		
			
			|  |  |  | int cur_flush_segment_index = 0, next_exp_index = -1; | 
		
	
		
			
			|  |  |  | if (stream >= 0) { | 
		
	
		
			
			|  |  |  | cur_flush_segment_index = c->streams[stream].segment_index; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | //finding the next segment's expected index, based on the current pts value | 
		
	
		
			
			|  |  |  | if (c->use_template && !c->use_timeline && c->index_correction && | 
		
	
		
			
			|  |  |  | c->streams[stream].last_pts != AV_NOPTS_VALUE && | 
		
	
		
			
			|  |  |  | c->streams[stream].first_pts != AV_NOPTS_VALUE) { | 
		
	
		
			
			|  |  |  | int64_t pts_diff = av_rescale_q(c->streams[stream].last_pts - | 
		
	
		
			
			|  |  |  | c->streams[stream].first_pts, | 
		
	
		
			
			|  |  |  | s->streams[stream]->time_base, | 
		
	
		
			
			|  |  |  | AV_TIME_BASE_Q); | 
		
	
		
			
			|  |  |  | next_exp_index = (pts_diff / c->seg_duration) + 1; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | for (i = 0; i < s->nb_streams; i++) { | 
		
	
		
			
			|  |  |  | OutputStream *os = &c->streams[i]; | 
		
	
		
			
			|  |  |  | AVStream *st = s->streams[i]; | 
		
	
	
		
			
				|  |  | @@ -1240,7 +1259,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) | 
		
	
		
			
			|  |  |  | if (bitrate >= 0) | 
		
	
		
			
			|  |  |  | os->bit_rate = bitrate; | 
		
	
		
			
			|  |  |  | } | 
		
	
		
			
			|  |  |  | add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length); | 
		
	
		
			
			|  |  |  | add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index); | 
		
	
		
			
			|  |  |  | av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path); | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | os->pos += range_length; | 
		
	
	
		
			
				|  |  | @@ -1303,6 +1322,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (os->first_pts == AV_NOPTS_VALUE) | 
		
	
		
			
			|  |  |  | os->first_pts = pkt->pts; | 
		
	
		
			
			|  |  |  | os->last_pts = pkt->pts; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
		
			
			|  |  |  | if (!c->availability_start_time[0]) | 
		
	
		
			
			|  |  |  | format_date_now(c->availability_start_time, | 
		
	
	
		
			
				|  |  | @@ -1485,6 +1505,7 @@ static const AVOption options[] = { | 
		
	
		
			
			|  |  |  | { "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, | 
		
	
		
			
			|  |  |  | { "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, | 
		
	
		
			
			|  |  |  | { "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E }, | 
		
	
		
			
			|  |  |  | { "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, | 
		
	
		
			
			|  |  |  | { NULL }, | 
		
	
		
			
			|  |  |  | }; | 
		
	
		
			
			|  |  |  | 
 | 
		
	
	
		
			
				|  |  | 
 |