From a88eda66d29a5c630a65ac667075adbfd30cdab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Brzezi=C5=84ski?= Date: Mon, 27 Jan 2025 16:38:38 +0100 Subject: [PATCH] osxaudio: Always expose max amount of channels with no positions For outputs with a high number of channels, macOS has a bug where initially CoreAudio will report incorrect positions for all channels, but after you run Audio MIDI Setup and configure the speaker layout there, macOS will always report those few as positioned, with no option to revert that (other than deleting some internal files). In such scenario our code would just ignore all the unpositioned channels. Since you can only position max. 16 channels in macOS, if you had more on your output device, those would be unusable. This commit makes sure that in addition to the usual positioned layout (if there is one), we will expose caps for a no-positions layout that always has the maximum amount of channels available. Part-of: --- .../sys/osxaudio/gstosxcoreaudio.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c index 9504492aba..774f89a2ab 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c @@ -866,7 +866,7 @@ gst_core_audio_get_channel_layout (GstCoreAudio * core_audio, gboolean outer) GstCaps * gst_core_audio_probe_caps (GstCoreAudio * core_audio, GstCaps * in_caps) { - guint i, channels; + guint i, channels, channels_max = 0; gboolean spdif_allowed; AudioChannelLayout *layout; AudioStreamBasicDescription outer_asbd; @@ -898,6 +898,17 @@ gst_core_audio_probe_caps (GstCoreAudio * core_audio, GstCaps * in_caps) channel_mask = 0; } + if (channel_mask != 0 && channels > 2 && + layout->mChannelLayoutTag == + kAudioChannelLayoutTag_UseChannelDescriptions) { + /* CoreAudio gave us a positioned layout, which might mean we're ignoring some unpositioned channels. + * For example, with a 64ch output, macOS only allows assigning positions to 16 channels at most. + * Let's make sure we also expose the actual maximum amount of channels in our caps, + * without any positions assigned. */ + channels_max = + MIN (layout->mNumberChannelDescriptions, GST_OSX_AUDIO_MAX_CHANNEL); + } + /* If available, start with the preferred caps. */ if (got_outer_asbd) caps = gst_core_audio_asbd_to_caps (&outer_asbd, layout); @@ -982,7 +993,17 @@ gst_core_audio_probe_caps (GstCoreAudio * core_audio, GstCaps * in_caps) gst_caps_append_structure (caps, out_s); gst_caps_append_structure (caps, mono); } else { - /* Otherwise just add the caps */ + /* Otherwise, if needed, add an unpositioned max-channels variant ... */ + if (channels_max > 0) { + GstStructure *unpos_s = gst_structure_copy (in_s); + gst_structure_set (unpos_s, "channels", G_TYPE_INT, channels_max, + NULL); + gst_structure_set (unpos_s, "channel-mask", GST_TYPE_BITMASK, 0, + NULL); + gst_caps_append_structure (caps, unpos_s); + } + + /* ... and just add the caps */ gst_caps_append_structure (caps, out_s); } }