From e519dcd937c7c98815ba9884867590e302272016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20Gro=C3=9Fe?= Date: Sun, 29 Jan 2017 15:26:25 +0100 Subject: [PATCH] dashenc: separate segments based on current segment duration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current implementation creates new segments comparing pkt->pts - first_pts > nb_segs * min_seg_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, new segments are created based on the actual written duration. Otherwise the option name "min_seg_duration" is misleading. Signed-off-by: Peter Große Signed-off-by: Martin Storsjö --- libavformat/dashenc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c index 198932caa4..98722cd24e 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -868,7 +868,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); @@ -898,8 +897,8 @@ static int dash_write_packet(AVFormatContext *s, AVPacket *pkt) 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) { + av_compare_ts(pkt->pts - os->start_pts, 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,