Revision 40c3fe2c

View differences:

cmdutils.c
35 35
#include "libswscale/swscale.h"
36 36
#include "libpostproc/postprocess.h"
37 37
#include "libavutil/avstring.h"
38
#include "libavutil/parseutils.h"
38 39
#include "libavutil/pixdesc.h"
39 40
#include "libavutil/eval.h"
40 41
#include "libavcodec/opt.h"
......
113 114

  
114 115
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
115 116
{
116
    int64_t us = parse_date(timestr, is_duration);
117
    if (us == INT64_MIN) {
117
    int64_t us;
118
    if (av_parse_time(&us, timestr, is_duration) < 0) {
118 119
        fprintf(stderr, "Invalid %s specification for %s: %s\n",
119 120
                is_duration ? "duration" : "date", context, timestr);
120 121
        exit(1);
libavformat/avformat.h
1478 1478
                                          const char *arg);
1479 1479
#endif
1480 1480

  
1481
#if FF_API_PARSE_DATE
1481 1482
/**
1482 1483
 * Parse datestr and return a corresponding number of microseconds.
1484
 *
1483 1485
 * @param datestr String representing a date or a duration.
1484
 * - If a date the syntax is:
1485
 * @code
1486
 *  now|{[{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z|z]}
1487
 * @endcode
1488
 * If the value is "now" it takes the current time.
1489
 * Time is local time unless Z is appended, in which case it is
1490
 * interpreted as UTC.
1491
 * If the year-month-day part is not specified it takes the current
1492
 * year-month-day.
1493
 * @return the number of microseconds since 1st of January, 1970 up to
1494
 * the time of the parsed date or INT64_MIN if datestr cannot be
1495
 * successfully parsed.
1496
 * - If a duration the syntax is:
1497
 * @code
1498
 *  [-]HH[:MM[:SS[.m...]]]
1499
 *  [-]S+[.m...]
1500
 * @endcode
1501
 * @return the number of microseconds contained in a time interval
1502
 * with the specified duration or INT64_MIN if datestr cannot be
1503
 * successfully parsed.
1504
 * @param duration Flag which tells how to interpret datestr, if
1505
 * not zero datestr is interpreted as a duration, otherwise as a
1506
 * date.
1486
 * See av_parse_time() for the syntax of the provided string.
1487
 * @deprecated in favor of av_parse_time()
1507 1488
 */
1489
attribute_deprecated
1508 1490
int64_t parse_date(const char *datestr, int duration);
1491
#endif
1509 1492

  
1510 1493
/**
1511 1494
 * Get the current time in microseconds.
libavformat/cutils.c
42 42
    *nb_ptr = nb;
43 43
}
44 44

  
45
time_t mktimegm(struct tm *tm)
46
{
47
    time_t t;
48

  
49
    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
50

  
51
    if (m < 3) {
52
        m += 12;
53
        y--;
54
    }
55

  
56
    t = 86400 *
57
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
58

  
59
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
60

  
61
    return t;
62
}
63

  
64 45
#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
65 46
#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
66 47

  
......
95 76

  
96 77
    return tm;
97 78
}
98

  
99
/* get a positive number between n_min and n_max, for a maximum length
100
   of len_max. Return -1 if error. */
101
static int date_get_num(const char **pp,
102
                        int n_min, int n_max, int len_max)
103
{
104
    int i, val, c;
105
    const char *p;
106

  
107
    p = *pp;
108
    val = 0;
109
    for(i = 0; i < len_max; i++) {
110
        c = *p;
111
        if (!isdigit(c))
112
            break;
113
        val = (val * 10) + c - '0';
114
        p++;
115
    }
116
    /* no number read ? */
117
    if (p == *pp)
118
        return -1;
119
    if (val < n_min || val > n_max)
120
        return -1;
121
    *pp = p;
122
    return val;
123
}
124

  
125
/* small strptime for ffmpeg */
126
const char *small_strptime(const char *p, const char *fmt,
127
                           struct tm *dt)
128
{
129
    int c, val;
130

  
131
    for(;;) {
132
        c = *fmt++;
133
        if (c == '\0') {
134
            return p;
135
        } else if (c == '%') {
136
            c = *fmt++;
137
            switch(c) {
138
            case 'H':
139
                val = date_get_num(&p, 0, 23, 2);
140
                if (val == -1)
141
                    return NULL;
142
                dt->tm_hour = val;
143
                break;
144
            case 'M':
145
                val = date_get_num(&p, 0, 59, 2);
146
                if (val == -1)
147
                    return NULL;
148
                dt->tm_min = val;
149
                break;
150
            case 'S':
151
                val = date_get_num(&p, 0, 59, 2);
152
                if (val == -1)
153
                    return NULL;
154
                dt->tm_sec = val;
155
                break;
156
            case 'Y':
157
                val = date_get_num(&p, 0, 9999, 4);
158
                if (val == -1)
159
                    return NULL;
160
                dt->tm_year = val - 1900;
161
                break;
162
            case 'm':
163
                val = date_get_num(&p, 1, 12, 2);
164
                if (val == -1)
165
                    return NULL;
166
                dt->tm_mon = val - 1;
167
                break;
168
            case 'd':
169
                val = date_get_num(&p, 1, 31, 2);
170
                if (val == -1)
171
                    return NULL;
172
                dt->tm_mday = val;
173
                break;
174
            case '%':
175
                goto match;
176
            default:
177
                return NULL;
178
            }
179
        } else {
180
        match:
181
            if (c != *p)
182
                return NULL;
183
            p++;
184
        }
185
    }
186
    return p;
187
}
188

  
libavformat/internal.h
48 48
} while(0)
49 49
#endif
50 50

  
51
time_t mktimegm(struct tm *tm);
52 51
struct tm *brktimegm(time_t secs, struct tm *tm);
53
const char *small_strptime(const char *p, const char *fmt,
54
                           struct tm *dt);
55 52

  
56 53
char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase);
57 54

  
libavformat/utils.c
3380 3380
  return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
3381 3381
}
3382 3382

  
3383
int64_t parse_date(const char *datestr, int duration)
3384
{
3385
    const char *p;
3386
    int64_t t;
3387
    struct tm dt;
3388
    int i;
3389
    static const char * const date_fmt[] = {
3390
        "%Y-%m-%d",
3391
        "%Y%m%d",
3392
    };
3393
    static const char * const time_fmt[] = {
3394
        "%H:%M:%S",
3395
        "%H%M%S",
3396
    };
3397
    const char *q;
3398
    int is_utc, len;
3399
    char lastch;
3400
    int negative = 0;
3401

  
3402
#undef time
3403
    time_t now = time(0);
3404

  
3405
    len = strlen(datestr);
3406
    if (len > 0)
3407
        lastch = datestr[len - 1];
3408
    else
3409
        lastch = '\0';
3410
    is_utc = (lastch == 'z' || lastch == 'Z');
3411

  
3412
    memset(&dt, 0, sizeof(dt));
3413

  
3414
    p = datestr;
3415
    q = NULL;
3416
    if (!duration) {
3417
        if (!strncasecmp(datestr, "now", len))
3418
            return (int64_t) now * 1000000;
3419

  
3420
        /* parse the year-month-day part */
3421
        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
3422
            q = small_strptime(p, date_fmt[i], &dt);
3423
            if (q) {
3424
                break;
3425
            }
3426
        }
3427

  
3428
        /* if the year-month-day part is missing, then take the
3429
         * current year-month-day time */
3430
        if (!q) {
3431
            if (is_utc) {
3432
                dt = *gmtime(&now);
3433
            } else {
3434
                dt = *localtime(&now);
3435
            }
3436
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
3437
        } else {
3438
            p = q;
3439
        }
3440

  
3441
        if (*p == 'T' || *p == 't' || *p == ' ')
3442
            p++;
3443

  
3444
        /* parse the hour-minute-second part */
3445
        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
3446
            q = small_strptime(p, time_fmt[i], &dt);
3447
            if (q) {
3448
                break;
3449
            }
3450
        }
3451
    } else {
3452
        /* parse datestr as a duration */
3453
        if (p[0] == '-') {
3454
            negative = 1;
3455
            ++p;
3456
        }
3457
        /* parse datestr as HH:MM:SS */
3458
        q = small_strptime(p, time_fmt[0], &dt);
3459
        if (!q) {
3460
            /* parse datestr as S+ */
3461
            dt.tm_sec = strtol(p, (char **)&q, 10);
3462
            if (q == p)
3463
                /* the parsing didn't succeed */
3464
                return INT64_MIN;
3465
            dt.tm_min = 0;
3466
            dt.tm_hour = 0;
3467
        }
3468
    }
3469

  
3470
    /* Now we have all the fields that we can get */
3471
    if (!q) {
3472
        return INT64_MIN;
3473
    }
3474

  
3475
    if (duration) {
3476
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
3477
    } else {
3478
        dt.tm_isdst = -1;       /* unknown */
3479
        if (is_utc) {
3480
            t = mktimegm(&dt);
3481
        } else {
3482
            t = mktime(&dt);
3483
        }
3484
    }
3485

  
3486
    t *= 1000000;
3383
#if FF_API_PARSE_DATE
3384
#include "libavutil/parseutils.h"
3487 3385

  
3488
    /* parse the .m... part */
3489
    if (*q == '.') {
3490
        int val, n;
3491
        q++;
3492
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
3493
            if (!isdigit(*q))
3494
                break;
3495
            val += n * (*q - '0');
3496
        }
3497
        t += val;
3498
    }
3499
    return negative ? -t : t;
3386
int64_t parse_date(const char *timestr, int duration)
3387
{
3388
    int64_t timeval;
3389
    av_parse_time(&timeval, timestr, duration);
3390
    return timeval;
3500 3391
}
3392
#endif
3501 3393

  
3502 3394
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
3503 3395
{
libavformat/version.h
95 95
#ifndef FF_API_DUMP_FORMAT
96 96
#define FF_API_DUMP_FORMAT             (LIBAVFORMAT_VERSION_MAJOR < 54)
97 97
#endif
98
#ifndef FF_API_PARSE_DATE
99
#define FF_API_PARSE_DATE              (LIBAVFORMAT_VERSION_MAJOR < 54)
100
#endif
98 101

  
99 102
#endif //AVFORMAT_VERSION_H
libavutil/parseutils.c
22 22
 */
23 23

  
24 24
#include <strings.h>
25
#include <sys/time.h>
26
#include <time.h>
25 27
#include "parseutils.h"
26 28
#include "libavutil/avutil.h"
27 29
#include "libavutil/eval.h"
......
371 373
    return 0;
372 374
}
373 375

  
376
/* get a positive number between n_min and n_max, for a maximum length
377
   of len_max. Return -1 if error. */
378
static int date_get_num(const char **pp,
379
                        int n_min, int n_max, int len_max)
380
{
381
    int i, val, c;
382
    const char *p;
383

  
384
    p = *pp;
385
    val = 0;
386
    for(i = 0; i < len_max; i++) {
387
        c = *p;
388
        if (!isdigit(c))
389
            break;
390
        val = (val * 10) + c - '0';
391
        p++;
392
    }
393
    /* no number read ? */
394
    if (p == *pp)
395
        return -1;
396
    if (val < n_min || val > n_max)
397
        return -1;
398
    *pp = p;
399
    return val;
400
}
401

  
402
/* small strptime for ffmpeg */
403
static
404
const char *small_strptime(const char *p, const char *fmt,
405
                           struct tm *dt)
406
{
407
    int c, val;
408

  
409
    for(;;) {
410
        c = *fmt++;
411
        if (c == '\0') {
412
            return p;
413
        } else if (c == '%') {
414
            c = *fmt++;
415
            switch(c) {
416
            case 'H':
417
                val = date_get_num(&p, 0, 23, 2);
418
                if (val == -1)
419
                    return NULL;
420
                dt->tm_hour = val;
421
                break;
422
            case 'M':
423
                val = date_get_num(&p, 0, 59, 2);
424
                if (val == -1)
425
                    return NULL;
426
                dt->tm_min = val;
427
                break;
428
            case 'S':
429
                val = date_get_num(&p, 0, 59, 2);
430
                if (val == -1)
431
                    return NULL;
432
                dt->tm_sec = val;
433
                break;
434
            case 'Y':
435
                val = date_get_num(&p, 0, 9999, 4);
436
                if (val == -1)
437
                    return NULL;
438
                dt->tm_year = val - 1900;
439
                break;
440
            case 'm':
441
                val = date_get_num(&p, 1, 12, 2);
442
                if (val == -1)
443
                    return NULL;
444
                dt->tm_mon = val - 1;
445
                break;
446
            case 'd':
447
                val = date_get_num(&p, 1, 31, 2);
448
                if (val == -1)
449
                    return NULL;
450
                dt->tm_mday = val;
451
                break;
452
            case '%':
453
                goto match;
454
            default:
455
                return NULL;
456
            }
457
        } else {
458
        match:
459
            if (c != *p)
460
                return NULL;
461
            p++;
462
        }
463
    }
464
    return p;
465
}
466

  
467
static time_t mktimegm(struct tm *tm)
468
{
469
    time_t t;
470

  
471
    int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
472

  
473
    if (m < 3) {
474
        m += 12;
475
        y--;
476
    }
477

  
478
    t = 86400 *
479
        (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
480

  
481
    t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
482

  
483
    return t;
484
}
485

  
486
int av_parse_time(int64_t *timeval, const char *datestr, int duration)
487
{
488
    const char *p;
489
    int64_t t;
490
    struct tm dt;
491
    int i;
492
    static const char * const date_fmt[] = {
493
        "%Y-%m-%d",
494
        "%Y%m%d",
495
    };
496
    static const char * const time_fmt[] = {
497
        "%H:%M:%S",
498
        "%H%M%S",
499
    };
500
    const char *q;
501
    int is_utc, len;
502
    char lastch;
503
    int negative = 0;
504

  
505
#undef time
506
    time_t now = time(0);
507

  
508
    len = strlen(datestr);
509
    if (len > 0)
510
        lastch = datestr[len - 1];
511
    else
512
        lastch = '\0';
513
    is_utc = (lastch == 'z' || lastch == 'Z');
514

  
515
    memset(&dt, 0, sizeof(dt));
516

  
517
    p = datestr;
518
    q = NULL;
519
    if (!duration) {
520
        if (!strncasecmp(datestr, "now", len)) {
521
            *timeval = (int64_t) now * 1000000;
522
            return 0;
523
        }
524

  
525
        /* parse the year-month-day part */
526
        for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
527
            q = small_strptime(p, date_fmt[i], &dt);
528
            if (q) {
529
                break;
530
            }
531
        }
532

  
533
        /* if the year-month-day part is missing, then take the
534
         * current year-month-day time */
535
        if (!q) {
536
            if (is_utc) {
537
                dt = *gmtime(&now);
538
            } else {
539
                dt = *localtime(&now);
540
            }
541
            dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
542
        } else {
543
            p = q;
544
        }
545

  
546
        if (*p == 'T' || *p == 't' || *p == ' ')
547
            p++;
548

  
549
        /* parse the hour-minute-second part */
550
        for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
551
            q = small_strptime(p, time_fmt[i], &dt);
552
            if (q) {
553
                break;
554
            }
555
        }
556
    } else {
557
        /* parse datestr as a duration */
558
        if (p[0] == '-') {
559
            negative = 1;
560
            ++p;
561
        }
562
        /* parse datestr as HH:MM:SS */
563
        q = small_strptime(p, time_fmt[0], &dt);
564
        if (!q) {
565
            /* parse datestr as S+ */
566
            dt.tm_sec = strtol(p, (char **)&q, 10);
567
            if (q == p) {
568
                /* the parsing didn't succeed */
569
                *timeval = INT64_MIN;
570
                return AVERROR(EINVAL);
571
            }
572
            dt.tm_min = 0;
573
            dt.tm_hour = 0;
574
        }
575
    }
576

  
577
    /* Now we have all the fields that we can get */
578
    if (!q) {
579
        *timeval = INT64_MIN;
580
        return AVERROR(EINVAL);
581
    }
582

  
583
    if (duration) {
584
        t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
585
    } else {
586
        dt.tm_isdst = -1;       /* unknown */
587
        if (is_utc) {
588
            t = mktimegm(&dt);
589
        } else {
590
            t = mktime(&dt);
591
        }
592
    }
593

  
594
    t *= 1000000;
595

  
596
    /* parse the .m... part */
597
    if (*q == '.') {
598
        int val, n;
599
        q++;
600
        for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
601
            if (!isdigit(*q))
602
                break;
603
            val += n * (*q - '0');
604
        }
605
        t += val;
606
    }
607
    *timeval = negative ? -t : t;
608
    return 0;
609
}
610

  
374 611
#ifdef TEST
375 612

  
376 613
#undef printf
libavutil/parseutils.h
72 72
int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
73 73
                   void *log_ctx);
74 74

  
75
/**
76
 * Parses timestr and returns in *time a corresponding number of
77
 * microseconds.
78
 *
79
 * @param timeval puts here the number of microseconds corresponding
80
 * to the string in timestr. If the string represents a duration, it
81
 * is the number of microseconds contained in the time interval.  If
82
 * the string is a date, is the number of microseconds since 1st of
83
 * January, 1970 up to the time of the parsed date.  If timestr cannot
84
 * be successfully parsed, set *time to INT64_MIN.
85

  
86
 * @param datestr a string representing a date or a duration.
87
 * - If a date the syntax is:
88
 * @code
89
 * [{YYYY-MM-DD|YYYYMMDD}[T|t| ]]{{HH[:MM[:SS[.m...]]]}|{HH[MM[SS[.m...]]]}}[Z]
90
 * now
91
 * @endcode
92
 * If the value is "now" it takes the current time.
93
 * Time is local time unless Z is appended, in which case it is
94
 * interpreted as UTC.
95
 * If the year-month-day part is not specified it takes the current
96
 * year-month-day.
97
 * - If a duration the syntax is:
98
 * @code
99
 * [-]HH[:MM[:SS[.m...]]]
100
 * [-]S+[.m...]
101
 * @endcode
102
 * @param duration flag which tells how to interpret timestr, if not
103
 * zero timestr is interpreted as a duration, otherwise as a date
104
 * @return 0 in case of success, a negative value corresponding to an
105
 * AVERROR code otherwise
106
 */
107
int av_parse_time(int64_t *timeval, const char *timestr, int duration);
108

  
75 109
#endif /* AVUTIL_PARSEUTILS_H */

Also available in: Unified diff