From patchwork Sat Jan 21 21:11:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Peter_Gro=C3=9Fe?= X-Patchwork-Id: 2284 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp632473vsb; Sat, 21 Jan 2017 13:11:28 -0800 (PST) X-Received: by 10.28.15.2 with SMTP id 2mr8966462wmp.66.1485033088472; Sat, 21 Jan 2017 13:11:28 -0800 (PST) Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g29si12778657wra.178.2017.01.21.13.11.28; Sat, 21 Jan 2017 13:11:28 -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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 838A168A8AD; Sat, 21 Jan 2017 23:11:14 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from james.theweblords.de (james.theweblords.de [217.11.55.87]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 3CD7C68A1A0 for ; Sat, 21 Jan 2017 23:11:08 +0200 (EET) Received: (qmail 24274 invoked by uid 210); 21 Jan 2017 21:11:19 -0000 X-Qmail-Scanner-Diagnostics: from x5d808bdc.dyn.telefonica.de (petronios@theweblords.de@x5d808bdc.dyn.telefonica.de) by james (envelope-from , uid 201) with qmail-scanner-2.10st (mhr: 1.0. spamassassin: 3.4.1. perlscan: 2.10st. Clear:RC:1(93.128.139.220):. Processed in 0.042932 secs); 21 Jan 2017 21:11:19 -0000 Received: from x5d808bdc.dyn.telefonica.de (HELO montepegro.fem.tu-ilmenau.de) (petronios@theweblords.de@93.128.139.220) by james.theweblords.de with ESMTPA; 21 Jan 2017 21:11:19 -0000 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= To: ffmpeg-devel@ffmpeg.org Date: Sat, 21 Jan 2017 22:11:08 +0100 Message-Id: <20170121211108.10616-1-pegro@friiks.de> X-Mailer: git-send-email 2.10.2 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/1] libavformat/dashenc: separate segments based on segment duration instead of total duration 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: ischluff@mailbox.org, pegro@friiks.de Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" The current implementation creates new segments comparing pkt->pts - first_pts > total_duration This works fine, but if the keyframe interval is smaller than "min_seg_duration" segments shorter than the minimum segment duration are created. Example: keyint=50, min_seg_duration=3000000 segment 1 contains keyframe 1 (duration=2s < total_duration=3s) and keyframe 2 (duration=4s >= total_duration=3s) segment 2 contains keyframe 3 (duration=6s >= total_duration=6s) segment 3 contains keyframe 4 (duration=8s < total_duration=9s) and keyframe 5 (duration=10s >= total_duration=9s) ... Segment 2 is only 2s long, shorter than min_seg_duration = 3s. To fix this, either rename "min_seg_duration" to something more accurate. Or apply this patch to create new segments based on the actual written duration. Signed-off-by: Peter Große --- libavformat/dashenc.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index e4bb923..c3a5dc5 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -73,7 +73,7 @@ typedef struct OutputStream { AVFormatContext *ctx; int ctx_inited, as_idx; AVIOContext *out; - int packets_written; + int duration_written; char initfile[1024]; int64_t init_start_pos, pos; int init_range_length; @@ -1032,7 +1032,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) char filename[1024] = "", full_path[1024], temp_path[1024]; int range_length, index_length = 0; - if (!os->packets_written) + if (!os->duration_written) continue; // Flush the single stream that got a keyframe right now. @@ -1081,7 +1081,7 @@ static int dash_flush(AVFormatContext *s, int final, int stream) av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, full_path); // set new position - os->packets_written = 0; + os->duration_written = 0; os->pos += range_length; // write chunk header @@ -1119,7 +1119,6 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) DASHContext *c = s->priv_data; AVStream *st = s->streams[pkt->stream_index]; OutputStream *os = &c->streams[pkt->stream_index]; - int64_t seg_end_duration = (os->segment_index) * (int64_t) c->min_seg_duration; int ret; ret = update_stream_extradata(s, os, st->codecpar); @@ -1148,9 +1147,9 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) os->first_pts = pkt->pts; if ((!c->has_video || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && - pkt->flags & AV_PKT_FLAG_KEY && os->packets_written && - av_compare_ts(pkt->pts - os->first_pts, st->time_base, - seg_end_duration, AV_TIME_BASE_Q) >= 0) { + pkt->flags & AV_PKT_FLAG_KEY && os->duration_written && + av_compare_ts(os->duration_written + pkt->duration, st->time_base, + c->min_seg_duration, AV_TIME_BASE_Q) >= 0) { int64_t prev_duration = c->last_duration; c->last_duration = av_rescale_q(pkt->pts - os->start_pts, @@ -1173,7 +1172,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } - if (!os->packets_written) { + if (!os->duration_written) { // If we wrote a previous segment, adjust the start time of the segment // to the end of the previous one (which is the same as the mp4 muxer // does). This avoids gaps in the timeline. @@ -1186,7 +1185,7 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) os->max_pts = pkt->pts + pkt->duration; else os->max_pts = FFMAX(os->max_pts, pkt->pts + pkt->duration); - os->packets_written++; + os->duration_written += pkt->duration; return ff_write_chained(os->ctx, 0, pkt, s, 0); }