summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hervey <edward@centricular.com>2017-11-20 09:32:07 +0100
committerEdward Hervey <bilboed@bilboed.com>2017-11-20 10:00:52 +0100
commit2b5ca38500880fddd74d717b63761379262dc5ae (patch)
tree534a15aefe31e63ba7d22e2d7c377548d542b031
parent838d9c69077e3e9ad628f966af8b0fed13a3e1b2 (diff)
downloadgstreamer-2b5ca38500880fddd74d717b63761379262dc5ae.tar.gz
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
-rw-r--r--gst/rtsp-server/rtsp-media.c17
-rw-r--r--tests/check/gst/media.c10
2 files changed, 20 insertions, 7 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c
index 996f453133..fb2211fac7 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
@@ -1740,6 +1744,8 @@ gst_rtsp_media_collect_streams (GstRTSPMedia * media)
priv->dynamic = g_list_prepend (priv->dynamic, elem);
g_mutex_unlock (&priv->lock);
+ priv->nb_dynamic_elements++;
+
have_elem = TRUE;
more_elem_remaining = TRUE;
mode |= GST_RTSP_TRANSPORT_MODE_PLAY;
@@ -2648,9 +2654,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;
@@ -2955,6 +2967,7 @@ gst_rtsp_media_prepare (GstRTSPMedia * media, GstRTSPThread * thread)
priv->is_live = FALSE;
priv->seekable = FALSE;
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 b0ddb19967..37d8d464e9 100644
--- a/tests/check/gst/media.c
+++ b/tests/check/gst/media.c
@@ -419,21 +419,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);