mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
osxaudio: Clean up a GstCoreAudio -> GstOsxAudioSrc/Sink reference
Now that device selection has no sink/source-specific bits, we can have generic device selection for this path. We do need to now track state changes so we can look up the final device_id once the device is open, though. https://bugzilla.gnome.org/show_bug.cgi?id=740987
This commit is contained in:
parent
5c2f041286
commit
ffcb1577fa
8 changed files with 112 additions and 53 deletions
|
@ -149,9 +149,8 @@ static gboolean
|
||||||
gst_osx_audio_ring_buffer_open_device (GstAudioRingBuffer * buf)
|
gst_osx_audio_ring_buffer_open_device (GstAudioRingBuffer * buf)
|
||||||
{
|
{
|
||||||
GstOsxAudioRingBuffer *osxbuf = GST_OSX_AUDIO_RING_BUFFER (buf);;
|
GstOsxAudioRingBuffer *osxbuf = GST_OSX_AUDIO_RING_BUFFER (buf);;
|
||||||
GstElement *parent = GST_ELEMENT_CAST (GST_OBJECT_PARENT (buf));
|
|
||||||
|
|
||||||
if (!osxbuf->select_device (parent, osxbuf))
|
if (!gst_core_audio_select_device (osxbuf->core_audio))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return gst_core_audio_open (osxbuf->core_audio);
|
return gst_core_audio_open (osxbuf->core_audio);
|
||||||
|
|
|
@ -81,9 +81,6 @@ struct _GstOsxAudioRingBuffer
|
||||||
|
|
||||||
GstCoreAudio *core_audio;
|
GstCoreAudio *core_audio;
|
||||||
|
|
||||||
/* Set by the parent to select the required device */
|
|
||||||
gboolean (*select_device) (GstElement * element, GstOsxAudioRingBuffer * buf);
|
|
||||||
|
|
||||||
guint buffer_len;
|
guint buffer_len;
|
||||||
guint segoffset;
|
guint segoffset;
|
||||||
};
|
};
|
||||||
|
|
|
@ -116,6 +116,10 @@ static void gst_osx_audio_sink_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
|
static void gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
static GstStateChangeReturn
|
||||||
|
gst_osx_audio_sink_change_state (GstElement * element,
|
||||||
|
GstStateChange transition);
|
||||||
|
|
||||||
static gboolean gst_osx_audio_sink_query (GstBaseSink * base, GstQuery * query);
|
static gboolean gst_osx_audio_sink_query (GstBaseSink * base, GstQuery * query);
|
||||||
|
|
||||||
static gboolean gst_osx_audio_sink_stop (GstBaseSink * base);
|
static gboolean gst_osx_audio_sink_stop (GstBaseSink * base);
|
||||||
|
@ -130,8 +134,6 @@ static GstAudioRingBuffer
|
||||||
* gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink);
|
* gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink);
|
||||||
static void gst_osx_audio_sink_osxelement_init (gpointer g_iface,
|
static void gst_osx_audio_sink_osxelement_init (gpointer g_iface,
|
||||||
gpointer iface_data);
|
gpointer iface_data);
|
||||||
static gboolean gst_osx_audio_sink_select_device (GstElement * sink,
|
|
||||||
GstOsxAudioRingBuffer * ringbuffer);
|
|
||||||
static void gst_osx_audio_sink_probe_caps (GstOsxAudioSink * sink);
|
static void gst_osx_audio_sink_probe_caps (GstOsxAudioSink * sink);
|
||||||
static void gst_osx_audio_sink_set_volume (GstOsxAudioSink * sink);
|
static void gst_osx_audio_sink_set_volume (GstOsxAudioSink * sink);
|
||||||
|
|
||||||
|
@ -179,6 +181,9 @@ gst_osx_audio_sink_class_init (GstOsxAudioSinkClass * klass)
|
||||||
gobject_class->set_property = gst_osx_audio_sink_set_property;
|
gobject_class->set_property = gst_osx_audio_sink_set_property;
|
||||||
gobject_class->get_property = gst_osx_audio_sink_get_property;
|
gobject_class->get_property = gst_osx_audio_sink_get_property;
|
||||||
|
|
||||||
|
gstelement_class->change_state =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_osx_audio_sink_change_state);
|
||||||
|
|
||||||
#ifndef HAVE_IOS
|
#ifndef HAVE_IOS
|
||||||
g_object_class_install_property (gobject_class, ARG_DEVICE,
|
g_object_class_install_property (gobject_class, ARG_DEVICE,
|
||||||
g_param_spec_int ("device", "Device ID", "Device ID of output device",
|
g_param_spec_int ("device", "Device ID", "Device ID of output device",
|
||||||
|
@ -248,6 +253,44 @@ gst_osx_audio_sink_set_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstStateChangeReturn
|
||||||
|
gst_osx_audio_sink_change_state (GstElement * element,
|
||||||
|
GstStateChange transition)
|
||||||
|
{
|
||||||
|
GstOsxAudioSink *osxsink = GST_OSX_AUDIO_SINK (element);
|
||||||
|
GstOsxAudioRingBuffer *ringbuffer;
|
||||||
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||||
|
/* Device has been selected, AudioUnit set up, so initialize volume */
|
||||||
|
gst_osx_audio_sink_set_volume (osxsink);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
|
/* The device is open now, so fix our device_id if it changed */
|
||||||
|
ringbuffer =
|
||||||
|
GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SINK (osxsink)->ringbuffer);
|
||||||
|
osxsink->device_id = ringbuffer->core_audio->device_id;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
|
gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec)
|
GValue * value, GParamSpec * pspec)
|
||||||
|
@ -452,13 +495,15 @@ gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink)
|
||||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink),
|
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink),
|
||||||
(void *) gst_osx_audio_sink_io_proc);
|
(void *) gst_osx_audio_sink_io_proc);
|
||||||
|
|
||||||
ringbuffer->select_device =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_osx_audio_sink_select_device);
|
|
||||||
|
|
||||||
ringbuffer->core_audio->element =
|
ringbuffer->core_audio->element =
|
||||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink);
|
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink);
|
||||||
ringbuffer->core_audio->is_src = FALSE;
|
ringbuffer->core_audio->is_src = FALSE;
|
||||||
|
|
||||||
|
if (ringbuffer->core_audio->device_id != osxsink->device_id) {
|
||||||
|
ringbuffer->core_audio->device_id = osxsink->device_id;
|
||||||
|
g_object_notify (G_OBJECT (osxsink), "device");
|
||||||
|
}
|
||||||
|
|
||||||
return GST_AUDIO_RING_BUFFER (ringbuffer);
|
return GST_AUDIO_RING_BUFFER (ringbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -648,19 +693,3 @@ gst_osx_audio_sink_probe_caps (GstOsxAudioSink * osxsink)
|
||||||
osxsink->cached_caps = caps;
|
osxsink->cached_caps = caps;
|
||||||
osxsink->channels = channels;
|
osxsink->channels = channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_osx_audio_sink_select_device (GstElement * sink,
|
|
||||||
GstOsxAudioRingBuffer * ringbuffer)
|
|
||||||
{
|
|
||||||
GstOsxAudioSink *osxsink = GST_OSX_AUDIO_SINK (sink);
|
|
||||||
|
|
||||||
if (!gst_core_audio_select_device (&osxsink->device_id, TRUE))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ringbuffer->core_audio->device_id = osxsink->device_id;
|
|
||||||
|
|
||||||
gst_osx_audio_sink_set_volume (osxsink);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -99,6 +99,10 @@ static void gst_osx_audio_src_set_property (GObject * object, guint prop_id,
|
||||||
static void gst_osx_audio_src_get_property (GObject * object, guint prop_id,
|
static void gst_osx_audio_src_get_property (GObject * object, guint prop_id,
|
||||||
GValue * value, GParamSpec * pspec);
|
GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
|
static GstStateChangeReturn
|
||||||
|
gst_osx_audio_src_change_state (GstElement * element,
|
||||||
|
GstStateChange transition);
|
||||||
|
|
||||||
static GstCaps *gst_osx_audio_src_get_caps (GstBaseSrc * src, GstCaps * filter);
|
static GstCaps *gst_osx_audio_src_get_caps (GstBaseSrc * src, GstCaps * filter);
|
||||||
|
|
||||||
static GstAudioRingBuffer *gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc
|
static GstAudioRingBuffer *gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc
|
||||||
|
@ -109,8 +113,6 @@ static OSStatus gst_osx_audio_src_io_proc (GstOsxAudioRingBuffer * buf,
|
||||||
AudioUnitRenderActionFlags * ioActionFlags,
|
AudioUnitRenderActionFlags * ioActionFlags,
|
||||||
const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber,
|
const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber,
|
||||||
UInt32 inNumberFrames, AudioBufferList * bufferList);
|
UInt32 inNumberFrames, AudioBufferList * bufferList);
|
||||||
static gboolean gst_osx_audio_src_select_device (GstElement * src,
|
|
||||||
GstOsxAudioRingBuffer * ringbuffer);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_osx_audio_src_do_init (GType type)
|
gst_osx_audio_src_do_init (GType type)
|
||||||
|
@ -127,6 +129,7 @@ gst_osx_audio_src_do_init (GType type)
|
||||||
&osxelement_info);
|
&osxelement_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define gst_osx_audio_src_parent_class parent_class
|
||||||
G_DEFINE_TYPE_WITH_CODE (GstOsxAudioSrc, gst_osx_audio_src,
|
G_DEFINE_TYPE_WITH_CODE (GstOsxAudioSrc, gst_osx_audio_src,
|
||||||
GST_TYPE_AUDIO_BASE_SRC, gst_osx_audio_src_do_init (g_define_type_id));
|
GST_TYPE_AUDIO_BASE_SRC, gst_osx_audio_src_do_init (g_define_type_id));
|
||||||
|
|
||||||
|
@ -146,6 +149,9 @@ gst_osx_audio_src_class_init (GstOsxAudioSrcClass * klass)
|
||||||
gobject_class->set_property = gst_osx_audio_src_set_property;
|
gobject_class->set_property = gst_osx_audio_src_set_property;
|
||||||
gobject_class->get_property = gst_osx_audio_src_get_property;
|
gobject_class->get_property = gst_osx_audio_src_get_property;
|
||||||
|
|
||||||
|
gstelement_class->change_state =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_osx_audio_src_change_state);
|
||||||
|
|
||||||
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_osx_audio_src_get_caps);
|
gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_osx_audio_src_get_caps);
|
||||||
|
|
||||||
g_object_class_install_property (gobject_class, ARG_DEVICE,
|
g_object_class_install_property (gobject_class, ARG_DEVICE,
|
||||||
|
@ -205,6 +211,38 @@ gst_osx_audio_src_get_property (GObject * object, guint prop_id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstStateChangeReturn
|
||||||
|
gst_osx_audio_src_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
{
|
||||||
|
GstOsxAudioSrc *osxsrc = GST_OSX_AUDIO_SRC (element);
|
||||||
|
GstOsxAudioRingBuffer *ringbuffer;
|
||||||
|
GstStateChangeReturn ret;
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
||||||
|
if (ret == GST_STATE_CHANGE_FAILURE)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
|
/* The device is open now, so fix our device_id if it changed */
|
||||||
|
ringbuffer =
|
||||||
|
GST_OSX_AUDIO_RING_BUFFER (GST_AUDIO_BASE_SRC (osxsrc)->ringbuffer);
|
||||||
|
osxsrc->device_id = ringbuffer->core_audio->device_id;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_osx_audio_src_get_caps (GstBaseSrc * src, GstCaps * filter)
|
gst_osx_audio_src_get_caps (GstBaseSrc * src, GstCaps * filter)
|
||||||
{
|
{
|
||||||
|
@ -258,13 +296,15 @@ gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc * src)
|
||||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc),
|
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc),
|
||||||
(void *) gst_osx_audio_src_io_proc);
|
(void *) gst_osx_audio_src_io_proc);
|
||||||
|
|
||||||
ringbuffer->select_device =
|
|
||||||
GST_DEBUG_FUNCPTR (gst_osx_audio_src_select_device);
|
|
||||||
|
|
||||||
ringbuffer->core_audio->element =
|
ringbuffer->core_audio->element =
|
||||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc);
|
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc);
|
||||||
ringbuffer->core_audio->is_src = TRUE;
|
ringbuffer->core_audio->is_src = TRUE;
|
||||||
|
|
||||||
|
if (ringbuffer->core_audio->device_id != osxsrc->device_id) {
|
||||||
|
ringbuffer->core_audio->device_id = osxsrc->device_id;
|
||||||
|
g_object_notify (G_OBJECT (osxsrc), "device");
|
||||||
|
}
|
||||||
|
|
||||||
return GST_AUDIO_RING_BUFFER (ringbuffer);
|
return GST_AUDIO_RING_BUFFER (ringbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,16 +366,3 @@ gst_osx_audio_src_osxelement_init (gpointer g_iface, gpointer iface_data)
|
||||||
|
|
||||||
iface->io_proc = (AURenderCallback) gst_osx_audio_src_io_proc;
|
iface->io_proc = (AURenderCallback) gst_osx_audio_src_io_proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gst_osx_audio_src_select_device (GstOsxAudioSrc * osxsrc)
|
|
||||||
{
|
|
||||||
GstOsxAudioSrc *osxsrc = GST_OSX_AUDIO_SRC (element);
|
|
||||||
|
|
||||||
if (!gst_core_audio_select_device (&osxsrc->device_id, FALSE))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
ringbuffer->core_audio->device_id = osxsrc->device_id;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
|
@ -196,9 +196,9 @@ gst_core_audio_set_volume (GstCoreAudio * core_audio, gfloat volume)
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
gst_core_audio_select_device (AudioDeviceID * device_id, gboolean output)
|
gst_core_audio_select_device (GstCoreAudio * core_audio)
|
||||||
{
|
{
|
||||||
return gst_core_audio_select_device_impl (device_id, output);
|
return gst_core_audio_select_device_impl (core_audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -139,7 +139,7 @@ void gst_core_audio_set_volume (GstCoreAudio *core
|
||||||
gboolean gst_core_audio_audio_device_is_spdif_avail (AudioDeviceID device_id);
|
gboolean gst_core_audio_audio_device_is_spdif_avail (AudioDeviceID device_id);
|
||||||
|
|
||||||
|
|
||||||
gboolean gst_core_audio_select_device (AudioDeviceID *device_id, gboolean output);
|
gboolean gst_core_audio_select_device (GstCoreAudio * core_audio);
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,8 @@ _audio_system_get_default_device (gboolean output)
|
||||||
GST_ERROR ("failed getting default output device: %d", (int) status);
|
GST_ERROR ("failed getting default output device: %d", (int) status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GST_DEBUG ("Default device id: %u", (unsigned) device_id);
|
||||||
|
|
||||||
return device_id;
|
return device_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,11 +1150,13 @@ done:
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_core_audio_select_device_impl (AudioDeviceID * device_id, gboolean output)
|
gst_core_audio_select_device_impl (GstCoreAudio * core_audio)
|
||||||
{
|
{
|
||||||
AudioDeviceID *devices = NULL;
|
AudioDeviceID *devices = NULL;
|
||||||
|
AudioDeviceID device_id = core_audio->device_id;
|
||||||
AudioDeviceID default_device_id = 0;
|
AudioDeviceID default_device_id = 0;
|
||||||
gint i, ndevices = 0;
|
gint i, ndevices = 0;
|
||||||
|
gboolean output = !core_audio->is_src;
|
||||||
gboolean res = FALSE;
|
gboolean res = FALSE;
|
||||||
#ifdef GST_CORE_AUDIO_DEBUG
|
#ifdef GST_CORE_AUDIO_DEBUG
|
||||||
AudioChannelLayout *channel_layout;
|
AudioChannelLayout *channel_layout;
|
||||||
|
@ -1197,9 +1201,9 @@ gst_core_audio_select_device_impl (AudioDeviceID * device_id, gboolean output)
|
||||||
|
|
||||||
/* Here we decide if selected device is valid or autoselect
|
/* Here we decide if selected device is valid or autoselect
|
||||||
* the default one when required */
|
* the default one when required */
|
||||||
if (*device_id == kAudioDeviceUnknown) {
|
if (device_id == kAudioDeviceUnknown) {
|
||||||
if (default_device_id != kAudioDeviceUnknown) {
|
if (default_device_id != kAudioDeviceUnknown) {
|
||||||
*device_id = default_device_id;
|
device_id = default_device_id;
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
} else {
|
} else {
|
||||||
/* No device of required type available */
|
/* No device of required type available */
|
||||||
|
@ -1207,18 +1211,21 @@ gst_core_audio_select_device_impl (AudioDeviceID * device_id, gboolean output)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < ndevices; i++) {
|
for (i = 0; i < ndevices; i++) {
|
||||||
if (*device_id == devices[i]) {
|
if (device_id == devices[i]) {
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res && !_audio_device_is_alive (*device_id, output)) {
|
if (res && !_audio_device_is_alive (device_id, output)) {
|
||||||
GST_ERROR ("Requested device not usable");
|
GST_ERROR ("Requested device not usable");
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (res)
|
||||||
|
core_audio->device_id = device_id;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
g_free (devices);
|
g_free (devices);
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -106,7 +106,7 @@ gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_core_audio_select_device_impl (AudioDeviceID * device_id, gboolean output)
|
gst_core_audio_select_device_impl (GstCoreAudio * core_audio)
|
||||||
{
|
{
|
||||||
/* No device selection in iOS */
|
/* No device selection in iOS */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Reference in a new issue