[FFmpeg-cvslog] avcodec/wavpack: fix decoding of files with many channels

Paul B Mahol git at videolan.org
Fri Dec 28 13:26:52 EET 2018


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Fri Dec 28 12:16:39 2018 +0100| [cfa7709d05b1ad6cdafe3d20c91d38d7db503b3e] | committer: Paul B Mahol

avcodec/wavpack: fix decoding of files with many channels

Fixes decoding of Run_The_Race_-_3rd_Order_Ambisonic_SN3D.wv

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=cfa7709d05b1ad6cdafe3d20c91d38d7db503b3e
---

 libavcodec/wavpack.c | 18 ++++++++++++++----
 libavformat/wvdec.c  |  9 ++++++++-
 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);



More information about the ffmpeg-cvslog mailing list