summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2012-06-07 15:03:02 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2012-06-07 15:03:02 +0200
commitf14a69fe260a21a9e3df0f34c46223a445f30ac9 (patch)
tree1637133be9bd8b47225550c737841e227bffc597 /ext
parente62d5bdace82f263385d005dcc2f57560cdfcdb9 (diff)
downloadgstreamer-plugins-good-f14a69fe260a21a9e3df0f34c46223a445f30ac9.tar.gz
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.c32
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;