rtpjitterbuffer: Ignore unsolicited rtx packets.
authorThomas Bluemel <tbluemel@control4.com>
Sun, 30 Jun 2019 05:17:28 +0000 (23:17 -0600)
committerThomas Bluemel <tbluemel@control4.com>
Wed, 3 Jul 2019 12:23:07 +0000 (06:23 -0600)
If an rtx packet arrives that hasn't been requested (it might
have been requested from prior to a reset), ignore it so that
it doesn't inadvertently trigger a clock skew.

gst/rtpmanager/gstrtpjitterbuffer.c
gst/rtpmanager/rtpjitterbuffer.c

index 3baad7d..de6b958 100644 (file)
@@ -3023,13 +3023,19 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
 
   /* now check against our expected seqnum */
   if (G_UNLIKELY (expected == -1)) {
+    if (G_UNLIKELY (GST_BUFFER_IS_RETRANSMISSION (buffer))) {
+      /* If the first buffer is an (old) rtx, e.g. from before a reset,
+       * ignore it. */
+      goto unsolicited_rtx;
+    }
+
     GST_DEBUG_OBJECT (jitterbuffer, "First buffer #%d", seqnum);
 
     /* calculate a pts based on rtptime and arrival time (dts) */
     pts =
         rtp_jitter_buffer_calculate_pts (priv->jbuf, dts, estimated_dts,
         rtptime, gst_element_get_base_time (GST_ELEMENT_CAST (jitterbuffer)),
-        0, GST_BUFFER_IS_RETRANSMISSION (buffer));
+        0, FALSE);
 
     if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (pts))) {
       /* A valid timestamp cannot be calculated, discard packet */
@@ -3053,6 +3059,19 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent,
     GST_DEBUG_OBJECT (jitterbuffer, "expected #%d, got #%d, gap of %d",
         expected, seqnum, gap);
 
+    if (G_UNLIKELY (GST_BUFFER_IS_RETRANSMISSION (buffer))) {
+      if (G_UNLIKELY (!priv->do_retransmission))
+        goto unsolicited_rtx;
+
+      /* If this packet is a rtx that we may have actually requested,
+       * make sure we actually did, or whether we still need it. */
+      timer = find_timer (jitterbuffer, seqnum);
+      if (!timer)
+        timer = timer_queue_find (priv->rtx_stats_timers, seqnum);
+      if (!timer)
+        goto unsolicited_rtx;
+    }
+
     if (G_UNLIKELY (gap > 0 && priv->timers->len >= max_dropout)) {
       /* If we have timers for more than RTP_MAX_DROPOUT packets
        * pending this means that we have a huge gap overall. We can
@@ -3317,6 +3336,13 @@ rtx_duplicate:
     gst_buffer_unref (buffer);
     goto finished;
   }
+unsolicited_rtx:
+  {
+    GST_DEBUG_OBJECT (jitterbuffer,
+        "Unsolicited RTX packet #%d detected, dropping", seqnum);
+    gst_buffer_unref (buffer);
+    goto finished;
+  }
 discard_invalid:
   {
     GST_DEBUG_OBJECT (jitterbuffer,
index 9831461..84052ac 100644 (file)
@@ -530,7 +530,7 @@ update_buffer_level (RTPJitterBuffer * jbuf, gint * percent)
  */
 static GstClockTime
 calculate_skew (RTPJitterBuffer * jbuf, guint64 ext_rtptime,
-    GstClockTime gstrtptime, GstClockTime time, gint gap)
+    GstClockTime gstrtptime, GstClockTime time, gint gap, gboolean is_rtx)
 {
   guint64 send_diff, recv_diff;
   gint64 delta;
@@ -544,7 +544,7 @@ calculate_skew (RTPJitterBuffer * jbuf, guint64 ext_rtptime,
 
   /* we don't have an arrival timestamp so we can't do skew detection. we
    * should still apply a timestamp based on RTP timestamp and base_time */
-  if (time == -1 || jbuf->base_time == -1)
+  if (time == -1 || jbuf->base_time == -1 || is_rtx)
     goto no_skew;
 
   /* elapsed time at receiver, includes the jitter */
@@ -925,7 +925,7 @@ rtp_jitter_buffer_calculate_pts (RTPJitterBuffer * jbuf, GstClockTime dts,
 
     /* do skew calculation by measuring the difference between rtptime and the
      * receive dts, this function will return the skew corrected rtptime. */
-    pts = calculate_skew (jbuf, ext_rtptime, gstrtptime, dts, gap);
+    pts = calculate_skew (jbuf, ext_rtptime, gstrtptime, dts, gap, is_rtx);
   }
 
   /* check if timestamps are not going backwards, we can only check this if we