diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2012-06-07 15:03:02 +0200 |
---|---|---|
committer | Wim Taymans <wim.taymans@collabora.co.uk> | 2012-06-07 15:03:02 +0200 |
commit | f14a69fe260a21a9e3df0f34c46223a445f30ac9 (patch) | |
tree | 1637133be9bd8b47225550c737841e227bffc597 /ext | |
parent | e62d5bdace82f263385d005dcc2f57560cdfcdb9 (diff) |
pulsesrc: improve clock handling
Post the notify outside of the pa_lock to avoid a deadlock caused by basesrc
calling get_time with the object lock.
Reset the clock on connect.
Post clock-lost and clock-provide messages.
Fixes https://bugzilla.gnome.org/show_bug.cgi?id=673977
Diffstat (limited to 'ext')
-rw-r--r-- | ext/pulse/pulsesrc.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c index d8387bdb3..371eb2b36 100644 --- a/ext/pulse/pulsesrc.c +++ b/ext/pulse/pulsesrc.c @@ -401,12 +401,12 @@ gst_pulsesrc_init (GstPulseSrc * pulsesrc, GstPulseSrcClass * klass) gst_base_audio_src_set_slave_method (GST_BASE_AUDIO_SRC (pulsesrc), GST_BASE_AUDIO_SRC_SLAVE_SKEW); - // override with a custom clock - if (GST_BASE_AUDIO_SRC (pulsesrc)->clock) { + /* override with a custom clock */ + if (GST_BASE_AUDIO_SRC (pulsesrc)->clock) gst_object_unref (GST_BASE_AUDIO_SRC (pulsesrc)->clock); - } - GST_BASE_AUDIO_SRC (pulsesrc)->clock = gst_audio_clock_new ("GstPulseSrcClock", + GST_BASE_AUDIO_SRC (pulsesrc)->clock = + gst_audio_clock_new ("GstPulseSrcClock", (GstAudioClockGetTimeFunc) gst_pulsesrc_get_time, pulsesrc); } @@ -1118,9 +1118,6 @@ gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length) GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc); size_t sum = 0; - pa_threaded_mainloop_lock (pulsesrc->mainloop); - pulsesrc->in_read = TRUE; - #ifdef HAVE_PULSE_1_0 if (g_atomic_int_compare_and_exchange (&pulsesrc->notify, 1, 0)) { g_object_notify (G_OBJECT (pulsesrc), "volume"); @@ -1128,6 +1125,9 @@ gst_pulsesrc_read (GstAudioSrc * asrc, gpointer data, guint length) } #endif + pa_threaded_mainloop_lock (pulsesrc->mainloop); + pulsesrc->in_read = TRUE; + if (pulsesrc->paused) goto was_paused; @@ -1431,6 +1431,7 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) #ifdef HAVE_PULSE_1_0 pa_operation *o; #endif + GstAudioClock *clock; pa_threaded_mainloop_lock (pulsesrc->mainloop); @@ -1477,6 +1478,10 @@ gst_pulsesrc_prepare (GstAudioSrc * asrc, GstRingBufferSpec * spec) goto unlock_and_fail; } + /* our clock will now start from 0 again */ + clock = GST_AUDIO_CLOCK (GST_BASE_AUDIO_SRC (pulsesrc)->clock); + gst_audio_clock_reset (clock, 0); + pulsesrc->corked = TRUE; for (;;) { @@ -1700,6 +1705,11 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition) gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server, this->device, GST_PULSEMIXER_SOURCE); break; + case GST_STATE_CHANGE_READY_TO_PAUSED: + gst_element_post_message (element, + gst_message_new_clock_provide (GST_OBJECT_CAST (element), + GST_BASE_AUDIO_SRC (this)->clock, TRUE)); + break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: /* uncork and start recording */ gst_pulsesrc_play (this); @@ -1738,6 +1748,12 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition) this->mainloop = NULL; } break; + case GST_STATE_CHANGE_PAUSED_TO_READY: + /* format_lost is reset in release() in baseaudiosink */ + gst_element_post_message (element, + gst_message_new_clock_lost (GST_OBJECT_CAST (element), + GST_BASE_AUDIO_SRC (this)->clock)); + break; default: break; } @@ -1778,7 +1794,7 @@ gst_pulsesrc_get_time (GstClock * clock, GstPulseSrc * src) } - unlock_and_out: +unlock_and_out: pa_threaded_mainloop_unlock (src->mainloop); return time; |