| 466 | } |
| 467 | |
| 468 | static int parse_times(void *log_ctx, int64_t **times, int *nb_times, |
| 469 | const char *times_str) |
| 470 | { |
| 471 | char *p; |
| 472 | int i, ret = 0; |
| 473 | char *times_str1 = av_strdup(times_str); |
| 474 | char *saveptr = NULL; |
| 475 | |
| 476 | if (!times_str1) |
| 477 | return AVERROR(ENOMEM); |
| 478 | |
| 479 | #define FAIL(err) ret = err; goto end |
| 480 | |
| 481 | *nb_times = 1; |
| 482 | for (p = times_str1; *p; p++) |
| 483 | if (*p == ',') |
| 484 | (*nb_times)++; |
| 485 | |
| 486 | *times = av_malloc_array(*nb_times, sizeof(**times)); |
| 487 | if (!*times) { |
| 488 | av_log(log_ctx, AV_LOG_ERROR, "Could not allocate forced times array\n"); |
| 489 | FAIL(AVERROR(ENOMEM)); |
| 490 | } |
| 491 | |
| 492 | p = times_str1; |
| 493 | for (i = 0; i < *nb_times; i++) { |
| 494 | int64_t t; |
| 495 | char *tstr = av_strtok(p, ",", &saveptr); |
| 496 | p = NULL; |
| 497 | |
| 498 | if (!tstr || !tstr[0]) { |
| 499 | av_log(log_ctx, AV_LOG_ERROR, "Empty time specification in times list %s\n", |
| 500 | times_str); |
| 501 | FAIL(AVERROR(EINVAL)); |
| 502 | } |
| 503 | |
| 504 | ret = av_parse_time(&t, tstr, 1); |
| 505 | if (ret < 0) { |
| 506 | av_log(log_ctx, AV_LOG_ERROR, |
| 507 | "Invalid time duration specification '%s' in times list %s\n", tstr, times_str); |
| 508 | FAIL(AVERROR(EINVAL)); |
| 509 | } |
| 510 | (*times)[i] = t; |
| 511 | |
| 512 | /* check on monotonicity */ |
| 513 | if (i && (*times)[i-1] > (*times)[i]) { |
| 514 | av_log(log_ctx, AV_LOG_ERROR, |
| 515 | "Specified time %f is smaller than the last time %f\n", |
| 516 | (float)((*times)[i])/1000000, (float)((*times)[i-1])/1000000); |
| 517 | FAIL(AVERROR(EINVAL)); |
| 518 | } |
| 519 | } |
| 520 | |
| 521 | end: |
| 522 | av_free(times_str1); |
| 523 | return ret; |
| 524 | } |
| 525 |
no test coverage detected