From a18b8c3f169f08c9ad7c8e56935ee7b9178e5ab8 Mon Sep 17 00:00:00 2001 From: Jan Schmidt Date: Mon, 20 Jan 2025 20:00:33 +1100 Subject: [PATCH] rtsp-media: Make sure to add appsink and appsrc to the pipeline When decoupling send/receive loops in rtsp-media using appsink/appsrc, put the appsink in the bin before linking it, as this code path had that wrong. For both sender and receiver paths, if the pipeline already started also add the other appsrc/appsink of the pair to the pipeline immediately instead of putting it in the pending elements list, as they won't get added later. Part-of: --- .../gst/rtsp-server/rtsp-media.c | 39 +++++++++++++++---- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-media.c b/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-media.c index 0b303c94b4..de938b5594 100644 --- a/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-media.c +++ b/subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-media.c @@ -1086,6 +1086,7 @@ gst_rtsp_media_take_pipeline (GstRTSPMedia * media, GstPipeline * pipeline) g_return_if_fail (GST_IS_PIPELINE (pipeline)); priv = media->priv; + GST_DEBUG_OBJECT (media, "Taking pipeline %" GST_PTR_FORMAT, pipeline); g_mutex_lock (&priv->lock); old = priv->pipeline; @@ -2616,31 +2617,53 @@ gst_rtsp_media_create_stream (GstRTSPMedia * media, GstElement * payloader, GstElement *appsink, *appsrc; GstPad *sinkpad, *srcpad; - appsink = gst_element_factory_make ("appsink", NULL); - appsrc = gst_element_factory_make ("appsrc", NULL); + GST_DEBUG_OBJECT (media, + "Using appsrc+appsink to break loops for stream %u", idx); + + gchar *appsink_name = g_strdup_printf ("appsink_stream_%u", idx); + appsink = gst_element_factory_make ("appsink", appsink_name); + g_free (appsink_name); + + gchar *appsrc_name = g_strdup_printf ("appsrc_stream_%u", idx); + appsrc = gst_element_factory_make ("appsrc", appsrc_name); + g_free (appsrc_name); if (GST_PAD_IS_SINK (pad)) { srcpad = gst_element_get_static_pad (appsrc, "src"); gst_bin_add (GST_BIN (priv->element), appsrc); - gst_pad_link (srcpad, pad); + GstPadLinkReturn pad_link = gst_pad_link (srcpad, pad); + g_assert (pad_link == GST_PAD_LINK_OK); + gst_object_unref (srcpad); streampad = gst_element_get_static_pad (appsink, "sink"); - priv->pending_pipeline_elements = - g_list_prepend (priv->pending_pipeline_elements, appsink); + if (priv->pipeline != NULL) { + gst_bin_add (GST_BIN_CAST (priv->pipeline), appsink); + } else { + priv->pending_pipeline_elements = + g_list_prepend (priv->pending_pipeline_elements, appsink); + } } else { sinkpad = gst_element_get_static_pad (appsink, "sink"); - gst_pad_link (pad, sinkpad); + gst_bin_add (GST_BIN (priv->element), appsink); + + GstPadLinkReturn pad_link = gst_pad_link (pad, sinkpad); + g_assert (pad_link == GST_PAD_LINK_OK); + gst_object_unref (sinkpad); streampad = gst_element_get_static_pad (appsrc, "src"); - priv->pending_pipeline_elements = - g_list_prepend (priv->pending_pipeline_elements, appsrc); + if (priv->pipeline != NULL) { + gst_bin_add (GST_BIN_CAST (priv->pipeline), appsrc); + } else { + priv->pending_pipeline_elements = + g_list_prepend (priv->pending_pipeline_elements, appsrc); + } } g_object_set (appsrc, "block", TRUE, "format", GST_FORMAT_TIME, "is-live",