diff options
author | Paul B Mahol <onemda@gmail.com> | 2015-11-01 13:15:36 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2015-11-06 13:45:50 +0100 |
commit | b456ece55731c545d0bf62641fee2da437861987 (patch) | |
tree | c022717fc064f9c7b3b7f5dd3f13e51085b2e7a3 /libavformat/riffdec.c | |
parent | c8780822bacc38a8d84c882d564b07dd152366ed (diff) | |
download | ffmpeg-b456ece55731c545d0bf62641fee2da437861987.tar.gz |
XMA1 and XMA2 stereo decoders
Signed-off-by: Paul B Mahol <onemda@gmail.com>
Diffstat (limited to 'libavformat/riffdec.c')
-rw-r--r-- | libavformat/riffdec.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/libavformat/riffdec.c b/libavformat/riffdec.c index 26779e1bfb..e75aee5de9 100644 --- a/libavformat/riffdec.c +++ b/libavformat/riffdec.c @@ -99,10 +99,12 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, codec->codec_type = AVMEDIA_TYPE_AUDIO; if (!big_endian) { id = avio_rl16(pb); - codec->channels = avio_rl16(pb); - codec->sample_rate = avio_rl32(pb); - bitrate = avio_rl32(pb) * 8LL; - codec->block_align = avio_rl16(pb); + if (id != 0x0165) { + codec->channels = avio_rl16(pb); + codec->sample_rate = avio_rl32(pb); + bitrate = avio_rl32(pb) * 8LL; + codec->block_align = avio_rl16(pb); + } } else { id = avio_rb16(pb); codec->channels = avio_rb16(pb); @@ -126,7 +128,7 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample); } - if (size >= 18) { /* We're obviously dealing with WAVEFORMATEX */ + if (size >= 18 && id != 0x0165) { /* We're obviously dealing with WAVEFORMATEX */ int cbSize = avio_rl16(pb); /* cbSize */ if (big_endian) { avpriv_report_missing_feature(codec, "WAVEFORMATEX support for RIFX files\n"); @@ -149,6 +151,21 @@ int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, /* It is possible for the chunk to contain garbage at the end */ if (size > 0) avio_skip(pb, size); + } else if (id == 0x0165 && size >= 32) { + int nb_streams, i; + + size -= 4; + av_freep(&codec->extradata); + if (ff_get_extradata(codec, pb, size) < 0) + return AVERROR(ENOMEM); + nb_streams = AV_RL16(codec->extradata + 4); + codec->sample_rate = AV_RL32(codec->extradata + 12); + codec->channels = 0; + bitrate = 0; + if (size < 8 + nb_streams * 20) + return AVERROR_INVALIDDATA; + for (i = 0; i < nb_streams; i++) + codec->channels += codec->extradata[8 + i * 20 + 17]; } if (bitrate > INT_MAX) { |