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:
Arun Raghavan 2014-11-28 22:23:17 +05:30
parent 5c2f041286
commit ffcb1577fa
8 changed files with 112 additions and 53 deletions

View file

@ -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);

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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;

View file

@ -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;