Am 03.07.19 um 10:52 schrieb Michael Niedermayer: > >>>> -#define av_ts2timestr(ts, tb) >>>> av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb) >>>> +#define av_ts2timestr(ts, tb) >>>> av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){'\0'}, ts, tb) >>>> + >>>> +/** >>>> + * Fill the provided buffer with a string containing a timestamp time >>>> + * representation in minutes and seconds. >>>> + * >>>> + * @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 >>>> + */ >>>> +static inline char *av_ts_make_minute_string(char *buf, int64_t ts, >>>> AVRational *tb) >>>> +{ >>>> + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, >>>> "NOPTS"); >>>> + else { >>>> + double time = av_q2d(*tb) * ts; >>> If this could be done without float/double that would be preferred as it >>> avoids inaccuracies / slight differences between platforms >> I too thought on that, but the existing functions too rely on >> float/double. Should I anyway provide a solution with integer arithmetic? > its indepedant of your patch but i think all these should use integers > unless its too messy
Thanks for you opinion. Here comes a new patch. -Ulf
From 5d62406366560cfab5711120c514a77867bd8c2e Mon Sep 17 00:00:00 2001 From: Ulf Zibis <ulf.zi...@cosoco.de> Date: 29.06.2019, 17:52:06 avutil/timestamp: added av_ts2us() and 2 new print formats diff --git a/libavutil/timestamp.h b/libavutil/timestamp.h index e082f01..8cb6e8f 100644 --- a/libavutil/timestamp.h +++ b/libavutil/timestamp.h @@ -33,6 +33,17 @@ #define AV_TS_MAX_STRING_SIZE 32 /** + * Convert a time base scaled timestamp to micro seconds. + * + * @param ts the timestamp to convert, must be less than 2**63/1,000,000/tb->num + * @param tb the timebase of the timestamp + * @return the timestamp in micro seconds + */ +static inline int64_t av_ts2us(int64_t ts, AVRational *tb) { + return ts * 1000000 * tb->num / tb->den; +} + +/** * Fill the provided buffer with a string containing a timestamp * representation. * @@ -55,7 +66,7 @@ /** * Fill the provided buffer with a string containing a timestamp time - * representation. + * representation in seconds. * * @param buf a buffer with size in bytes of at least AV_TS_MAX_STRING_SIZE * @param ts the timestamp to represent @@ -75,4 +86,60 @@ */ #define av_ts2timestr(ts, tb) av_ts_make_time_string((char[AV_TS_MAX_STRING_SIZE]){0}, ts, tb) +/** + * Fill the provided buffer with a string containing a timestamp time + * representation in minutes and seconds. + * + * @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 + */ +static char *av_ts_make_minute_string(char *buf, int64_t ts, AVRational *tb) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else { + int64_t us = av_ts2us(ts, tb); + int len = snprintf(buf, AV_TS_MAX_STRING_SIZE, "%3ld:%02d.%06d", + us / 60000000, (int)(us / 1000000 % 60), (int)(us % 1000000)); + while (buf[--len] == '0'); // search trailing zeros or ... + buf[len + (buf[len] != '.')] = '\0'; // dot and strip them + } + return buf; +} + +/** + * Convenience macro. The return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2minutestr(ts, tb) av_ts_make_minute_string((char[AV_TS_MAX_STRING_SIZE]){'\0'}, ts, tb) + +/** + * Fill the provided buffer with a string containing a timestamp time + * representation in hours, minutes and seconds. + * + * @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 + */ +static char *av_ts_make_hour_string(char *buf, int64_t ts, AVRational *tb) +{ + if (ts == AV_NOPTS_VALUE) snprintf(buf, AV_TS_MAX_STRING_SIZE, "NOPTS"); + else { + int64_t us = av_ts2us(ts, tb); + int len = snprintf(buf, AV_TS_MAX_STRING_SIZE, "%ld:%02d:%02d.%06d", + us / 3600000000, (int)(us / 60000000 % 60), (int)(us / 1000000 % 60), (int)(us % 1000000)); + while (buf[--len] == '0'); // search trailing zeros or ... + buf[len + (buf[len] != '.')] = '\0'; // dot and strip them + } + return buf; +} + +/** + * Convenience macro. The return value should be used only directly in + * function arguments but never stand-alone. + */ +#define av_ts2hourstr(ts, tb) av_ts_make_hour_string((char[AV_TS_MAX_STRING_SIZE]){'\0'}, ts, tb) + #endif /* AVUTIL_TIMESTAMP_H */
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".