diff options
author | Roman Shaposhnik <roman@shaposhnik.org> | 2003-03-12 01:35:47 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2003-03-12 01:35:47 +0000 |
commit | 2e7973bbe7c8c98acb0bd9cdd828a6f8cba02e98 (patch) | |
tree | 57eea2484a6457a2bf1954ded6f354601241d1a5 /libavformat/wav.c | |
parent | 69db4e10f27abe4d3a7036d5cdb29e1f9745c7a4 (diff) | |
download | ffmpeg-2e7973bbe7c8c98acb0bd9cdd828a6f8cba02e98.tar.gz |
correct AUDIO strf parsing patch by (Roman Shaposhnick <rvs at sun dot com>)
Originally committed as revision 1664 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/wav.c')
-rw-r--r-- | libavformat/wav.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/libavformat/wav.c b/libavformat/wav.c index 7fe2f8e73b..81301122d5 100644 --- a/libavformat/wav.c +++ b/libavformat/wav.c @@ -103,26 +103,44 @@ int put_wav_header(ByteIOContext *pb, AVCodecContext *enc) return hdrsize; } -void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, - int has_extra_data) +/* We could be given one of the three possible structures here: + * WAVEFORMAT, PCMWAVEFORMAT or WAVEFORMATEX. Each structure + * is an expansion of the previous one with the fields added + * at the bottom. PCMWAVEFORMAT adds 'WORD wBitsPerSample' and + * WAVEFORMATEX adds 'WORD cbSize' and basically makes itself + * an openended structure. + */ +void get_wav_header(ByteIOContext *pb, AVCodecContext *codec, int size) { int id; id = get_le16(pb); + codec->codec_id = wav_codec_get_id(id, codec->frame_bits); codec->codec_type = CODEC_TYPE_AUDIO; codec->codec_tag = id; codec->channels = get_le16(pb); codec->sample_rate = get_le32(pb); codec->bit_rate = get_le32(pb) * 8; codec->block_align = get_le16(pb); - codec->bits_per_sample = get_le16(pb); /* bits per sample */ - codec->codec_id = wav_codec_get_id(id, codec->frame_bits); - if (has_extra_data) { + if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ + codec->bits_per_sample = 8; + return; + } + + codec->bits_per_sample = get_le16(pb); + if (size > 16) { /* We're obviously dealing with WAVEFORMATEX */ codec->extradata_size = get_le16(pb); if (codec->extradata_size > 0) { + if (codec->extradata_size > size - 18) + codec->extradata_size = size - 18; codec->extradata = av_mallocz(codec->extradata_size); get_buffer(pb, codec->extradata, codec->extradata_size); - } + } else + codec->extradata_size = 0; + + /* It is possible for the chunk to contain garbage at the end */ + if (size - codec->extradata_size - 18 > 0) + url_fskip(pb, size - codec->extradata_size - 18); } } @@ -259,7 +277,7 @@ static int wav_read_header(AVFormatContext *s, if (!st) return AVERROR_NOMEM; - get_wav_header(pb, &st->codec, (size >= 18)); + get_wav_header(pb, &st->codec, size); size = find_tag(pb, MKTAG('d', 'a', 't', 'a')); if (size < 0) |