* Parse WTV chunks * @param mode SEEK_TO_DATA or SEEK_TO_PTS * @param seekts timestamp * @param[out] len_ptr Length of data chunk * @return stream index of data chunk, or <0 on error */
| 772 | * @return stream index of data chunk, or <0 on error |
| 773 | */ |
| 774 | static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr) |
| 775 | { |
| 776 | WtvContext *wtv = s->priv_data; |
| 777 | AVIOContext *pb = wtv->pb; |
| 778 | int ret; |
| 779 | while (!avio_feof(pb)) { |
| 780 | ff_asf_guid g; |
| 781 | int len, sid, consumed; |
| 782 | |
| 783 | ff_get_guid(pb, &g); |
| 784 | len = avio_rl32(pb); |
| 785 | if (len < 32 || len > INT_MAX - 7) { |
| 786 | int ret; |
| 787 | if (avio_feof(pb)) |
| 788 | return AVERROR_EOF; |
| 789 | av_log(s, AV_LOG_WARNING, "encountered broken chunk\n"); |
| 790 | if ((ret = recover(wtv, avio_tell(pb) - 20)) < 0) |
| 791 | return ret; |
| 792 | continue; |
| 793 | } |
| 794 | sid = avio_rl32(pb) & 0x7FFF; |
| 795 | avio_skip(pb, 8); |
| 796 | consumed = 32; |
| 797 | |
| 798 | if (!ff_guidcmp(g, ff_SBE2_STREAM_DESC_EVENT)) { |
| 799 | if (ff_find_stream_index(s, sid) < 0) { |
| 800 | ff_asf_guid mediatype, subtype, formattype; |
| 801 | int size; |
| 802 | avio_skip(pb, 28); |
| 803 | ff_get_guid(pb, &mediatype); |
| 804 | ff_get_guid(pb, &subtype); |
| 805 | avio_skip(pb, 12); |
| 806 | ff_get_guid(pb, &formattype); |
| 807 | size = avio_rl32(pb); |
| 808 | if (size < 0 || size > INT_MAX - 92 - consumed) |
| 809 | return AVERROR_INVALIDDATA; |
| 810 | parse_media_type(s, 0, sid, mediatype, subtype, formattype, size); |
| 811 | consumed += 92 + size; |
| 812 | } |
| 813 | } else if (!ff_guidcmp(g, ff_stream2_guid)) { |
| 814 | int stream_index = ff_find_stream_index(s, sid); |
| 815 | if (stream_index >= 0 && s->streams[stream_index]->priv_data && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) { |
| 816 | ff_asf_guid mediatype, subtype, formattype; |
| 817 | int size; |
| 818 | avio_skip(pb, 12); |
| 819 | ff_get_guid(pb, &mediatype); |
| 820 | ff_get_guid(pb, &subtype); |
| 821 | avio_skip(pb, 12); |
| 822 | ff_get_guid(pb, &formattype); |
| 823 | size = avio_rl32(pb); |
| 824 | if (size < 0 || size > INT_MAX - 76 - consumed) |
| 825 | return AVERROR_INVALIDDATA; |
| 826 | parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size); |
| 827 | consumed += 76 + size; |
| 828 | } |
| 829 | } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) || |
| 830 | !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) || |
| 831 | !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) || |
no test coverage detected