| 659 | } |
| 660 | |
| 661 | static int concat_read_header(AVFormatContext *avf) |
| 662 | { |
| 663 | ConcatContext *cat = avf->priv_data; |
| 664 | int64_t time = 0; |
| 665 | unsigned i; |
| 666 | int ret; |
| 667 | |
| 668 | ret = concat_parse_script(avf); |
| 669 | if (ret < 0) |
| 670 | return ret; |
| 671 | if (!cat->nb_files) { |
| 672 | av_log(avf, AV_LOG_ERROR, "No files to concat\n"); |
| 673 | return AVERROR_INVALIDDATA; |
| 674 | } |
| 675 | |
| 676 | for (i = 0; i < cat->nb_files; i++) { |
| 677 | if (cat->files[i].start_time == AV_NOPTS_VALUE) |
| 678 | cat->files[i].start_time = time; |
| 679 | else |
| 680 | time = cat->files[i].start_time; |
| 681 | if (cat->files[i].user_duration == AV_NOPTS_VALUE) { |
| 682 | if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE || |
| 683 | cat->files[i].outpoint - (uint64_t)cat->files[i].inpoint != av_sat_sub64(cat->files[i].outpoint, cat->files[i].inpoint) |
| 684 | ) |
| 685 | break; |
| 686 | cat->files[i].user_duration = cat->files[i].outpoint - cat->files[i].inpoint; |
| 687 | } |
| 688 | cat->files[i].duration = cat->files[i].user_duration; |
| 689 | if (time + (uint64_t)cat->files[i].user_duration > INT64_MAX) |
| 690 | return AVERROR_INVALIDDATA; |
| 691 | time += cat->files[i].user_duration; |
| 692 | } |
| 693 | if (i == cat->nb_files) { |
| 694 | avf->duration = time; |
| 695 | cat->seekable = 1; |
| 696 | } |
| 697 | |
| 698 | cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID : |
| 699 | MATCH_ONE_TO_ONE; |
| 700 | if ((ret = open_file(avf, 0)) < 0) |
| 701 | return ret; |
| 702 | |
| 703 | return 0; |
| 704 | } |
| 705 | |
| 706 | static int open_next_file(AVFormatContext *avf) |
| 707 | { |
nothing calls this directly
no test coverage detected