From patchwork Wed Dec 28 05:47:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Bradshaw X-Patchwork-Id: 1959 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.103.89.21 with SMTP id n21csp1800628vsb; Tue, 27 Dec 2016 21:48:09 -0800 (PST) X-Received: by 10.28.0.210 with SMTP id 201mr31488704wma.49.1482904089248; Tue, 27 Dec 2016 21:48:09 -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 w19si28232104wme.77.2016.12.27.21.48.08; Tue, 27 Dec 2016 21:48:09 -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=@gmail.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; dmarc=fail (p=NONE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id A534C689E0A; Wed, 28 Dec 2016 07:47:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pg0-f66.google.com (mail-pg0-f66.google.com [74.125.83.66]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 83A94689DDA for ; Wed, 28 Dec 2016 07:47:49 +0200 (EET) Received: by mail-pg0-f66.google.com with SMTP id g1so14612982pgn.0 for ; Tue, 27 Dec 2016 21:47:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pg9LMs+uIPDc8b92JB/5HhTNsq3jQ8hW1fbWpITvSyA=; b=maaYt3IcO2SCwD0DdVD2SbVVn9EouwcUth4QE2FSwwmqr+Z6RIcxTJ3Yv3NM0iKK/+ 2jWIczNSInUB9rFPBymJHutHbVDWDzvFP4Dw+zwVssX7g49vEZh03ornnqrrapyiOmz/ f5W/HCO/vN+ZipQLUtgErTNonviug2rmLIgddMjz2D4QTqqmTsGLUReCWb5Ulo+DT5vY AnVo3rDA4tYZLxNwKrysLSccbdFv1vyHUOe+rTbHeBKpx/zqmXutbDtCxWuGwTimuEzT +Gm6CLC+MLaC2unM2sGw5HA8qLpNpNbIFiTegKqbax2T7GoBnu15cUYYvuwsQWs//o22 JcQQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pg9LMs+uIPDc8b92JB/5HhTNsq3jQ8hW1fbWpITvSyA=; b=hf8D0gXhfZpoHbuAdInl3P9ZHhyijJL0N6w7jffJYucQANFkbEsEYqd+jeJiygzzPb JEVC+zqciNh4hDmsUgouut74s9MSZ3lTZJ7VqRnn0Ltsjxq4lndI8uNPk7zUGrtA8Me7 RgHCMhQ5Kyl4XCQ1Ll/pKJJKyKlQ/PqF9pFjpU89bQ19ldNcImNGWPA51jlgs4ygeNpA lKsglFm6FIAVJNSKUPXxgxtt7/C0fAwyYwjZl31VQ8BBnHkHzN3WFcVwNYx5K5z9jMYw vTJJ/NjRyTRMoRPDFiCMU1JbfHkp/0ItGy6ArsicvQ23fCGJcEiWBA5fT7vJBpcR3CyG znhA== X-Gm-Message-State: AIkVDXKELlQKeyOxli8hubBvEt1vl42GTBTF/AmTFS0FYkqdHnZlEWDBz9DHk6DybU/uwg== X-Received: by 10.84.216.8 with SMTP id m8mr74174129pli.116.1482904071131; Tue, 27 Dec 2016 21:47:51 -0800 (PST) Received: from localhost.localdomain (c-73-189-103-209.hsd1.ca.comcast.net. [73.189.103.209]) by smtp.gmail.com with ESMTPSA id o126sm94079061pga.34.2016.12.27.21.47.49 (version=TLS1 cipher=AES128-SHA bits=128/128); Tue, 27 Dec 2016 21:47:50 -0800 (PST) From: Michael Bradshaw To: ffmpeg-devel@ffmpeg.org Date: Tue, 27 Dec 2016 21:47:47 -0800 Message-Id: <20161228054747.40683-2-mjbshaw@gmail.com> X-Mailer: git-send-email 2.10.1 (Apple Git-78) In-Reply-To: <20161228054747.40683-1-mjbshaw@gmail.com> References: <20161228054747.40683-1-mjbshaw@gmail.com> Subject: [FFmpeg-devel] [PATCH] avformat/matroskaenc: Accept time base hint 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: Michael Bradshaw MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" From: Michael Bradshaw Signed-off-by: Michael Bradshaw --- libavformat/matroskaenc.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 827d755..2c2c930 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -117,6 +117,7 @@ typedef struct mkv_attachments { typedef struct MatroskaMuxContext { const AVClass *class; int mode; + int timecode_scale; AVIOContext *dyn_bc; AVIOContext *tags_bc; ebml_master tags; @@ -1757,7 +1758,7 @@ static int mkv_write_header(AVFormatContext *s) return ret; pb = mkv->info_bc; - put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); + put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, mkv->timecode_scale); if ((tag = av_dict_get(s->metadata, "title", NULL, 0))) put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); if (!(s->flags & AVFMT_FLAG_BITEXACT)) { @@ -1799,11 +1800,11 @@ static int mkv_write_header(AVFormatContext *s) int64_t metadata_duration = get_metadata_duration(s); if (s->duration > 0) { - int64_t scaledDuration = av_rescale(s->duration, 1000, AV_TIME_BASE); + int64_t scaledDuration = av_rescale(s->duration, 1000000000, AV_TIME_BASE * (int64_t)mkv->timecode_scale); put_ebml_float(pb, MATROSKA_ID_DURATION, scaledDuration); av_log(s, AV_LOG_DEBUG, "Write early duration from recording time = %" PRIu64 "\n", scaledDuration); } else if (metadata_duration > 0) { - int64_t scaledDuration = av_rescale(metadata_duration, 1000, AV_TIME_BASE); + int64_t scaledDuration = av_rescale(metadata_duration, 1000000000, AV_TIME_BASE * (int64_t)mkv->timecode_scale); put_ebml_float(pb, MATROSKA_ID_DURATION, scaledDuration); av_log(s, AV_LOG_DEBUG, "Write early duration from metadata = %" PRIu64 "\n", scaledDuration); } else { @@ -1864,12 +1865,12 @@ static int mkv_write_header(AVFormatContext *s) // after 4k and on a keyframe if (pb->seekable) { if (mkv->cluster_time_limit < 0) - mkv->cluster_time_limit = 5000; + mkv->cluster_time_limit = av_rescale(5, 1000000000, mkv->timecode_scale); if (mkv->cluster_size_limit < 0) mkv->cluster_size_limit = 5 * 1024 * 1024; } else { if (mkv->cluster_time_limit < 0) - mkv->cluster_time_limit = 1000; + mkv->cluster_time_limit = 1000000000 / mkv->timecode_scale; if (mkv->cluster_size_limit < 0) mkv->cluster_size_limit = 32 * 1024; } @@ -2458,6 +2459,7 @@ static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance) static int mkv_init(struct AVFormatContext *s) { + MatroskaMuxContext *mkv = s->priv_data; int i; if (s->avoid_negative_ts < 0) { @@ -2465,9 +2467,31 @@ static int mkv_init(struct AVFormatContext *s) s->internal->avoid_negative_ts_use_pts = 1; } + // ms precision is the de-facto standard timescale for mkv files + mkv->timecode_scale = 1000000; + + // If the user has supplied a desired time base, use it if possible + if (s->nb_streams > 0) { + AVRational time_base = s->streams[0]->time_base; + for (i = 1; i < s->nb_streams; i++) { + if (time_base.num != s->streams[i]->time_base.num || + time_base.den != s->streams[i]->time_base.den) { + time_base = av_make_q(0, 0); + break; + } + } + // Make sure the time base is valid, can losslessly be converted to + // nanoseconds, and isn't longer than 1 second + if (time_base.num > 0 && + time_base.den > 0 && + 1000000000 % time_base.den == 0 && + time_base.num <= time_base.den) { + mkv->timecode_scale = (int)av_rescale(time_base.num, 1000000000, time_base.den); + } + } + for (i = 0; i < s->nb_streams; i++) { - // ms precision is the de-facto standard timescale for mkv files - avpriv_set_pts_info(s->streams[i], 64, 1, 1000); + avpriv_set_pts_info(s->streams[i], 64, mkv->timecode_scale, 1000000000); } return 0;