summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathieu Duponchelle <mathieu@centricular.com>2021-12-16 21:04:53 +0100
committerTim-Philipp Müller <tim@centricular.com>2022-01-17 19:43:58 +0000
commitef5909627d812da8efe284d3ffac3c33aa60f14a (patch)
tree88fe22e1f8c914f4120afac374f19f7f2362def5
parent665a60452c68de9b5bd2789ff2d28dd247a9cb31 (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.c56
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 {