From 4a58ebf487faee3e7295ba0ef60156146476a316 Mon Sep 17 00:00:00 2001 From: Arun Raghavan Date: Mon, 1 Dec 2014 21:06:27 +0530 Subject: [PATCH] osxaudiosrc: Probe channel layout too https://bugzilla.gnome.org/show_bug.cgi?id=740987 --- sys/osxaudio/gstosxaudiosink.c | 57 ++---------------------- sys/osxaudio/gstosxaudiosink.h | 2 - sys/osxaudio/gstosxaudiosrc.c | 25 +++++++++-- sys/osxaudio/gstosxcoreaudio.c | 80 ++++++++++++++++++++++++++++++++-- sys/osxaudio/gstosxcoreaudio.h | 8 +++- sys/osxaudio/gstosxcoreaudioremoteio.c | 3 +- 6 files changed, 112 insertions(+), 63 deletions(-) diff --git a/sys/osxaudio/gstosxaudiosink.c b/sys/osxaudio/gstosxaudiosink.c index 5ab648a..fd8be0c 100644 --- a/sys/osxaudio/gstosxaudiosink.c +++ b/sys/osxaudio/gstosxaudiosink.c @@ -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 */ diff --git a/sys/osxaudio/gstosxaudiosink.h b/sys/osxaudio/gstosxaudiosink.h index 84949b7..01d9966 100644 --- a/sys/osxaudio/gstosxaudiosink.h +++ b/sys/osxaudio/gstosxaudiosink.h @@ -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; diff --git a/sys/osxaudio/gstosxaudiosrc.c b/sys/osxaudio/gstosxaudiosrc.c index a32ccca..99f48b8 100644 --- a/sys/osxaudio/gstosxaudiosrc.c +++ b/sys/osxaudio/gstosxaudiosrc.c @@ -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); diff --git a/sys/osxaudio/gstosxcoreaudio.c b/sys/osxaudio/gstosxcoreaudio.c index d99ff29..c2dcd17 100644 --- a/sys/osxaudio/gstosxcoreaudio.c +++ b/sys/osxaudio/gstosxcoreaudio.c @@ -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); diff --git a/sys/osxaudio/gstosxcoreaudio.h b/sys/osxaudio/gstosxcoreaudio.h index 39670f4..a9d701c 100644 --- a/sys/osxaudio/gstosxcoreaudio.h +++ b/sys/osxaudio/gstosxcoreaudio.h @@ -27,6 +27,7 @@ #endif #include +#include #ifdef HAVE_IOS #include #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 diff --git a/sys/osxaudio/gstosxcoreaudioremoteio.c b/sys/osxaudio/gstosxcoreaudioremoteio.c index 238617b..1d3c843 100644 --- a/sys/osxaudio/gstosxcoreaudioremoteio.c +++ b/sys/osxaudio/gstosxcoreaudioremoteio.c @@ -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; } -- 2.7.4