diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c
index 6b2ec19bf1..e0350ce732 100644
--- a/libavcodec/wavpack.c
+++ b/libavcodec/wavpack.c
@@ -1412,25 +1412,23 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 size = bytestream2_get_byte(&gb);
                 chan  |= (bytestream2_get_byte(&gb) & 0xF) << 8;
                 chan  += 1;
-                if (avctx->channels != chan)
+                if (avctx->ch_layout.nb_channels != chan)
                     av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
-                           " instead of %i.\n", chan, avctx->channels);
+                           " instead of %i.\n", chan, avctx->ch_layout.nb_channels);
                 chmask = bytestream2_get_le24(&gb);
                 break;
             case 5:
                 size = bytestream2_get_byte(&gb);
                 chan  |= (bytestream2_get_byte(&gb) & 0xF) << 8;
                 chan  += 1;
-                if (avctx->channels != chan)
+                if (avctx->ch_layout.nb_channels != chan)
                     av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
-                           " instead of %i.\n", chan, avctx->channels);
+                           " instead of %i.\n", chan, avctx->ch_layout.nb_channels);
                 chmask = bytestream2_get_le32(&gb);
                 break;
             default:
                 av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
                        size);
-                chan   = avctx->channels;
-                chmask = avctx->channel_layout;
             }
             break;
         case WP_ID_SAMPLE_RATE:
@@ -1494,8 +1492,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
     }
 
     if (!wc->ch_offset) {
-        int      new_channels = avctx->channels;
-        uint64_t new_chmask   = avctx->channel_layout;
+        AVChannelLayout new_ch_layout = { 0 };
         int new_samplerate;
         int sr = (s->frame_flags >> 23) & 0xf;
         if (sr == 0xf) {
@@ -1512,36 +1509,32 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
         new_samplerate *= rate_x;
 
         if (multiblock) {
-            if (chan)
-                new_channels = chan;
-            if (chmask)
-                new_chmask = chmask;
+            if (chmask) {
+                av_channel_layout_from_mask(&new_ch_layout, chmask);
+                if (chan && new_ch_layout.nb_channels != chan) {
+                    av_log(avctx, AV_LOG_ERROR, "Channel mask does not match the channel count\n");
+                    return AVERROR_INVALIDDATA;
+                }
+            } else
+                av_channel_layout_copy(&new_ch_layout, &avctx->ch_layout);
         } else {
-            new_channels = s->stereo ? 2 : 1;
-            new_chmask   = s->stereo ? AV_CH_LAYOUT_STEREO :
-                                       AV_CH_LAYOUT_MONO;
-        }
-
-        if (new_chmask &&
-            av_get_channel_layout_nb_channels(new_chmask) != new_channels) {
-            av_log(avctx, AV_LOG_ERROR, "Channel mask does not match the channel count\n");
-            return AVERROR_INVALIDDATA;
+            av_channel_layout_default(&new_ch_layout, s->stereo + 1);
         }
 
         /* clear DSD state if stream properties change */
-        if (new_channels   != wc->dsd_channels      ||
-            new_chmask     != avctx->channel_layout ||
+        if (new_ch_layout.nb_channels != wc->dsd_channels ||
+            av_channel_layout_compare(&new_ch_layout, &avctx->ch_layout) ||
             new_samplerate != avctx->sample_rate    ||
             !!got_dsd      != !!wc->dsdctx) {
-            ret = wv_dsd_reset(wc, got_dsd ? new_channels : 0);
+            ret = wv_dsd_reset(wc, got_dsd ? new_ch_layout.nb_channels : 0);
             if (ret < 0) {
                 av_log(avctx, AV_LOG_ERROR, "Error reinitializing the DSD context\n");
                 return ret;
             }
             ff_thread_release_buffer(avctx, &wc->curr_frame);
         }
-        avctx->channels            = new_channels;
-        avctx->channel_layout      = new_chmask;
+        av_channel_layout_uninit(&avctx->ch_layout);
+        av_channel_layout_copy(&avctx->ch_layout, &new_ch_layout);
         avctx->sample_rate         = new_samplerate;
         avctx->sample_fmt          = sample_fmt;
         avctx->bits_per_raw_sample = orig_bpp;
@@ -1558,7 +1551,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
         ff_thread_finish_setup(avctx);
     }
 
-    if (wc->ch_offset + s->stereo >= avctx->channels) {
+    if (wc->ch_offset + s->stereo >= avctx->ch_layout.nb_channels) {
         av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
         return ((avctx->err_recognition & AV_EF_EXPLODE) || !wc->ch_offset) ? AVERROR_INVALIDDATA : 0;
     }
@@ -1668,7 +1661,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
         buf_size -= frame_size;
     }
 
-    if (s->ch_offset != avctx->channels) {
+    if (s->ch_offset != avctx->ch_layout.nb_channels) {
         av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
         ret = AVERROR_INVALIDDATA;
         goto error;
@@ -1678,7 +1671,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
     ff_thread_release_buffer(avctx, &s->prev_frame);
 
     if (s->modulation == MODULATION_DSD)
-        avctx->execute2(avctx, dsd_channel, s->frame, NULL, avctx->channels);
+        avctx->execute2(avctx, dsd_channel, s->frame, NULL, avctx->ch_layout.nb_channels);
 
     ff_thread_report_progress(&s->curr_frame, INT_MAX, 0);
 
diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c
index dc4f4e303b..bc1049db0a 100644
--- a/libavcodec/wavpackenc.c
+++ b/libavcodec/wavpackenc.c
@@ -130,8 +130,8 @@ static av_cold int wavpack_encode_init(AVCodecContext *avctx)
 
     s->avctx = avctx;
 
-    if (avctx->channels > 255) {
-        av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->channels);
+    if (avctx->ch_layout.nb_channels > 255) {
+        av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->ch_layout.nb_channels);
         return AVERROR(EINVAL);
     }
 
@@ -142,10 +142,10 @@ static av_cold int wavpack_encode_init(AVCodecContext *avctx)
         else
             block_samples = avctx->sample_rate;
 
-        while (block_samples * avctx->channels > WV_MAX_SAMPLES)
+        while (block_samples * avctx->ch_layout.nb_channels > WV_MAX_SAMPLES)
             block_samples /= 2;
 
-        while (block_samples * avctx->channels < 40000)
+        while (block_samples * avctx->ch_layout.nb_channels < 40000)
             block_samples *= 2;
         avctx->frame_size = block_samples;
     } else if (avctx->frame_size && (avctx->frame_size < 128 ||
@@ -2572,7 +2572,7 @@ static int wavpack_encode_block(WavPackEncodeContext *s,
 
     s->ch_offset += 1 + !(s->flags & WV_MONO);
 
-    if (s->ch_offset == s->avctx->channels)
+    if (s->ch_offset == s->avctx->ch_layout.nb_channels)
         s->flags |= WV_FINAL_BLOCK;
 
     bytestream2_init_writer(&pb, out, out_size);
@@ -2587,11 +2587,12 @@ static int wavpack_encode_block(WavPackEncodeContext *s,
     bytestream2_put_le32(&pb, crc);
 
     if (s->flags & WV_INITIAL_BLOCK &&
-        s->avctx->channel_layout != AV_CH_LAYOUT_MONO &&
-        s->avctx->channel_layout != AV_CH_LAYOUT_STEREO) {
+        s->avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
+        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_MONO &&
+        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_STEREO) {
         put_metadata_block(&pb, WP_ID_CHANINFO, 5);
-        bytestream2_put_byte(&pb, s->avctx->channels);
-        bytestream2_put_le32(&pb, s->avctx->channel_layout);
+        bytestream2_put_byte(&pb, s->avctx->ch_layout.nb_channels);
+        bytestream2_put_le32(&pb, s->avctx->ch_layout.u.mask);
         bytestream2_put_byte(&pb, 0);
     }
 
@@ -2862,20 +2863,20 @@ static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                           sizeof(int32_t) * s->block_samples);
     if (!s->samples[0])
         return AVERROR(ENOMEM);
-    if (avctx->channels > 1) {
+    if (avctx->ch_layout.nb_channels > 1) {
         av_fast_padded_malloc(&s->samples[1], &s->samples_size[1],
                               sizeof(int32_t) * s->block_samples);
         if (!s->samples[1])
             return AVERROR(ENOMEM);
     }
 
-    buf_size = s->block_samples * avctx->channels * 8
-             + 200 * avctx->channels /* for headers */;
+    buf_size = s->block_samples * avctx->ch_layout.nb_channels * 8
+             + 200 * avctx->ch_layout.nb_channels /* for headers */;
     if ((ret = ff_alloc_packet(avctx, avpkt, buf_size)) < 0)
         return ret;
     buf = avpkt->data;
 
-    for (s->ch_offset = 0; s->ch_offset < avctx->channels;) {
+    for (s->ch_offset = 0; s->ch_offset < avctx->ch_layout.nb_channels;) {
         set_samplerate(s);
 
         switch (s->avctx->sample_fmt) {
@@ -2885,7 +2886,7 @@ static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
         }
 
         fill_buffer(s, frame->extended_data[s->ch_offset], s->samples[0], s->block_samples);
-        if (avctx->channels - s->ch_offset == 1) {
+        if (avctx->ch_layout.nb_channels - s->ch_offset == 1) {
             s->flags |= WV_MONO;
         } else {
             s->flags |= WV_CROSS_DECORR;
