[FFmpeg-devel] [PATCH 2/5] Deprecate parse_date() in favor of av_parse_time().

Anton Khirnov anton
Wed Feb 16 09:52:36 CET 2011


From: Stefano Sabatini <stefano.sabatini-lala at poste.it>

The new av_parse_time() is created in libavutil/parseutils.h, all the
internal functions used by parse_date are moved to
libavutil/parseutils.c and made static.
---
 cmdutils.c             |    5 +-
 libavformat/avformat.h |   29 +-----
 libavformat/cutils.c   |  110 ----------------------
 libavformat/internal.h |    3 -
 libavformat/utils.c    |  124 ++-----------------------
 libavformat/version.h  |    3 +
 libavutil/parseutils.c |  237 ++++++++++++++++++++++++++++++++++++++++++++++++
 libavutil/parseutils.h |   34 +++++++
 8 files changed, 291 insertions(+), 254 deletions(-)

diff --git a/cmdutils.c b/cmdutils.c
index 9809d2f..514ebad 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -35,6 +35,7 @@
 #include "libswscale/swscale.h"
 #include "libpostproc/postprocess.h"
 #include "libavutil/avstring.h"
+#include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
 #include "libavutil/eval.h"
 #include "libavcodec/opt.h"
@@ -113,8 +114,8 @@ double parse_number_or_die(const char *context, const char *numstr, int type, do
 
 int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
 {
-    int64_t us = parse_date(timestr, is_duration);
-    if (us == INT64_MIN) {
+    int64_t us;
+    if (av_parse_time(&us, timestr, is_duration) < 0) {
         fprintf(stderr, "Invalid %s specification for %s: %s\n",
                 is_duration ? "duration" : "date", context, timestr);
         exit(1);
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index b30d98f..caf6cc5 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1474,34 +1474,17 @@ attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base,
                                           const char *arg);
 #endif
 
+#if FF_API_PARSE_DATE
 /**
  * Parse datestr and return a corresponding number of microseconds.
+ *
  * @param datestr String representing a date or a duration.
- * - If a date the syntax is:
- * @code
- *  now|{[{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z|z]}
- * @endcode
- * If the value is "now" it takes the current time.
- * Time is local time unless Z is appended, in which case it is
- * interpreted as UTC.
- * If the year-month-day part is not specified it takes the current
- * year-month-day.
- * @return the number of microseconds since 1st of January, 1970 up to
- * the time of the parsed date or INT64_MIN if datestr cannot be
- * successfully parsed.
- * - If a duration the syntax is:
- * @code
- *  [-]HH[:MM[:SS[.m...]]]
- *  [-]S+[.m...]
- * @endcode
- * @return the number of microseconds contained in a time interval
- * with the specified duration or INT64_MIN if datestr cannot be
- * successfully parsed.
- * @param duration Flag which tells how to interpret datestr, if
- * not zero datestr is interpreted as a duration, otherwise as a
- * date.
+ * See av_parse_time() for the syntax of the provided string.
+ * @deprecated in favor of av_parse_time()
  */
+attribute_deprecated
 int64_t parse_date(const char *datestr, int duration);
+#endif
 
 /**
  * Get the current time in microseconds.
diff --git a/libavformat/cutils.c b/libavformat/cutils.c
index c1b5613..e6578df 100644
--- a/libavformat/cutils.c
+++ b/libavformat/cutils.c
@@ -42,25 +42,6 @@ void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
     *nb_ptr = nb;
 }
 
-time_t mktimegm(struct tm *tm)
-{
-    time_t t;
-
-    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
-
-    if (m < 3) {
-        m += 12;
-        y--;
-    }
-
-    t = 86400 *
-        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
-
-    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
-
-    return t;
-}
-
 #define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
 #define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
 
@@ -95,94 +76,3 @@ struct tm *brktimegm(time_t secs, struct tm *tm)
 
     return tm;
 }
-
-/* get a positive number between n_min and n_max, for a maximum length
-   of len_max. Return -1 if error. */
-static int date_get_num(const char **pp,
-                        int n_min, int n_max, int len_max)
-{
-    int i, val, c;
-    const char *p;
-
-    p = *pp;
-    val = 0;
-    for(i = 0; i < len_max; i++) {
-        c = *p;
-        if (!isdigit(c))
-            break;
-        val = (val * 10) + c - '0';
-        p++;
-    }
-    /* no number read ? */
-    if (p == *pp)
-        return -1;
-    if (val < n_min || val > n_max)
-        return -1;
-    *pp = p;
-    return val;
-}
-
-/* small strptime for ffmpeg */
-const char *small_strptime(const char *p, const char *fmt,
-                           struct tm *dt)
-{
-    int c, val;
-
-    for(;;) {
-        c = *fmt++;
-        if (c == '\0') {
-            return p;
-        } else if (c == '%') {
-            c = *fmt++;
-            switch(c) {
-            case 'H':
-                val = date_get_num(&p, 0, 23, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_hour = val;
-                break;
-            case 'M':
-                val = date_get_num(&p, 0, 59, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_min = val;
-                break;
-            case 'S':
-                val = date_get_num(&p, 0, 59, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_sec = val;
-                break;
-            case 'Y':
-                val = date_get_num(&p, 0, 9999, 4);
-                if (val == -1)
-                    return NULL;
-                dt->tm_year = val - 1900;
-                break;
-            case 'm':
-                val = date_get_num(&p, 1, 12, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_mon = val - 1;
-                break;
-            case 'd':
-                val = date_get_num(&p, 1, 31, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_mday = val;
-                break;
-            case '%':
-                goto match;
-            default:
-                return NULL;
-            }
-        } else {
-        match:
-            if (c != *p)
-                return NULL;
-            p++;
-        }
-    }
-    return p;
-}
-
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 2fdf61f..16aa0af 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -48,10 +48,7 @@ do {\
 } while(0)
 #endif
 
-time_t mktimegm(struct tm *tm);
 struct tm *brktimegm(time_t secs, struct tm *tm);
-const char *small_strptime(const char *p, const char *fmt,
-                           struct tm *dt);
 
 char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase);
 
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 7d97852..354aee5 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3380,124 +3380,16 @@ uint64_t ff_ntp_time(void)
   return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
 }
 
-int64_t parse_date(const char *datestr, int duration)
-{
-    const char *p;
-    int64_t t;
-    struct tm dt;
-    int i;
-    static const char * const date_fmt[] = {
-        "%Y-%m-%d",
-        "%Y%m%d",
-    };
-    static const char * const time_fmt[] = {
-        "%H:%M:%S",
-        "%H%M%S",
-    };
-    const char *q;
-    int is_utc, len;
-    char lastch;
-    int negative = 0;
-
-#undef time
-    time_t now = time(0);
-
-    len = strlen(datestr);
-    if (len > 0)
-        lastch = datestr[len - 1];
-    else
-        lastch = '\0';
-    is_utc = (lastch == 'z' || lastch == 'Z');
-
-    memset(&dt, 0, sizeof(dt));
-
-    p = datestr;
-    q = NULL;
-    if (!duration) {
-        if (!strncasecmp(datestr, "now", len))
-            return (int64_t) now * 1000000;
-
-        /* parse the year-month-day part */
-        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
-            q = small_strptime(p, date_fmt[i], &dt);
-            if (q) {
-                break;
-            }
-        }
-
-        /* if the year-month-day part is missing, then take the
-         * current year-month-day time */
-        if (!q) {
-            if (is_utc) {
-                dt = *gmtime(&now);
-            } else {
-                dt = *localtime(&now);
-            }
-            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
-        } else {
-            p = q;
-        }
-
-        if (*p == 'T' || *p == 't' || *p == ' ')
-            p++;
-
-        /* parse the hour-minute-second part */
-        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
-            q = small_strptime(p, time_fmt[i], &dt);
-            if (q) {
-                break;
-            }
-        }
-    } else {
-        /* parse datestr as a duration */
-        if (p[0] == '-') {
-            negative = 1;
-            ++p;
-        }
-        /* parse datestr as HH:MM:SS */
-        q = small_strptime(p, time_fmt[0], &dt);
-        if (!q) {
-            /* parse datestr as S+ */
-            dt.tm_sec = strtol(p, (char **)&q, 10);
-            if (q == p)
-                /* the parsing didn't succeed */
-                return INT64_MIN;
-            dt.tm_min = 0;
-            dt.tm_hour = 0;
-        }
-    }
-
-    /* Now we have all the fields that we can get */
-    if (!q) {
-        return INT64_MIN;
-    }
-
-    if (duration) {
-        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
-    } else {
-        dt.tm_isdst = -1;       /* unknown */
-        if (is_utc) {
-            t = mktimegm(&dt);
-        } else {
-            t = mktime(&dt);
-        }
-    }
-
-    t *= 1000000;
+#if FF_API_PARSE_DATE
+#include "libavutil/parseutils.h"
 
-    /* parse the .m... part */
-    if (*q == '.') {
-        int val, n;
-        q++;
-        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
-            if (!isdigit(*q))
-                break;
-            val += n * (*q - '0');
-        }
-        t += val;
-    }
-    return negative ? -t : t;
+int64_t parse_date(const char *timestr, int duration)
+{
+    int64_t timeval;
+    av_parse_time(&timeval, timestr, duration);
+    return timeval;
 }
+#endif
 
 int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
 {
diff --git a/libavformat/version.h b/libavformat/version.h
index 922dd89..3663ec5 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -95,5 +95,8 @@
 #ifndef FF_API_DUMP_FORMAT
 #define FF_API_DUMP_FORMAT             (LIBAVFORMAT_VERSION_MAJOR < 54)
 #endif
+#ifndef FF_API_PARSE_DATE
+#define FF_API_PARSE_DATE              (LIBAVFORMAT_VERSION_MAJOR < 54)
+#endif
 
 #endif //AVFORMAT_VERSION_H
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 09eebcf..8e09dad 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -22,6 +22,8 @@
  */
 
 #include <strings.h>
+#include <sys/time.h>
+#include <time.h>
 #include "parseutils.h"
 #include "libavutil/avutil.h"
 #include "libavutil/eval.h"
@@ -371,6 +373,241 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
     return 0;
 }
 
+/* get a positive number between n_min and n_max, for a maximum length
+   of len_max. Return -1 if error. */
+static int date_get_num(const char **pp,
+                        int n_min, int n_max, int len_max)
+{
+    int i, val, c;
+    const char *p;
+
+    p = *pp;
+    val = 0;
+    for(i = 0; i < len_max; i++) {
+        c = *p;
+        if (!isdigit(c))
+            break;
+        val = (val * 10) + c - '0';
+        p++;
+    }
+    /* no number read ? */
+    if (p == *pp)
+        return -1;
+    if (val < n_min || val > n_max)
+        return -1;
+    *pp = p;
+    return val;
+}
+
+/* small strptime for ffmpeg */
+static
+const char *small_strptime(const char *p, const char *fmt,
+                           struct tm *dt)
+{
+    int c, val;
+
+    for(;;) {
+        c = *fmt++;
+        if (c == '\0') {
+            return p;
+        } else if (c == '%') {
+            c = *fmt++;
+            switch(c) {
+            case 'H':
+                val = date_get_num(&p, 0, 23, 2);
+                if (val == -1)
+                    return NULL;
+                dt->tm_hour = val;
+                break;
+            case 'M':
+                val = date_get_num(&p, 0, 59, 2);
+                if (val == -1)
+                    return NULL;
+                dt->tm_min = val;
+                break;
+            case 'S':
+                val = date_get_num(&p, 0, 59, 2);
+                if (val == -1)
+                    return NULL;
+                dt->tm_sec = val;
+                break;
+            case 'Y':
+                val = date_get_num(&p, 0, 9999, 4);
+                if (val == -1)
+                    return NULL;
+                dt->tm_year = val - 1900;
+                break;
+            case 'm':
+                val = date_get_num(&p, 1, 12, 2);
+                if (val == -1)
+                    return NULL;
+                dt->tm_mon = val - 1;
+                break;
+            case 'd':
+                val = date_get_num(&p, 1, 31, 2);
+                if (val == -1)
+                    return NULL;
+                dt->tm_mday = val;
+                break;
+            case '%':
+                goto match;
+            default:
+                return NULL;
+            }
+        } else {
+        match:
+            if (c != *p)
+                return NULL;
+            p++;
+        }
+    }
+    return p;
+}
+
+static time_t mktimegm(struct tm *tm)
+{
+    time_t t;
+
+    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
+
+    if (m < 3) {
+        m += 12;
+        y--;
+    }
+
+    t = 86400 *
+        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
+
+    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
+
+    return t;
+}
+
+int av_parse_time(int64_t *timeval, const char *datestr, int duration)
+{
+    const char *p;
+    int64_t t;
+    struct tm dt;
+    int i;
+    static const char * const date_fmt[] = {
+        "%Y-%m-%d",
+        "%Y%m%d",
+    };
+    static const char * const time_fmt[] = {
+        "%H:%M:%S",
+        "%H%M%S",
+    };
+    const char *q;
+    int is_utc, len;
+    char lastch;
+    int negative = 0;
+
+#undef time
+    time_t now = time(0);
+
+    len = strlen(datestr);
+    if (len > 0)
+        lastch = datestr[len - 1];
+    else
+        lastch = '\0';
+    is_utc = (lastch == 'z' || lastch == 'Z');
+
+    memset(&dt, 0, sizeof(dt));
+
+    p = datestr;
+    q = NULL;
+    if (!duration) {
+        if (!strncasecmp(datestr, "now", len)) {
+            *timeval = (int64_t) now * 1000000;
+            return 0;
+        }
+
+        /* parse the year-month-day part */
+        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
+            q = small_strptime(p, date_fmt[i], &dt);
+            if (q) {
+                break;
+            }
+        }
+
+        /* if the year-month-day part is missing, then take the
+         * current year-month-day time */
+        if (!q) {
+            if (is_utc) {
+                dt = *gmtime(&now);
+            } else {
+                dt = *localtime(&now);
+            }
+            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
+        } else {
+            p = q;
+        }
+
+        if (*p == 'T' || *p == 't' || *p == ' ')
+            p++;
+
+        /* parse the hour-minute-second part */
+        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
+            q = small_strptime(p, time_fmt[i], &dt);
+            if (q) {
+                break;
+            }
+        }
+    } else {
+        /* parse datestr as a duration */
+        if (p[0] == '-') {
+            negative = 1;
+            ++p;
+        }
+        /* parse datestr as HH:MM:SS */
+        q = small_strptime(p, time_fmt[0], &dt);
+        if (!q) {
+            /* parse datestr as S+ */
+            dt.tm_sec = strtol(p, (char **)&q, 10);
+            if (q == p) {
+                /* the parsing didn't succeed */
+                *timeval = INT64_MIN;
+                return AVERROR(EINVAL);
+            }
+            dt.tm_min = 0;
+            dt.tm_hour = 0;
+        }
+    }
+
+    /* Now we have all the fields that we can get */
+    if (!q) {
+        *timeval = INT64_MIN;
+        return AVERROR(EINVAL);
+    }
+
+    if (duration) {
+        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
+    } else {
+        dt.tm_isdst = -1;       /* unknown */
+        if (is_utc) {
+            t = mktimegm(&dt);
+        } else {
+            t = mktime(&dt);
+        }
+    }
+
+    t *= 1000000;
+
+    /* parse the .m... part */
+    if (*q == '.') {
+        int val, n;
+        q++;
+        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
+            if (!isdigit(*q))
+                break;
+            val += n * (*q - '0');
+        }
+        t += val;
+    }
+    *timeval = negative ? -t : t;
+    return 0;
+}
+
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/parseutils.h b/libavutil/parseutils.h
index 2c99872..517f125 100644
--- a/libavutil/parseutils.h
+++ b/libavutil/parseutils.h
@@ -72,4 +72,38 @@ int av_parse_video_rate(AVRational *rate, const char *str);
 int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
                    void *log_ctx);
 
+/**
+ * Parses timestr and returns in *time a corresponding number of
+ * microseconds.
+ *
+ * @param timeval puts here the number of microseconds corresponding
+ * to the string in timestr. If the string represents a duration, it
+ * is the number of microseconds contained in the time interval.  If
+ * the string is a date, is the number of microseconds since 1st of
+ * January, 1970 up to the time of the parsed date.  If timestr cannot
+ * be successfully parsed, set *time to INT64_MIN.
+
+ * @param datestr a string representing a date or a duration.
+ * - If a date the syntax is:
+ * @code
+ * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z]
+ * now
+ * @endcode
+ * If the value is "now" it takes the current time.
+ * Time is local time unless Z is appended, in which case it is
+ * interpreted as UTC.
+ * If the year-month-day part is not specified it takes the current
+ * year-month-day.
+ * - If a duration the syntax is:
+ * @code
+ * [-]HH[:MM[:SS[.m...]]]
+ * [-]S+[.m...]
+ * @endcode
+ * @param duration flag which tells how to interpret timestr, if not
+ * zero timestr is interpreted as a duration, otherwise as a date
+ * @return 0 in case of success, a negative value corresponding to an
+ * AVERROR code otherwise
+ */
+int av_parse_time(int64_t *timeval, const char *timestr, int duration);
+
 #endif /* AVUTIL_PARSEUTILS_H */
-- 
1.7.2.3




More information about the ffmpeg-devel mailing list