X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fwavdec.c;h=8c78666f845220fcb2b390558ff3e51f94a075c0;hb=8ca39b855a7b0e4d9f726fa9d285bc8edcb953e6;hp=1b427117baee198f7c108f6a642c40a8ff5d6ad7;hpb=13f57a4d881ec669b87bf82f424bfff502433060;p=ffmpeg diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 1b427117bae..8c78666f845 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -23,6 +23,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + #include "libavutil/avassert.h" #include "libavutil/dict.h" #include "libavutil/log.h" @@ -49,6 +51,12 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag) return avio_rl32(pb); } +/* RIFF chunks are always on a even offset. */ +static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence) +{ + return avio_seek(s, offset + (offset & 1), whence); +} + /* return the size of the found tag */ static int64_t find_tag(AVIOContext *pb, uint32_t tag1) { @@ -61,7 +69,7 @@ static int64_t find_tag(AVIOContext *pb, uint32_t tag1) size = next_tag(pb, &tag); if (tag == tag1) break; - avio_skip(pb, size); + wav_seek_tag(pb, size, SEEK_CUR); } return size; } @@ -73,9 +81,9 @@ static int wav_probe(AVProbeData *p) return 0; if (!memcmp(p->buf + 8, "WAVE", 4)) { if (!memcmp(p->buf, "RIFF", 4)) - /* Since ACT demuxer has standard WAV header at top of it's - * own, returning score is decreased to avoid probe conflict - * between ACT and WAV. */ + /* Since the ACT demuxer has a standard WAV header at the top of + * its own, the returned score is decreased to avoid a probe + * conflict between ACT and WAV. */ return AVPROBE_SCORE_MAX - 1; else if (!memcmp(p->buf, "RF64", 4) && !memcmp(p->buf + 12, "ds64", 4)) @@ -94,12 +102,12 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) if (!*st) return AVERROR(ENOMEM); - ret = ff_get_wav_header(pb, (*st)->codec, size); + ret = ff_get_wav_header(s, pb, (*st)->codecpar, size); if (ret < 0) return ret; (*st)->need_parsing = AVSTREAM_PARSE_FULL; - avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate); + avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate); return 0; } @@ -219,18 +227,18 @@ static int wav_read_header(AVFormatContext *s) rf64 = tag == MKTAG('R', 'F', '6', '4'); if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F')) - return -1; + return AVERROR_INVALIDDATA; avio_rl32(pb); /* file size */ tag = avio_rl32(pb); if (tag != MKTAG('W', 'A', 'V', 'E')) - return -1; + return AVERROR_INVALIDDATA; if (rf64) { if (avio_rl32(pb) != MKTAG('d', 's', '6', '4')) - return -1; + return AVERROR_INVALIDDATA; size = avio_rl32(pb); if (size < 16) - return -1; + return AVERROR_INVALIDDATA; avio_rl64(pb); /* RIFF size */ data_size = avio_rl64(pb); @@ -281,7 +289,7 @@ static int wav_read_header(AVFormatContext *s) /* don't look for footer metadata if we can't seek or if we don't * know where the data tag ends */ - if (!pb->seekable || (!rf64 && !size)) + if (!(pb->seekable & AVIO_SEEKABLE_NORMAL) || (!rf64 && !size)) goto break_loop; break; case MKTAG('f', 'a', 'c', 't'): @@ -307,7 +315,7 @@ static int wav_read_header(AVFormatContext *s) /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || - avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) { + wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) { break; } } @@ -320,11 +328,11 @@ break_loop: avio_seek(pb, data_ofs, SEEK_SET); - if (!sample_count && st->codec->channels && - av_get_bits_per_sample(st->codec->codec_id)) + if (!sample_count && st->codecpar->channels && + av_get_bits_per_sample(st->codecpar->codec_id)) sample_count = (data_size << 3) / - (st->codec->channels * - (uint64_t)av_get_bits_per_sample(st->codec->codec_id)); + (st->codecpar->channels * + (uint64_t)av_get_bits_per_sample(st->codecpar->codec_id)); if (sample_count) st->duration = sample_count; @@ -383,10 +391,10 @@ static int wav_read_packet(AVFormatContext *s, AVPacket *pkt) } size = MAX_SIZE; - if (st->codec->block_align > 1) { - if (size < st->codec->block_align) - size = st->codec->block_align; - size = (size / st->codec->block_align) * st->codec->block_align; + if (st->codecpar->block_align > 1) { + if (size < st->codecpar->block_align) + size = st->codecpar->block_align; + size = (size / st->codecpar->block_align) * st->codecpar->block_align; } size = FFMIN(size, left); ret = av_get_packet(s->pb, pkt, size); @@ -403,7 +411,7 @@ static int wav_read_seek(AVFormatContext *s, AVStream *st; st = s->streams[0]; - switch (st->codec->codec_id) { + switch (st->codecpar->codec_id) { case AV_CODEC_ID_MP2: case AV_CODEC_ID_MP3: case AV_CODEC_ID_AC3: @@ -467,22 +475,22 @@ static int w64_read_header(AVFormatContext *s) avio_read(pb, guid, 16); if (memcmp(guid, guid_riff, 16)) - return -1; + return AVERROR_INVALIDDATA; /* riff + wave + fmt + sizes */ if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8) - return -1; + return AVERROR_INVALIDDATA; avio_read(pb, guid, 16); if (memcmp(guid, guid_wave, 16)) { av_log(s, AV_LOG_ERROR, "could not find wave guid\n"); - return -1; + return AVERROR_INVALIDDATA; } size = find_guid(pb, guid_fmt); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find fmt guid\n"); - return -1; + return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); @@ -490,19 +498,19 @@ static int w64_read_header(AVFormatContext *s) return AVERROR(ENOMEM); /* subtract chunk header size - normal wav file doesn't count it */ - ret = ff_get_wav_header(pb, st->codec, size - 24); + ret = ff_get_wav_header(s, pb, st->codecpar, size - 24); if (ret < 0) return ret; avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); st->need_parsing = AVSTREAM_PARSE_FULL; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); + avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); size = find_guid(pb, guid_data); if (size < 0) { av_log(s, AV_LOG_ERROR, "could not find data guid\n"); - return -1; + return AVERROR_INVALIDDATA; } wav->data_end = avio_tell(pb) + size - 24; wav->w64 = 1;