From 67dbe75703497c985c35f9d8ac88d7667484475c Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Thu, 11 Nov 2021 03:20:23 +1100 Subject: [PATCH] playsink: Fix reconfiguration after removing text_sink If we previously had subtitles coming in, the video may be chained through a text overlay block. Before, the code would end up trying to link pads that were already linked and video would not get reconnected properly. To fix that, make sure that the candidate pads are actually unlinked first. If a textoverlay is present and no longer needed, it will be cleaned up later in the reconfiguration sequence. Part-of: --- .../gst-plugins-base/gst/playback/gstplaysink.c | 44 +++++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/subprojects/gst-plugins-base/gst/playback/gstplaysink.c b/subprojects/gst-plugins-base/gst/playback/gstplaysink.c index ebef70d..071ba67 100644 --- a/subprojects/gst-plugins-base/gst/playback/gstplaysink.c +++ b/subprojects/gst-plugins-base/gst/playback/gstplaysink.c @@ -3424,19 +3424,43 @@ gst_play_sink_do_reconfigure (GstPlaySink * playsink) /* if we are not part of vis or subtitles, set the ghostpad target */ if (!need_vis && !need_text && (!playsink->textchain || !playsink->text_pad)) { + GstPad *old_sink_peer = gst_pad_get_peer (playsink->videochain->sinkpad); + GstPad *new_peer = NULL; + GST_DEBUG_OBJECT (playsink, "ghosting video sinkpad"); - gst_pad_unlink (playsink->video_srcpad_stream_synchronizer, - playsink->videochain->sinkpad); - if (playsink->videodeinterlacechain - && playsink->videodeinterlacechain->srcpad) - gst_pad_unlink (playsink->videodeinterlacechain->srcpad, - playsink->videochain->sinkpad); if (need_deinterlace) - gst_pad_link_full (playsink->videodeinterlacechain->srcpad, - playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING); + new_peer = playsink->videodeinterlacechain->srcpad; else - gst_pad_link_full (playsink->video_srcpad_stream_synchronizer, - playsink->videochain->sinkpad, GST_PAD_LINK_CHECK_NOTHING); + new_peer = playsink->video_srcpad_stream_synchronizer; + + if (old_sink_peer != new_peer) { + /* Make sure the srcpad we're linking to is unlinked. This may + * leave a deinterlace or text overlay unlinked and lying around, + * but that will be cleaned up below */ + GstPad *old_src_peer = gst_pad_get_peer (new_peer); + if (old_src_peer != NULL) { + gst_pad_unlink (new_peer, old_src_peer); + gst_clear_object (&old_src_peer); + } + + /* And that the pad we're linking to is unlinked */ + if (old_sink_peer != NULL) + gst_pad_unlink (old_sink_peer, playsink->videochain->sinkpad); + + if (!GST_PAD_LINK_SUCCESSFUL (gst_pad_link_full (new_peer, + playsink->videochain->sinkpad, + GST_PAD_LINK_CHECK_NOTHING))) { + if (need_deinterlace) { + GST_WARNING_OBJECT (playsink, + "Failed to link deinterlace srcpad to video sinkpad"); + } else { + GST_WARNING_OBJECT (playsink, + "Failed to link stream synchronizer srcpad to video sinkpad"); + } + } + } + + gst_clear_object (&old_sink_peer); } } else { GST_DEBUG_OBJECT (playsink, "no video needed"); -- 2.7.4