summaryrefslogtreecommitdiff
path: root/libavformat/wavdec.c
diff options
context:
space:
mode:
authorbnnm <bananaman255@gmail.com>2017-10-03 23:49:00 +0200
committerPaul B Mahol <onemda@gmail.com>2017-10-09 17:06:19 +0200
commit1954e625b1d6bcb8de0fdc2c89f0a62f2fea7328 (patch)
treee4056de089963f353c45f5aa3fe11e9b1ed2ba13 /libavformat/wavdec.c
parent73789b85a759f3874112618120194e1712d7adcd (diff)
avcodec/wmaprodec: support multichannel XMA stream configurations
Signed-off-by: bnnm <bananaman255@gmail.com> Now accepts any combination of 1/2ch streams, described in the RIFF chunks/extradata
Diffstat (limited to 'libavformat/wavdec.c')
-rw-r--r--libavformat/wavdec.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c
index 81dbc9f16e..b016185a1b 100644
--- a/libavformat/wavdec.c
+++ b/libavformat/wavdec.c
@@ -180,9 +180,9 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st)
{
AVIOContext *pb = s->pb;
- int num_streams, i, channels = 0;
+ int version, num_streams, i, channels = 0;
- if (size < 44)
+ if (size < 36)
return AVERROR_INVALIDDATA;
*st = avformat_new_stream(s, NULL);
@@ -193,13 +193,17 @@ static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st)
(*st)->codecpar->codec_id = AV_CODEC_ID_XMA2;
(*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
- avio_skip(pb, 1);
+ version = avio_r8(pb);
+ if (version != 3 && version != 4)
+ return AVERROR_INVALIDDATA;
num_streams = avio_r8(pb);
- if (size < 40 + num_streams * 4)
+ if (size != (32 + ((version==3)?0:8) + 4*num_streams))
return AVERROR_INVALIDDATA;
avio_skip(pb, 10);
(*st)->codecpar->sample_rate = avio_rb32(pb);
- avio_skip(pb, 12);
+ if (version == 4)
+ avio_skip(pb, 8);
+ avio_skip(pb, 4);
(*st)->duration = avio_rb32(pb);
avio_skip(pb, 8);
@@ -213,9 +217,11 @@ static int wav_parse_xma2_tag(AVFormatContext *s, int64_t size, AVStream **st)
return AVERROR_INVALIDDATA;
avpriv_set_pts_info(*st, 64, 1, (*st)->codecpar->sample_rate);
- if (ff_alloc_extradata((*st)->codecpar, 34))
+
+ avio_seek(pb, -size, SEEK_CUR);
+ av_freep(&(*st)->codecpar->extradata);
+ if (ff_get_extradata(s, (*st)->codecpar, pb, size) < 0)
return AVERROR(ENOMEM);
- memset((*st)->codecpar->extradata, 0, 34);
return 0;
}