[vlc-commits] [Git][videolan/vlc][master] 14 commits: windows_audio: more readable structs

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat Nov 5 20:07:14 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
95a53de5 by Thomas Guillem at 2022-11-05T19:47:45+00:00
windows_audio: more readable structs

No functional changes

- - - - -
b73f7c40 by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: fix original value never set

Regression from 91f426996c98

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

- - - - -
12683ccc by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: fix layout tag mismatch for L R C Cs

- - - - -
0405833c by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: refactor aout_CheckChannelReorder() usage

- - - - -
87bbf8f2 by Thomas Guillem at 2022-11-05T19:47:45+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...).

- - - - -
9d676d26 by Thomas Guillem at 2022-11-05T19:47:45+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.

- - - - -
0a65098f by Thomas Guillem at 2022-11-05T19:47:45+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 ?

- - - - -
082a0305 by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: add Lsd/Rsd mapping

Could not test it.

- - - - -
c65da638 by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: rename SetupInputLayout

- - - - -
28e4d7fe by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: MapInputLayout() can now return any type of AudioChannelLayout

- - - - -
704d6fcf by Thomas Guillem at 2022-11-05T19:47:45+00:00
coreaudio: remove useless log

There is one more complete just after.

- - - - -
3d92b1c3 by Thomas Guillem at 2022-11-05T19:47:45+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.

- - - - -
cac29a17 by Thomas Guillem at 2022-11-05T19:47:45+00:00
audiounit_ios: move debug log

- - - - -
ebc27c6e by Thomas Guillem at 2022-11-05T19:47:45+00:00
audiounit_ios: don't fetch the output layout

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

- - - - -


3 changed files:

- modules/audio_output/audiounit_ios.m
- modules/audio_output/coreaudio_common.c
- modules/demux/windows_audio_commons.h


Changes:

=====================================
modules/audio_output/audiounit_ios.m
=====================================
@@ -268,12 +268,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)
 {
     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;
@@ -296,64 +294,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;
 }
 
@@ -611,10 +556,17 @@ 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;
 
+    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);
@@ -632,7 +584,7 @@ Start(audio_output_t *p_aout, audio_sample_format_t *restrict fmt)
         vlc_tick_from_sec([p_sys->avInstance outputLatency]);
     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;
 
@@ -660,7 +612,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
=====================================
@@ -601,21 +601,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)
@@ -646,25 +711,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 =
@@ -672,11 +740,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)
         {
@@ -684,195 +760,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;
-
-            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");
-
-            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;
-
-            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;
+    uint32_t chans_out[AOUT_CHAN_MAX] = { 0, };
+
+    unsigned channels = aout_FormatNbChannels(fmt);
+
+    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;
+
+    *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;
 }
 
@@ -882,7 +831,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;
@@ -893,13 +844,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);
@@ -912,7 +869,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 */
@@ -934,6 +895,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));
@@ -945,6 +907,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;
     }
 
@@ -960,21 +923,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 */


=====================================
modules/demux/windows_audio_commons.h
=====================================
@@ -25,14 +25,21 @@
 #include <vlc_aout.h>
 #include <vlc_codecs.h>
 
-static const uint32_t pi_channels_src[] = { WAVE_SPEAKER_FRONT_LEFT,
-    WAVE_SPEAKER_FRONT_RIGHT, WAVE_SPEAKER_FRONT_CENTER,
-    WAVE_SPEAKER_LOW_FREQUENCY, WAVE_SPEAKER_BACK_LEFT, WAVE_SPEAKER_BACK_RIGHT,
-    WAVE_SPEAKER_BACK_CENTER, WAVE_SPEAKER_SIDE_LEFT, WAVE_SPEAKER_SIDE_RIGHT, 0 };
+static const uint32_t pi_channels_src[] = {
+    WAVE_SPEAKER_FRONT_LEFT, WAVE_SPEAKER_FRONT_RIGHT,
+    WAVE_SPEAKER_FRONT_CENTER, WAVE_SPEAKER_LOW_FREQUENCY,
+    WAVE_SPEAKER_BACK_LEFT, WAVE_SPEAKER_BACK_RIGHT, WAVE_SPEAKER_BACK_CENTER,
+    WAVE_SPEAKER_SIDE_LEFT, WAVE_SPEAKER_SIDE_RIGHT,
+    0
+};
 
-static const uint32_t pi_channels_aout[] = { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
-    AOUT_CHAN_CENTER, AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
-    AOUT_CHAN_REARCENTER, AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, 0 };
+static const uint32_t pi_channels_aout[] = {
+    AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
+    AOUT_CHAN_CENTER, AOUT_CHAN_LFE,
+    AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARCENTER,
+    AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
+    0
+};
 
 static inline unsigned getChannelMask( uint32_t * wvfextChannelMask, int i_channels, int * i_match )
 {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/91d69ce6dcb6fd324ac6b974b95aa5945fa4a794...ebc27c6e4053a0a6dfe42a0d0acd89e394df1d2b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/91d69ce6dcb6fd324ac6b974b95aa5945fa4a794...ebc27c6e4053a0a6dfe42a0d0acd89e394df1d2b
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