From patchwork Sat Mar 23 11:14:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 47362 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:c889:b0:1a3:b6bb:3029 with SMTP id hb9csp158254pzb; Sat, 23 Mar 2024 04:14:53 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVDhilitFPM4byWzb0bmSodjCfcYce9lZ1Qtgl6zdfKkgyvO+u2Nyx+j4FZabwmmpx7zRB+pvpfRLIYmBhuxoVqL2NzrBBxOwnI6Q== X-Google-Smtp-Source: AGHT+IGo/P6KcIg9Y4Dfm9pEqxMNTr6brjK+d6UcQy7gfnTyIeRcQ8nRoFD0HKhfR2zFB0yHbfh7 X-Received: by 2002:a50:9547:0:b0:567:a318:ac0b with SMTP id v7-20020a509547000000b00567a318ac0bmr1407693eda.16.1711192493486; Sat, 23 Mar 2024 04:14:53 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1711192493; cv=none; d=google.com; s=arc-20160816; b=cDFqd3eV6i6wsQrDeUSbIuIA7Gmd3Bkbkax0yeOCnxO8T6h/h0KDp2z1DGNInmJ2dG LQK7WAG9yJ3HEB3zoI6oJqllh+tlnC7Eo1ir1jh/VQxAfTctEFv1Z4tOMVoZ51ZD9Qkg 2FIk/BY6L9nucJn7/b8CZTtsf+EsOr31hob5zw7V3dmpNAy0wRCLMmNuaiAKNUpN0jcF +/xiXL6he8fHUDq648rcGeKJGPsAV1iKME3oC4ycAxmZ0OvdstmFVCHOJkDftgS2XehA Hy7TucZjRSb3wKMMlDoYeVEJ7LYepd+e3bVG4wZFpXlB4oVHnP4KLwXtEBGZIAA3cVJn 6pLA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:delivered-to; bh=46p4TbByjTcu/CAV+b9xxom9CEyBplodOwFZgtgiUwQ=; fh=s+G8Ss4JbeMFkWPSp2LmIH/LXFyBlALRiww1j3FPjHY=; b=s8EDABw/6zNsBh7Gw8vCaz0Gftuu5fCTSDSIHWQX+Vg8yitF1NrctLzc44pf0zfnDp QkYKcFXNxhJ1amOEJ4G/Vc2Q45lJH16GFh+pkdGAUsAyIcJljMUwAFEZOMA5upIlw52T RpQK8g2fYkp7sd25NC1f1Rn2auiKTT8R2SP32tOQ8jptCMFK2LkwoxMWnaf/niZPQoKa wly2PN4KIy1VNUbJHrfBM9mYSkOpj/YYSbmBO8Wqg3uTknoQZSD+dfXGCl7udYuIcHiN AjguRQhU8d8dEmX74Nx2D8UZk02hmLc0rk/5eXCpnVKRlQLUMUXclelh+Q/4bKlHHh0V GsYg==; dara=google.com ARC-Authentication-Results: i=1; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id g17-20020a056402091100b0056ba6c01211si739705edz.338.2024.03.23.04.14.53; Sat, 23 Mar 2024 04:14:53 -0700 (PDT) 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 4F03168D1F0; Sat, 23 Mar 2024 13:14:49 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 29C1E68CFCE for ; Sat, 23 Mar 2024 13:14:42 +0200 (EET) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id DE3C6EA1EE; Sat, 23 Mar 2024 12:14:40 +0100 (CET) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id AcsYg4N_CFld; Sat, 23 Mar 2024 12:14:38 +0100 (CET) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 707ECE9A30; Sat, 23 Mar 2024 12:14:38 +0100 (CET) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Sat, 23 Mar 2024 12:14:13 +0100 Message-Id: <20240323111414.25547-1-cus@passwd.hu> X-Mailer: git-send-email 2.35.3 In-Reply-To: References: MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/2] avutil/timestamp: introduce av_ts_make_time_string2 for better precision X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Marton Balint Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: r3qs7UKa7fZ+ av_ts_make_time_string() used "%.6g" format, but this format was losing precision even when the timestamp to be printed was not that large. For example for 3 hours (10800) seconds, only 1 decimal digit was printed, which made this format inaccurate when it was used in e.g. the silencedetect filter. Other detection filters printing timestamps had similar issues. Also time base parameter of the function was *AVRational instead of AVRational. Resolve these problems by introducing a new function, av_ts_make_time_string2(). We change the used format to "%.*f", use a precision of 6, except when printing values near 0, in which case we calculate the precision dynamically to aim for a similar precision in normal form as with %.6g. No longer using scientific representation can make parsing the timestamp easier for the users, we can safely do this because the theoretical maximum of INT64_MAX*INT32_MAX still fits into the string buffer in normal form. We somewhat imitate %g by trimming ending zeroes and the potential decimal point characters. In order not to trim "inf" as well, we assume that the decimal point string does not contain the letter "f". Note that depending on printf %f implementation, we might trim "infinity" to "inf". Thanks for Allan Cady for bringing up this issue. Signed-off-by: Marton Balint --- doc/APIchanges | 5 +++++ libavutil/Makefile | 1 + libavutil/timestamp.c | 36 ++++++++++++++++++++++++++++++++++++ libavutil/timestamp.h | 8 ++++++++ libavutil/version.h | 2 +- 5 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 libavutil/timestamp.c diff --git a/doc/APIchanges b/doc/APIchanges index 2796b4d0c2..9c6fa381e1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -2,6 +2,11 @@ The last version increases of all libraries were on 2024-03-07 API changes, most recent first: +2024-03-xx - xxxxxxxxxx - lavu 59.5.100 - timestamp.h + Add av_ts_make_time_string2() for better timestamp precision, the new + function accepts AVRational as time base instead of *AVRational, and is not + an inline function like its predecessor. + 2024-03-xx - xxxxxxxxxx - lavc 61.3.100 - jni.h Add av_jni_set_android_app_ctx() and av_jni_get_android_app_ctx(). diff --git a/libavutil/Makefile b/libavutil/Makefile index 008fcfcd9c..6e6fa8d800 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -174,6 +174,7 @@ OBJS = adler32.o \ threadmessage.o \ time.o \ timecode.o \ + timestamp.o \ tree.o \ twofish.o \ utils.o \ diff --git a/libavutil/timestamp.c b/libavutil/timestamp.c new file mode 100644 index 0000000000..2a3e3012a4 --- /dev/null +++ b/libavutil/timestamp.c @@ -0,0 +1,36 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "timestamp.h" + +char *av_ts_make_time_string2(char *buf, int64_t ts, AVRational tb) +{ + if (ts == AV_NOPTS_VALUE) { + snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + } else { + double val = av_q2d(tb) * ts; + double log = floor(log10(fabs(val))); + int precision = (isfinite(log) && log < 0) ? -log + 5 : 6; + int last = snprintf(buf, AV_TS_MAX_STRING_SIZE, "%.*f", precision, val); + last = FFMIN(last, AV_TS_MAX_STRING_SIZE - 1) - 1; + for (; last && buf[last] == '0'; last--); + for (; last && buf[last] != 'f' && (buf[last] < '0' || buf[0] > '9'); last--); + buf[last + 1] = '\0'; + } + return buf; +} diff --git a/libavutil/timestamp.h b/libavutil/timestamp.h index 2b37781eba..7e6da894df 100644 --- a/libavutil/timestamp.h +++ b/libavutil/timestamp.h @@ -62,6 +62,14 @@ static inline char *av_ts_make_string(char *buf, int64_t ts) * @param tb the timebase of the timestamp * @return the buffer in input */ +char *av_ts_make_time_string2(char *buf, int64_t ts, AVRational tb); + +/** + * Fill the provided buffer with a string containing a timestamp + * representation. + * + * @see av_ts_make_time_string2 + */ static inline char *av_ts_make_time_string(char *buf, int64_t ts, const AVRational *tb) { diff --git a/libavutil/version.h b/libavutil/version.h index 882003f719..8a1ecd4451 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 59 -#define LIBAVUTIL_VERSION_MINOR 4 +#define LIBAVUTIL_VERSION_MINOR 5 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \