diff options
author | Ludvig Rappe <ludvigr@axis.com> | 2020-05-26 15:31:22 +0200 |
---|---|---|
committer | GStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2020-05-27 16:35:49 +0000 |
commit | ae58f7d771998539087a975b2b8a3942f9b7d516 (patch) | |
tree | 75ab508183e76ff1516f7ee03f3f35e022726483 | |
parent | 0526a5c9bb07642f8d3bb050835723dc91758292 (diff) |
rtsp-media: wait for all GstRTSPStreamBlocking messages
Make sure rtsp-media have received a GstRTSPStreamBlocking message from
each active stream when checking if all streams are blocked.
Without this change there will be a race condition when using two or
more streams and rtsp-media receives a GstRTSPStreamBlocking message
from one of the streams. This is because rtsp-media then checks if all
streams are blocked by calling gst_rtsp_stream_is_blocking() for each
stream. This function call returns TRUE if the stream has sent a
GstRTSPStreamBlocking message, however, rtsp-media may have yet to
receive this message. This would then result in that rtsp-media
erroneously thinks it is blocking all streams which could result in
rtsp-media changing state, from PREPARING to PREPARED. In the case of a
preroll, this could result in that rtsp-media thinks that the pipeline
is prerolled even though that might not be the case.
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/merge_requests/124>
-rw-r--r-- | gst/rtsp-server/rtsp-media.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index 1493ecc..b17ced1 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -114,6 +114,7 @@ struct _GstRTSPMediaPrivate gboolean blocked; GstRTSPTransportMode transport_mode; gboolean stop_on_disconnect; + guint blocking_msg_received; GstElement *element; GRecMutex state_lock; /* locking order: state lock, lock */ @@ -493,6 +494,7 @@ gst_rtsp_media_init (GstRTSPMedia * media) priv->do_rate_control = DEFAULT_DO_RATE_CONTROL; priv->dscp_qos = DEFAULT_DSCP_QOS; priv->expected_async_done = FALSE; + priv->blocking_msg_received = 0; } static void @@ -2739,6 +2741,9 @@ media_streams_set_blocked (GstRTSPMedia * media, gboolean blocked) GST_DEBUG ("media %p set blocked %d", media, blocked); priv->blocked = blocked; g_ptr_array_foreach (priv->streams, (GFunc) stream_update_blocked, media); + + if (!blocked) + priv->blocking_msg_received = 0; } static void @@ -2757,6 +2762,7 @@ media_unblock (GstRTSPMedia * media) * streams that are complete */ priv->blocked = FALSE; g_ptr_array_foreach (priv->streams, (GFunc) stream_unblock, media); + priv->blocking_msg_received = 0; } static void @@ -3140,6 +3146,25 @@ set_target_state (GstRTSPMedia * media, GstState state, gboolean do_state) return ret; } +static void +stream_collect_active (GstRTSPStream * stream, guint * active_streams) +{ + if (gst_rtsp_stream_is_complete (stream)) + (*active_streams)++; +} + +static guint +nbr_active_streams (GstRTSPMedia * media) +{ + guint ret = 0; + + g_ptr_array_foreach (media->priv->streams, (GFunc) stream_collect_active, + &ret); + + return ret; +} + + /* called with state-lock */ /* called with state-lock */ static gboolean default_handle_message (GstRTSPMedia * media, GstMessage * message) @@ -3247,8 +3272,11 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message) s = gst_message_get_structure (message); if (gst_structure_has_name (s, "GstRTSPStreamBlocking")) { GST_DEBUG ("media received blocking message"); + priv->blocking_msg_received++; if (priv->blocked && media_streams_blocking (media) && - priv->no_more_pads_pending == 0) { + priv->no_more_pads_pending == 0 && + (priv->blocking_msg_received == nbr_active_streams (media) || + priv->blocking_msg_received == priv->streams->len)) { GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "media is blocking"); g_mutex_lock (&priv->lock); collect_media_stats (media); @@ -3256,6 +3284,8 @@ default_handle_message (GstRTSPMedia * media, GstMessage * message) if (priv->status == GST_RTSP_MEDIA_STATUS_PREPARING) gst_rtsp_media_set_status (media, GST_RTSP_MEDIA_STATUS_PREPARED); + + priv->blocking_msg_received = 0; } } break; |