diff mbox

[FFmpeg-devel,v4] Add 2 timestamp print formats

Message ID b3fbf8af-78fb-ef3a-31f9-1e0038c55ccf@CoSoCo.de
State Superseded
Headers show

Commit Message

Ulf Zibis July 3, 2019, 2:49 p.m. UTC
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

Comments

Nicolas George July 3, 2019, 2:52 p.m. UTC | #1
Ulf Zibis (12019-07-03):
> From 5d62406366560cfab5711120c514a77867bd8c2e Mon Sep 17 00:00:00 2001
> From: Ulf Zibis <Ulf.Zibis@CoSoCo.de>
> Date: 29.06.2019, 17:52:06
> 
> avutil/timestamp: added av_ts2us() and 2 new print formats

The features you add here seem useful, but I wonder: have you considered
the option of making them a single function with a parameter to select
the format? That may make it easier to add new formats later, and have
them supported by any component where this is relevant.

Regards,
Ulf Zibis July 3, 2019, 5:14 p.m. UTC | #2
Am 03.07.19 um 16:52 schrieb Nicolas George:
> The features you add here seem useful, but I wonder: have you considered
> the option of making them a single function with a parameter to select
> the format? That may make it easier to add new formats later, and have
> them supported by any component where this is relevant.

I didn't have considerd that. If one of the project managers will agree
to, please make a suggestion for the parameters you want, and I can do
an additional patch.

-Ulf
diff mbox

Patch

From 5d62406366560cfab5711120c514a77867bd8c2e Mon Sep 17 00:00:00 2001
From: Ulf Zibis <Ulf.Zibis@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 */