mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-10 17:35:59 +00:00
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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5274>
This commit is contained in:
parent
81e3f7b4a4
commit
314d67b8cc
10 changed files with 203 additions and 146 deletions
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ struct _GstOsxAudioSink
|
|||
GstAudioBaseSink sink;
|
||||
|
||||
AudioDeviceID device_id;
|
||||
const char *unique_id;
|
||||
|
||||
AudioUnit audiounit;
|
||||
double volume;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ struct _GstOsxAudioSrc
|
|||
GstAudioBaseSrc src;
|
||||
|
||||
AudioDeviceID device_id;
|
||||
const char *unique_id;
|
||||
};
|
||||
|
||||
struct _GstOsxAudioSrcClass
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#include "gstosxcoreaudio.h"
|
||||
#include "gstosxcoreaudiocommon.h"
|
||||
#include <CoreAudio/CoreAudio.h>
|
||||
|
||||
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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue