From patchwork Thu Oct 17 18:59:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 15822 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id DE1D844A238 for ; Thu, 17 Oct 2019 22:00:16 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C1A9568AB36; Thu, 17 Oct 2019 22:00:16 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f193.google.com (mail-qt1-f193.google.com [209.85.160.193]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CADFD68AAD5 for ; Thu, 17 Oct 2019 22:00:13 +0300 (EEST) Received: by mail-qt1-f193.google.com with SMTP id m61so5162118qte.7 for ; Thu, 17 Oct 2019 12:00:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=KWrJMLyWeBa63EakASGTjI/vk6Jx8U67KFE4UgPsQx4=; b=UndXa0R/LBfFqtkYreg0jE/xsTWFh/mD7iqufcZ9HElwelgshlQSIdYESGQsf2TMZd qeAMFTPA85xAC5qnPRcqe8yZjwv4ntSlY2tABLcDix3tQkSUuqXWIi3Cv7SyqakXxiM8 3GV+EE5GNuggRivshdn7sC58M8kCYh8iBjnzhFGc2o81zooo7sAVCa+0R8QFKVFbM8h5 JVW7OxO6O9PBXcbX2/l4pNElVrH8uZWiP1dZ05Ouiq/2s8d/ZM+wflPL84RUtJJaEckn 1R2Y3kGbYNxi/xiQliFzgxQ/785h4mE0/kOJujwytJvGFklJ81tdraJ1cUXxhbabpU4O A47g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KWrJMLyWeBa63EakASGTjI/vk6Jx8U67KFE4UgPsQx4=; b=dx5evaZX/f+DKajwGvcxwve8kDhNxiMkBcla2RkzFckmOjkMR2Q6B4H05kEQn9pfQN PNTYYRy7hNsHe/V2gAwAO5wk6dtI91cXXujXihR1ohjBQl4JGO3x8+stUfXqBxoc6EbP XC4/g8QzFcwgbKF0ZDvvHSIi+NeXaRQGXcNNKxGewxz3bAca+dvC0je/Y6qwjVTAzTL0 4OEE7S5gVRBUzNIxDGhp44gSJ8bDEcGZNJ5EaM3rmA9sAgeET0lX8nBipYrlAfFeuihD /aZMBGD8tAWMuMUAME9QRUlKgW2GMdHlBdkpERRdHapsPOvsm3fR9WqCt5e7Yi0td+pX F6Fw== X-Gm-Message-State: APjAAAW6GVaUf4zvdnUPiWiNjJa+5DBZRy84HHuTqdERjX4DfIJQKhNw EXPrQ+Pv0SG4hA2Rk2HMbIqXQUjG X-Google-Smtp-Source: APXvYqxY64tGhspHFLD8mGnMSM9r3U5IvlGlRu8P/O05F1YIwqpGEMFHoKTZBQ4oAm4zp0VgOJ2x5Q== X-Received: by 2002:aed:2ce7:: with SMTP id g94mr5438541qtd.305.1571338812483; Thu, 17 Oct 2019 12:00:12 -0700 (PDT) Received: from localhost.localdomain ([191.83.221.234]) by smtp.gmail.com with ESMTPSA id v141sm798933qka.59.2019.10.17.12.00.11 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 17 Oct 2019 12:00:12 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Thu, 17 Oct 2019 15:59:15 -0300 Message-Id: <20191017185916.2957-11-jamrial@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191017185916.2957-1-jamrial@gmail.com> References: <20191017185916.2957-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 10/11] avformat/dashenc: add an option to enable low latency Dash manifest X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" 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 --- 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\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 },