mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
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
This commit is contained in:
parent
bc0ea0dbbb
commit
3573f71c91
1 changed files with 111 additions and 36 deletions
|
@ -340,43 +340,116 @@ gst_core_audio_parse_channel_layout (AudioChannelLayout * layout,
|
|||
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 @@ gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd,
|
|||
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 @@ gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd,
|
|||
}
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue