[vlc-commits] [Git][videolan/vlc][3.0.x] 13 commits: coreaudio: fix original value never set

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Nov 8 09:40:07 UTC 2022



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
20c96c57 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: fix original value never set

Regression from 91f426996c98

This fixes the shortcut to map channels to Center or Stereo.

(cherry picked from commit b73f7c40d8a8355f188d10ce919f90ecfaf745d7)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
fd8b5163 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: fix layout tag mismatch for L R C Cs

(cherry picked from commit 12683cccac45230ad10533d7357ff7a31f8c6253)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
96cb65e3 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: refactor aout_CheckChannelReorder() usage

(cherry picked from commit 0405833cd8a5cafcccc5253f1e5a9b58b5471b26)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
ea9c3017 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: either use output or input layout

And not both.

On macOS, VLC need to adapt its fmt to the output layout (it can't
change it).
on tvOS, VLC can send its custom input layout.

Fixes #27474
Also fix 7.1 mapping on macOS (Center was on Left...).

(cherry picked from commit 87bbf8f272ef6b38b6ed1c002e96f570aba0f4a8)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
dc181df1 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: use a switch case instead of an array

The current size of the array is 35 for 9 elements.

The maximum value for AudioChannelLabel is 65536 and we want to avoid
having an array of 65536 for very few elements.

(cherry picked from commit 9d676d26b39c8b571e76990eced97eead0b4dcb4)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
c3d728d5 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: swap Surround with RearSurround when needed

Tested on macOS 12.5, compared with the same vlc/sample/amplifier on
Windows.

Surround and RearSurround are indeed swapped for 7.1, same for tvOS (cf.
next).

But why ?

(cherry picked from commit 0a65098fcd0d7ddc4c56fa10c616ddd044eeee32)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
b344e738 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: add Lsd/Rsd mapping

Could not test it.

(cherry picked from commit 082a0305f1765495e74e7650b07baf83e9e6eef3)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
8e749c61 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: rename SetupInputLayout

(cherry picked from commit c65da6381ac6a7b454115790ac933c7ece36cde8)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
8457f069 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: MapInputLayout() can now return any type of AudioChannelLayout

(cherry picked from commit 28e4d7fe50b28cbc7267aa72ec0fa28a26924aa2)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
2edac7c5 by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: remove useless log

There is one more complete just after.

(cherry picked from commit 704d6fcfa0c9530a4461c62e61049e837ba080b0)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
6eb4f99d by Thomas Guillem at 2022-11-08T09:26:29+00:00
coreaudio: use ChannelDescriptions for MapInputLayout()

Simpler, tested on tvOS 14 and 16. On tvOS, the device can adapt to the
VLC input format, in contrary to macOS.

Fixes 7.1 surround.

(cherry picked from commit 3d92b1c3017f45c6410dc0dde7b3e2095ce176d7)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
d58a68dd by Thomas Guillem at 2022-11-08T09:26:29+00:00
audiounit_ios: move debug log

(cherry picked from commit cac29a174030fbdda0abb5537c7515e5750d2281)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -
638a07db by Thomas Guillem at 2022-11-08T09:26:29+00:00
audiounit_ios: don't fetch the output layout

That way, we will always use MapInputLayout() on tvOS/iOS.

(cherry picked from commit ebc27c6e4053a0a6dfe42a0d0acd89e394df1d2b)
Signed-off-by: Thomas Guillem <thomas at gllm.fr>

- - - - -


2 changed files:

- modules/audio_output/audiounit_ios.m
- modules/audio_output/coreaudio_common.c


Changes:

=====================================
modules/audio_output/audiounit_ios.m
=====================================
@@ -283,12 +283,10 @@ avas_resetPreferredNumberOfChannels(audio_output_t *p_aout)
 }
 
 static int
-avas_GetOptimalChannelLayout(audio_output_t *p_aout, enum port_type *pport_type,
-                             AudioChannelLayout **playout)
+avas_GetPortType(audio_output_t *p_aout, enum port_type *pport_type)
 {
     struct aout_sys_t * p_sys = p_aout->sys;
     AVAudioSession *instance = p_sys->avInstance;
-    AudioChannelLayout *layout = NULL;
     *pport_type = PORT_TYPE_DEFAULT;
 
     long last_channel_count = 0;
@@ -311,64 +309,11 @@ avas_GetOptimalChannelLayout(audio_output_t *p_aout, enum port_type *pport_type,
             p_sys->b_spatial_audio_supported = out.spatialAudioEnabled;
         }
 
-        NSArray<AVAudioSessionChannelDescription *> *chans = [out channels];
-
-        if (chans.count > last_channel_count || port_type == PORT_TYPE_HDMI)
-        {
-            /* We don't need a layout specification for stereo */
-            if (chans.count > 2)
-            {
-                bool labels_valid = false;
-                for (AVAudioSessionChannelDescription *chan in chans)
-                {
-                    if ([chan channelLabel] != kAudioChannelLabel_Unknown)
-                    {
-                        labels_valid = true;
-                        break;
-                    }
-                }
-                if (!labels_valid)
-                {
-                    /* TODO: Guess labels ? */
-                    msg_Warn(p_aout, "no valid channel labels");
-                    continue;
-                }
-
-                if (layout == NULL
-                 || layout->mNumberChannelDescriptions < chans.count)
-                {
-                    const size_t layout_size = sizeof(AudioChannelLayout)
-                        + chans.count * sizeof(AudioChannelDescription);
-                    layout = realloc_or_free(layout, layout_size);
-                    if (layout == NULL)
-                        return VLC_ENOMEM;
-                }
-
-                layout->mChannelLayoutTag =
-                    kAudioChannelLayoutTag_UseChannelDescriptions;
-                layout->mNumberChannelDescriptions = chans.count;
-
-                unsigned i = 0;
-                for (AVAudioSessionChannelDescription *chan in chans)
-                    layout->mChannelDescriptions[i++].mChannelLabel
-                        = [chan channelLabel];
-
-                last_channel_count = chans.count;
-            }
-            *pport_type = port_type;
-        }
-
+        *pport_type = port_type;
         if (port_type == PORT_TYPE_HDMI) /* Prefer HDMI */
             break;
     }
 
-    msg_Dbg(p_aout, "Output on %s, channel count: %u, spatialAudioEnabled %i",
-            *pport_type == PORT_TYPE_HDMI ? "HDMI" :
-            *pport_type == PORT_TYPE_USB ? "USB" :
-            *pport_type == PORT_TYPE_HEADPHONES ? "Headphones" : "Default",
-            layout ? (unsigned) layout->mNumberChannelDescriptions : 2, p_sys->b_spatial_audio_supported);
-
-    *playout = layout;
     return VLC_SUCCESS;
 }
 
@@ -649,7 +594,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     }
 
     enum port_type port_type;
-    int ret = avas_GetOptimalChannelLayout(p_aout, &port_type, &layout);
+    int ret = avas_GetPortType(p_aout, &port_type);
     if (ret != VLC_SUCCESS)
         goto error;
 
@@ -660,6 +605,13 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
             goto error;
     }
 
+    msg_Dbg(p_aout, "Output on %s, channel count: %ld, spatialAudioEnabled %i",
+            port_type == PORT_TYPE_HDMI ? "HDMI" :
+            port_type == PORT_TYPE_USB ? "USB" :
+            port_type == PORT_TYPE_HEADPHONES ? "Headphones" : "Default",
+            (long) [p_sys->avInstance outputNumberOfChannels],
+            p_sys->b_spatial_audio_supported);
+
     p_aout->current_sink_info.headphones = port_type == PORT_TYPE_HEADPHONES;
 
     p_sys->au_unit = au_NewOutputInstance(p_aout, kAudioUnitSubType_RemoteIO);
@@ -676,7 +628,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     const mtime_t latency_us = [p_sys->avInstance outputLatency] * CLOCK_FREQ;
     msg_Dbg(p_aout, "Current device has a latency of %lld us", latency_us);
 
-    ret = au_Initialize(p_aout, p_sys->au_unit, fmt, layout, latency_us, NULL);
+    ret = au_Initialize(p_aout, p_sys->au_unit, fmt, NULL, latency_us, NULL);
     if (ret != VLC_SUCCESS)
         goto error;
 
@@ -705,7 +657,6 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
     return VLC_SUCCESS;
 
 error:
-    free(layout);
     if (p_sys->au_unit != NULL)
         AudioComponentInstanceDispose(p_sys->au_unit);
     avas_resetPreferredNumberOfChannels(p_aout);


=====================================
modules/audio_output/coreaudio_common.c
=====================================
@@ -603,21 +603,86 @@ GetLayoutDescription(audio_output_t *p_aout,
     return reslayout;
 }
 
+static unsigned
+AudioChannelLabelToVlcChan(AudioChannelLabel chan, bool swap_rear_surround)
+{
+    /* maps auhal channels to vlc ones */
+    switch (chan)
+    {
+        case kAudioChannelLabel_Left:
+            return AOUT_CHAN_LEFT;
+        case kAudioChannelLabel_Right:
+            return AOUT_CHAN_RIGHT;
+        case kAudioChannelLabel_Center:
+            return AOUT_CHAN_CENTER;
+        case kAudioChannelLabel_LFEScreen:
+            return AOUT_CHAN_LFE;
+        case kAudioChannelLabel_LeftSurround:
+            return swap_rear_surround ? AOUT_CHAN_MIDDLELEFT
+                                      : AOUT_CHAN_REARLEFT;
+        case kAudioChannelLabel_RightSurround:
+            return swap_rear_surround ? AOUT_CHAN_MIDDLERIGHT
+                                      : AOUT_CHAN_REARRIGHT;
+        case kAudioChannelLabel_RearSurroundLeft:
+            return swap_rear_surround ? AOUT_CHAN_REARLEFT
+                                      : AOUT_CHAN_MIDDLELEFT;
+        case kAudioChannelLabel_RearSurroundRight:
+            return swap_rear_surround ? AOUT_CHAN_REARRIGHT
+                                      : AOUT_CHAN_MIDDLERIGHT;
+        case kAudioChannelLabel_CenterSurround:
+            return AOUT_CHAN_REARCENTER;
+        case kAudioChannelLabel_LeftSurroundDirect:
+            return AOUT_CHAN_MIDDLELEFT;
+        case kAudioChannelLabel_RightSurroundDirect:
+            return AOUT_CHAN_MIDDLERIGHT;
+        default:
+            return 0;
+    }
+}
+
+static AudioChannelLabel
+VlcChanToAudioChannelLabel(unsigned chan, bool swap_rear_surround)
+{
+    /* maps auhal channels to vlc ones */
+    switch (chan)
+    {
+        case AOUT_CHAN_LEFT:
+            return kAudioChannelLabel_Left;
+        case AOUT_CHAN_RIGHT:
+            return kAudioChannelLabel_Right;
+        case AOUT_CHAN_CENTER:
+            return kAudioChannelLabel_Center;
+        case AOUT_CHAN_LFE:
+            return kAudioChannelLabel_LFEScreen;
+        case AOUT_CHAN_REARLEFT:
+            return swap_rear_surround ? kAudioChannelLabel_RearSurroundLeft
+                                      : kAudioChannelLabel_LeftSurround;
+        case AOUT_CHAN_REARRIGHT:
+            return swap_rear_surround ? kAudioChannelLabel_RearSurroundRight
+                                      : kAudioChannelLabel_RightSurround;
+        case AOUT_CHAN_MIDDLELEFT:
+            return swap_rear_surround ? kAudioChannelLabel_LeftSurround
+                                      : kAudioChannelLabel_RearSurroundLeft;
+        case AOUT_CHAN_MIDDLERIGHT:
+            return swap_rear_surround ? kAudioChannelLabel_RightSurround
+                                      : kAudioChannelLabel_RearSurroundRight;
+        case AOUT_CHAN_REARCENTER:
+            return kAudioChannelLabel_CenterSurround;
+        default:
+            vlc_assert_unreachable();
+    }
+}
+
 static int
 MapOutputLayout(audio_output_t *p_aout, audio_sample_format_t *fmt,
                 const AudioChannelLayout *outlayout, bool *warn_configuration)
 {
+    struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
     /* Fill VLC physical_channels from output layout */
-    fmt->i_physical_channels = 0;
     uint32_t i_original = fmt->i_physical_channels;
+    fmt->i_physical_channels = 0;
     AudioChannelLayout *reslayout = NULL;
-
-    if (outlayout == NULL)
-    {
-        msg_Dbg(p_aout, "not output layout, default to Stereo");
-        fmt->i_physical_channels = AOUT_CHANS_STEREO;
-        goto end;
-    }
+    assert(outlayout != NULL);
 
     if (outlayout->mChannelLayoutTag !=
         kAudioChannelLayoutTag_UseChannelDescriptions)
@@ -648,25 +713,28 @@ MapOutputLayout(audio_output_t *p_aout, audio_sample_format_t *fmt,
 
         msg_Dbg(p_aout, "output layout of AUHAL has %i channels",
                 outlayout->mNumberChannelDescriptions);
+        uint32_t chans_out[AOUT_CHAN_MAX];
+
+        /* For 7.1, AOUT_CHAN_MIDDLELEFT/RIGHT needs to be swapped with
+         * AOUT_CHAN_REARLEFT/RIGHT. Auhal
+         * kAudioChannelLabel_Left/RightSurround are used as surround for 5.1,
+         * but as middle speakers for rear 7.1. */
+        unsigned swap_rear_surround = 0;
+        if (outlayout->mNumberChannelDescriptions == 8)
+        {
+            for (unsigned i = 0; i < outlayout->mNumberChannelDescriptions; i++)
+            {
+                AudioChannelLabel chan =
+                    outlayout->mChannelDescriptions[i].mChannelLabel;
+                if (chan == kAudioChannelLabel_RearSurroundLeft
+                 || chan == kAudioChannelLabel_RearSurroundRight)
+                    swap_rear_surround++;
+            }
+            if (swap_rear_surround == 2)
+                msg_Dbg(p_aout, "swapping Surround and RearSurround channels "
+                        "for 7.1 Rear Surround");
+        }
 
-        /* maps auhal channels to vlc ones */
-        static const unsigned i_auhal_channel_mapping[] = {
-            [kAudioChannelLabel_Left]           = AOUT_CHAN_LEFT,
-            [kAudioChannelLabel_Right]          = AOUT_CHAN_RIGHT,
-            [kAudioChannelLabel_Center]         = AOUT_CHAN_CENTER,
-            [kAudioChannelLabel_LFEScreen]      = AOUT_CHAN_LFE,
-            [kAudioChannelLabel_LeftSurround]   = AOUT_CHAN_REARLEFT,
-            [kAudioChannelLabel_RightSurround]  = AOUT_CHAN_REARRIGHT,
-            /* needs to be swapped with rear */
-            [kAudioChannelLabel_RearSurroundLeft]  = AOUT_CHAN_MIDDLELEFT,
-            /* needs to be swapped with rear */
-            [kAudioChannelLabel_RearSurroundRight] = AOUT_CHAN_MIDDLERIGHT,
-            [kAudioChannelLabel_CenterSurround] = AOUT_CHAN_REARCENTER
-        };
-        static const size_t i_auhal_size = sizeof(i_auhal_channel_mapping)
-                                         / sizeof(i_auhal_channel_mapping[0]);
-
-        /* We want more than stereo and we can do that */
         for (unsigned i = 0; i < outlayout->mNumberChannelDescriptions; i++)
         {
             AudioChannelLabel chan =
@@ -674,11 +742,19 @@ MapOutputLayout(audio_output_t *p_aout, audio_sample_format_t *fmt,
 #ifndef NDEBUG
             msg_Dbg(p_aout, "this is channel: %d", (int) chan);
 #endif
-            if (chan < i_auhal_size && i_auhal_channel_mapping[chan] > 0)
-                fmt->i_physical_channels |= i_auhal_channel_mapping[chan];
+            unsigned mapped_chan =
+                AudioChannelLabelToVlcChan(chan, swap_rear_surround == 2);
+            if (mapped_chan != 0)
+            {
+                chans_out[i] = mapped_chan;
+                fmt->i_physical_channels |= mapped_chan;
+            }
             else
+            {
+                chans_out[i] = 0;
                 msg_Dbg(p_aout, "found nonrecognized channel %d at index "
                         "%d", chan, i);
+            }
         }
         if (fmt->i_physical_channels == 0)
         {
@@ -686,195 +762,68 @@ MapOutputLayout(audio_output_t *p_aout, audio_sample_format_t *fmt,
             if (warn_configuration)
                 *warn_configuration = true;
         }
-
+        else
+        {
+            p_sys->chans_to_reorder =
+                aout_CheckChannelReorder(NULL, chans_out,
+                                         fmt->i_physical_channels,
+                                         p_sys->chan_table);
+            if (p_sys->chans_to_reorder)
+                msg_Dbg(p_aout, "channel reordering needed");
+        }
     }
 
-end:
     free(reslayout);
     aout_FormatPrepare(fmt);
 
-    msg_Dbg(p_aout, "selected %d physical channels for device output",
-            aout_FormatNbChannels(fmt));
     msg_Dbg(p_aout, "VLC will output: %s", aout_FormatPrintChannels(fmt));
 
     return VLC_SUCCESS;
 }
 
 static int
-SetupInputLayout(audio_output_t *p_aout, const audio_sample_format_t *fmt,
-                 AudioChannelLayoutTag *inlayout_tag)
+MapInputLayout(audio_output_t *p_aout, const audio_sample_format_t *fmt,
+               AudioChannelLayout **inlayoutp, size_t *inlayout_size)
 {
     struct aout_sys_common *p_sys = (struct aout_sys_common *) p_aout->sys;
-    uint32_t chans_out[AOUT_CHAN_MAX];
-
-    /* Some channel abbreviations used below:
-     * L - left
-     * R - right
-     * C - center
-     * Ls - left surround
-     * Rs - right surround
-     * Cs - center surround
-     * Rls - rear left surround
-     * Rrs - rear right surround
-     * Lw - left wide
-     * Rw - right wide
-     * Lsd - left surround direct
-     * Rsd - right surround direct
-     * Lc - left center
-     * Rc - right center
-     * Ts - top surround
-     * Vhl - vertical height left
-     * Vhc - vertical height center
-     * Vhr - vertical height right
-     * Lt - left matrix total. for matrix encoded stereo.
-     * Rt - right matrix total. for matrix encoded stereo. */
-
-    switch (aout_FormatNbChannels(fmt))
-    {
-        case 1:
-            *inlayout_tag = kAudioChannelLayoutTag_Mono;
-            break;
-        case 2:
-            *inlayout_tag = kAudioChannelLayoutTag_Stereo;
-            break;
-        case 3:
-            if (fmt->i_physical_channels & AOUT_CHAN_CENTER) /* L R C */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_7;
-            else if (fmt->i_physical_channels & AOUT_CHAN_LFE) /* L R LFE */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_4;
-            break;
-        case 4:
-            if (fmt->i_physical_channels & (AOUT_CHAN_CENTER | AOUT_CHAN_LFE)) /* L R C LFE */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_10;
-            else if (fmt->i_physical_channels & AOUT_CHANS_REAR) /* L R Ls Rs */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_3;
-            else if (fmt->i_physical_channels & AOUT_CHANS_CENTER) /* L R C Cs */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_3;
-            break;
-        case 5:
-            if (fmt->i_physical_channels & (AOUT_CHAN_CENTER)) /* L R Ls Rs C */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_19;
-            else if (fmt->i_physical_channels & (AOUT_CHAN_LFE)) /* L R Ls Rs LFE */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_18;
-            break;
-        case 6:
-            if (fmt->i_physical_channels & (AOUT_CHAN_LFE))
-            {
-                /* L R Ls Rs C LFE */
-                *inlayout_tag = kAudioChannelLayoutTag_DVD_20;
-
-                chans_out[0] = AOUT_CHAN_LEFT;
-                chans_out[1] = AOUT_CHAN_RIGHT;
-                chans_out[2] = AOUT_CHAN_REARLEFT;
-                chans_out[3] = AOUT_CHAN_REARRIGHT;
-                chans_out[4] = AOUT_CHAN_CENTER;
-                chans_out[5] = AOUT_CHAN_LFE;
-
-                p_sys->chans_to_reorder =
-                    aout_CheckChannelReorder(NULL, chans_out,
-                                             fmt->i_physical_channels,
-                                             p_sys->chan_table);
-                if (p_sys->chans_to_reorder)
-                    msg_Dbg(p_aout, "channel reordering needed for 5.1 output");
-            }
-            else
-            {
-                /* L R Ls Rs C Cs */
-                *inlayout_tag = kAudioChannelLayoutTag_AudioUnit_6_0;
-
-                chans_out[0] = AOUT_CHAN_LEFT;
-                chans_out[1] = AOUT_CHAN_RIGHT;
-                chans_out[2] = AOUT_CHAN_REARLEFT;
-                chans_out[3] = AOUT_CHAN_REARRIGHT;
-                chans_out[4] = AOUT_CHAN_CENTER;
-                chans_out[5] = AOUT_CHAN_REARCENTER;
-
-                p_sys->chans_to_reorder =
-                    aout_CheckChannelReorder(NULL, chans_out,
-                                             fmt->i_physical_channels,
-                                             p_sys->chan_table);
-                if (p_sys->chans_to_reorder)
-                    msg_Dbg(p_aout, "channel reordering needed for 6.0 output");
-            }
-            break;
-        case 7:
-            /* L R C LFE Ls Rs Cs */
-            *inlayout_tag = kAudioChannelLayoutTag_MPEG_6_1_A;
-
-            chans_out[0] = AOUT_CHAN_LEFT;
-            chans_out[1] = AOUT_CHAN_RIGHT;
-            chans_out[2] = AOUT_CHAN_CENTER;
-            chans_out[3] = AOUT_CHAN_LFE;
-            chans_out[4] = AOUT_CHAN_REARLEFT;
-            chans_out[5] = AOUT_CHAN_REARRIGHT;
-            chans_out[6] = AOUT_CHAN_REARCENTER;
+    uint32_t chans_out[AOUT_CHAN_MAX] = { 0, };
 
-            p_sys->chans_to_reorder =
-                aout_CheckChannelReorder(NULL, chans_out,
-                                         fmt->i_physical_channels,
-                                         p_sys->chan_table);
-            if (p_sys->chans_to_reorder)
-                msg_Dbg(p_aout, "channel reordering needed for 6.1 output");
+    unsigned channels = aout_FormatNbChannels(fmt);
 
-            break;
-        case 8:
-            if (fmt->i_physical_channels & (AOUT_CHAN_LFE))
-            {
-                /* L R C LFE Ls Rs Rls Rrs */
-                *inlayout_tag = kAudioChannelLayoutTag_MPEG_7_1_C;
-
-                chans_out[0] = AOUT_CHAN_LEFT;
-                chans_out[1] = AOUT_CHAN_RIGHT;
-                chans_out[2] = AOUT_CHAN_CENTER;
-                chans_out[3] = AOUT_CHAN_LFE;
-                chans_out[4] = AOUT_CHAN_MIDDLELEFT;
-                chans_out[5] = AOUT_CHAN_MIDDLERIGHT;
-                chans_out[6] = AOUT_CHAN_REARLEFT;
-                chans_out[7] = AOUT_CHAN_REARRIGHT;
-            }
-            else
-            {
-                /* Lc C Rc L R Ls Cs Rs */
-                *inlayout_tag = kAudioChannelLayoutTag_DTS_8_0_B;
-
-                chans_out[0] = AOUT_CHAN_MIDDLELEFT;
-                chans_out[1] = AOUT_CHAN_CENTER;
-                chans_out[2] = AOUT_CHAN_MIDDLERIGHT;
-                chans_out[3] = AOUT_CHAN_LEFT;
-                chans_out[4] = AOUT_CHAN_RIGHT;
-                chans_out[5] = AOUT_CHAN_REARLEFT;
-                chans_out[6] = AOUT_CHAN_REARCENTER;
-                chans_out[7] = AOUT_CHAN_REARRIGHT;
-            }
-            p_sys->chans_to_reorder =
-                aout_CheckChannelReorder(NULL, chans_out,
-                                         fmt->i_physical_channels,
-                                         p_sys->chan_table);
-            if (p_sys->chans_to_reorder)
-                msg_Dbg(p_aout, "channel reordering needed for 7.1 / 8.0 output");
-            break;
-        case 9:
-            /* Lc C Rc L R Ls Cs Rs LFE */
-            *inlayout_tag = kAudioChannelLayoutTag_DTS_8_1_B;
-            chans_out[0] = AOUT_CHAN_MIDDLELEFT;
-            chans_out[1] = AOUT_CHAN_CENTER;
-            chans_out[2] = AOUT_CHAN_MIDDLERIGHT;
-            chans_out[3] = AOUT_CHAN_LEFT;
-            chans_out[4] = AOUT_CHAN_RIGHT;
-            chans_out[5] = AOUT_CHAN_REARLEFT;
-            chans_out[6] = AOUT_CHAN_REARCENTER;
-            chans_out[7] = AOUT_CHAN_REARRIGHT;
-            chans_out[8] = AOUT_CHAN_LFE;
+    size_t size;
+    if (mul_overflow(channels, sizeof(AudioChannelDescription), &size))
+        return VLC_ENOMEM;
+    if (add_overflow(size, sizeof(AudioChannelLayout), &size))
+        return VLC_ENOMEM;
+    AudioChannelLayout *inlayout = malloc(size);
+    if (inlayout == NULL)
+        return VLC_ENOMEM;
 
-            p_sys->chans_to_reorder =
-                aout_CheckChannelReorder(NULL, chans_out,
-                                         fmt->i_physical_channels,
-                                         p_sys->chan_table);
-            if (p_sys->chans_to_reorder)
-                msg_Dbg(p_aout, "channel reordering needed for 8.1 output");
-            break;
+    *inlayoutp = inlayout;
+    *inlayout_size = size;
+    inlayout->mChannelLayoutTag = kAudioChannelLayoutTag_UseChannelDescriptions;
+    inlayout->mNumberChannelDescriptions = aout_FormatNbChannels(fmt);
+
+    bool swap_rear_surround = fmt->i_physical_channels & AOUT_CHANS_7_0;
+    if (swap_rear_surround)
+        msg_Dbg(p_aout, "swapping Surround and RearSurround channels "
+                "for 7.1 Rear Surround");
+    unsigned chan_idx = 0;
+    for (unsigned i = 0; i < AOUT_CHAN_MAX; ++i)
+    {
+        unsigned vlcchan = pi_vlc_chan_order_wg4[i];
+        if ((vlcchan & fmt->i_physical_channels) == 0)
+            continue;
+
+        inlayout->mChannelDescriptions[chan_idx].mChannelLabel =
+            VlcChanToAudioChannelLabel(vlcchan, swap_rear_surround);
+        inlayout->mChannelDescriptions[chan_idx].mChannelFlags =
+            kAudioChannelFlags_AllOff;
+        chan_idx++;
     }
 
+    msg_Dbg(p_aout, "VLC keeping the same input layout");
+
     return VLC_SUCCESS;
 }
 
@@ -884,7 +833,9 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
               bool *warn_configuration)
 {
     int ret;
-    AudioChannelLayoutTag inlayout_tag;
+    AudioChannelLayout *inlayout_buf = NULL;
+    const AudioChannelLayout *inlayout = NULL;
+    size_t inlayout_size = 0;
 
     if (warn_configuration)
         *warn_configuration = false;
@@ -895,13 +846,19 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
     {
         /* PCM */
         fmt->i_format = VLC_CODEC_FL32;
-        ret = MapOutputLayout(p_aout, fmt, outlayout, warn_configuration);
-        if (ret != VLC_SUCCESS)
-            return ret;
-
-        ret = SetupInputLayout(p_aout, fmt, &inlayout_tag);
-        if (ret != VLC_SUCCESS)
-            return ret;
+        if (outlayout != NULL)
+        {
+            ret = MapOutputLayout(p_aout, fmt, outlayout, warn_configuration);
+            if (ret != VLC_SUCCESS)
+                return ret;
+        }
+        else
+        {
+            ret = MapInputLayout(p_aout, fmt, &inlayout_buf, &inlayout_size);
+            if (ret != VLC_SUCCESS)
+                return ret;
+            inlayout = inlayout_buf;
+        }
 
         desc.mFormatFlags = kAudioFormatFlagsNativeFloatPacked;
         desc.mChannelsPerFrame = aout_FormatNbChannels(fmt);
@@ -914,7 +871,11 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
         fmt->i_bytes_per_frame = 4;
         fmt->i_frame_length = 1;
 
-        inlayout_tag = kAudioChannelLayoutTag_Stereo;
+        static const AudioChannelLayout inlayout_spdif = {
+            .mChannelLayoutTag = kAudioChannelLayoutTag_Stereo,
+        };
+        inlayout = &inlayout_spdif;
+        inlayout_size = sizeof(inlayout_spdif);
 
         desc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger |
                             kLinearPCMFormatFlagIsPacked; /* S16LE */
@@ -936,6 +897,7 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
     if (err != noErr)
     {
         ca_LogErr("failed to set stream format");
+        free(inlayout_buf);
         return VLC_EGENERIC;
     }
     msg_Dbg(p_aout, STREAM_FORMAT_MSG("Current AU format: " , desc));
@@ -947,6 +909,7 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
     if (err != noErr)
     {
         ca_LogErr("failed to set stream format");
+        free(inlayout_buf);
         return VLC_EGENERIC;
     }
 
@@ -962,21 +925,23 @@ au_Initialize(audio_output_t *p_aout, AudioUnit au, audio_sample_format_t *fmt,
     if (err != noErr)
     {
         ca_LogErr("failed to setup render callback");
+        free(inlayout_buf);
         return VLC_EGENERIC;
     }
 
-    /* Set the input_layout as the layout VLC will use to feed the AU unit.
-     * Yes, it must be the INPUT scope */
-    AudioChannelLayout inlayout = {
-        .mChannelLayoutTag = inlayout_tag,
-    };
-    err = AudioUnitSetProperty(au, kAudioUnitProperty_AudioChannelLayout,
-                               kAudioUnitScope_Input, 0, &inlayout,
-                               sizeof(inlayout));
-    if (err != noErr)
+    if (inlayout != NULL)
     {
-        ca_LogErr("failed to setup input layout");
-        return VLC_EGENERIC;
+        /* Set the input_layout as the layout VLC will use to feed the AU unit.
+         * Yes, it must be the INPUT scope */
+        err = AudioUnitSetProperty(au, kAudioUnitProperty_AudioChannelLayout,
+                                   kAudioUnitScope_Input, 0, inlayout,
+                                   inlayout_size);
+        free(inlayout_buf);
+        if (err != noErr)
+        {
+            ca_LogErr("failed to setup input layout");
+            return VLC_EGENERIC;
+        }
     }
 
     /* AU init */



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/921c47e26743bbceedf02df36a8441e6d853163a...638a07dba08b4e20c7e574288bc4bfdc770664ee

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/921c47e26743bbceedf02df36a8441e6d853163a...638a07dba08b4e20c7e574288bc4bfdc770664ee
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list