From patchwork Fri Mar 23 05:27:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dixit, Vishwanath" X-Patchwork-Id: 8119 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.1.70 with SMTP id c67csp20085jad; Thu, 22 Mar 2018 22:28:10 -0700 (PDT) X-Google-Smtp-Source: AG47ELtbHRwBi0MerHlD0aV3L6Iq8X/Fgy9sJi+m8vmXLS02KOkfOV+d3Ray4/ebwDCAK/QOa9/1 X-Received: by 10.223.134.213 with SMTP id 21mr20279716wry.221.1521782890752; Thu, 22 Mar 2018 22:28:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521782890; cv=none; d=google.com; s=arc-20160816; b=CZgH1oA4u9RoJp1YFjDMSSJW1HlnDwmBLNB4RrKDxYBdlMqPsrZK8CAHERzFXcVyrR bTDfGVF+UnfinVCd4rEGNAGzCaDv94RPE11oKGDVeZBqioeiT3ah+PXv3AuiwM9QeK1l xief6AjNOKUlzMV8pLPIgrjWJdnCK0km2Q3+xY+UUmmj+f5OOEyahLqZqFF7G3ZqpVon u22ZnLfNZ/52dxneArKQ4sYZu5qNsPsQISu15uUz83LRKm1GEBpn5Om438osjlJhx0x3 iI5EbUqByMOCEcGvf1TA8wmu3n36H43XVqJJs0VAbELSDrpepaaaJqdZaUun3oCkF8n+ F+4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:feedback-id:message-id:date:to:from :dkim-signature:delivered-to:arc-authentication-results; bh=XO9ellFVNPZ4psuSUVDs90tJy0yByO5k69f4+7oMurY=; b=zByU0XgbC7e1fawnmCQ711qeMY3uJdoCsHUKk4MCdqKAMDFwrB+dSoADtS7KVxr+wg JpXDeq9sPkS5sRJaRmD7VxoBR5WohvDw+6cP8+mFG+1rQJX/Mp3AaSBJBfrVxfByT8vy 9TqW5g7QfHs0RJKjJBZq54thsSA8nhY2cuP7vw9/4tlezPp1A3fBwDMPW6vQoLQRSXwh 183RulcfVBMM8EwGBQn/Zhdq19mo3dxRQnd5SILH76Xmpe/YxpgqQjSJn2Yq6PerwCnd Zpvokoh1m3hqClvYQl3/TY+6OyriV5N1nI4S0zY+teUWeR/F2WXhEaRjyn14dC76s7Rj FZbw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@smtpservice.net header.s=m78bu0.a1-4.dyn header.b=dOoHDv7i; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=akamai.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id 42si6888744wrk.441.2018.03.22.22.28.10; Thu, 22 Mar 2018 22:28:10 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@smtpservice.net header.s=m78bu0.a1-4.dyn header.b=dOoHDv7i; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=akamai.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DDAAD689A34; Fri, 23 Mar 2018 07:27:52 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from a2i831.smtp2go.com (a2i831.smtp2go.com [103.47.207.63]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 090A1680193 for ; Fri, 23 Mar 2018 07:27:47 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpservice.net; s=m78bu0.a1-4.dyn; x=1521783788; h=Feedback-ID: X-Smtpcorp-Track:Message-Id:Date:Subject:To:From:Reply-To:Sender: List-Unsubscribe; bh=BGSV3TYfGMuAYkSUsD6bvqtWnARETJpoa/shRNoa0Mw=; b=dOoHDv7i n+6Px87Ru0BtrStdmpNNlWB/LrDYsp/ElgX62kh47/r0xbBX0r2IaCPWKcuGAsm76Od5izxCGXB5M OCk5doVVeTneWckJzDjWI3Vs1fN/Bn/hueTx+a/tAmMfy/qB1MuuQh0j+z7pj0IZ7KEAqWsVLABT7 4ujyqV67epHBHvmu0uw1yZ8QBcDAvHNWLb1Ys99T3BPckVOCRzvIWkf+S5is+Y44FASL/1Sfb9svT OxfJ5Ra2qdwwe1/7v8vKfdTplakxSsu7WUAk77u5offKAcJCIOaLD/w7nZdT6epWkEALBLXAjIzoz QWvZiCdWHCejCBDQKPgifvhvtQ==; From: vdixit@akamai.com To: ffmpeg-devel@ffmpeg.org Date: Fri, 23 Mar 2018 10:57:55 +0530 Message-Id: <1521782875-27623-1-git-send-email-vdixit@akamai.com> X-Mailer: git-send-email 1.9.1 X-Smtpcorp-Track: 1-zFFjDIIhNY1j.tNUhG8-wt Feedback-ID: 337386m:337386asVRLGB:337386sRCwmZHEum:SMTPCORP X-Report-Abuse: Please forward a copy of this message, including all headers, to Subject: [FFmpeg-devel] [PATCH 11/11] avformat/dashenc: addition of segment index correction logic 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 Cc: Vishwanath Dixit MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Vishwanath Dixit The logic is applicable only when use_template is enabled and use_timeline is disabled. The logic monitors the flow of segment indexes. If a streams's segment index value is not at the expected real time position, then the logic corrects that index value. Typically this logic is needed in live streaming use cases. The network bandwidth fluctuations are common during long run streaming. Each fluctuation can cause the segment indexes fall behind the expected real time position. Without this logic, players will not be able to consume the content, even after encoder's network condition comes back to normal state. --- doc/muxers.texi | 11 +++++++++++ libavformat/dashenc.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index 7130cd0..9b31ea0 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -268,6 +268,17 @@ To map all video (or audio) streams to an AdaptationSet, "v" (or "a") can be use When no assignment is defined, this defaults to an AdaptationSet for each stream. @item -timeout @var{timeout} Set timeout for socket I/O operations. Applicable only for HTTP output. +@item -index_correction @var{index_correction} +Enable (1) or Disable (0) segment index correction logic. Applicable only when +@var{use_template} is enabled and @var{use_timeline} is disabled. + +When enabled, the logic monitors the flow of segment indexes. If a streams's +segment index value is not at the expected real time position, then the logic +corrects that index value. + +Typically this logic is needed in live streaming use cases. The network bandwidth +fluctuations are common during long run streaming. Each fluctuation can cause +the segment indexes fall behind the expected real time position. @end table @anchor{framecrc} diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index f691fb3..47484eb 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]; @@ -120,6 +120,7 @@ typedef struct DASHContext { AVIOContext *m3u8_out; int streaming; int64_t timeout; + int index_correction; } DASHContext; static struct codec_string { @@ -1050,7 +1051,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; @@ -1078,6 +1079,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; } @@ -1167,10 +1174,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]; @@ -1230,7 +1249,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; @@ -1293,6 +1312,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, @@ -1469,6 +1489,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 }, };