| 459 | }; |
| 460 | |
| 461 | static int concat_parse_script(AVFormatContext *avf) |
| 462 | { |
| 463 | ConcatContext *cat = avf->priv_data; |
| 464 | unsigned nb_files_alloc = 0; |
| 465 | AVBPrint bp; |
| 466 | uint8_t *cursor, *keyword; |
| 467 | ConcatFile *file = NULL; |
| 468 | AVStream *stream = NULL; |
| 469 | AVChapter *chapter = NULL; |
| 470 | unsigned line = 0, arg; |
| 471 | const ParseSyntax *dir; |
| 472 | char *arg_kw[MAX_ARGS]; |
| 473 | char *arg_str[MAX_ARGS] = { 0 }; |
| 474 | int64_t arg_int[MAX_ARGS]; |
| 475 | int ret; |
| 476 | |
| 477 | av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED); |
| 478 | |
| 479 | while ((ret = ff_read_line_to_bprint_overwrite(avf->pb, &bp)) >= 0) { |
| 480 | line++; |
| 481 | cursor = bp.str; |
| 482 | keyword = get_keyword(&cursor); |
| 483 | if (!*keyword || *keyword == '#') |
| 484 | continue; |
| 485 | for (dir = syntax; dir < syntax + FF_ARRAY_ELEMS(syntax); dir++) |
| 486 | if (!strcmp(dir->keyword, keyword)) |
| 487 | break; |
| 488 | if (dir >= syntax + FF_ARRAY_ELEMS(syntax)) { |
| 489 | av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n", |
| 490 | line, keyword); |
| 491 | FAIL(AVERROR_INVALIDDATA); |
| 492 | } |
| 493 | |
| 494 | /* Flags check */ |
| 495 | if ((dir->flags & NEEDS_UNSAFE) && cat->safe) { |
| 496 | av_log(avf, AV_LOG_ERROR, "Line %d: %s not allowed if safe\n", line, keyword); |
| 497 | FAIL(AVERROR_INVALIDDATA); |
| 498 | } |
| 499 | if ((dir->flags & NEEDS_FILE) && !cat->nb_files) { |
| 500 | av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n", line, keyword); |
| 501 | FAIL(AVERROR_INVALIDDATA); |
| 502 | } |
| 503 | if ((dir->flags & NEEDS_STREAM) && !avf->nb_streams) { |
| 504 | av_log(avf, AV_LOG_ERROR, "Line %d: %s without stream\n", line, keyword); |
| 505 | FAIL(AVERROR_INVALIDDATA); |
| 506 | } |
| 507 | |
| 508 | /* Arguments parsing */ |
| 509 | for (arg = 0; arg < FF_ARRAY_ELEMS(dir->args) && dir->args[arg]; arg++) { |
| 510 | switch (dir->args[arg]) { |
| 511 | case 'd': /* duration */ |
| 512 | arg_kw[arg] = get_keyword(&cursor); |
| 513 | ret = av_parse_time(&arg_int[arg], arg_kw[arg], 1); |
| 514 | if (ret < 0) { |
| 515 | av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n", |
| 516 | line, arg_kw[arg]); |
| 517 | goto fail; |
| 518 | } |
no test coverage detected