summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArun Raghavan <ford_prefect@gentoo.org>2010-08-12 10:32:53 +0000
committerArun Raghavan <ford_prefect@gentoo.org>2010-08-12 10:32:53 +0000
commit8d5fdd742b4ceebe502fd4a853fb02d1175a1f06 (patch)
tree78f3c062781159961a0a1665ce623d7f0b4c09f1
parentVersion bump, fixes bug #331757. Remove old (diff)
downloadgentoo-2-8d5fdd742b4ceebe502fd4a853fb02d1175a1f06.tar.gz
gentoo-2-8d5fdd742b4ceebe502fd4a853fb02d1175a1f06.tar.bz2
gentoo-2-8d5fdd742b4ceebe502fd4a853fb02d1175a1f06.zip
Bump .22 to -r1. Adds some critical patches from upstream addressing crashes. (bug #330401)
(Portage version: 2.2_rc67/cvs/Linux x86_64)
-rw-r--r--media-plugins/gst-plugins-pulse/ChangeLog14
-rw-r--r--media-plugins/gst-plugins-pulse/files/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch115
-rw-r--r--media-plugins/gst-plugins-pulse/files/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch49
-rw-r--r--media-plugins/gst-plugins-pulse/files/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch83
-rw-r--r--media-plugins/gst-plugins-pulse/files/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch168
-rw-r--r--media-plugins/gst-plugins-pulse/files/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch31
-rw-r--r--media-plugins/gst-plugins-pulse/gst-plugins-pulse-0.10.22-r1.ebuild27
7 files changed, 486 insertions, 1 deletions
diff --git a/media-plugins/gst-plugins-pulse/ChangeLog b/media-plugins/gst-plugins-pulse/ChangeLog
index b6b0d2941e30..d1266a032fcd 100644
--- a/media-plugins/gst-plugins-pulse/ChangeLog
+++ b/media-plugins/gst-plugins-pulse/ChangeLog
@@ -1,6 +1,18 @@
# ChangeLog for media-plugins/gst-plugins-pulse
# Copyright 1999-2010 Gentoo Foundation; Distributed under the GPL v2
-# $Header: /var/cvsroot/gentoo-x86/media-plugins/gst-plugins-pulse/ChangeLog,v 1.41 2010/08/10 16:24:33 jer Exp $
+# $Header: /var/cvsroot/gentoo-x86/media-plugins/gst-plugins-pulse/ChangeLog,v 1.42 2010/08/12 10:32:53 ford_prefect Exp $
+
+*gst-plugins-pulse-0.10.22-r1 (12 Aug 2010)
+
+ 12 Aug 2010; Arun Raghavan <ford_prefect@gentoo.org>
+ +files/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch,
+ +files/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch,
+ +files/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch,
+ +files/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch,
+ +files/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch,
+ +gst-plugins-pulse-0.10.22-r1.ebuild:
+ Bump .22 to -r1. Adds some critical patches from upstream addressing
+ crashes. (bug #330401)
10 Aug 2010; Jeroen Roovers <jer@gentoo.org>
gst-plugins-pulse-0.10.22.ebuild:
diff --git a/media-plugins/gst-plugins-pulse/files/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch b/media-plugins/gst-plugins-pulse/files/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch
new file mode 100644
index 000000000000..30d5b9aafdc5
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/files/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch
@@ -0,0 +1,115 @@
+5332287 pulsesink: Create and free the PA mainloop in NULL->READY/READY->NULL
+ ext/pulse/pulsesink.c | 54 +++++++++++++++++++++++++++++++++++++++----------
+ 1 files changed, 43 insertions(+), 11 deletions(-)
+
+diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
+index 0460748..4b45a2f 100644
+--- a/ext/pulse/pulsesink.c
++++ b/ext/pulse/pulsesink.c
+@@ -1405,6 +1405,9 @@ static void gst_pulsesink_finalize (GObject * object);
+
+ static gboolean gst_pulsesink_event (GstBaseSink * sink, GstEvent * event);
+
++static GstStateChangeReturn gst_pulsesink_change_state (GstElement * element,
++ GstStateChange transition);
++
+ static void gst_pulsesink_init_interfaces (GType type);
+
+ #if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
+@@ -1544,6 +1547,7 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)
+ GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass);
+ GstBaseSinkClass *bc;
+ GstBaseAudioSinkClass *gstaudiosink_class = GST_BASE_AUDIO_SINK_CLASS (klass);
++ GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
+
+ gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_pulsesink_finalize);
+ gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pulsesink_set_property);
+@@ -1555,6 +1559,9 @@ gst_pulsesink_class_init (GstPulseSinkClass * klass)
+ bc = g_type_class_peek (GST_TYPE_BASE_SINK);
+ gstbasesink_class->activate_pull = GST_DEBUG_FUNCPTR (bc->activate_pull);
+
++ gstelement_class->change_state =
++ GST_DEBUG_FUNCPTR (gst_pulsesink_change_state);
++
+ gstaudiosink_class->create_ringbuffer =
+ GST_DEBUG_FUNCPTR (gst_pulsesink_create_ringbuffer);
+
+@@ -1635,8 +1642,6 @@ server_dead:
+ static void
+ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
+ {
+- guint res;
+-
+ pulsesink->server = NULL;
+ pulsesink->device = NULL;
+ pulsesink->device_description = NULL;
+@@ -1655,11 +1660,6 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
+ GST_DEBUG_OBJECT (pulsesink, "using pulseaudio version %s",
+ pulsesink->pa_version);
+
+- pulsesink->mainloop = pa_threaded_mainloop_new ();
+- g_assert (pulsesink->mainloop != NULL);
+- res = pa_threaded_mainloop_start (pulsesink->mainloop);
+- g_assert (res == 0);
+-
+ /* TRUE for sinks, FALSE for sources */
+ pulsesink->probe = gst_pulseprobe_new (G_OBJECT (pulsesink),
+ G_OBJECT_GET_CLASS (pulsesink), PROP_DEVICE, pulsesink->device,
+@@ -1678,14 +1678,10 @@ gst_pulsesink_finalize (GObject * object)
+ {
+ GstPulseSink *pulsesink = GST_PULSESINK_CAST (object);
+
+- pa_threaded_mainloop_stop (pulsesink->mainloop);
+-
+ g_free (pulsesink->server);
+ g_free (pulsesink->device);
+ g_free (pulsesink->device_description);
+
+- pa_threaded_mainloop_free (pulsesink->mainloop);
+-
+ if (pulsesink->probe) {
+ gst_pulseprobe_free (pulsesink->probe);
+ pulsesink->probe = NULL;
+@@ -2264,3 +2260,39 @@ gst_pulsesink_event (GstBaseSink * sink, GstEvent * event)
+
+ return GST_BASE_SINK_CLASS (parent_class)->event (sink, event);
+ }
++
++static GstStateChangeReturn
++gst_pulsesink_change_state (GstElement * element, GstStateChange transition)
++{
++ GstPulseSink *pulsesink = GST_PULSESINK (element);
++ GstStateChangeReturn ret;
++ guint res;
++
++ switch (transition) {
++ case GST_STATE_CHANGE_NULL_TO_READY:
++ g_assert (pulsesink->mainloop == NULL);
++ pulsesink->mainloop = pa_threaded_mainloop_new ();
++ g_assert (pulsesink->mainloop != NULL);
++ res = pa_threaded_mainloop_start (pulsesink->mainloop);
++ g_assert (res == 0);
++ break;
++ default:
++ break;
++ }
++
++ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
++
++ switch (transition) {
++ case GST_STATE_CHANGE_READY_TO_NULL:
++ if (pulsesink->mainloop) {
++ pa_threaded_mainloop_stop (pulsesink->mainloop);
++ pa_threaded_mainloop_free (pulsesink->mainloop);
++ pulsesink->mainloop = NULL;
++ }
++ break;
++ default:
++ break;
++ }
++
++ return ret;
++}
+--
+1.7.2
+
diff --git a/media-plugins/gst-plugins-pulse/files/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch b/media-plugins/gst-plugins-pulse/files/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch
new file mode 100644
index 000000000000..288eed63c833
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/files/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch
@@ -0,0 +1,49 @@
+e69ba0f pulsesink: Allocate and free the custom clock in NULL<->READY
+ ext/pulse/pulsesink.c | 17 ++++++++++-------
+ 1 files changed, 10 insertions(+), 7 deletions(-)
+
+diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
+index 4b45a2f..e39b672 100644
+--- a/ext/pulse/pulsesink.c
++++ b/ext/pulse/pulsesink.c
+@@ -1664,13 +1664,6 @@ gst_pulsesink_init (GstPulseSink * pulsesink, GstPulseSinkClass * klass)
+ pulsesink->probe = gst_pulseprobe_new (G_OBJECT (pulsesink),
+ G_OBJECT_GET_CLASS (pulsesink), PROP_DEVICE, pulsesink->device,
+ TRUE, FALSE);
+-
+- /* override with a custom clock */
+- if (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock)
+- gst_object_unref (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock);
+- GST_BASE_AUDIO_SINK (pulsesink)->provided_clock =
+- gst_audio_clock_new ("GstPulseSinkClock",
+- (GstAudioClockGetTimeFunc) gst_pulsesink_get_time, pulsesink);
+ }
+
+ static void
+@@ -2275,6 +2268,13 @@ gst_pulsesink_change_state (GstElement * element, GstStateChange transition)
+ g_assert (pulsesink->mainloop != NULL);
+ res = pa_threaded_mainloop_start (pulsesink->mainloop);
+ g_assert (res == 0);
++
++ /* override with a custom clock */
++ if (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock)
++ gst_object_unref (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock);
++ GST_BASE_AUDIO_SINK (pulsesink)->provided_clock =
++ gst_audio_clock_new ("GstPulseSinkClock",
++ (GstAudioClockGetTimeFunc) gst_pulsesink_get_time, pulsesink);
+ break;
+ default:
+ break;
+@@ -2284,6 +2284,9 @@ gst_pulsesink_change_state (GstElement * element, GstStateChange transition)
+
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
++ if (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock)
++ gst_object_unref (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock);
++ GST_BASE_AUDIO_SINK (pulsesink)->provided_clock = NULL;
+ if (pulsesink->mainloop) {
+ pa_threaded_mainloop_stop (pulsesink->mainloop);
+ pa_threaded_mainloop_free (pulsesink->mainloop);
+--
+1.7.2
+
diff --git a/media-plugins/gst-plugins-pulse/files/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch b/media-plugins/gst-plugins-pulse/files/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch
new file mode 100644
index 000000000000..24b33223e0ed
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/files/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch
@@ -0,0 +1,83 @@
+4a492f2 pulsesrc: Allocate/free PA mainloop during state changes
+ ext/pulse/pulsesrc.c | 31 +++++++++++++++++--------------
+ 1 files changed, 17 insertions(+), 14 deletions(-)
+
+diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c
+index 9fe7f51..0ddaa43 100644
+--- a/ext/pulse/pulsesrc.c
++++ b/ext/pulse/pulsesrc.c
+@@ -250,8 +250,6 @@ gst_pulsesrc_class_init (GstPulseSrcClass * klass)
+ static void
+ gst_pulsesrc_init (GstPulseSrc * pulsesrc, GstPulseSrcClass * klass)
+ {
+- int e;
+-
+ pulsesrc->server = NULL;
+ pulsesrc->device = NULL;
+ pulsesrc->device_description = NULL;
+@@ -274,12 +272,6 @@ gst_pulsesrc_init (GstPulseSrc * pulsesrc, GstPulseSrcClass * klass)
+ pulsesrc->paused = FALSE;
+ pulsesrc->in_read = FALSE;
+
+- pulsesrc->mainloop = pa_threaded_mainloop_new ();
+- g_assert (pulsesrc->mainloop);
+-
+- e = pa_threaded_mainloop_start (pulsesrc->mainloop);
+- g_assert (e == 0);
+-
+ pulsesrc->mixer = NULL;
+
+ pulsesrc->probe = gst_pulseprobe_new (G_OBJECT (pulsesrc), G_OBJECT_GET_CLASS (pulsesrc), PROP_DEVICE, pulsesrc->server, FALSE, TRUE); /* FALSE for sinks, TRUE for sources */
+@@ -320,15 +312,9 @@ gst_pulsesrc_finalize (GObject * object)
+ {
+ GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (object);
+
+- pa_threaded_mainloop_stop (pulsesrc->mainloop);
+-
+- gst_pulsesrc_destroy_context (pulsesrc);
+-
+ g_free (pulsesrc->server);
+ g_free (pulsesrc->device);
+
+- pa_threaded_mainloop_free (pulsesrc->mainloop);
+-
+ if (pulsesrc->mixer) {
+ gst_pulsemixer_ctrl_free (pulsesrc->mixer);
+ pulsesrc->mixer = NULL;
+@@ -1177,9 +1163,16 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition)
+ {
+ GstStateChangeReturn ret;
+ GstPulseSrc *this = GST_PULSESRC_CAST (element);
++ int e;
+
+ switch (transition) {
+ case GST_STATE_CHANGE_NULL_TO_READY:
++ this->mainloop = pa_threaded_mainloop_new ();
++ g_assert (this->mainloop);
++
++ e = pa_threaded_mainloop_start (this->mainloop);
++ g_assert (e == 0);
++
+ if (!this->mixer)
+ this->mixer =
+ gst_pulsemixer_ctrl_new (G_OBJECT (this), this->server,
+@@ -1212,6 +1205,16 @@ gst_pulsesrc_change_state (GstElement * element, GstStateChange transition)
+ gst_pulsemixer_ctrl_free (this->mixer);
+ this->mixer = NULL;
+ }
++
++ if (this->mainloop)
++ pa_threaded_mainloop_stop (this->mainloop);
++
++ gst_pulsesrc_destroy_context (this);
++
++ if (this->mainloop) {
++ pa_threaded_mainloop_free (this->mainloop);
++ this->mainloop = NULL;
++ }
+ break;
+ default:
+ break;
+--
+1.7.2
+
diff --git a/media-plugins/gst-plugins-pulse/files/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch b/media-plugins/gst-plugins-pulse/files/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch
new file mode 100644
index 000000000000..82c4490f208e
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/files/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch
@@ -0,0 +1,168 @@
+a8103fa pulse: Don't lock the mainloop in NULL
+ ext/pulse/pulsesink.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ ext/pulse/pulsesrc.c | 9 ++++++++
+ 2 files changed, 58 insertions(+), 1 deletions(-)
+
+diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
+index e39b672..8d5f0fe 100644
+--- a/ext/pulse/pulsesink.c
++++ b/ext/pulse/pulsesink.c
+@@ -1692,6 +1692,9 @@ gst_pulsesink_set_volume (GstPulseSink * psink, gdouble volume)
+ GstPulseRingBuffer *pbuf;
+ uint32_t idx;
+
++ if (!psink->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (psink->mainloop);
+
+ GST_DEBUG_OBJECT (psink, "setting volume to %f", volume);
+@@ -1720,6 +1723,14 @@ unlock:
+ return;
+
+ /* ERRORS */
++no_mainloop:
++ {
++ psink->volume = volume;
++ psink->volume_set = TRUE;
++
++ GST_DEBUG_OBJECT (psink, "we have no mainloop");
++ return;
++ }
+ no_buffer:
+ {
+ psink->volume = volume;
+@@ -1749,6 +1760,9 @@ gst_pulsesink_set_mute (GstPulseSink * psink, gboolean mute)
+ GstPulseRingBuffer *pbuf;
+ uint32_t idx;
+
++ if (!psink->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (psink->mainloop);
+
+ GST_DEBUG_OBJECT (psink, "setting mute state to %d", mute);
+@@ -1775,6 +1789,14 @@ unlock:
+ return;
+
+ /* ERRORS */
++no_mainloop:
++ {
++ psink->mute = mute;
++ psink->mute_set = TRUE;
++
++ GST_DEBUG_OBJECT (psink, "we have no mainloop");
++ return;
++ }
+ no_buffer:
+ {
+ psink->mute = mute;
+@@ -1833,6 +1855,9 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
+ gdouble v = DEFAULT_VOLUME;
+ uint32_t idx;
+
++ if (!psink->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (psink->mainloop);
+
+ pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
+@@ -1852,9 +1877,9 @@ gst_pulsesink_get_volume (GstPulseSink * psink)
+ goto unlock;
+ }
+
++unlock:
+ v = psink->volume;
+
+-unlock:
+ if (o)
+ pa_operation_unref (o);
+
+@@ -1868,6 +1893,12 @@ unlock:
+ return v;
+
+ /* ERRORS */
++no_mainloop:
++ {
++ v = psink->volume;
++ GST_DEBUG_OBJECT (psink, "we have no mainloop");
++ return v;
++ }
+ no_buffer:
+ {
+ GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
+@@ -1895,6 +1926,9 @@ gst_pulsesink_get_mute (GstPulseSink * psink)
+ uint32_t idx;
+ gboolean mute = FALSE;
+
++ if (!psink->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (psink->mainloop);
+ mute = psink->mute;
+
+@@ -1924,6 +1958,12 @@ unlock:
+ return mute;
+
+ /* ERRORS */
++no_mainloop:
++ {
++ mute = psink->mute;
++ GST_DEBUG_OBJECT (psink, "we have no mainloop");
++ return mute;
++ }
+ no_buffer:
+ {
+ GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
+@@ -1976,6 +2016,9 @@ gst_pulsesink_device_description (GstPulseSink * psink)
+ pa_operation *o = NULL;
+ gchar *t;
+
++ if (!psink->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (psink->mainloop);
+ pbuf = GST_PULSERING_BUFFER_CAST (GST_BASE_AUDIO_SINK (psink)->ringbuffer);
+ if (pbuf == NULL || pbuf->stream == NULL)
+@@ -2002,6 +2045,11 @@ unlock:
+ return t;
+
+ /* ERRORS */
++no_mainloop:
++ {
++ GST_DEBUG_OBJECT (psink, "we have no mainloop");
++ return NULL;
++ }
+ no_buffer:
+ {
+ GST_DEBUG_OBJECT (psink, "we have no ringbuffer");
+diff --git a/ext/pulse/pulsesrc.c b/ext/pulse/pulsesrc.c
+index b3126f4..2f1aacd 100644
+--- a/ext/pulse/pulsesrc.c
++++ b/ext/pulse/pulsesrc.c
+@@ -396,6 +396,9 @@ gst_pulsesrc_device_description (GstPulseSrc * pulsesrc)
+ pa_operation *o = NULL;
+ gchar *t;
+
++ if (!pulsesrc->mainloop)
++ goto no_mainloop;
++
+ pa_threaded_mainloop_lock (pulsesrc->mainloop);
+
+ if (!pulsesrc->stream)
+@@ -429,6 +432,12 @@ unlock:
+ pa_threaded_mainloop_unlock (pulsesrc->mainloop);
+
+ return t;
++
++no_mainloop:
++ {
++ GST_DEBUG_OBJECT (pulsesrc, "have no mainloop");
++ return NULL;
++ }
+ }
+
+ static void
+--
+1.7.2
+
diff --git a/media-plugins/gst-plugins-pulse/files/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch b/media-plugins/gst-plugins-pulse/files/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch
new file mode 100644
index 000000000000..28ab10931b48
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/files/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch
@@ -0,0 +1,31 @@
+f5057a9 pulsesink: Post provide-clock message on the bus if the clock appears/disappears
+ ext/pulse/pulsesink.c | 6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/ext/pulse/pulsesink.c b/ext/pulse/pulsesink.c
+index 8d5f0fe..08a1d7e 100644
+--- a/ext/pulse/pulsesink.c
++++ b/ext/pulse/pulsesink.c
+@@ -2323,6 +2323,9 @@ gst_pulsesink_change_state (GstElement * element, GstStateChange transition)
+ GST_BASE_AUDIO_SINK (pulsesink)->provided_clock =
+ gst_audio_clock_new ("GstPulseSinkClock",
+ (GstAudioClockGetTimeFunc) gst_pulsesink_get_time, pulsesink);
++ gst_element_post_message (element,
++ gst_message_new_clock_provide (GST_OBJECT_CAST (element),
++ GST_BASE_AUDIO_SINK (pulsesink)->provided_clock, TRUE));
+ break;
+ default:
+ break;
+@@ -2332,6 +2335,9 @@ gst_pulsesink_change_state (GstElement * element, GstStateChange transition)
+
+ switch (transition) {
+ case GST_STATE_CHANGE_READY_TO_NULL:
++ gst_element_post_message (element,
++ gst_message_new_clock_provide (GST_OBJECT_CAST (element), NULL,
++ FALSE));
+ if (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock)
+ gst_object_unref (GST_BASE_AUDIO_SINK (pulsesink)->provided_clock);
+ GST_BASE_AUDIO_SINK (pulsesink)->provided_clock = NULL;
+--
+1.7.2
+
diff --git a/media-plugins/gst-plugins-pulse/gst-plugins-pulse-0.10.22-r1.ebuild b/media-plugins/gst-plugins-pulse/gst-plugins-pulse-0.10.22-r1.ebuild
new file mode 100644
index 000000000000..24073cc519f8
--- /dev/null
+++ b/media-plugins/gst-plugins-pulse/gst-plugins-pulse-0.10.22-r1.ebuild
@@ -0,0 +1,27 @@
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/media-plugins/gst-plugins-pulse/gst-plugins-pulse-0.10.22-r1.ebuild,v 1.1 2010/08/12 10:32:53 ford_prefect Exp $
+
+inherit gst-plugins-good
+
+DESCRIPTION="GStreamer plugin for the PulseAudio sound server"
+KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 ~sh ~sparc ~x86"
+IUSE=""
+
+# >=0.9.15 ensures working per-stream volume
+RDEPEND=">=media-sound/pulseaudio-0.9.15
+ >=media-libs/gst-plugins-base-0.10.29"
+DEPEND="${RDEPEND}"
+
+src_unpack() {
+ gst-plugins-good_src_unpack
+ cd "${S}"
+
+ # These fix a couple of races condition that can lead to a crash. See
+ # bug #330401 for details.
+ epatch "${FILESDIR}/0001-pulsesink-Create-and-free-the-PA-mainloop-in-NULL-RE.patch"
+ epatch "${FILESDIR}/0002-pulsesink-Allocate-and-free-the-custom-clock-in-NULL.patch"
+ epatch "${FILESDIR}/0003-pulsesrc-Allocate-free-PA-mainloop-during-state-chan.patch"
+ epatch "${FILESDIR}/0004-pulse-Don-t-lock-the-mainloop-in-NULL.patch"
+ epatch "${FILESDIR}/0005-pulsesink-Post-provide-clock-message-on-the-bus-if-t.patch"
+}