rtsp-stream: fix get_rates raciness
authorMathieu Duponchelle <mathieu@centricular.com>
Thu, 16 Dec 2021 20:04:53 +0000 (21:04 +0100)
committerGStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 16 Dec 2021 22:18:12 +0000 (22:18 +0000)
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/gstreamer/-/merge_requests/1452>

subprojects/gst-rtsp-server/gst/rtsp-server/rtsp-stream.c

index 92ef358..90aa191 100644 (file)
@@ -5295,7 +5295,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;
@@ -5382,6 +5382,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)
 {
@@ -5406,11 +5441,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 {