From: Sebastian Dröge Date: Mon, 22 Dec 2014 09:23:01 +0000 (+0100) Subject: osxaudio: Fix deadlock and property change notification in device selection code X-Git-Tag: 1.6.0~694 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e7b10a107d7a255f658c8acb07f7e5e7968dfd66;p=platform%2Fupstream%2Fgst-plugins-good.git osxaudio: Fix deadlock and property change notification in device selection code After creating the ringbuffer we have to set the device on the ringbuffer as it defaults to kAudioDeviceUnknown. At this point it can't have changed to anything else yet and we don't have to notify about changes to the sink/src "device" property. It's also not a good idea because GstAudioBaseSrc has the object lock taken while the ringbuffer is created, which might cause a deadlock if something calls back into the element from "notify::device". Once the base class is done with the NULL_TO_READY state change, it has opened the device via the ringbuffer and this might have chosen a different device. Especially if we initially used kAudioDeviceUnknown. Also notify about this property change as initially intended by this code. --- diff --git a/sys/osxaudio/gstosxaudiosink.c b/sys/osxaudio/gstosxaudiosink.c index 3b1e5a4..53d4c29 100644 --- a/sys/osxaudio/gstosxaudiosink.c +++ b/sys/osxaudio/gstosxaudiosink.c @@ -274,13 +274,14 @@ gst_osx_audio_sink_change_state (GstElement * element, 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; + if (ringbuffer->core_audio->device_id != osxsink->device_id) { + osxsink->device_id = ringbuffer->core_audio->device_id; + g_object_notify (G_OBJECT (osxsink), "device"); + } break; default: @@ -520,10 +521,12 @@ gst_osx_audio_sink_create_ringbuffer (GstAudioBaseSink * sink) GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsink); ringbuffer->core_audio->is_src = FALSE; - if (ringbuffer->core_audio->device_id != osxsink->device_id) { + /* 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; - g_object_notify (G_OBJECT (osxsink), "device"); - } return GST_AUDIO_RING_BUFFER (ringbuffer); } diff --git a/sys/osxaudio/gstosxaudiosrc.c b/sys/osxaudio/gstosxaudiosrc.c index 8592b7c..266be57 100644 --- a/sys/osxaudio/gstosxaudiosrc.c +++ b/sys/osxaudio/gstosxaudiosrc.c @@ -229,11 +229,14 @@ gst_osx_audio_src_change_state (GstElement * element, GstStateChange transition) goto out; switch (transition) { - case GST_STATE_CHANGE_READY_TO_PAUSED: + case GST_STATE_CHANGE_NULL_TO_READY: /* 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; + if (ringbuffer->core_audio->device_id != osxsrc->device_id) { + osxsrc->device_id = ringbuffer->core_audio->device_id; + g_object_notify (G_OBJECT (osxsrc), "device"); + } break; default: @@ -369,10 +372,12 @@ gst_osx_audio_src_create_ringbuffer (GstAudioBaseSrc * src) GST_OSX_AUDIO_ELEMENT_GET_INTERFACE (osxsrc); ringbuffer->core_audio->is_src = TRUE; - if (ringbuffer->core_audio->device_id != osxsrc->device_id) { + /* 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; - g_object_notify (G_OBJECT (osxsrc), "device"); - } return GST_AUDIO_RING_BUFFER (ringbuffer); }