mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-08 23:42:28 +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;
|
channels = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (channels) {
|
if (!gst_core_audio_parse_channel_layout (layout, channels, &channel_mask,
|
||||||
case 0:
|
pos)) {
|
||||||
pos[0] = GST_AUDIO_CHANNEL_POSITION_NONE;
|
GST_WARNING_OBJECT (osxsink, "Failed to parse channel layout");
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (layout);
|
g_free (layout);
|
||||||
|
|
||||||
/* Recover the template caps */
|
/* Recover the template caps */
|
||||||
|
|
|
@ -66,8 +66,6 @@ G_BEGIN_DECLS
|
||||||
#define GST_IS_OSX_AUDIO_SINK(obj) \
|
#define GST_IS_OSX_AUDIO_SINK(obj) \
|
||||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSX_AUDIO_SINK))
|
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OSX_AUDIO_SINK))
|
||||||
|
|
||||||
#define GST_OSX_AUDIO_MAX_CHANNEL (9)
|
|
||||||
|
|
||||||
typedef struct _GstOsxAudioSink GstOsxAudioSink;
|
typedef struct _GstOsxAudioSink GstOsxAudioSink;
|
||||||
typedef struct _GstOsxAudioSinkClass GstOsxAudioSinkClass;
|
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);
|
GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SRC (osxsrc)->ringbuffer);
|
||||||
GstCoreAudio *core_audio = ringbuffer->core_audio;
|
GstCoreAudio *core_audio = ringbuffer->core_audio;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
|
gint channels;
|
||||||
|
AudioChannelLayout *layout;
|
||||||
AudioStreamBasicDescription asbd_in;
|
AudioStreamBasicDescription asbd_in;
|
||||||
UInt32 propertySize;
|
UInt32 propertySize;
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
@ -262,11 +264,28 @@ gst_osx_audio_src_probe_caps (GstOsxAudioSrc * osxsrc)
|
||||||
if (status)
|
if (status)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
caps = gst_core_audio_asbd_to_caps (&asbd_in);
|
layout = gst_core_audio_audio_device_get_channel_layout (osxsrc->device_id,
|
||||||
if (!caps)
|
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");
|
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);
|
GST_DEBUG_OBJECT (osxsrc, "Got caps on device: %p", caps);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (layout);
|
||||||
|
|
||||||
if (osxsrc->cached_caps)
|
if (osxsrc->cached_caps)
|
||||||
gst_caps_unref (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);
|
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 *
|
GstCaps *
|
||||||
gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd)
|
gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd,
|
||||||
|
AudioChannelLayout * layout)
|
||||||
{
|
{
|
||||||
GstAudioInfo info;
|
GstAudioInfo info;
|
||||||
GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
|
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;
|
gboolean sign, interleaved;
|
||||||
|
|
||||||
if (asbd->mFormatID != kAudioFormatLinearPCM) {
|
if (asbd->mFormatID != kAudioFormatLinearPCM) {
|
||||||
|
@ -247,7 +315,13 @@ gst_core_audio_asbd_to_caps (AudioStreamBasicDescription * asbd)
|
||||||
goto error;
|
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);
|
return gst_audio_info_to_caps (&info);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/audio/audio-channels.h>
|
||||||
#ifdef HAVE_IOS
|
#ifdef HAVE_IOS
|
||||||
#include <CoreAudio/CoreAudioTypes.h>
|
#include <CoreAudio/CoreAudioTypes.h>
|
||||||
#define AudioDeviceID gint
|
#define AudioDeviceID gint
|
||||||
|
@ -62,6 +63,8 @@ G_BEGIN_DECLS
|
||||||
#define GST_IS_CORE_AUDIO_CLASS(klass) \
|
#define GST_IS_CORE_AUDIO_CLASS(klass) \
|
||||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CORE_AUDIO))
|
(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_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"
|
#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);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,8 @@ gst_core_audio_initialize_impl (GstCoreAudio * core_audio,
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioChannelLayout *
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue