From 496f0f2a659c1339d1e37330d446e9b6ce96e76b Mon Sep 17 00:00:00 2001
From: Ilkka Ollakka <ileoo@videolan.org>
Date: Wed, 5 Jul 2023 13:33:09 +0300
Subject: [PATCH] avcodec: audio decoder to use ch_layout

---
 modules/codec/avcodec/audio.c | 42 ++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 8 deletions(-)

diff --git a/modules/codec/avcodec/audio.c b/modules/codec/avcodec/audio.c
index 5044e1556231..2c85d83005c5 100644
--- a/modules/codec/avcodec/audio.c
+++ b/modules/codec/avcodec/audio.c
@@ -138,7 +138,11 @@ static int OpenAudioCodec( decoder_t *p_dec )
     }
 
     ctx->sample_rate = p_dec->fmt_in->audio.i_rate;
+#if LIBAVCODEC_VERSION_CHECK(59, 24, 100)
+    av_channel_layout_default( &ctx->ch_layout, p_dec->fmt_in->audio.i_channels );
+#else
     ctx->channels = p_dec->fmt_in->audio.i_channels;
+#endif
     ctx->block_align = p_dec->fmt_in->audio.i_blockalign;
     ctx->bit_rate = p_dec->fmt_in->i_bitrate;
     ctx->bits_per_coded_sample = p_dec->fmt_in->audio.i_bitspersample;
@@ -403,12 +407,17 @@ static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
         ret = avcodec_receive_frame( ctx, frame );
         if( ret == 0 )
         {
+#if LIBAVCODEC_VERSION_CHECK(59, 24, 100)
+            int channels = frame->ch_layout.nb_channels;
+#else
+            int channels = ctx->channels;
+#endif
             /* checks and init from first decoded frame */
-            if( ctx->channels <= 0 || ctx->channels > INPUT_CHAN_MAX
+            if( channels <= 0 || channels > INPUT_CHAN_MAX
              || ctx->sample_rate <= 0 )
             {
                 msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
-                          ctx->channels, ctx->sample_rate );
+                          channels, ctx->sample_rate );
                 goto drop;
             }
             else if( p_dec->fmt_out.audio.i_rate != (unsigned int)ctx->sample_rate )
@@ -588,6 +597,16 @@ static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
     p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
 
     /* */
+#if LIBAVCODEC_VERSION_CHECK(59, 24, 100)
+    if( p_sys->i_previous_channels == p_sys->p_context->ch_layout.nb_channels &&
+        p_sys->i_previous_layout == p_sys->p_context->ch_layout.u.mask )
+        return;
+    if( b_trust )
+    {
+        p_sys->i_previous_channels = p_sys->p_context->ch_layout.nb_channels;
+        p_sys->i_previous_layout = p_sys->p_context->ch_layout.u.mask;
+    }
+#else
     if( p_sys->i_previous_channels == p_sys->p_context->channels &&
         p_sys->i_previous_layout == p_sys->p_context->channel_layout )
         return;
@@ -596,25 +615,32 @@ static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
         p_sys->i_previous_channels = p_sys->p_context->channels;
         p_sys->i_previous_layout = p_sys->p_context->channel_layout;
     }
+#endif
 
     const unsigned i_order_max = sizeof(pi_channels_map)/sizeof(*pi_channels_map);
     uint32_t pi_order_src[i_order_max];
 
     int i_channels_src = 0;
-    uint64_t channel_layout =
+#if LIBAVCODEC_VERSION_CHECK(59, 24, 100)
+    uint64_t channel_layout_mask = p_sys->p_context->ch_layout.u.mask;
+    int channel_count = p_sys->p_context->ch_layout.nb_channels;
+#else
+    uint64_t channel_layout_mask =
         p_sys->p_context->channel_layout ? p_sys->p_context->channel_layout :
         (uint64_t)av_get_default_channel_layout( p_sys->p_context->channels );
+    int channel_count = p_sys->p_context->channels;
+#endif
 
-    if( channel_layout )
+    if( channel_layout_mask )
     {
         for( unsigned i = 0; i < i_order_max
-         && i_channels_src < p_dec->fmt_out.audio.i_channels; i++ )
+         && i_channels_src < channel_count; i++ )
         {
-            if( channel_layout & pi_channels_map[i][0] )
+            if( channel_layout_mask & pi_channels_map[i][0] )
                 pi_order_src[i_channels_src++] = pi_channels_map[i][1];
         }
 
-        if( i_channels_src != p_dec->fmt_out.audio.i_channels && b_trust )
+        if( i_channels_src != channel_count && b_trust )
             msg_Err( p_dec, "Channel layout not understood" );
 
         /* Detect special dual mono case */
@@ -646,7 +672,7 @@ static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
     {
         msg_Warn( p_dec, "no channel layout found");
         p_dec->fmt_out.audio.i_physical_channels = 0;
-        p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
+        p_dec->fmt_out.audio.i_channels = channel_count;
     }
 
     aout_FormatPrepare( &p_dec->fmt_out.audio );
-- 
GitLab