Commit 79fef14e authored by Håvard Graff's avatar Håvard Graff

rtpjitterbuffer: add failing test that reproduces a stall

So what happens here is that at some point we receive packet #10508,
which triggers the big gap logic, placing that buffer inside the
gap_packets GList:
gst_rtp_jitter_buffer_chain: expected #10529, got #10508, gap of -21
handle_big_gap_buffer: buffer too old -21 < -20, first one - waiting

Then packet #10550 arrives:
gst_rtp_jitter_buffer_chain: expected #10530, got #10550, gap of 20

This causes too many timers to be pending, causing a reset:
gst_rtp_jitter_buffer_chain: 182 pending timers > 180 - resetting
gst_rtp_jitter_buffer_reset:< flush and reset jitterbuffer

Inside the reset() code, the next_seqnum is set to the first buffer
in gap_packets, #10508:
gst_rtp_jitter_buffer_reset: setting next_seqnum to #10508

And reset() calls chain() with all its gap_packets, pushing it out:
gst_rtp_jitter_buffer_chain: Received packet #10508 at time 123:45:05.364650711, discont 0, rtx 1

However, #10508 is actually an RTX packet, so it gets dropped:
gst_rtp_jitter_buffer_chain:<rtpjitterbuffer0> Unsolicited RTX packet #10508 detected, dropping

Next #10550 is pushed from reset():
gst_rtp_jitter_buffer_chain:<rtpjitterbuffer0> Received packet #10550 at time 123:45:05.516136868, discont 0, rtx 0

But because next_seqnum is set to #10508, we get this:
handle_next_buffer: Sequence number GAP detected: expected 10508 instead of 10550 (42 missing)

So now the jitterbuffer is completely stalled, all buffer arriving now will
just queue up until it sees the promised #10508, which will be ~65000
packets from now, and we will trigger the "full" logic before then,
causing a deadlock.
parent 3368ed44
Pipeline #126632 failed with stages
in 76 minutes and 56 seconds
......@@ -2743,6 +2743,9 @@ gst_rtp_jitter_buffer_reset (GstRtpJitterBuffer * jitterbuffer,
priv->next_seqnum = seqnum;
}
GST_DEBUG_OBJECT (jitterbuffer, "setting next_seqnum to #%u",
priv->next_seqnum);
priv->last_in_pts = -1;
priv->next_in_seqnum = -1;
......
......@@ -3108,6 +3108,28 @@ GST_START_TEST (test_reset_timers_does_not_stall)
GST_END_TEST;
GST_START_TEST (test_reset_timers_does_not_stall_2)
{
GstHarness *h = gst_harness_new ("rtpjitterbuffer");
BufferArrayCtx bufs[] = {
/* *INDENT-OFF* */
{278, 21920, FALSE, 31695},
{ 37, 5920, FALSE, 89911},
{173, 13600, FALSE, 108078},
{ 30, 27200, FALSE, 190920},
{-20, 43840, TRUE, 150552},
{ 42, 4480, FALSE, 131498},
/* *INDENT-ON* */
};
g_object_set (h->element, "latency", 200,
"do-retransmission", TRUE, "do-lost", TRUE, NULL);
fail_unless (check_for_stall (h, bufs, G_N_ELEMENTS (bufs)));
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST (test_multiple_lost_do_not_stall)
{
GstHarness *h = gst_harness_new ("rtpjitterbuffer");
......@@ -3195,6 +3217,7 @@ rtpjitterbuffer_suite (void)
tcase_add_test (tc_chain, test_drop_messages_interval);
tcase_add_test (tc_chain, test_reset_timers_does_not_stall);
tcase_add_test (tc_chain, test_reset_timers_does_not_stall_2);
tcase_add_test (tc_chain, test_multiple_lost_do_not_stall);
return s;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment