[gstreamer-plugins-base] Backport a deadlock fix

Adam Jackson ajax at fedoraproject.org
Thu Oct 3 14:09:00 UTC 2013


commit e12d69c342ea15a46ef893eda0ed8c1dffb281fe
Author: Adam Jackson <ajax at redhat.com>
Date:   Thu Oct 3 10:08:51 2013 -0400

    Backport a deadlock fix

 ...-the-visualisation-is-changing-and-reconf.patch |  203 ++++++++++++++++++++
 gstreamer-plugins-base.spec                        |    7 +-
 2 files changed, 209 insertions(+), 1 deletions(-)
---
diff --git a/0001-playsink-If-the-visualisation-is-changing-and-reconf.patch b/0001-playsink-If-the-visualisation-is-changing-and-reconf.patch
new file mode 100644
index 0000000..3e10507
--- /dev/null
+++ b/0001-playsink-If-the-visualisation-is-changing-and-reconf.patch
@@ -0,0 +1,203 @@
+From dd4fe544bcafcf0f00660811d6c5d2b68b69ca25 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= <slomo at circular-chaos.org>
+Date: Wed, 2 Oct 2013 15:02:44 +0200
+Subject: [PATCH] playsink: If the visualisation is changing and
+ reconfiguration is pending, do it all during reconfiguration
+
+Otherwise we will have two pad blocks that want to use the same mutex
+and block each other via the streamlock.
+
+https://bugzilla.gnome.org/show_bug.cgi?id=709210
+---
+ gst/playback/gstplaysink.c | 107 ++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 91 insertions(+), 16 deletions(-)
+
+diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c
+index e690c77..7f21c68 100644
+--- a/gst/playback/gstplaysink.c
++++ b/gst/playback/gstplaysink.c
+@@ -230,6 +230,8 @@ struct _GstPlaySink
+   GstPad *text_sinkpad_stream_synchronizer;
+   gulong text_block_id;
+ 
++  gulong vis_pad_block_id;
++
+   guint32 pending_blocked_pads;
+ 
+   /* properties */
+@@ -937,6 +939,8 @@ gst_play_sink_vis_blocked (GstPad * tee_pad, GstPadProbeInfo * info,
+       chain->vissrcpad);
+ 
+ done:
++  playsink->vis_pad_block_id = 0;
++
+   GST_PLAY_SINK_UNLOCK (playsink);
+ 
+   /* remove the probe and unblock the pad */
+@@ -977,8 +981,11 @@ gst_play_sink_set_vis_plugin (GstPlaySink * playsink, GstElement * vis)
+    * function returns FALSE but the previous pad block will do the right thing
+    * anyway. */
+   GST_DEBUG_OBJECT (playsink, "blocking vis pad");
+-  gst_pad_add_probe (chain->blockpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+-      gst_play_sink_vis_blocked, playsink, NULL);
++  if (!playsink->vis_pad_block_id && !playsink->audio_block_id
++      && !playsink->video_block_id && !playsink->text_block_id)
++    playsink->vis_pad_block_id =
++        gst_pad_add_probe (chain->blockpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
++        gst_play_sink_vis_blocked, playsink, NULL);
+ done:
+   GST_PLAY_SINK_UNLOCK (playsink);
+ 
+@@ -3339,21 +3346,54 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink)
+ 
+     if (playsink->vischain) {
+       GST_DEBUG_OBJECT (playsink, "setting up vis chain");
+-      srcpad =
+-          gst_element_get_static_pad (playsink->vischain->chain.bin, "src");
+-      add_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE);
+-      activate_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE);
+-      if (playsink->audio_tee_vissrc == NULL) {
+-        playsink->audio_tee_vissrc =
+-            gst_element_get_request_pad (playsink->audio_tee, "src_%u");
++
++      /* Just change vis plugin or set up chain? */
++      if (playsink->vischain->vis != playsink->visualisation) {
++        /* unlink the old plugin and unghost the pad */
++        gst_pad_unlink (playsink->vischain->vispeerpad,
++            playsink->vischain->vissinkpad);
++        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
++                vischain->srcpad), NULL);
++
++        /* set the old plugin to NULL and remove */
++        gst_element_set_state (playsink->vischain->vis, GST_STATE_NULL);
++        gst_bin_remove (GST_BIN_CAST (playsink->vischain->chain.bin),
++            playsink->vischain->vis);
++
++        /* add new plugin and set state to playing */
++        playsink->vischain->vis = playsink->visualisation;
++        gst_bin_add (GST_BIN_CAST (playsink->vischain->chain.bin),
++            playsink->vischain->vis);
++        gst_element_set_state (playsink->vischain->vis, GST_STATE_PLAYING);
++
++        /* get pads */
++        playsink->vischain->vissinkpad =
++            gst_element_get_static_pad (playsink->vischain->vis, "sink");
++        playsink->vischain->vissrcpad =
++            gst_element_get_static_pad (playsink->vischain->vis, "src");
++
++        /* link pads */
++        gst_pad_link_full (playsink->vischain->vispeerpad,
++            playsink->vischain->vissinkpad, GST_PAD_LINK_CHECK_NOTHING);
++        gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (playsink->
++                vischain->srcpad), playsink->vischain->vissrcpad);
++      } else {
++        srcpad =
++            gst_element_get_static_pad (playsink->vischain->chain.bin, "src");
++        add_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE);
++        activate_chain (GST_PLAY_CHAIN (playsink->vischain), TRUE);
++        if (playsink->audio_tee_vissrc == NULL) {
++          playsink->audio_tee_vissrc =
++              gst_element_get_request_pad (playsink->audio_tee, "src_%u");
++        }
++        gst_pad_link_full (playsink->audio_tee_vissrc,
++            playsink->vischain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
++        gst_pad_link_full (srcpad, playsink->video_sinkpad_stream_synchronizer,
++            GST_PAD_LINK_CHECK_NOTHING);
++        gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
++            playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
++        gst_object_unref (srcpad);
+       }
+-      gst_pad_link_full (playsink->audio_tee_vissrc,
+-          playsink->vischain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
+-      gst_pad_link_full (srcpad, playsink->video_sinkpad_stream_synchronizer,
+-          GST_PAD_LINK_CHECK_NOTHING);
+-      gst_pad_link_full (playsink->video_srcpad_stream_synchronizer,
+-          playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING);
+-      gst_object_unref (srcpad);
+     }
+   } else {
+     GST_DEBUG_OBJECT (playsink, "no vis needed");
+@@ -3802,6 +3842,11 @@ video_set_blocked (GstPlaySink * playsink, gboolean blocked)
+         GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
+             (playsink->video_pad)));
+     if (blocked && playsink->video_block_id == 0) {
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       playsink->video_block_id =
+           gst_pad_add_probe (opad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+           sinkpad_blocked_cb, playsink, NULL);
+@@ -3824,10 +3869,20 @@ audio_set_blocked (GstPlaySink * playsink, gboolean blocked)
+         GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
+             (playsink->audio_pad)));
+     if (blocked && playsink->audio_block_id == 0) {
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       playsink->audio_block_id =
+           gst_pad_add_probe (opad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+           sinkpad_blocked_cb, playsink, NULL);
+     } else if (!blocked && playsink->audio_block_id) {
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       gst_pad_remove_probe (opad, playsink->audio_block_id);
+       PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO_RAW);
+       PENDING_FLAG_UNSET (playsink, GST_PLAY_SINK_TYPE_AUDIO);
+@@ -3846,6 +3901,11 @@ text_set_blocked (GstPlaySink * playsink, gboolean blocked)
+         GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD
+             (playsink->text_pad)));
+     if (blocked && playsink->text_block_id == 0) {
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       playsink->text_block_id =
+           gst_pad_add_probe (opad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+           sinkpad_blocked_cb, playsink, NULL);
+@@ -3995,6 +4055,11 @@ gst_play_sink_refresh_pad (GstPlaySink * playsink, GstPad * pad,
+     GstPad *blockpad =
+         GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (pad)));
+ 
++    if (playsink->vis_pad_block_id)
++      gst_pad_remove_probe (((GstPlayVisChain *) playsink->vischain)->blockpad,
++          playsink->vis_pad_block_id);
++    playsink->vis_pad_block_id = 0;
++
+     *block_id =
+         gst_pad_add_probe (blockpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+         sinkpad_blocked_cb, playsink, NULL);
+@@ -4128,6 +4193,11 @@ gst_play_sink_request_pad (GstPlaySink * playsink, GstPlaySinkType type)
+       GstPad *blockpad =
+           GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD (res)));
+ 
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       *block_id =
+           gst_pad_add_probe (blockpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
+           sinkpad_blocked_cb, playsink, NULL);
+@@ -4433,6 +4503,11 @@ gst_play_sink_change_state (GstElement * element, GstStateChange transition)
+       video_set_blocked (playsink, FALSE);
+       audio_set_blocked (playsink, FALSE);
+       text_set_blocked (playsink, FALSE);
++      if (playsink->vis_pad_block_id)
++        gst_pad_remove_probe (((GstPlayVisChain *) playsink->
++                vischain)->blockpad, playsink->vis_pad_block_id);
++      playsink->vis_pad_block_id = 0;
++
+       GST_PLAY_SINK_UNLOCK (playsink);
+       /* fall through */
+     case GST_STATE_CHANGE_READY_TO_NULL:
+-- 
+1.8.3.1
+
diff --git a/gstreamer-plugins-base.spec b/gstreamer-plugins-base.spec
index a876cca..461c2f7 100644
--- a/gstreamer-plugins-base.spec
+++ b/gstreamer-plugins-base.spec
@@ -4,7 +4,7 @@
 
 Name:           %{gstreamer}-plugins-base
 Version:        %{gstreamer_version}
-Release:        5%{?dist}
+Release:        6%{?dist}
 Summary:        GStreamer streaming media framework base plug-ins
 
 Group:          Applications/Multimedia
@@ -43,6 +43,7 @@ BuildRequires:  gtk-doc >= 1.3
 BuildRequires:  PyXML
 
 Patch0: 0001-missing-plugins-Remove-the-mpegaudioversion-field.patch
+Patch1: 0001-playsink-If-the-visualisation-is-changing-and-reconf.patch
 
 %description
 GStreamer is a streaming media framework, based on graphs of filters which
@@ -57,6 +58,7 @@ This package contains a set of well-maintained base plug-ins.
 %prep
 %setup -q -n gst-plugins-base-%{version}
 %patch0 -p1 -b .mpegaudioversion
+%patch1 -p1 -b .deadlock
 
 %build
 %configure \
@@ -325,6 +327,9 @@ library.
 %doc %{_datadir}/gtk-doc/html/gst-plugins-base-plugins-%{majorminor}
 
 %changelog
+* Thu Oct 03 2013 Adam Jackson <ajax at redhat.com> 0.10.36-6
+- Backport a deadlock fix
+
 * Sat Aug 03 2013 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.10.36-5
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
 


More information about the scm-commits mailing list