From 314d67b8ccbd46827dedf34885f1befd57bb8450 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Wed, 31 Jul 2024 00:09:21 +0530 Subject: [PATCH] osxaudio: Implement unique-id property on elements The actual value is stored on GstCoreAudio now, which involved a lot of moving code around due to the strange layering in the plugin. Part-of: --- .../sys/osxaudio/gstosxaudiodeviceprovider.c | 153 +++++------------- .../sys/osxaudio/gstosxaudioringbuffer.c | 1 - .../sys/osxaudio/gstosxaudiosink.c | 26 +-- .../sys/osxaudio/gstosxaudiosink.h | 1 + .../sys/osxaudio/gstosxaudiosrc.c | 27 ++-- .../sys/osxaudio/gstosxaudiosrc.h | 1 + .../sys/osxaudio/gstosxcoreaudio.c | 86 ++++++++-- .../sys/osxaudio/gstosxcoreaudio.h | 3 +- .../sys/osxaudio/gstosxcoreaudiocommon.c | 48 ++++++ .../sys/osxaudio/gstosxcoreaudiocommon.h | 3 + 10 files changed, 203 insertions(+), 146 deletions(-) diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiodeviceprovider.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiodeviceprovider.c index 363f461b83..aab3ab952b 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiodeviceprovider.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiodeviceprovider.c @@ -93,15 +93,19 @@ gst_osx_audio_device_provider_init (GstOsxAudioDeviceProvider * provider) static GstOsxAudioDevice * gst_osx_audio_device_provider_probe_device (GstOsxAudioDeviceProvider * provider, AudioDeviceID device_id, const gchar * device_name, - GstOsxAudioDeviceType type, gboolean is_default) + GstOsxAudioDeviceType type) { GstOsxAudioDevice *device = NULL; GstCoreAudio *core_audio; + gboolean is_src = type == GST_OSX_AUDIO_DEVICE_TYPE_SOURCE ? TRUE : FALSE; - core_audio = gst_core_audio_new (NULL); - core_audio->is_src = type == GST_OSX_AUDIO_DEVICE_TYPE_SOURCE ? TRUE : FALSE; - core_audio->device_id = device_id; - core_audio->is_default = is_default; + core_audio = g_object_new (GST_TYPE_CORE_AUDIO, + "is-src", is_src, "device", device_id, NULL); + + if (!gst_core_audio_select_device (core_audio)) { + GST_ERROR ("CoreAudio device coult not be selected"); + goto done; + } if (!gst_core_audio_open (core_audio)) { GST_ERROR ("CoreAudio device could not be opened"); @@ -118,69 +122,6 @@ done: return device; } -static inline gchar * -_audio_device_get_cfstring_prop (AudioDeviceID device_id, gboolean output, - AudioObjectPropertyElement prop_id) -{ - OSStatus status = noErr; - UInt32 propertySize = 0; - CFStringRef prop_val; - gchar *result = NULL; - - AudioObjectPropertyAddress propAddress = { - prop_id, - kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMain - }; - - propAddress.mScope = output ? kAudioDevicePropertyScopeOutput : - kAudioDevicePropertyScopeInput; - - /* Get the length of the device name */ - status = AudioObjectGetPropertyDataSize (device_id, - &propAddress, 0, NULL, &propertySize); - if (status != noErr) { - goto beach; - } - - /* Get the requested property */ - status = AudioObjectGetPropertyData (device_id, - &propAddress, 0, NULL, &propertySize, &prop_val); - if (status != noErr) { - goto beach; - } - - /* Convert to UTF-8 C String */ - CFIndex prop_len = CFStringGetLength (prop_val); - CFIndex max_size = - CFStringGetMaximumSizeForEncoding (prop_len, kCFStringEncodingUTF8) + 1; - result = g_malloc (max_size); - - if (!CFStringGetCString (prop_val, result, max_size, kCFStringEncodingUTF8)) { - g_free (result); - result = NULL; - } - - CFRelease (prop_val); - -beach: - return result; -} - -static inline gchar * -_audio_device_get_name (AudioDeviceID device_id, gboolean output) -{ - return _audio_device_get_cfstring_prop (device_id, output, - kAudioObjectPropertyName); -} - -static inline gchar * -_audio_device_get_uid (AudioDeviceID device_id, gboolean output) -{ - return _audio_device_get_cfstring_prop (device_id, output, - kAudioDevicePropertyDeviceUID); -} - static inline gboolean _audio_device_has_output (AudioDeviceID device_id) { @@ -361,53 +302,42 @@ _stop_audio_device_watcher (GstOsxAudioDeviceProvider * self) static void gst_osx_audio_device_provider_probe_internal (GstOsxAudioDeviceProvider * self, - gboolean is_src, AudioDeviceID * osx_devices, gint ndevices, - GList ** devices) + AudioDeviceID * osx_devices, gint ndevices, GList ** devices) { - gint i = 0; - GstOsxAudioDeviceType type = GST_OSX_AUDIO_DEVICE_TYPE_INVALID; - GstOsxAudioDevice *device = NULL; + for (int i = 0; i < ndevices; i++) { + char *device_name; + GstOsxAudioDevice *device; - if (is_src) { - type = GST_OSX_AUDIO_DEVICE_TYPE_SOURCE; - } else { - type = GST_OSX_AUDIO_DEVICE_TYPE_SINK; - } - - AudioDeviceID default_device = _audio_system_get_default_device (!is_src); - - for (i = 0; i < ndevices; i++) { - gchar *device_name; - - if ((device_name = _audio_device_get_name (osx_devices[i], FALSE))) { - gboolean has_output = _audio_device_has_output (osx_devices[i]); - gboolean has_input = _audio_device_has_input (osx_devices[i]); - gboolean is_default = (default_device == osx_devices[i]); - - if (is_src && !has_input) { - goto cleanup; - } else if (!is_src && !has_output) { - goto cleanup; - } + device_name = gst_core_audio_device_get_prop (osx_devices[i], + kAudioObjectPropertyName); + if (!device_name) + continue; + if (_audio_device_has_input (osx_devices[i])) { device = gst_osx_audio_device_provider_probe_device (self, osx_devices[i], - device_name, type, is_default); + device_name, GST_OSX_AUDIO_DEVICE_TYPE_SOURCE); if (device) { - if (is_src) { - GST_DEBUG ("Input Device ID: %u Name: %s", - (unsigned) osx_devices[i], device_name); - } else { - GST_DEBUG ("Output Device ID: %u Name: %s", - (unsigned) osx_devices[i], device_name); - } + GST_DEBUG ("Input Device ID: %u Name: %s", (unsigned) osx_devices[i], + device_name); gst_object_ref_sink (device); *devices = g_list_prepend (*devices, device); } - - cleanup: - g_free (device_name); } + + if (_audio_device_has_output (osx_devices[i])) { + device = + gst_osx_audio_device_provider_probe_device (self, osx_devices[i], + device_name, GST_OSX_AUDIO_DEVICE_TYPE_SINK); + if (device) { + GST_DEBUG ("Output Device ID: %u Name: %s", (unsigned) osx_devices[i], + device_name); + gst_object_ref_sink (device); + *devices = g_list_prepend (*devices, device); + } + } + + g_free (device_name); } } @@ -428,10 +358,8 @@ gst_osx_audio_device_provider_probe (GstDeviceProvider * provider) GST_INFO ("found %d audio device(s)", ndevices); - gst_osx_audio_device_provider_probe_internal (self, TRUE, osx_devices, - ndevices, &devices); - gst_osx_audio_device_provider_probe_internal (self, FALSE, osx_devices, - ndevices, &devices); + gst_osx_audio_device_provider_probe_internal (self, osx_devices, ndevices, + &devices); done: g_free (osx_devices); @@ -618,10 +546,9 @@ gst_osx_audio_device_new (AudioDeviceID device_id, const gchar * device_name, gst_structure_set (props, "is-default", G_TYPE_BOOLEAN, core_audio->is_default, NULL); - gchar *uid = _audio_device_get_uid (device_id, !core_audio->is_src); - if (uid != NULL) { - gst_structure_set (props, "unique-id", G_TYPE_STRING, uid, NULL); - g_free (uid); + if (core_audio->unique_id != NULL) { + gst_structure_set (props, "unique-id", G_TYPE_STRING, + core_audio->unique_id, NULL); } switch (type) { diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c index 5a8e58214d..9f08126366 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudioringbuffer.c @@ -121,7 +121,6 @@ gst_osx_audio_ring_buffer_class_init (GstOsxAudioRingBufferClass * klass) static void gst_osx_audio_ring_buffer_init (GstOsxAudioRingBuffer * ringbuffer) { - ringbuffer->core_audio = gst_core_audio_new (GST_OBJECT (ringbuffer)); } static void diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.c index 4b48e0dd59..51566dc620 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.c @@ -88,7 +88,8 @@ enum { ARG_0, ARG_DEVICE, - ARG_VOLUME + ARG_VOLUME, + ARG_UNIQUE_ID }; #define DEFAULT_VOLUME 1.0 @@ -176,6 +177,14 @@ gst_osx_audio_sink_class_init (GstOsxAudioSinkClass * klass) g_object_class_install_property (gobject_class, ARG_DEVICE, g_param_spec_int ("device", "Device ID", "Device ID of output device", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + + /* + * Since: 1.26 + */ + g_object_class_install_property (gobject_class, ARG_UNIQUE_ID, + g_param_spec_string ("unique-id", "Unique ID", + "Unique persistent ID for the input device", + NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); #endif gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_osx_audio_sink_query); @@ -257,6 +266,7 @@ gst_osx_audio_sink_change_state (GstElement * element, GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SINK (osxsink)->ringbuffer); if (ringbuffer->core_audio->device_id != osxsink->device_id) { osxsink->device_id = ringbuffer->core_audio->device_id; + osxsink->unique_id = ringbuffer->core_audio->unique_id; g_object_notify (G_OBJECT (osxsink), "device"); } break; @@ -279,6 +289,9 @@ gst_osx_audio_sink_get_property (GObject * object, guint prop_id, case ARG_DEVICE: g_value_set_int (value, sink->device_id); break; + case ARG_UNIQUE_ID: + g_value_set_string (value, sink->unique_id); + break; #endif case ARG_VOLUME: g_value_set_double (value, sink->volume); @@ -493,16 +506,11 @@ gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink) GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink), (void *) gst_osx_audio_sink_io_proc); + ringbuffer->core_audio = g_object_new (GST_TYPE_CORE_AUDIO, + "is-src", FALSE, "device", osxsink->device_id, NULL); + ringbuffer->core_audio->osxbuf = GST_OBJECT (ringbuffer); ringbuffer->core_audio->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink); - ringbuffer->core_audio->is_src = FALSE; - - /* By default the coreaudio instance created by the ringbuffer - * has device_id==kAudioDeviceUnknown. The user might have - * selected a different one here - */ - if (ringbuffer->core_audio->device_id != osxsink->device_id) - ringbuffer->core_audio->device_id = osxsink->device_id; return GST_AUDIO_RING_BUFFER (ringbuffer); } diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.h b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.h index a15b0ec3c3..236dfb02a9 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.h +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosink.h @@ -82,6 +82,7 @@ struct _GstOsxAudioSink GstAudioBaseSink sink; AudioDeviceID device_id; + const char *unique_id; AudioUnit audiounit; double volume; diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.c index 75793bb692..066341efb6 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.c @@ -76,7 +76,8 @@ enum enum { ARG_0, - ARG_DEVICE + ARG_DEVICE, + ARG_UNIQUE_ID, }; static GstStaticPadTemplate src_factory = GST_STATIC_PAD_TEMPLATE ("src", @@ -151,6 +152,14 @@ gst_osx_audio_src_class_init (GstOsxAudioSrcClass * klass) g_param_spec_int ("device", "Device ID", "Device ID of input device", 0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); + /* + * Since: 1.26 + */ + g_object_class_install_property (gobject_class, ARG_UNIQUE_ID, + g_param_spec_string ("unique-id", "Unique ID", + "Unique persistent ID for the input device", + NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + gstaudiobasesrc_class->create_ringbuffer = GST_DEBUG_FUNCPTR (gst_osx_audio_src_create_ringbuffer); @@ -168,6 +177,7 @@ gst_osx_audio_src_init (GstOsxAudioSrc * src) gst_base_src_set_live (GST_BASE_SRC (src), TRUE); src->device_id = kAudioDeviceUnknown; + src->unique_id = NULL; } static void @@ -196,6 +206,9 @@ gst_osx_audio_src_get_property (GObject * object, guint prop_id, case ARG_DEVICE: g_value_set_int (value, src->device_id); break; + case ARG_UNIQUE_ID: + g_value_set_string (value, src->unique_id); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -225,6 +238,7 @@ gst_osx_audio_src_change_state (GstElement * element, GstStateChange transition) GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SRC (osxsrc)->ringbuffer); if (ringbuffer->core_audio->device_id != osxsrc->device_id) { osxsrc->device_id = ringbuffer->core_audio->device_id; + osxsrc->unique_id = ringbuffer->core_audio->unique_id; g_object_notify (G_OBJECT (osxsrc), "device"); } break; @@ -314,16 +328,11 @@ gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc * src) GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc), (void *) gst_osx_audio_src_io_proc); + ringbuffer->core_audio = g_object_new (GST_TYPE_CORE_AUDIO, + "is-src", TRUE, "device", osxsrc->device_id, NULL); + ringbuffer->core_audio->osxbuf = GST_OBJECT (ringbuffer); ringbuffer->core_audio->element = GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc); - ringbuffer->core_audio->is_src = TRUE; - - /* By default the coreaudio instance created by the ringbuffer - * has device_id==kAudioDeviceUnknown. The user might have - * selected a different one here - */ - if (ringbuffer->core_audio->device_id != osxsrc->device_id) - ringbuffer->core_audio->device_id = osxsrc->device_id; return GST_AUDIO_RING_BUFFER (ringbuffer); } diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.h b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.h index 980cf91722..7b495c3082 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.h +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxaudiosrc.h @@ -73,6 +73,7 @@ struct _GstOsxAudioSrc GstAudioBaseSrc src; AudioDeviceID device_id; + const char *unique_id; }; struct _GstOsxAudioSrcClass diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c index 3d6a88a63b..6246754ec2 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.c @@ -23,6 +23,7 @@ #include "gstosxcoreaudio.h" #include "gstosxcoreaudiocommon.h" +#include GST_DEBUG_CATEGORY (osx_coreaudio_debug); #define GST_CAT_DEFAULT osx_coreaudio_debug @@ -35,11 +36,24 @@ G_DEFINE_TYPE (GstCoreAudio, gst_core_audio, G_TYPE_OBJECT); #include "gstosxcoreaudiohal.c" #endif +enum +{ + PROP_0, + PROP_DEVICE, + PROP_IS_SRC, +}; + +static void gst_core_audio_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec); +static void gst_core_audio_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec); + static void gst_core_audio_finalize (GObject * object) { GstCoreAudio *core_audio = GST_CORE_AUDIO (object); g_mutex_clear (&core_audio->timing_lock); + g_free (core_audio->unique_id); G_OBJECT_CLASS (gst_core_audio_parent_class)->finalize (object); } @@ -49,6 +63,19 @@ gst_core_audio_class_init (GstCoreAudioClass * klass) { GObjectClass *object_klass = G_OBJECT_CLASS (klass); object_klass->finalize = gst_core_audio_finalize; + + object_klass->set_property = gst_core_audio_set_property; + object_klass->get_property = gst_core_audio_get_property; + + g_object_class_install_property (object_klass, PROP_DEVICE, + g_param_spec_int ("device", "Device ID", "Device ID of input device", + 0, G_MAXINT, 0, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property (object_klass, PROP_IS_SRC, + g_param_spec_boolean ("is-src", "Is source", "Is a source device", + FALSE, + G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } static void @@ -56,6 +83,7 @@ gst_core_audio_init (GstCoreAudio * core_audio) { core_audio->is_passthrough = FALSE; core_audio->device_id = kAudioDeviceUnknown; + core_audio->unique_id = NULL; core_audio->is_src = FALSE; core_audio->audiounit = NULL; core_audio->cached_caps = NULL; @@ -69,6 +97,44 @@ gst_core_audio_init (GstCoreAudio * core_audio) g_mutex_init (&core_audio->timing_lock); } +static void +gst_core_audio_set_property (GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec) +{ + GstCoreAudio *self = GST_CORE_AUDIO (object); + + switch (prop_id) { + case PROP_IS_SRC: + self->is_src = g_value_get_boolean (value); + break; + case PROP_DEVICE: + self->device_id = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_core_audio_get_property (GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec) +{ + GstCoreAudio *self = GST_CORE_AUDIO (object); + + switch (prop_id) { + case PROP_IS_SRC: + g_value_set_boolean (value, self->is_src); + break; + case PROP_DEVICE: + g_value_set_int (value, self->device_id); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static gboolean _is_outer_scope (AudioUnitScope scope, AudioUnitElement element) { @@ -128,17 +194,6 @@ _host_time_to_ns (GstCoreAudio * core_audio, uint64_t host_time) * Public API * *************************/ -GstCoreAudio * -gst_core_audio_new (GstObject * osxbuf) -{ - GstCoreAudio *core_audio; - - core_audio = g_object_new (GST_TYPE_CORE_AUDIO, NULL); - core_audio->osxbuf = osxbuf; - core_audio->cached_caps = NULL; - return core_audio; -} - gboolean gst_core_audio_close (GstCoreAudio * core_audio) { @@ -368,7 +423,14 @@ gst_core_audio_set_volume (GstCoreAudio * core_audio, gfloat volume) gboolean gst_core_audio_select_device (GstCoreAudio * core_audio) { - return gst_core_audio_select_device_impl (core_audio); + gboolean ret = gst_core_audio_select_device_impl (core_audio); + + if (core_audio->device_id != kAudioDeviceUnknown) + core_audio->unique_id = + gst_core_audio_device_get_prop (core_audio->device_id, + kAudioDevicePropertyDeviceUID); + + return ret; } void diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h index 0795c6262d..2c6b43d1d1 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudio.h @@ -91,6 +91,7 @@ struct _GstCoreAudio gboolean is_src; gboolean is_passthrough; AudioDeviceID device_id; + char *unique_id; gboolean is_default; gboolean cached_caps_valid; /* thread-safe flag */ GstCaps *cached_caps; @@ -129,8 +130,6 @@ GType gst_core_audio_get_type (void); void gst_core_audio_init_debug (void); -GstCoreAudio * gst_core_audio_new (GstObject *osxbuf); - gboolean gst_core_audio_open (GstCoreAudio *core_audio); gboolean gst_core_audio_close (GstCoreAudio *core_audio); diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.c b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.c index b3c77a7cd1..b34c12fae5 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.c +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.c @@ -559,3 +559,51 @@ gst_core_audio_dump_channel_layout (AudioChannelLayout * channel_layout) channel_desc->mCoordinates[2]); } } + +char * +gst_core_audio_device_get_prop (AudioDeviceID device_id, + AudioObjectPropertyElement prop_id) +{ + OSStatus status = noErr; + UInt32 propertySize = 0; + CFStringRef prop_val; + gchar *result = NULL; + + AudioObjectPropertyAddress propAddress = { + prop_id, + kAudioDevicePropertyScopeOutput, + kAudioObjectPropertyElementMain + }; + + propAddress.mScope = kAudioObjectPropertyScopeGlobal; + + /* Get the length of the device name */ + status = AudioObjectGetPropertyDataSize (device_id, + &propAddress, 0, NULL, &propertySize); + if (status != noErr) { + goto beach; + } + + /* Get the requested property */ + status = AudioObjectGetPropertyData (device_id, + &propAddress, 0, NULL, &propertySize, &prop_val); + if (status != noErr) { + goto beach; + } + + /* Convert to UTF-8 C String */ + CFIndex prop_len = CFStringGetLength (prop_val); + CFIndex max_size = + CFStringGetMaximumSizeForEncoding (prop_len, kCFStringEncodingUTF8) + 1; + result = g_malloc (max_size); + + if (!CFStringGetCString (prop_val, result, max_size, kCFStringEncodingUTF8)) { + g_free (result); + result = NULL; + } + + CFRelease (prop_val); + +beach: + return result; +} diff --git a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.h b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.h index f97b7cd352..e8c0f8e80d 100644 --- a/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.h +++ b/subprojects/gst-plugins-good/sys/osxaudio/gstosxcoreaudiocommon.h @@ -69,4 +69,7 @@ AudioChannelLabel gst_audio_channel_position_to_core_audio (GstAudioChannelPosit GstAudioChannelPosition gst_core_audio_channel_label_to_gst (AudioChannelLabel label, int channel, gboolean warn); +char * gst_core_audio_device_get_prop (AudioDeviceID device_id, + AudioObjectPropertyElement prop_id); + G_END_DECLS