mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 23:14:46 +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)
|
||||
{
|
||||
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 gst_core_audio_open (osxbuf->core_audio);
|
||||
|
|
|
@ -81,9 +81,6 @@ struct _GstOsxAudioRingBuffer
|
|||
|
||||
GstCoreAudio *core_audio;
|
||||
|
||||
/* Set by the parent to select the required device */
|
||||
gboolean (*select_device) (GstElement * element, GstOsxAudioRingBuffer * buf);
|
||||
|
||||
guint buffer_len;
|
||||
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,
|
||||
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_stop (GstBaseSink * base);
|
||||
|
@ -130,8 +134,6 @@ static GstAudioRingBuffer
|
|||
* gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink);
|
||||
static void gst_osx_audio_sink_osxelement_init (gpointer g_iface,
|
||||
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_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->get_property = gst_osx_audio_sink_get_property;
|
||||
|
||||
gstelement_class->change_state =
|
||||
GST_DEBUG_FUNCPTR (gst_osx_audio_sink_change_state);
|
||||
|
||||
#ifndef HAVE_IOS
|
||||
g_object_class_install_property (gobject_class, ARG_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
|
||||
gst_osx_audio_sink_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec)
|
||||
|
@ -452,13 +495,15 @@ gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink)
|
|||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink),
|
||||
(void *) gst_osx_audio_sink_io_proc);
|
||||
|
||||
ringbuffer->select_device =
|
||||
GST_DEBUG_FUNCPTR (gst_osx_audio_sink_select_device);
|
||||
|
||||
ringbuffer->core_audio->element =
|
||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -648,19 +693,3 @@ gst_osx_audio_sink_probe_caps (GstOsxAudioSink * osxsink)
|
|||
osxsink->cached_caps = caps;
|
||||
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,
|
||||
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 GstAudioRingBuffer *gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc
|
||||
|
@ -109,8 +113,6 @@ static OSStatus gst_osx_audio_src_io_proc (GstOsxAudioRingBuffer * buf,
|
|||
AudioUnitRenderActionFlags * ioActionFlags,
|
||||
const AudioTimeStamp * inTimeStamp, UInt32 inBusNumber,
|
||||
UInt32 inNumberFrames, AudioBufferList * bufferList);
|
||||
static gboolean gst_osx_audio_src_select_device (GstElement * src,
|
||||
GstOsxAudioRingBuffer * ringbuffer);
|
||||
|
||||
static void
|
||||
gst_osx_audio_src_do_init (GType type)
|
||||
|
@ -127,6 +129,7 @@ gst_osx_audio_src_do_init (GType type)
|
|||
&osxelement_info);
|
||||
}
|
||||
|
||||
#define gst_osx_audio_src_parent_class parent_class
|
||||
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));
|
||||
|
||||
|
@ -146,6 +149,9 @@ gst_osx_audio_src_class_init (GstOsxAudioSrcClass * klass)
|
|||
gobject_class->set_property = gst_osx_audio_src_set_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);
|
||||
|
||||
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 *
|
||||
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),
|
||||
(void *) gst_osx_audio_src_io_proc);
|
||||
|
||||
ringbuffer->select_device =
|
||||
GST_DEBUG_FUNCPTR (gst_osx_audio_src_select_device);
|
||||
|
||||
ringbuffer->core_audio->element =
|
||||
GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
|
|
|
@ -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_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);
|
||||
|
||||
|
|
|
@ -71,6 +71,8 @@ _audio_system_get_default_device (gboolean output)
|
|||
GST_ERROR ("failed getting default output device: %d", (int) status);
|
||||
}
|
||||
|
||||
GST_DEBUG ("Default device id: %u", (unsigned) device_id);
|
||||
|
||||
return device_id;
|
||||
}
|
||||
|
||||
|
@ -1148,11 +1150,13 @@ done:
|
|||
}
|
||||
|
||||
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 device_id = core_audio->device_id;
|
||||
AudioDeviceID default_device_id = 0;
|
||||
gint i, ndevices = 0;
|
||||
gboolean output = !core_audio->is_src;
|
||||
gboolean res = FALSE;
|
||||
#ifdef GST_CORE_AUDIO_DEBUG
|
||||
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
|
||||
* the default one when required */
|
||||
if (*device_id == kAudioDeviceUnknown) {
|
||||
if (device_id == kAudioDeviceUnknown) {
|
||||
if (default_device_id != kAudioDeviceUnknown) {
|
||||
*device_id = default_device_id;
|
||||
device_id = default_device_id;
|
||||
res = TRUE;
|
||||
} else {
|
||||
/* No device of required type available */
|
||||
|
@ -1207,18 +1211,21 @@ gst_core_audio_select_device_impl (AudioDeviceID * device_id, gboolean output)
|
|||
}
|
||||
} else {
|
||||
for (i = 0; i < ndevices; i++) {
|
||||
if (*device_id == devices[i]) {
|
||||
if (device_id == devices[i]) {
|
||||
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");
|
||||
res = FALSE;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (res)
|
||||
core_audio->device_id = device_id;
|
||||
|
||||
done:
|
||||
g_free (devices);
|
||||
return res;
|
||||
|
|
|
@ -106,7 +106,7 @@ gst_core_audio_audio_device_get_channel_layout (AudioDeviceID device_id)
|
|||
}
|
||||
|
||||
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 */
|
||||
return TRUE;
|
||||
|
|
Loading…
Reference in a new issue