diff --git a/gst/playback/gstplaysink.c b/gst/playback/gstplaysink.c index e690c77fca..7f21c68385 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: