[FFmpeg-devel] [PATCH 10/11] avformat/dashenc: add an option to enable low latency Dash manifest

James Almer jamrial at gmail.com
Thu Oct 17 21:59:15 EEST 2019


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 <jamrial at gmail.com>
---
 libavformat/dashenc.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
index 2ef0461c88..b32ff7393b 100644
--- a/libavformat/dashenc.c
+++ b/libavformat/dashenc.c
@@ -143,6 +143,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;
@@ -166,6 +167,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;
@@ -1047,7 +1049,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 +1063,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 +1231,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;
@@ -1855,6 +1863,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) {
@@ -1933,6 +1942,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);
             }
         }
     }
@@ -2095,6 +2105,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.23.0



More information about the ffmpeg-devel mailing list