From 080eba64de68161026f2b451033d6b455cb92a05 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Sat, 29 Jun 2019 23:17:28 -0600 Subject: [PATCH] rtpjitterbuffer: Ignore unsolicited rtx packets. 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 | 28 +++++++++++++++++++++++++++- gst/rtpmanager/rtpjitterbuffer.c | 6 +++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index 3baad7d..de6b958 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -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, diff --git a/gst/rtpmanager/rtpjitterbuffer.c b/gst/rtpmanager/rtpjitterbuffer.c index 9831461..84052ac 100644 --- a/gst/rtpmanager/rtpjitterbuffer.c +++ b/gst/rtpmanager/rtpjitterbuffer.c @@ -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 -- 2.7.4