diff options
author | Mathieu Duponchelle <mathieu@centricular.com> | 2021-12-16 21:04:53 +0100 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.com> | 2022-01-17 19:43:58 +0000 |
commit | ef5909627d812da8efe284d3ffac3c33aa60f14a (patch) | |
tree | 88fe22e1f8c914f4120afac374f19f7f2362def5 | |
parent | 665a60452c68de9b5bd2789ff2d28dd247a9cb31 (diff) |
rtsp-stream: fix get_rates raciness
Prior to this patch, we considered that a stream was blocking
whenever a pad probe was triggered for either the RTP pad or
the RTCP pad.
This led to situations where we subsequently unblocked and expected
to find a segment on the RTP pad, which was racy.
Instead, we now only consider that the stream is blocking when
the pad probe for the RTP pad has triggered with a blockable object
(buffer, buffer list, gap event).
The RTCP pad is simply blocked without affecting the state of the
stream otherwise.
Fixes #929
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/merge_requests/218>
-rw-r--r-- | gst/rtsp-server/rtsp-stream.c | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/gst/rtsp-server/rtsp-stream.c b/gst/rtsp-server/rtsp-stream.c index e211a28..6889580 100644 --- a/gst/rtsp-server/rtsp-stream.c +++ b/gst/rtsp-server/rtsp-stream.c @@ -5219,7 +5219,7 @@ restart: } static GstPadProbeReturn -pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) +rtp_pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GstRTSPStreamPrivate *priv; GstRTSPStream *stream; @@ -5306,6 +5306,41 @@ done: return ret; } +static GstPadProbeReturn +rtcp_pad_blocking (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) +{ + GstRTSPStreamPrivate *priv; + GstRTSPStream *stream; + GstPadProbeReturn ret = GST_PAD_PROBE_OK; + + stream = user_data; + priv = stream->priv; + + g_mutex_lock (&priv->lock); + + if ((info->type & GST_PAD_PROBE_TYPE_BUFFER) || + (info->type & GST_PAD_PROBE_TYPE_BUFFER_LIST)) { + GST_DEBUG_OBJECT (pad, "Now blocking on buffer"); + } else if ((info->type & GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM)) { + if (GST_EVENT_TYPE (info->data) == GST_EVENT_GAP) { + GST_DEBUG_OBJECT (pad, "Now blocking on gap event"); + ret = GST_PAD_PROBE_OK; + } else { + ret = GST_PAD_PROBE_PASS; + g_mutex_unlock (&priv->lock); + goto done; + } + } else { + g_assert_not_reached (); + } + + g_mutex_unlock (&priv->lock); + +done: + return ret; +} + + static void set_blocked (GstRTSPStream * stream, gboolean blocked) { @@ -5330,11 +5365,20 @@ set_blocked (GstRTSPStream * stream, gboolean blocked) priv->blocked_buffer = FALSE; priv->blocked_running_time = GST_CLOCK_TIME_NONE; priv->blocked_clock_rate = 0; - priv->blocked_id[i] = gst_pad_add_probe (priv->send_src[i], - GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER | - GST_PAD_PROBE_TYPE_BUFFER_LIST | - GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, pad_blocking, - g_object_ref (stream), g_object_unref); + + if (i == 0) { + priv->blocked_id[i] = gst_pad_add_probe (priv->send_src[i], + GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER | + GST_PAD_PROBE_TYPE_BUFFER_LIST | + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, rtp_pad_blocking, + g_object_ref (stream), g_object_unref); + } else { + priv->blocked_id[i] = gst_pad_add_probe (priv->send_src[i], + GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER | + GST_PAD_PROBE_TYPE_BUFFER_LIST | + GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM, rtcp_pad_blocking, + g_object_ref (stream), g_object_unref); + } } } } else { |