| @@ -552,7 +552,7 @@ static int w64_probe(AVProbeData *p) · 551 unmodified lines |
| 552 | 552 | |
| 553 | 553 | static int w64_read_header(AVFormatContext *s) |
| 554 | 554 | { |
| 555 | | − int64_t size; |
| 555 | + int64_t size, data_ofs = 0; |
| 556 | 556 | AVIOContext *pb = s->pb; |
| 557 | 557 | WAVDemuxContext *wav = s->priv_data; |
| 558 | 558 | AVStream *st; |
| @@ -572,34 +572,80 @@ static int w64_read_header(AVFormatContext *s) · 13 unmodified lines |
| 572 | 572 | return -1; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | | − size = find_guid(pb, ff_w64_guid_fmt); |
| 576 | | − if (size < 0) { |
| 577 | | − av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); |
| 578 | | − return -1; |
| 579 | | − } |
| 575 | + wav->w64 = 1; |
| 580 | 576 | |
| 581 | 577 | st = avformat_new_stream(s, NULL); |
| 582 | 578 | if (!st) |
| 583 | 579 | return AVERROR(ENOMEM); |
| 584 | 580 | |
| 585 | | − /* subtract chunk header size - normal wav file doesn't count it */ |
| 586 | | − ret = ff_get_wav_header(pb, st->codec, size - 24); |
| 587 | | − if (ret < 0) |
| 588 | | − return ret; |
| 589 | | − avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); |
| 581 | + while (!url_feof(pb)) { |
| 582 | + if (avio_read(pb, guid, 16) != 16) |
| 583 | + break; |
| 584 | + size = avio_rl64(pb); |
| 585 | + if (size <= 24 || INT64_MAX - size < avio_tell(pb)) |
| 586 | + return AVERROR_INVALIDDATA; |
| 590 | 587 | |
| 591 | | − handle_stream_probing(st); |
| 592 | | − st->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
| 588 | + if (!memcmp(guid, ff_w64_guid_fmt, 16)) { |
| 589 | + /* subtract chunk header size - normal wav file doesn't count it */ |
| 590 | + ret = ff_get_wav_header(pb, st->codec, size - 24); |
| 591 | + if (ret < 0) |
| 592 | + return ret; |
| 593 | + avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); |
| 593 | 594 | |
| 594 | | − avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 595 | + avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); |
| 596 | + } else if (!memcmp(guid, ff_w64_guid_data, 16)) { |
| 597 | + wav->data_end = avio_tell(pb) + size - 24; |
| 595 | 598 | |
| 596 | | − size = find_guid(pb, ff_w64_guid_data); |
| 597 | | − if (size < 0) { |
| 598 | | − av_log(s, AV_LOG_ERROR, "could not find data guid\n"); |
| 599 | | − return -1; |
| 599 | + data_ofs = avio_tell(pb); |
| 600 | + if (!pb->seekable) |
| 601 | + break; |
| 602 | + |
| 603 | + avio_skip(pb, size - 24); |
| 604 | + } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) { |
| 605 | + int64_t start, end, cur; |
| 606 | + uint32_t count, chunk_size, i; |
| 607 | + |
| 608 | + start = avio_tell(pb); |
| 609 | + end = start + size; |
| 610 | + count = avio_rl32(pb); |
| 611 | + |
| 612 | + for (i = 0; i < count; i++) { |
| 613 | + char chunk_key[5], *value; |
| 614 | + |
| 615 | + if (url_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */) |
| 616 | + break; |
| 617 | + |
| 618 | + chunk_key[4] = 0; |
| 619 | + avio_read(pb, chunk_key, 4); |
| 620 | + chunk_size = avio_rl32(pb); |
| 621 | + |
| 622 | + value = av_mallocz(chunk_size + 1); |
| 623 | + if (!value) |
| 624 | + return AVERROR(ENOMEM); |
| 625 | + |
| 626 | + ret = avio_get_str16le(pb, chunk_size, value, chunk_size); |
| 627 | + avio_skip(pb, chunk_size - ret); |
| 628 | + |
| 629 | + av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL); |
| 630 | + } |
| 631 | + |
| 632 | + avio_skip(pb, end - avio_tell(pb)); |
| 633 | + } else { |
| 634 | + av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid)); |
| 635 | + avio_skip(pb, size - 24); |
| 636 | + } |
| 600 | 637 | } |
| 601 | | − wav->data_end = avio_tell(pb) + size - 24; |
| 602 | | − wav->w64 = 1; |
| 638 | + |
| 639 | + if (!data_ofs) |
| 640 | + return AVERROR_EOF; |
| 641 | + |
| 642 | + ff_metadata_conv_ctx(s, NULL, wav_metadata_conv); |
| 643 | + ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); |
| 644 | + |
| 645 | + handle_stream_probing(st); |
| 646 | + st->need_parsing = AVSTREAM_PARSE_FULL_RAW; |
| 647 | + |
| 648 | + avio_seek(pb, data_ofs, SEEK_SET); |
| 603 | 649 | |
| 604 | 650 | return 0; |
| 605 | 651 | } |