2012-01-17 19:12:42 +03:00
|
|
|
/*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @file
|
|
|
|
* timestamp utils, mostly useful for debugging/logging purposes
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef AVUTIL_TIMESTAMP_H
|
|
|
|
#define AVUTIL_TIMESTAMP_H
|
|
|
|
|
2021-07-23 14:06:58 +02:00
|
|
|
#include "avutil.h"
|
2012-01-17 19:12:42 +03:00
|
|
|
|
2014-03-13 19:32:15 +03:00
|
|
|
#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64)
|
|
|
|
#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS
|
|
|
|
#endif
|
|
|
|
|
2012-01-17 19:12:42 +03:00
|
|
|
#define AV_TS_MAX_STRING_SIZE 32
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fill the provided buffer with a string containing a timestamp
|
|
|
|
* representation.
|
|
|
|
*
|
|
|
|
* @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
|
|
|
|
* @param ts the timestamp to represent
|
|
|
|
* @return the buffer in input
|
|
|
|
*/
|
|
|
|
static inline char *av_ts_make_string(char *buf, int64_t ts)
|
|
|
|
{
|
|
|
|
if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS");
|
2016-08-31 21:48:45 +02:00
|
|
|
else snprintf(buf, AV_TS_MAX_STRING_SIZE, "%" PRId64, ts);
|
2012-01-17 19:12:42 +03:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience macro, the return value should be used only directly in
|
|
|
|
* function arguments but never stand-alone.
|
|
|
|
*/
|
|
|
|
#define av_ts2str(ts) av_ts_make_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fill the provided buffer with a string containing a timestamp time
|
|
|
|
* representation.
|
|
|
|
*
|
|
|
|
* @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE
|
|
|
|
* @param ts the timestamp to represent
|
|
|
|
* @param tb the timebase of the timestamp
|
|
|
|
* @return the buffer in input
|
|
|
|
*/
|
avutil/timestamp: introduce av_ts_make_time_string2 for better precision
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 <cus@passwd.hu>
2024-03-18 00:35:24 +02:00
|
|
|
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
|
|
|
|
*/
|
2024-02-28 20:47:50 +02:00
|
|
|
static inline char *av_ts_make_time_string(char *buf, int64_t ts,
|
|
|
|
const AVRational *tb)
|
2012-01-17 19:12:42 +03:00
|
|
|
{
|
2024-03-23 04:12:16 +02:00
|
|
|
return av_ts_make_time_string2(buf, ts, *tb);
|
2012-01-17 19:12:42 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience macro, the return value should be used only directly in
|
|
|
|
* function arguments but never stand-alone.
|
|
|
|
*/
|
|
|
|
#define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb)
|
|
|
|
|
|
|
|
#endif /* AVUTIL_TIMESTAMP_H */
|