aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2018-12-28 12:16:39 +0100
committerPaul B Mahol <onemda@gmail.com>2018-12-28 12:16:39 +0100
commitcfa7709d05b1ad6cdafe3d20c91d38d7db503b3e (patch)
treec795108701bec53c06e489e1e461e2610d304c9c
parent1a6cca19898c5e65d0e3cb9b9b293146b8268dcc (diff)
downloadffmpeg-cfa7709d05b1ad6cdafe3d20c91d38d7db503b3e.tar.gz
avcodec/wavpack: fix decoding of files with many channels
Fixes decoding of Run_The_Race_-_3rd_Order_Ambisonic_SN3D.wv
-rw-r--r--libavcodec/wavpack.c18
-rw-r--r--libavformat/wvdec.c9
2 files changed, 22 insertions, 5 deletions
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 8306ec020f..d0242809fe 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -940,13 +940,23 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
case 3:
chmask = bytestream2_get_le32(&gb);
break;
- case 5:
+ case 4:
size = bytestream2_get_byte(&gb);
- if (avctx->channels != size)
+ chan |= (bytestream2_get_byte(&gb) & 0xF) << 8;
+ chan += 1;
+ if (avctx->channels != chan)
av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
- " instead of %i.\n", size, avctx->channels);
+ " instead of %i.\n", chan, avctx->channels);
+ chmask = bytestream2_get_le24(&gb);
+ break;
+ case 5:
+ size = bytestream2_get_byte(&gb);
chan |= (bytestream2_get_byte(&gb) & 0xF) << 8;
- chmask = bytestream2_get_le16(&gb);
+ chan += 1;
+ if (avctx->channels != chan)
+ av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
+ " instead of %i.\n", chan, avctx->channels);
+ chmask = bytestream2_get_le32(&gb);
break;
default:
av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
diff --git a/libavformat/wvdec.c b/libavformat/wvdec.c
index 82526563ec..b6932e65af 100644
--- a/libavformat/wvdec.c
+++ b/libavformat/wvdec.c
@@ -153,11 +153,18 @@ static int wv_read_block_header(AVFormatContext *ctx, AVIOContext *pb)
case 3:
chmask = avio_rl32(pb);
break;
- case 5:
+ case 4:
avio_skip(pb, 1);
chan |= (avio_r8(pb) & 0xF) << 8;
+ chan += 1;
chmask = avio_rl24(pb);
break;
+ case 5:
+ avio_skip(pb, 1);
+ chan |= (avio_r8(pb) & 0xF) << 8;
+ chan += 1;
+ chmask = avio_rl32(pb);
+ break;
default:
av_log(ctx, AV_LOG_ERROR,
"Invalid channel info size %d\n", size);