From: Edward Hervey Date: Mon, 20 Nov 2017 08:32:07 +0000 (+0100) Subject: rtsp-media: Handle multiple dynamic elements X-Git-Tag: 1.19.3~495^2~377 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2386e91c3642f3a83de6a74c981e0b9ac85a3dd1;p=platform%2Fupstream%2Fgstreamer.git rtsp-media: Handle multiple dynamic elements If we have more than one dynamic payloader in the pipeline, we need to wait until the *last* one emits 'no-more-pads' before switching to PREPARED. Failure to do so would result in a race where some of the streams wouldn't properly be prepared https://bugzilla.gnome.org/show_bug.cgi?id=769521 --- diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 0f8a194..0a9898b 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -142,6 +142,10 @@ struct _GstRTSPMediaPrivate guint latency; /* protected by lock */ GstClock *clock; /* protected by lock */ GstRTSPPublishClockMode publish_clock_mode; + + /* Dynamic element handling */ + guint nb_dynamic_elements; + guint no_more_pads_pending; }; #define DEFAULT_SHARED FALSE @@ -1821,6 +1825,8 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media) gst_object_unref (pad); gst_object_unref (elem); + priv->nb_dynamic_elements++; + have_elem = TRUE; more_elem_remaining = TRUE; mode |= GST_RTSP_TRANSPORT_MODE_RECORD; @@ -2743,9 +2749,15 @@ static void no_more_pads_cb (GstElement * element, GstRTSPMedia * media) { GstRTSPMediaPrivate *priv = media->priv; + gboolean remaining_dynamic; - GST_INFO ("no more pads"); - remove_fakesink (priv); + GST_INFO_OBJECT (element, "no more pads"); + g_mutex_lock (&priv->lock); + priv->no_more_pads_pending--; + remaining_dynamic = priv->no_more_pads_pending; + g_mutex_unlock (&priv->lock); + if (remaining_dynamic == 0) + remove_fakesink (priv); } typedef struct _DynPaySignalHandlers DynPaySignalHandlers; @@ -3047,6 +3059,7 @@ gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread) priv->is_live = FALSE; priv->seekable = -1; priv->buffering = FALSE; + priv->no_more_pads_pending = priv->nb_dynamic_elements; /* we're preparing now */ gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARING); diff --git a/tests/check/gst/media.c b/tests/check/gst/media.c index cf09814..b734673 100644 --- a/tests/check/gst/media.c +++ b/tests/check/gst/media.c @@ -486,21 +486,21 @@ GST_START_TEST (test_media_multidyn_prepare) pool = gst_rtsp_thread_pool_new (); - fail_unless (gst_rtsp_media_n_streams (media) == 0); + fail_unless_equals_int (gst_rtsp_media_n_streams (media), 0); thread = gst_rtsp_thread_pool_get_thread (pool, GST_RTSP_THREAD_TYPE_MEDIA, NULL); fail_unless (gst_rtsp_media_prepare (media, thread)); - fail_unless (gst_rtsp_media_n_streams (media) == 2); + fail_unless_equals_int (gst_rtsp_media_n_streams (media), 2); fail_unless (gst_rtsp_media_unprepare (media)); - fail_unless (gst_rtsp_media_n_streams (media) == 0); + fail_unless_equals_int (gst_rtsp_media_n_streams (media), 0); thread = gst_rtsp_thread_pool_get_thread (pool, GST_RTSP_THREAD_TYPE_MEDIA, NULL); fail_unless (gst_rtsp_media_prepare (media, thread)); - fail_unless (gst_rtsp_media_n_streams (media) == 2); + fail_unless_equals_int (gst_rtsp_media_n_streams (media), 2); fail_unless (gst_rtsp_media_unprepare (media)); - fail_unless (gst_rtsp_media_n_streams (media) == 0); + fail_unless_equals_int (gst_rtsp_media_n_streams (media), 0); gst_object_unref (srcpad0); gst_object_unref (srcpad1);