From patchwork Mon Apr 20 17:57:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wheatley X-Patchwork-Id: 19109 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 0838144A819 for ; Mon, 20 Apr 2020 20:58:41 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DF70968B78C; Mon, 20 Apr 2020 20:58:40 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A58668B491 for ; Mon, 20 Apr 2020 20:58:35 +0300 (EEST) Received: by mail-wm1-f50.google.com with SMTP id x4so557689wmj.1 for ; Mon, 20 Apr 2020 10:58:35 -0700 (PDT) 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=8NdIulyfCKorboPicfyMXSzRpKDon0Ip7+a0CIl3HHw=; b=TyDtGBD1DLXNKy/SWZ3W631TtVfkpCr1kK3cO6Fe5/X2VeAUM4K6f+yTxfSjcVepAi 3XGgTNvDVREeNH536LSx2L36XyI2InsE5+nIuhDdoF6byFDYlgxbpSP1DGwsNd9grGik Mnppl7citrcVigUs+GEbKbX/Yutg0kayHL5rXZoDfxry8rGQZbWHiwt74NrseCA/xl/M VAy8eJWDyqaDrrB0QGpKMKbiLBgPgPBtpMLXtPYEiMbkwEbzuVyx4d5PVrZXKefJSY+1 M8C3iikzK27CuQS18w5EtZsAgqI4QJex4ViMjzFHyVtwnVirpi/JirPmGxeDy5Xx4IAB Q7Cg== 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=8NdIulyfCKorboPicfyMXSzRpKDon0Ip7+a0CIl3HHw=; b=J0HmVagra38/t69Ob7+aa5Imcz5bAzkZ00MCqjiKGQgYYDdrx6LV4CcZQUfhf9BWd3 zRj40Dql4JJf7MGjdGWgEE45Llhv5QpIeCvpGppzTNDzxL92cWDmFxMUNylOaIxAr2EJ G5MVEd5uzbYHPH1lJNa4F2Z9t9YbBB4IImKR9KPabUDmB42JjBH4XfsoGpNg5u7Eh8TP BKcVz2ALc59hbaaWuMeIuun/4k0YFyedWDSrd1O9310ucWAhryvVAl30eQ3SFk0/RQyg UWXoQH6Fz/+MOyJvVMSVf+8Lyyv9rLKHZxK+brOBTvnC1OqNV4BHfHPkggGFjzbjKKW7 R7xA== X-Gm-Message-State: AGi0PuaXdQDV9euq4hgM/SiUUYMmVxNbIQL6WgSSlsalF7TkyVao+3k3 tkn+F3S6FpJ5788U8Su4dU4A+tMq4rE= X-Google-Smtp-Source: APiQypLmcJLMwMBXyo6HOxGgvoBFnXSEL5CFT+xsGXgYYHOrLzhfSjTekUxEohGAs0EJCsDOVsgMKA== X-Received: by 2002:a7b:c38b:: with SMTP id s11mr525468wmj.55.1587405514156; Mon, 20 Apr 2020 10:58:34 -0700 (PDT) Received: from derwent.ldn.framestore.com (ldndefault.framestore.com. [185.101.14.7]) by smtp.gmail.com with ESMTPSA id l5sm287930wrm.66.2020.04.20.10.58.33 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Apr 2020 10:58:33 -0700 (PDT) From: Kevin Wheatley To: ffmpeg-devel@ffmpeg.org Date: Mon, 20 Apr 2020 18:57:37 +0100 Message-Id: <1587405459-29001-2-git-send-email-kevin.j.wheatley@gmail.com> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> References: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> Subject: [FFmpeg-devel] [PATCH 1/3] avformat/movenc: Add command line option to set base mov file timescale 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: Kevin Wheatley MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Kevin Wheatley --- libavformat/movenc.c | 1 + libavformat/movenc.h | 1 + 2 files changed, 2 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 253cff8..7d79eca 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -91,6 +91,7 @@ static const AVOption options[] = { { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + { "mov_timescale", "set timescale of mov container", offsetof(MOVMuxContext, mov_timescale), AV_OPT_TYPE_INT, {.i64 = MOV_TIMESCALE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM }, { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM}, diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 997b2d6..322968c 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -205,6 +205,7 @@ typedef struct MOVMuxContext { AVIOContext *mdat_buf; int first_trun; + int mov_timescale; int video_track_timescale; int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise From patchwork Mon Apr 20 17:57:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wheatley X-Patchwork-Id: 19111 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 3914044BC44 for ; Mon, 20 Apr 2020 21:06:12 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 1501568B783; Mon, 20 Apr 2020 21:06:12 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B51D1689D18 for ; Mon, 20 Apr 2020 21:06:05 +0300 (EEST) Received: by mail-wm1-f67.google.com with SMTP id h2so558340wmb.4 for ; Mon, 20 Apr 2020 11:06:05 -0700 (PDT) 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=iqhJX8uZDjV0ZnZc1IiVWXYI0NfU/Uq7sC7Yizt0JDc=; b=gkQo9d1hdiOZXls6y1RTE3Dwq/1CbPtPXxpC0sJ/7G4ysYzMqORL4khbbGVi8ZCPqU fyhUSgyjMVjmFx+xnisvs3LDZEedD0IhqcwOiOzaxBF/k1FFzm/qaFS/5ywRYLyfXlmM 1aVbB1KVMRHYrKXJI5O7WTCDwMkWVHYdjOgVSBVH4eDjxZiG6eBXzaVHB8DfYAOta2Jr G3+SG5s8u7ZFvOMN+AIuEXYEWgMx9bXkE92uZEWdfrSVdPWNd8cW0NGPjARtNCMkI6k+ yJYcwKdX5R22vua4rqH2DruVqXgOBHceIToHp2CZkczUo4BAH++w3ba3g3Aj+JfBS+gk 0heg== 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=iqhJX8uZDjV0ZnZc1IiVWXYI0NfU/Uq7sC7Yizt0JDc=; b=mwbjaeT18vhXz+L7kqV4Tc+LN+XTPDbFfk//amhjdXVza61010dESY640J5VA2HmkP t+3UBG84aD0vHI+b+sVvf1VRwMhxsTL941SlggtAGBvpQ53fvuj820vxKYFN1bMg4NVF jkWKusjb68+HAhbEdhAuLu+MaiF6NZDMEs3rbiq+CxiywrByCT1WRFYpLpqtyKeJVALp EcJQ0p5bn1AU97zNwl0dI2BX8Zgu6ZH8nm61UT143NrYvVC83aVLgqy/41PIHnNOEKJs Mu97wB60AheMsBLETWcZbQ+tszfSf2dL0/6eDSEaQXoJ9z0bAUs+AV4T+TDaXarKNIR3 mxKA== X-Gm-Message-State: AGi0Pua+TOH5U3JXzzlrKHDWAR5lgDFhIbLl2BLNoZmq3wxppfDmkndP oddjx9BF7TjAEWxvmuA4wWTJIk2gtDk= X-Google-Smtp-Source: APiQypJs1vFSouJLx2dZd6qe58Nd0+Y45JYkOat5YjeDAiM1PkDOrwj3+gZu+yKb+VC1DI5GzHO4mQ== X-Received: by 2002:a1c:1985:: with SMTP id 127mr578196wmz.13.1587405514926; Mon, 20 Apr 2020 10:58:34 -0700 (PDT) Received: from derwent.ldn.framestore.com (ldndefault.framestore.com. [185.101.14.7]) by smtp.gmail.com with ESMTPSA id l5sm287930wrm.66.2020.04.20.10.58.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Apr 2020 10:58:34 -0700 (PDT) From: Kevin Wheatley To: ffmpeg-devel@ffmpeg.org Date: Mon, 20 Apr 2020 18:57:38 +0100 Message-Id: <1587405459-29001-3-git-send-email-kevin.j.wheatley@gmail.com> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> References: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/3] avformat/movenc: Use base container timescale, instead of hard coded default 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: Kevin Wheatley , Kevin Wheatley MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Kevin Wheatley --- libavformat/movenc.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 7d79eca..508fa73 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2879,7 +2879,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track, AVStream *st) { int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track), - MOV_TIMESCALE, track->timescale, + mov->mov_timescale, track->timescale, AV_ROUND_UP); int version = duration < INT32_MAX ? 0 : 1; int flags = MOV_TKHD_FLAG_IN_MOVIE; @@ -3027,7 +3027,7 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *track) { int64_t duration = av_rescale_rnd(calc_pts_duration(mov, track), - MOV_TIMESCALE, track->timescale, + mov->mov_timescale, track->timescale, AV_ROUND_UP); int version = duration < INT32_MAX ? 0 : 1; int entry_size, entry_count, size; @@ -3046,7 +3046,7 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, } } - delay = av_rescale_rnd(start_dts + start_ct, MOV_TIMESCALE, + delay = av_rescale_rnd(start_dts + start_ct, mov->mov_timescale, track->timescale, AV_ROUND_DOWN); version |= delay < INT32_MAX ? 0 : 1; @@ -3081,8 +3081,8 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVMuxContext *mov, /* Avoid accidentally ending up with start_ct = -1 which has got a * special meaning. Normally start_ct should end up positive or zero * here, but use FFMIN in case dts is a small positive integer - * rounded to 0 when represented in MOV_TIMESCALE units. */ - av_assert0(av_rescale_rnd(start_dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0); + * rounded to 0 when represented in mov->mov_timescale units. */ + av_assert0(av_rescale_rnd(start_dts, mov->mov_timescale, track->timescale, AV_ROUND_DOWN) <= 0); start_ct = -FFMIN(start_dts, 0); /* Note, this delay is calculated from the pts of the first sample, * ensuring that we don't reduce the duration for cases with @@ -3316,7 +3316,7 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) { int64_t max_track_len_temp = av_rescale_rnd( calc_pts_duration(mov, &mov->tracks[i]), - MOV_TIMESCALE, + mov->mov_timescale, mov->tracks[i].timescale, AV_ROUND_UP); if (max_track_len < max_track_len_temp) @@ -3345,7 +3345,7 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) avio_wb32(pb, mov->time); /* creation time */ avio_wb32(pb, mov->time); /* modification time */ } - avio_wb32(pb, MOV_TIMESCALE); + avio_wb32(pb, mov->mov_timescale); (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */ avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */ @@ -5921,7 +5921,7 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum) track->mode = mov->mode; track->tag = MKTAG('t','e','x','t'); - track->timescale = MOV_TIMESCALE; + track->timescale = mov->mov_timescale; track->par = avcodec_parameters_alloc(); if (!track->par) return AVERROR(ENOMEM); @@ -5982,8 +5982,8 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum) AVChapter *c = s->chapters[i]; AVDictionaryEntry *t; - int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE}); + int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,mov->mov_timescale}); + pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,mov->mov_timescale}); pkt.duration = end - pkt.dts; if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { @@ -6518,7 +6518,7 @@ static int mov_init(AVFormatContext *s) } else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) { track->timescale = st->time_base.den; } else { - track->timescale = MOV_TIMESCALE; + track->timescale = mov->mov_timescale; } if (!track->height) track->height = st->codecpar->height; From patchwork Mon Apr 20 17:57:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wheatley X-Patchwork-Id: 19110 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id CC325445146 for ; Mon, 20 Apr 2020 20:58:44 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B7B0B68B828; Mon, 20 Apr 2020 20:58:44 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7A85C68B491 for ; Mon, 20 Apr 2020 20:58:37 +0300 (EEST) Received: by mail-wm1-f50.google.com with SMTP id t63so539195wmt.3 for ; Mon, 20 Apr 2020 10:58:37 -0700 (PDT) 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=eNmYCjmeTeHx8hz07M8lXX5YGyUxONuAq1V/bYCtZfY=; b=IdUN7udX0HKwYyv9iI9h7SjOAG11CyH3ykGn3T31ISsoU6/7GP0VwqvTan/mPPhIKm KXx0PokxJa+D4J26MIrhkBIU0Wy+ukRAwA00dyImjCWJR0/8BrHvBShTjJJPAJbK+emK 7uuYPbQpeFtPYKSdomsWOafEVS5om3roblJUmY1HCgChebp7iX1n3Sz1zCsgQHzuEIwt RsXbsK1Beh+mBBJP82HkrRi+XU+6vdmmV8gl3EO4wpYPNFQqS8Ty/Bm0ovxI7C6f/wQ3 QccZJsXO0A/CZZ16ji8aPrkJKiBF06tq11OHU8NgJLHetZAxBHJIjMSX8IZl4NRuqESb 208Q== 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=eNmYCjmeTeHx8hz07M8lXX5YGyUxONuAq1V/bYCtZfY=; b=Tb/92kGuDU7fUoi2x0Kb1VppAh34e5ev2ZXhRd6GhD2gOQ834ojAWHatxMtccPktaQ i3uHwwZnZtOZYIgQ/CG5EzXLaEuXV8xM3nf8G/Z2x9NFaQqartlr6HIyWtU001nrspOp r02pkfGhArHIZp6A7SAie3xgSep1ch9ZApf6vq4A3irEAc7QzNoVh8HjARHKlQuRJ4s3 9xJ7VoaQu++lN3GVW9bpkdJH8xLeBL9x3ftzl3TQwJE1NvDvEtuZsWxB3mhpYOE8wZRA 24nXQAzmU86VRcDZYwRW/gEr54RKTCtEe26Y3BkLad6+kBwzVtOOyv8Pkf/W5HYIbziV zs/g== X-Gm-Message-State: AGi0PubwGjF9mITEcLEes8wF/RV92G3Xi/YtF/wP6jIxDJQ9Z6+XjQug BWSDd9NG1HSyaPAtrSJdR8d/iOi/T3Q= X-Google-Smtp-Source: APiQypKbtYlGxalH+EsBRFbeNntTnGUYIMijeZpNOl9GSC1rGnHlF25sabhdmM3Ymlaap9da2SoQpw== X-Received: by 2002:a1c:492:: with SMTP id 140mr567202wme.9.1587405516341; Mon, 20 Apr 2020 10:58:36 -0700 (PDT) Received: from derwent.ldn.framestore.com (ldndefault.framestore.com. [185.101.14.7]) by smtp.gmail.com with ESMTPSA id l5sm287930wrm.66.2020.04.20.10.58.34 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Apr 2020 10:58:35 -0700 (PDT) From: Kevin Wheatley To: ffmpeg-devel@ffmpeg.org Date: Mon, 20 Apr 2020 18:57:39 +0100 Message-Id: <1587405459-29001-4-git-send-email-kevin.j.wheatley@gmail.com> X-Mailer: git-send-email 1.8.5.6 In-Reply-To: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> References: <1587405459-29001-1-git-send-email-kevin.j.wheatley@gmail.com> Subject: [FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add an automatic timescale computation 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: Kevin Wheatley MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Activated when the -mov_timescale command line/MOVMuxContext parameter is set to 0 or less. If the user passes any value greater than 0, then it will be used as-is. The default value is kept unchanged at 1000. When active, it uses the base assumption from the QuickTime specification of 600 and combines the video stream time bases to compute an accurate answer if possible. In cases when the first stream result falls outside MOV_MAX_AUTO_TIMESCALE or if a non-integer video stream is encounted, then the first stream's time_base will be used as the base. Signed-off-by: Kevin Wheatley --- libavformat/movenc.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ libavformat/movenc.h | 1 + 2 files changed, 72 insertions(+) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 508fa73..8edb848 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -6208,6 +6208,70 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track, return 0; } +static int mov_determine_movie_timescale(AVFormatContext *s, MOVMuxContext *mov) +{ + // Assume typical integer frame rates: + // 600 is a common multiple of 24, 25, 30, 50, 60, etc. + // see p221, https://developer.apple.com/standards/qtff-2001.pdf + int timescale = 600; + AVRational temp; + int exact; + int first_video_track = 1; + + // If the user specified a timescale, just use it as-is + if (mov->mov_timescale > 0) { + return mov->mov_timescale; + } + + // Determine the timescale, based on the video stream time_base values + for (int i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + + // If the first video track is not an integer, use its denominator + // as the basis of the remaining calculations + if (first_video_track && st->time_base.num != 1) { + timescale = st->time_base.den; + av_log(s, AV_LOG_VERBOSE, "Using first video stream non-integer time_base: %d/%d\n", + st->time_base.den, st->time_base.num); + } + + // determine if we can make an even multiple of the current timescale and the video track + av_log(s, AV_LOG_VERBOSE, "Current estimated timescale: %d\n", timescale); + av_log(s, AV_LOG_TRACE, "Stream #%d time_base: %d/%d\n", i, + st->time_base.num, st->time_base.den); + + // Try keep the time_scale within a sensible bound + exact = av_reduce(&temp.num, &temp.den, + (int64_t)timescale * st->time_base.num, + st->time_base.den, + MOV_MAX_AUTO_TIMESCALE); + + // Use a scaled version of the timescale + if (exact) { + timescale *= temp.den; + av_log(s, AV_LOG_TRACE, "Adjusted timescale: %d/%d %d\n", + temp.den, temp.num, timescale); + } else { + // We overflowed try the denominator as is + timescale = temp.den; + av_log(s, AV_LOG_WARNING, "Timescale calculation out of bounds approximating %d/%d %d\n", + temp.den, temp.num, timescale); + } + + if (first_video_track && ((timescale > MOV_MAX_AUTO_TIMESCALE) || !exact)) { + timescale = st->time_base.den; + av_log(s, AV_LOG_WARNING, "Potentially large timescale, " + "using first video stream time_base: %d/%d\n", + st->time_base.den, st->time_base.num); + } + first_video_track = 0; + } + } + av_log(s, AV_LOG_VERBOSE, "Final timescale: %d\n", timescale); + return timescale; +} + static int mov_init(AVFormatContext *s) { MOVMuxContext *mov = s->priv_data; @@ -6266,6 +6330,13 @@ static int mov_init(AVFormatContext *s) mov->reserved_moov_size = -1; } + mov->mov_timescale = mov_determine_movie_timescale(s, mov); + if (mov->mov_timescale > MOV_MAX_AUTO_TIMESCALE) { + av_log(s, AV_LOG_WARNING, "Potentially large timescale %d, use " + "-mov_timescale if you have issues\n", + mov->mov_timescale); + } + if (mov->use_editlist < 0) { mov->use_editlist = 1; if (mov->flags & FF_MOV_FLAG_FRAGMENT && diff --git a/libavformat/movenc.h b/libavformat/movenc.h index 322968c..4d6b7b7 100644 --- a/libavformat/movenc.h +++ b/libavformat/movenc.h @@ -30,6 +30,7 @@ #define MOV_FRAG_INFO_ALLOC_INCREMENT 64 #define MOV_INDEX_CLUSTER_SIZE 1024 #define MOV_TIMESCALE 1000 +#define MOV_MAX_AUTO_TIMESCALE 10000 #define RTP_MAX_PACKET_SIZE 1450