mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
osxaudiosrc: Probe channel layout too
https://bugzilla.gnome.org/show_bug.cgi?id=740987
This commit is contained in:
parent
df610a7c18
commit
4a58ebf487
6 changed files with 112 additions and 63 deletions
|
@ -618,60 +618,11 @@ gst_osx_audio_sink_probe_caps (GstOsxAudioSink * osxsink)
|
|||
channels = 2;
|
||||
}
|
||||
|
||||
switch (channels) {
|
||||
case 0:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_NONE;
|
||||
break;
|
||||
case 1:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
|
||||
break;
|
||||
case 2:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
channel_mask |= GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT);
|
||||
channel_mask |= GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT);
|
||||
break;
|
||||
default:
|
||||
channels = MIN (layout->mNumberChannelDescriptions,
|
||||
GST_OSX_AUDIO_MAX_CHANNEL);
|
||||
for (i = 0; i < channels; i++) {
|
||||
switch (layout->mChannelDescriptions[i].mChannelLabel) {
|
||||
case kAudioChannelLabel_Left:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_Right:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_Center:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
|
||||
break;
|
||||
case kAudioChannelLabel_LFEScreen:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_LFE1;
|
||||
break;
|
||||
case kAudioChannelLabel_LeftSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_RightSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_RearSurroundLeft:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_RearSurroundRight:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_CenterSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
|
||||
break;
|
||||
default:
|
||||
GST_WARNING_OBJECT (osxsink, "unrecognized channel: %d",
|
||||
(int) layout->mChannelDescriptions[i].mChannelLabel);
|
||||
channel_mask = 0;
|
||||
channels = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!gst_core_audio_parse_channel_layout (layout, channels, &channel_mask,
|
||||
pos)) {
|
||||
GST_WARNING_OBJECT (osxsink, "Failed to parse channel layout");
|
||||
}
|
||||
|
||||
g_free (layout);
|
||||
|
||||
/* Recover the template caps */
|
||||
|
|
|
@ -66,8 +66,6 @@ G_BEGIN_DECLS
|
|||
#define GST_IS_OSX_AUDIO_SINK(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSX_AUDIO_SINK))
|
||||
|
||||
#define GST_OSX_AUDIO_MAX_CHANNEL (9)
|
||||
|
||||
typedef struct _GstOsxAudioSink GstOsxAudioSink;
|
||||
typedef struct _GstOsxAudioSinkClass GstOsxAudioSinkClass;
|
||||
|
||||
|
|
|
@ -251,6 +251,8 @@ gst_osx_audio_src_probe_caps (GstOsxAudioSrc * osxsrc)
|
|||
GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SRC (osxsrc)->ringbuffer);
|
||||
GstCoreAudio *core_audio = ringbuffer->core_audio;
|
||||
GstCaps *caps;
|
||||
gint channels;
|
||||
AudioChannelLayout *layout;
|
||||
AudioStreamBasicDescription asbd_in;
|
||||
UInt32 propertySize;
|
||||
OSStatus status;
|
||||
|
@ -262,11 +264,28 @@ gst_osx_audio_src_probe_caps (GstOsxAudioSrc * osxsrc)
|
|||
if (status)
|
||||
goto fail;
|
||||
|
||||
caps = gst_core_audio_asbd_to_caps (&asbd_in);
|
||||
if (!caps)
|
||||
layout = gst_core_audio_audio_device_get_channel_layout (osxsrc->device_id,
|
||||
FALSE);
|
||||
|
||||
if (layout) {
|
||||
channels = MIN (layout->mNumberChannelDescriptions,
|
||||
GST_OSX_AUDIO_MAX_CHANNEL);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (osxsrc, "This driver does not support "
|
||||
"kAudioDevicePropertyPreferredChannelLayout.");
|
||||
channels = 2;
|
||||
}
|
||||
|
||||
caps = gst_core_audio_asbd_to_caps (&asbd_in, layout);
|
||||
if (!caps) {
|
||||
GST_WARNING_OBJECT (osxsrc, "Could not get caps from stream description");
|
||||
else
|
||||
g_free (layout);
|
||||
goto fail;
|
||||
} else {
|
||||
GST_DEBUG_OBJECT (osxsrc, "Got caps on device: %p", caps);
|
||||
}
|
||||
|
||||
g_free (layout);
|
||||
|
||||
if (osxsrc->cached_caps)
|
||||
gst_caps_unref (osxsrc->cached_caps);
|
||||
|
|
|
@ -185,12 +185,80 @@ gst_core_audio_audio_device_is_spdif_avail (AudioDeviceID device_id)
|
|||
return gst_core_audio_audio_device_is_spdif_avail_impl (device_id);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gst_core_audio_parse_channel_layout (AudioChannelLayout * layout,
|
||||
gint channels, guint64 * channel_mask, GstAudioChannelPosition * pos)
|
||||
{
|
||||
gint i;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
g_return_val_if_fail (channels <= GST_OSX_AUDIO_MAX_CHANNEL, FALSE);
|
||||
|
||||
switch (channels) {
|
||||
case 0:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_NONE;
|
||||
break;
|
||||
case 1:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_MONO;
|
||||
break;
|
||||
case 2:
|
||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
pos[1] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
*channel_mask |= GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_LEFT);
|
||||
*channel_mask |= GST_AUDIO_CHANNEL_POSITION_MASK (FRONT_RIGHT);
|
||||
break;
|
||||
default:
|
||||
for (i = 0; i < channels; i++) {
|
||||
switch (layout->mChannelDescriptions[i].mChannelLabel) {
|
||||
case kAudioChannelLabel_Left:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_Right:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_Center:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER;
|
||||
break;
|
||||
case kAudioChannelLabel_LFEScreen:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_LFE1;
|
||||
break;
|
||||
case kAudioChannelLabel_LeftSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_RightSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_RearSurroundLeft:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT;
|
||||
break;
|
||||
case kAudioChannelLabel_RearSurroundRight:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT;
|
||||
break;
|
||||
case kAudioChannelLabel_CenterSurround:
|
||||
pos[i] = GST_AUDIO_CHANNEL_POSITION_REAR_CENTER;
|
||||
break;
|
||||
default:
|
||||
GST_WARNING ("unrecognized channel: %d",
|
||||
(int) layout->mChannelDescriptions[i].mChannelLabel);
|
||||
*channel_mask = 0;
|
||||
ret = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd)
|
||||
gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd,
|
||||
AudioChannelLayout * layout)
|
||||
{
|
||||
GstAudioInfo info;
|
||||
GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
|
||||
int rate, channels, bps, endianness;
|
||||
GstAudioChannelPosition pos[64] = { GST_AUDIO_CHANNEL_POSITION_INVALID, };
|
||||
gint rate, channels, bps, endianness;
|
||||
guint64 channel_mask;
|
||||
gboolean sign, interleaved;
|
||||
|
||||
if (asbd->mFormatID != kAudioFormatLinearPCM) {
|
||||
|
@ -247,7 +315,13 @@ gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd)
|
|||
goto error;
|
||||
}
|
||||
|
||||
gst_audio_info_set_format (&info, format, rate, channels, NULL);
|
||||
if (!gst_core_audio_parse_channel_layout (layout, channels, &channel_mask,
|
||||
pos)) {
|
||||
GST_WARNING ("Failed to parse channel layout");
|
||||
goto error;
|
||||
}
|
||||
|
||||
gst_audio_info_set_format (&info, format, rate, channels, pos);
|
||||
|
||||
return gst_audio_info_to_caps (&info);
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#endif
|
||||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/audio/audio-channels.h>
|
||||
#ifdef HAVE_IOS
|
||||
#include <CoreAudio/CoreAudioTypes.h>
|
||||
#define AudioDeviceID gint
|
||||
|
@ -62,6 +63,8 @@ G_BEGIN_DECLS
|
|||
#define GST_IS_CORE_AUDIO_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CORE_AUDIO))
|
||||
|
||||
#define GST_OSX_AUDIO_MAX_CHANNEL (9)
|
||||
|
||||
#define CORE_AUDIO_FORMAT_IS_SPDIF(f) ((f).mFormat.mFormatID == 'IAC3' || (f).mFormat.mFormatID == 'iac3' || (f).mFormat.mFormatID == kAudioFormat60958AC3 || (f).mFormat.mFormatID == kAudioFormatAC3)
|
||||
|
||||
#define CORE_AUDIO_FORMAT "FormatID: %" GST_FOURCC_FORMAT " rate: %f flags: 0x%x BytesPerPacket: %u FramesPerPacket: %u BytesPerFrame: %u ChannelsPerFrame: %u BitsPerChannel: %u"
|
||||
|
@ -143,7 +146,10 @@ gboolean gst_core_audio_select_device (GstCoreAudio * cor
|
|||
|
||||
AudioChannelLayout * gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id, gboolean output);
|
||||
|
||||
GstCaps * gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd);
|
||||
gboolean gst_core_audio_parse_channel_layout (AudioChannelLayout * layout,
|
||||
gint channels, guint64 * channel_mask, GstAudioChannelPosition * pos);
|
||||
GstCaps * gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd,
|
||||
AudioChannelLayout * layout);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -100,7 +100,8 @@ gst_core_audio_initialize_impl (GstCoreAudio * core_audio,
|
|||
}
|
||||
|
||||
AudioChannelLayout *
|
||||
gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id)
|
||||
gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id,
|
||||
gboolean output)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue