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 */
#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;
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;
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);
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) {
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);
#endif
#include <gst/gst.h>
+#include <gst/audio/audio-channels.h>
#ifdef HAVE_IOS
#include <CoreAudio/CoreAudioTypes.h>
#define AudioDeviceID gint
#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"
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
}
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;
}