summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/dashenc.c31
1 files changed, 26 insertions, 5 deletions
diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index bf8698f292..9e72636f0e 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -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 },
};