mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-03-30 20:59:44 +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;
|
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
|
static void
|
||||||
_core_audio_parse_channel_descriptions (AudioChannelLayout * layout,
|
_core_audio_parse_channel_descriptions (AudioChannelLayout * layout,
|
||||||
guint * channels, guint64 * channel_mask, GstAudioChannelPosition * pos)
|
guint * channels, guint64 * channel_mask, GstAudioChannelPosition * pos)
|
||||||
|
@ -502,6 +525,24 @@ _core_audio_parse_channel_descriptions (AudioChannelLayout * layout,
|
||||||
g_assert (layout->mChannelLayoutTag ==
|
g_assert (layout->mChannelLayoutTag ==
|
||||||
kAudioChannelLayoutTag_UseChannelDescriptions);
|
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);
|
positioned = _is_core_audio_layout_positioned (layout);
|
||||||
*channel_mask = 0;
|
*channel_mask = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue