In combination with the streaming option it constrains the value of a few elements, to prevet clients from buffering too much data before starting presentation.
Signed-off-by: James Almer <jamr...@gmail.com> --- libavformat/dashenc.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index baed933d6a..e352d37da4 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -144,6 +144,7 @@ typedef struct DASHContext { int has_video; int64_t last_duration; int64_t total_duration; + int64_t max_frag_duration; char availability_start_time[100]; time_t start_time_s; int64_t presentation_time_offset; @@ -167,6 +168,7 @@ typedef struct DASHContext { SegmentType segment_type_option; /* segment type as specified in options */ int ignore_io_errors; int lhls; + int ldash; int master_publish_rate; int nr_of_streams_to_flush; int nr_of_streams_flushed; @@ -640,6 +642,9 @@ static void output_segment_list(OutputStream *os, AVIOContext *out, AVFormatCont avio_printf(out, "availabilityTimeOffset=\"%.3f\" ", os->availability_time_offset); } + if (c->streaming && c->ldash && !final) + avio_printf(out, "availabilityTimeComplete=\"false\" "); + avio_printf(out, "initialization=\"%s\" media=\"%s\" startNumber=\"%d\"", os->init_seg_name, os->media_seg_name, c->use_timeline ? start_number : 1); if (c->presentation_time_offset) avio_printf(out, " presentationTimeOffset=\"%"PRId64"\"", c->presentation_time_offset); @@ -1047,7 +1052,8 @@ static int write_manifest(AVFormatContext *s, int final) if (c->use_template && !c->use_timeline) update_period = 500; avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period); - avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE); + if (!c->ldash) + avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE); if (c->availability_start_time[0]) avio_printf(out, "\tavailabilityStartTime=\"%s\"\n", c->availability_start_time); format_date(now_str, sizeof(now_str), av_gettime()); @@ -1060,7 +1066,7 @@ static int write_manifest(AVFormatContext *s, int final) } } avio_printf(out, "\tminBufferTime=\""); - write_time(out, c->last_duration * 2); + write_time(out, c->ldash && c->max_frag_duration ? c->max_frag_duration : c->last_duration * 2); avio_printf(out, "\">\n"); avio_printf(out, "\t<ProgramInformation>\n"); if (title) { @@ -1228,6 +1234,11 @@ static int dash_init(AVFormatContext *s) c->lhls = 0; } + if (c->ldash && !c->streaming) { + av_log(s, AV_LOG_WARNING, "LDash option will be ignored as streaming is not enabled\n"); + c->ldash = 0; + } + if (c->global_sidx && !c->single_file) { av_log(s, AV_LOG_WARNING, "Global SIDX option will be ignored as single_file is not enabled\n"); c->global_sidx = 0; @@ -1857,6 +1868,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) os->availability_time_offset = ((double) os->seg_duration - frame_duration) / AV_TIME_BASE; + c->max_frag_duration = FFMAX(frame_duration, c->max_frag_duration); } if (c->use_template && !c->use_timeline) { @@ -1935,6 +1947,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) AV_TIME_BASE_Q); os->availability_time_offset = ((double) os->seg_duration - frag_duration) / AV_TIME_BASE; + c->max_frag_duration = FFMAX(frag_duration, c->max_frag_duration); } } } @@ -2097,6 +2110,7 @@ static const AVOption options[] = { { "webm", "make segment file in WebM format", 0, AV_OPT_TYPE_CONST, {.i64 = SEGMENT_TYPE_WEBM }, 0, UINT_MAX, E, "segment_type"}, { "ignore_io_errors", "Ignore IO errors during open and write. Useful for long-duration runs with network output", OFFSET(ignore_io_errors), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "lhls", "Enable Low-latency HLS(Experimental). Adds #EXT-X-PREFETCH tag with current segment's URI", OFFSET(lhls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "ldash", "Enable Low-latency dash. Constrains the value of a few elements", OFFSET(ldash), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, { "master_m3u8_publish_rate", "Publish master playlist every after this many segment intervals", OFFSET(master_publish_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, UINT_MAX, E}, { "write_prft", "Write producer reference time element", OFFSET(write_prft), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, E}, { NULL }, -- 2.24.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".