diff --git a/gst/rtpmanager/gstrtpjitterbuffer.c b/gst/rtpmanager/gstrtpjitterbuffer.c index 37fcc77f40..f0571f4a78 100644 --- a/gst/rtpmanager/gstrtpjitterbuffer.c +++ b/gst/rtpmanager/gstrtpjitterbuffer.c @@ -2946,16 +2946,19 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent, expected = priv->next_in_seqnum; - packet_rate = - gst_rtp_packet_rate_ctx_update (&priv->packet_rate_ctx, seqnum, rtptime); + /* don't update packet-rate based on RTX, as those arrive highly unregularly */ + if (!is_rtx) { + packet_rate = gst_rtp_packet_rate_ctx_update (&priv->packet_rate_ctx, + seqnum, rtptime); + GST_TRACE_OBJECT (jitterbuffer, "updated packet_rate: %d", packet_rate); + } max_dropout = gst_rtp_packet_rate_ctx_get_max_dropout (&priv->packet_rate_ctx, priv->max_dropout_time); max_misorder = gst_rtp_packet_rate_ctx_get_max_misorder (&priv->packet_rate_ctx, priv->max_misorder_time); - GST_TRACE_OBJECT (jitterbuffer, - "packet_rate: %d, max_dropout: %d, max_misorder: %d", packet_rate, + GST_TRACE_OBJECT (jitterbuffer, "max_dropout: %d, max_misorder: %d", max_dropout, max_misorder); timer = rtp_timer_queue_find (priv->timers, seqnum); @@ -3021,7 +3024,7 @@ gst_rtp_jitter_buffer_chain (GstPad * pad, GstObject * parent, } /* Special handling of large gaps */ - if ((gap != -1 && gap < -max_misorder) || (gap >= max_dropout)) { + if (!is_rtx && ((gap != -1 && gap < -max_misorder) || (gap >= max_dropout))) { gboolean reset = handle_big_gap_buffer (jitterbuffer, buffer, pt, seqnum, gap, max_dropout, max_misorder); if (reset) { diff --git a/tests/check/elements/rtpjitterbuffer.c b/tests/check/elements/rtpjitterbuffer.c index f055b22432..99cc57ca0c 100644 --- a/tests/check/elements/rtpjitterbuffer.c +++ b/tests/check/elements/rtpjitterbuffer.c @@ -3126,6 +3126,29 @@ GST_START_TEST (test_multiple_lost_do_not_stall) GST_END_TEST; +GST_START_TEST (test_reset_using_rtx_packets_does_not_stall) +{ + GstHarness *h = gst_harness_new ("rtpjitterbuffer"); + BufferArrayCtx bufs[] = { + /* *INDENT-OFF* */ + { 1, 1 * TEST_RTP_TS_DURATION, FALSE, 2000000}, + { 62, 62 * TEST_RTP_TS_DURATION, FALSE, 0}, + { -13, -13 * TEST_RTP_TS_DURATION, TRUE, 10000}, + { 1, 1 * TEST_RTP_TS_DURATION, TRUE, 0}, + { 1, 1 * TEST_RTP_TS_DURATION, TRUE, 0}, + { 1, 1 * TEST_RTP_TS_DURATION, TRUE, 0}, + { 1, 1 * TEST_RTP_TS_DURATION, TRUE, 0}, + { 1, 1 * TEST_RTP_TS_DURATION, TRUE, 0}, + /* *INDENT-ON* */ + }; + + g_object_set (h->element, "latency", 400, + "do-retransmission", TRUE, "do-lost", TRUE, "max-misorder-time", 1, NULL); + fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs))); + gst_harness_teardown (h); +} + +GST_END_TEST; static Suite * rtpjitterbuffer_suite (void) @@ -3196,6 +3219,8 @@ rtpjitterbuffer_suite (void) tcase_add_test (tc_chain, test_reset_timers_does_not_stall); tcase_add_test (tc_chain, test_multiple_lost_do_not_stall); + tcase_add_test (tc_chain, test_reset_using_rtx_packets_does_not_stall); + return s; }