osxaudio: add support for parsing more channel layouts ...
... and fallback to gst_audio_info_set_format for not yet supported layouts.
Fix audio playback on iOS 12.
Based on patch from Byron Schiel <byron@canary.is>
https://bugzilla.gnome.org/show_bug.cgi?id=796919
diff --git a/sys/osxaudio/gstosxcoreaudio.c b/sys/osxaudio/gstosxcoreaudio.c
index 5d3b882..8809cc4 100644
--- a/sys/osxaudio/gstosxcoreaudio.c
+++ b/sys/osxaudio/gstosxcoreaudio.c
@@ -340,43 +340,116 @@
g_assert (channel_mask != NULL);
g_assert (layout != NULL);
- if (layout->mChannelLayoutTag !=
+ if (layout->mChannelLayoutTag ==
kAudioChannelLayoutTag_UseChannelDescriptions) {
- GST_ERROR
- ("Only kAudioChannelLayoutTag_UseChannelDescriptions is supported.");
+
+ switch (layout->mNumberChannelDescriptions) {
+ case 0:
+ if (pos)
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_NONE;
+ *channels = 0;
+ *channel_mask = 0;
+ return TRUE;
+ case 1:
+ if (pos)
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+ *channels = 1;
+ *channel_mask = 0;
+ return TRUE;
+ case 2:
+ if (pos) {
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ }
+ *channels = 2;
+ *channel_mask =
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT);
+ return TRUE;
+ default:
+ _core_audio_parse_channel_descriptions (layout, channels, channel_mask,
+ pos);
+ return TRUE;
+ }
+ } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_Mono) {
+ if (pos)
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
+ *channels = 1;
+ *channel_mask = 0;
+ return TRUE;
+ } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_Stereo ||
+ layout->mChannelLayoutTag == kAudioChannelLayoutTag_StereoHeadphones ||
+ layout->mChannelLayoutTag == kAudioChannelLayoutTag_Binaural) {
+ if (pos) {
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ }
+ *channels = 2;
+ *channel_mask =
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT);
+ return TRUE;
+ } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_Quadraphonic) {
+ if (pos) {
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ pos[2] = GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT;
+ pos[3] = GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT;
+ }
+ *channels = 4;
+ *channel_mask =
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (SURROUND_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (SURROUND_RIGHT);
+ return TRUE;
+ } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_Pentagonal) {
+ if (pos) {
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ pos[2] = GST_AUDIO_CHANNEL_POSITION_SURROUND_LEFT;
+ pos[3] = GST_AUDIO_CHANNEL_POSITION_SURROUND_RIGHT;
+ pos[4] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
+ }
+ *channels = 5;
+ *channel_mask =
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (SURROUND_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (SURROUND_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_CENTER);
+ return TRUE;
+ } else if (layout->mChannelLayoutTag == kAudioChannelLayoutTag_Cube) {
+ if (pos) {
+ pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
+ pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
+ pos[2] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
+ pos[3] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
+ pos[4] = GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT;
+ pos[5] = GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT;
+ pos[6] = GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT;
+ pos[7] = GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT;
+
+ }
+ *channels = 8;
+ *channel_mask =
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (REAR_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (REAR_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (TOP_FRONT_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (TOP_FRONT_RIGHT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (TOP_REAR_LEFT) |
+ GST_AUDIO_CHANNEL_POSITION_MASK (TOP_REAR_RIGHT);
+ return TRUE;
+ } else {
+ GST_WARNING
+ ("AudioChannelLayoutTag: %u not yet supported",
+ layout->mChannelLayoutTag);
*channels = 0;
*channel_mask = 0;
return FALSE;
}
-
- switch (layout->mNumberChannelDescriptions) {
- case 0:
- if (pos)
- pos[0] = GST_AUDIO_CHANNEL_POSITION_NONE;
- *channels = 0;
- *channel_mask = 0;
- return TRUE;
- case 1:
- if (pos)
- pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
- *channels = 1;
- *channel_mask = 0;
- return TRUE;
- case 2:
- if (pos) {
- pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
- pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
- }
- *channels = 2;
- *channel_mask =
- GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT) |
- GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT);
- return TRUE;
- default:
- _core_audio_parse_channel_descriptions (layout, channels, channel_mask,
- pos);
- return TRUE;
- }
}
/* Converts an AudioStreamBasicDescription to preferred caps.
@@ -405,6 +478,7 @@
guint rate, channels, bps, endianness;
guint64 channel_mask;
gboolean sign, interleaved;
+ GstAudioChannelPosition pos[GST_OSX_AUDIO_MAX_CHANNEL];
if (asbd->mFormatID != kAudioFormatLinearPCM) {
GST_WARNING ("Only linear PCM is supported");
@@ -457,14 +531,15 @@
}
if (layout) {
- GstAudioChannelPosition pos[GST_OSX_AUDIO_MAX_CHANNEL];
-
if (!gst_core_audio_parse_channel_layout (layout, &channels, &channel_mask,
pos)) {
- GST_WARNING ("Failed to parse channel layout");
- goto error;
+ GST_WARNING
+ ("Failed to parse channel layout, best effort channels layout mapping will be used");
+ layout = NULL;
}
+ }
+ if (layout) {
/* The AU can have arbitrary channel order, but we're using GstAudioInfo
* which supports only the GStreamer channel order.
* Also, we're eventually producing caps, which only have channel-mask