From patchwork Mon Feb 19 05:55:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dixit, Vishwanath" X-Patchwork-Id: 7648 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.150.33 with SMTP id c30csp1144053jai; Sun, 18 Feb 2018 21:55:54 -0800 (PST) X-Google-Smtp-Source: AH8x227g2dPIHe2ZVuqS5qcnzNQdZMEub+oYg33bHHyu2zjC21MzZySwlmZVq1tGLyTZtqty3DC9 X-Received: by 10.28.191.75 with SMTP id p72mr4415866wmf.109.1519019754224; Sun, 18 Feb 2018 21:55:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1519019754; cv=none; d=google.com; s=arc-20160816; b=lMwmOs85FYjgRTdSZvHP4DdVOyBv3fNmVLjU0roZ1W5fRzNkUx9Ewai7B1T7wTXe4S 0AA04Bpg8DmiJZ9Kq33XoYM9gA2i46/seTxBpawdbRZV88iZ2NPCnSQoHjKIhh9rwBOK vMa007tJDVGYNl0F91t591UFRhY8EX7hLtduCNph47M6Jv20Dh+046EGm/Sn2pA2IJwl DSJ/TqZNPfzTwdN5kL0agBFtuEAqv5TGrI7gTXRyiAI/6ZziDCGW74BksXJiRnAStKFE icZ/PO1cldPkfcS+GKVhi7+kT8mLLauyUizNeFHP8/XtlORzCor9K8oTrwtlEV8kwetz kS6w== 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=x6iDZ7UMCWz5eAlWvzKvl+2Jx74DUoqbhHJ8lz6Z5z8=; b=soDaRle1NXjqB2pmR8ftyO2hmZ2u6vr/OEIWPd+NRQ23p9mFlsp5E7m8w/tmui/M9p 6jycU//TLTGB4eNrh1Fo38NVH3uP66PuO/ZbVcATIoyWliVI+kCzldCS2RBU5J+vJHWv /necHQ22E4bTWj2b0rVTduyP2lDJ/l/SFezOUcq9XqS77HGnFkY67mlaSwFUt/CSDvjh 5QfMhBHhoHtH5YhDN+uRXFvqPGtOWrtgh3PeHbpFcMeyAklilz9ZnFfbTYV8D7BHLwb4 Nq4ZjoWGmpJkJwJgqEy58L8BPCH/SWYCaZXjLc6HTvZyXBtYM2YybKHKixjIVpmx1bgF YqCw== 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=AU/O3Rqm; 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 i195si1067241wmd.142.2018.02.18.21.55.53; Sun, 18 Feb 2018 21:55:54 -0800 (PST) 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=AU/O3Rqm; 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 14652689EC6; Mon, 19 Feb 2018 07:55: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 75590689EA6 for ; Mon, 19 Feb 2018 07:55:45 +0200 (EET) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=smtpservice.net; s=m78bu0.a1-4.dyn; x=1519020651; h=Feedback-ID: X-Smtpcorp-Track:Message-Id:Date:Subject:To:From:Reply-To:Sender: List-Unsubscribe; bh=OOi+Ecq8zNiWg+nQyR5Fz1U7JJfR5hcGhJjlbD4iBBE=; b=AU/O3Rqm 8EI9+2AfyEqq0qit91wkKr5hPCbdnbui5T2s/m+Fxmas0IMtDifxE2xvYs+7hAdFs4TU3oSPX29vY XkPAFi8s8U0m6y2oJdEx+Bu+1KfGpqLyl7eyBBHEyhBL62qKyQ494u2PeIg1prR8aQ08f8FlHWNQ+ epHIVcZ4QVnkdHM/9qwB+mYgiO0Y4ATifpSgjSaAMHq6FLYpp4zp7UUYFpR0apLu53I5k1HiKz5iD umj3Jk66nsu9dOG2nQka9h+cqAdlyp7TumNfJBc21kALEKZVuntDuTpWQjJjEe0FHfYJWLlG0NHhP t/3jylo1PpnJdMbYSAee0G+O1g==; From: vdixit@akamai.com To: ffmpeg-devel@ffmpeg.org Date: Mon, 19 Feb 2018 11:25:36 +0530 Message-Id: <1519019736-12551-1-git-send-email-vdixit@akamai.com> X-Mailer: git-send-email 1.9.1 X-Smtpcorp-Track: 1-n-QQNmF5Px0F.iiPfst6Dx Feedback-ID: 337386m:337386asVRLGB:337386sspWosh1sT:SMTPCORP X-Report-Abuse: Please forward a copy of this message, including all headers, to Subject: [FFmpeg-devel] [PATCH 3/3] avformat/dashenc: chunk streaming support for low latency use cases 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 --- doc/muxers.texi | 3 +++ libavformat/dashenc.c | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/doc/muxers.texi b/doc/muxers.texi index d9a5cc0..c156ec0 100644 --- a/doc/muxers.texi +++ b/doc/muxers.texi @@ -254,6 +254,9 @@ Use persistent HTTP connections. Applicable only for HTTP output. @item -hls_playlist @var{hls_playlist} Generate HLS playlist files as well. The master playlist is generated with the filename master.m3u8. One media playlist file is generated for each stream with filenames media_0.m3u8, media_1.m3u8, etc. +@item -streaming @var{streaming} +Enable (1) or disable (0) chunk streaming mode of output. In chunk streaming +mode, each frame will be a moof fragment which forms a chunk. @item -adaptation_sets @var{adaptation_sets} Assign streams to AdaptationSets. Syntax is "id=x,streams=a,b,c id=y,streams=d,e" with x and y being the IDs of the adaptation sets and a,b,c,d and e are the indices of the mapped streams. diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 0eb4b25..d6474f3 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -81,6 +81,7 @@ typedef struct OutputStream { char bandwidth_str[64]; char codec_str[100]; + int written_len; char filename[1024]; char full_path[1024]; char temp_path[1024]; @@ -114,6 +115,7 @@ typedef struct DASHContext { int master_playlist_created; AVIOContext *mpd_out; AVIOContext *m3u8_out; + int streaming; } DASHContext; static struct codec_string { @@ -250,7 +252,8 @@ static int flush_dynbuf(OutputStream *os, int *range_length) // write out to file *range_length = avio_close_dyn_buf(os->ctx->pb, &buffer); os->ctx->pb = NULL; - avio_write(os->out, buffer, *range_length); + avio_write(os->out, buffer + os->written_len, *range_length - os->written_len); + os->written_len = 0; av_free(buffer); // re-open buffer @@ -960,7 +963,10 @@ static int dash_init(AVFormatContext *s) os->init_start_pos = 0; if (!strcmp(os->format_name, "mp4")) { - av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); + if (c->streaming) + av_dict_set(&opts, "movflags", "frag_every_frame+dash+delay_moov", 0); + else + av_dict_set(&opts, "movflags", "frag_custom+dash+delay_moov", 0); } else { av_dict_set_int(&opts, "cluster_time_limit", c->min_seg_duration / 1000, 0); av_dict_set_int(&opts, "cluster_size_limit", 5 * 1024 * 1024, 0); // set a large cluster size limit @@ -1155,7 +1161,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) } if (!c->single_file) { - if (!strcmp(os->format_name, "mp4")) + if (!strcmp(os->format_name, "mp4") && !os->written_len) write_styp(os->ctx->pb); } else { snprintf(os->full_path, sizeof(os->full_path), "%s%s", c->dirname, os->initfile); @@ -1318,6 +1324,19 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) av_dict_free(&opts); } + //write out the data immediately in streaming mode + if (c->streaming && !strcmp(os->format_name, "mp4")) { + int len = 0; + uint8_t *buf = NULL; + if (!os->written_len) + write_styp(os->ctx->pb); + avio_flush(os->ctx->pb); + len = avio_get_dyn_buf (os->ctx->pb, &buf); + avio_write(os->out, buf + os->written_len, len - os->written_len); + os->written_len = len; + avio_flush(os->out); + } + return ret; } @@ -1394,6 +1413,7 @@ static const AVOption options[] = { { "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E}, { "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E }, { "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 }, { NULL }, };