mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-13 07:02:53 +00:00
osxaudio: Work around invalid channel positions from CoreAudio
By default, for devices with larger amounts of outputs, CoreAudio can provide invalid channel labels/positions, simply by starting at 0 and incrementing forward. For example, values 19 through 32 are not valid according to the CoreAudioBaseTypes.h header, but if your device has >19 output channels, you will find CoreAudio using those values. This is most likely a bug in CoreAudio, since in that case it should use unpositioned labels (e.g. _Discrete_X) instead. This commit aims to work around this by overriding all channels to be unpositioned if the case above is detected. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8311>
This commit is contained in:
parent
83e95af6e3
commit
c5c5327df6
1 changed files with 41 additions and 0 deletions
|
@ -492,6 +492,29 @@ _is_core_audio_layout_positioned (AudioChannelLayout * layout)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_core_audio_has_invalid_channel_labels (AudioChannelLayout * layout)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_assert (layout->mChannelLayoutTag ==
|
||||
kAudioChannelLayoutTag_UseChannelDescriptions);
|
||||
|
||||
for (i = 0; i < layout->mNumberChannelDescriptions; ++i) {
|
||||
/* Let's use our mapping to judge whether the value is valid.
|
||||
* It doesn't support all of the defined positions, but the missing ones
|
||||
* aren't useful to us anyway. */
|
||||
GstAudioChannelPosition p =
|
||||
gst_core_audio_channel_label_to_gst
|
||||
(layout->mChannelDescriptions[i].mChannelLabel, i, FALSE);
|
||||
|
||||
if (p == GST_AUDIO_CHANNEL_POSITION_INVALID)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_core_audio_parse_channel_descriptions (AudioChannelLayout * layout,
|
||||
guint * channels, guint64 * channel_mask, GstAudioChannelPosition * pos)
|
||||
|
@ -502,6 +525,24 @@ _core_audio_parse_channel_descriptions (AudioChannelLayout * layout,
|
|||
g_assert (layout->mChannelLayoutTag ==
|
||||
kAudioChannelLayoutTag_UseChannelDescriptions);
|
||||
|
||||
/* For >16ch devices, CoreAudio can give out completely incorrect
|
||||
* channel positions by default - instead of using kAudioChannelLabel_Discrete_X,
|
||||
* it just returns incrementing values starting from 0, some of which are not
|
||||
* valid if you check against the CoreAudioBaseTypes.h header.
|
||||
* If such case is detected, let's just swap all positions to Discrete,
|
||||
* which map to GST_AUDIO_CHANNEL_POSITION_NONE. */
|
||||
if (_core_audio_has_invalid_channel_labels (layout)) {
|
||||
GST_DEBUG
|
||||
("Invalid channel positions given by CoreAudio, setting all to unpositioned");
|
||||
if (pos) {
|
||||
for (i = 0; i < layout->mNumberChannelDescriptions; ++i)
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_NONE;
|
||||
}
|
||||
*channels = layout->mNumberChannelDescriptions;
|
||||
*channel_mask = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
positioned = _is_core_audio_layout_positioned (layout);
|
||||
*channel_mask = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue