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?= +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 +