Commit 1b868cc9 authored by Havard Graff's avatar Havard Graff Committed by Olivier Crête

rtpjitterbuffer: Add and expose more stats and increase testing of it

Add num-pushed and num-lost.
Expose num-late, num-duplicates and avg-jitter.

https://bugzilla.gnome.org/show_bug.cgi?id=769768
parent 531199d5
......@@ -333,6 +333,8 @@ struct _GstRtpJitterBufferPrivate
GstBuffer *last_sr;
/* some accounting */
guint64 num_pushed;
guint64 num_lost;
guint64 num_late;
guint64 num_duplicates;
guint64 num_rtx_requests;
......@@ -710,6 +712,34 @@ gst_rtp_jitter_buffer_class_init (GstRtpJitterBufferClass * klass)
* <listitem>
* <para>
* #guint64
* <classname>&quot;num-pushed&quot;</classname>:
* the number of packets pushed out.
* </para>
* </listitem>
* <listitem>
* <para>
* #guint64
* <classname>&quot;num-lost&quot;</classname>:
* the number of packets considered lost.
* </para>
* </listitem>
* <listitem>
* <para>
* #guint64
* <classname>&quot;num-late&quot;</classname>:
* the number of packets arriving too late.
* </para>
* </listitem>
* <listitem>
* <para>
* #guint64
* <classname>&quot;num-duplicates&quot;</classname>:
* the number of duplicate packets.
* </para>
* </listitem>
* <listitem>
* <para>
* #guint64
* <classname>&quot;rtx-count&quot;</classname>:
* the number of retransmissions requested.
* </para>
......@@ -3165,6 +3195,7 @@ pop_and_push_next (GstRtpJitterBuffer * jitterbuffer, guint seqnum)
"Pushing buffer %d, dts %" GST_TIME_FORMAT ", pts %" GST_TIME_FORMAT,
seqnum, GST_TIME_ARGS (GST_BUFFER_DTS (outbuf)),
GST_TIME_ARGS (GST_BUFFER_PTS (outbuf)));
priv->num_pushed++;
result = gst_pad_push (priv->srcpad, outbuf);
JBUF_LOCK_CHECK (priv, out_flushing);
......@@ -3446,7 +3477,7 @@ do_lost_timeout (GstRtpJitterBuffer * jitterbuffer, TimerData * timer,
else
GST_DEBUG_OBJECT (jitterbuffer, "Packet #%d lost", seqnum);
priv->num_late += lost_packets;
priv->num_lost += lost_packets;
priv->num_rtx_failed += num_rtx_retry;
next_in_seqnum = (seqnum + lost_packets) & 0xffff;
......@@ -4340,15 +4371,21 @@ gst_rtp_jitter_buffer_get_property (GObject * object,
static GstStructure *
gst_rtp_jitter_buffer_create_stats (GstRtpJitterBuffer * jbuf)
{
GstRtpJitterBufferPrivate *priv = jbuf->priv;
GstStructure *s;
JBUF_LOCK (jbuf->priv);
JBUF_LOCK (priv);
s = gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"rtx-count", G_TYPE_UINT64, jbuf->priv->num_rtx_requests,
"rtx-success-count", G_TYPE_UINT64, jbuf->priv->num_rtx_success,
"rtx-per-packet", G_TYPE_DOUBLE, jbuf->priv->avg_rtx_num,
"rtx-rtt", G_TYPE_UINT64, jbuf->priv->avg_rtx_rtt, NULL);
JBUF_UNLOCK (jbuf->priv);
"num-pushed", G_TYPE_UINT64, priv->num_pushed,
"num-lost", G_TYPE_UINT64, priv->num_lost,
"num-late", G_TYPE_UINT64, priv->num_late,
"num-duplicates", G_TYPE_UINT64, priv->num_duplicates,
"avg-jitter", G_TYPE_UINT64, priv->avg_jitter,
"rtx-count", G_TYPE_UINT64, priv->num_rtx_requests,
"rtx-success-count", G_TYPE_UINT64, priv->num_rtx_success,
"rtx-per-packet", G_TYPE_DOUBLE, priv->avg_rtx_num,
"rtx-rtt", G_TYPE_UINT64, priv->avg_rtx_rtt, NULL);
JBUF_UNLOCK (priv);
return s;
}
......@@ -520,6 +520,29 @@ verify_rtx_event (GstEvent * event, guint32 expected_seqnum,
gst_event_unref (event);
}
static gboolean
verify_jb_stats (GstElement * jb, GstStructure * expected)
{
gboolean ret;
GstStructure *actual;
g_object_get (jb, "stats", &actual, NULL);
ret = gst_structure_is_subset (actual, expected);
if (!ret) {
gchar *e_str = gst_structure_to_string (expected);
gchar *a_str = gst_structure_to_string (actual);
fail_unless (ret, "%s is not a subset of %s", e_str, a_str);
g_free (e_str);
g_free (a_str);
}
gst_structure_free (expected);
gst_structure_free (actual);
return ret;
}
GST_START_TEST (test_only_one_lost_event_on_large_gaps)
{
GstHarness *h = gst_harness_new ("rtpjitterbuffer");
......@@ -604,6 +627,10 @@ GST_START_TEST (test_only_one_lost_event_on_large_gaps)
fail_unless_equals_uint64 (10 * GST_SECOND, GST_BUFFER_PTS (out_buf));
gst_buffer_unref (out_buf);
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-lost", G_TYPE_UINT64, (guint64) 499, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -688,6 +715,11 @@ GST_START_TEST (test_two_lost_one_arrives_in_time)
fail_unless_equals_int (5, get_rtp_seq_num (out_buf));
gst_buffer_unref (out_buf);
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 5,
"num-lost", G_TYPE_UINT64, (guint64) 1, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -749,12 +781,76 @@ GST_START_TEST (test_late_packets_still_makes_lost_events)
fail_unless_equals_int (5, get_rtp_seq_num (out_buf));
gst_buffer_unref (out_buf);
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 4,
"num-lost", G_TYPE_UINT64, (guint64) 2, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST (test_num_late_when_considered_lost_arrives)
{
GstHarness *h = gst_harness_new ("rtpjitterbuffer");
gboolean do_lost = __i__ != 0;
gst_harness_set_src_caps (h, generate_caps ());
g_object_set (h->element, "do-lost", do_lost, "latency", 100, NULL);
/* push the first buffer through */
fail_unless_equals_int (GST_FLOW_OK,
gst_harness_push (h, generate_test_buffer (0)));
/* sync on the first packet */
gst_harness_crank_single_clock_wait (h);
/* gap of 1 */
fail_unless_equals_int (GST_FLOW_OK,
gst_harness_push (h, generate_test_buffer (2)));
/* crank to output lost-event */
gst_harness_crank_single_clock_wait (h);
if (do_lost) {
/* drop GstEventStreamStart & GstEventCaps & GstEventSegment */
for (gint i = 0; i < 3; i++)
gst_event_unref (gst_harness_pull_event (h));
/* we should now receive packet-lost-events for buffer 1 */
verify_lost_event (gst_harness_pull_event (h),
1, 1 * PCMU_BUF_DURATION, PCMU_BUF_DURATION);
}
/* pull out buffers to ensure determinism */
gst_buffer_unref (gst_harness_pull (h));
gst_buffer_unref (gst_harness_pull (h));
/* we have one lost packet in the stats */
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 2,
"num-lost", G_TYPE_UINT64, (guint64) 1,
"num-late", G_TYPE_UINT64, (guint64) 0, NULL)));
/* buffer 1 now arrives (too late) */
fail_unless_equals_int (GST_FLOW_OK,
gst_harness_push (h, generate_test_buffer (1)));
/* and this increments num-late */
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 2,
"num-lost", G_TYPE_UINT64, (guint64) 1,
"num-late", G_TYPE_UINT64, (guint64) 1, NULL)));
gst_harness_teardown (h);
}
GST_END_TEST;
GST_START_TEST (test_all_packets_are_timestamped_zero)
{
GstHarness *h = gst_harness_new ("rtpjitterbuffer");
......@@ -809,6 +905,11 @@ GST_START_TEST (test_all_packets_are_timestamped_zero)
fail_unless_equals_int (5, get_rtp_seq_num (out_buf));
gst_buffer_unref (out_buf);
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 4,
"num-lost", G_TYPE_UINT64, (guint64) 2, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -903,8 +1004,6 @@ GST_START_TEST (test_rtx_two_missing)
GstEvent *out_event;
gint jb_latency_ms = 200;
const GstClockTime rtx_retry_timeout = 40 * GST_MSECOND;
GstStructure *rtx_stats;
const GValue *rtx_stat;
gint i;
gst_harness_set_src_caps (h, generate_caps ());
......@@ -1010,17 +1109,12 @@ GST_START_TEST (test_rtx_two_missing)
so no events in the queue */
fail_unless_equals_int (0, gst_harness_events_in_queue (h));
g_object_get (h->element, "stats", &rtx_stats, NULL);
rtx_stat = gst_structure_get_value (rtx_stats, "rtx-count");
fail_unless_equals_uint64 (5, g_value_get_uint64 (rtx_stat));
rtx_stat = gst_structure_get_value (rtx_stats, "rtx-success-count");
fail_unless_equals_uint64 (1, g_value_get_uint64 (rtx_stat));
rtx_stat = gst_structure_get_value (rtx_stats, "rtx-rtt");
fail_unless_equals_uint64 (0, g_value_get_uint64 (rtx_stat));
gst_structure_free (rtx_stats);
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-lost", G_TYPE_UINT64, (guint64) 1,
"rtx-count", G_TYPE_UINT64, (guint64) 5,
"rtx-success-count", G_TYPE_UINT64, (guint64) 1,
"rtx-rtt", G_TYPE_UINT64, (guint64) 0, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
......@@ -1142,6 +1236,13 @@ GST_START_TEST (test_rtx_packet_delay)
fail_unless_equals_int (0, gst_harness_events_in_queue (h));
fail_unless_equals_int (20, gst_harness_upstream_events_in_queue (h));
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-lost", G_TYPE_UINT64, (guint64) 7,
"rtx-count", G_TYPE_UINT64, (guint64) 26,
"rtx-success-count", G_TYPE_UINT64, (guint64) 0,
"rtx-rtt", G_TYPE_UINT64, (guint64) 0, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -1274,6 +1375,15 @@ GST_START_TEST (test_gap_exceeds_latency)
fail_unless_equals_int (0, gst_harness_events_in_queue (h));
fail_unless_equals_int (0, gst_harness_buffers_in_queue (h));
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 11,
"num-lost", G_TYPE_UINT64, (guint64)7,
"rtx-count", G_TYPE_UINT64, (guint64)21,
"rtx-success-count", G_TYPE_UINT64, (guint64)5,
"rtx-rtt", G_TYPE_UINT64, (guint64)0,
NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -1360,6 +1470,10 @@ GST_START_TEST (test_dts_gap_larger_than_latency)
verify_lost_event (out_event, i, i * dur, dur);
}
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-lost", G_TYPE_UINT64, (guint64) 4, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -1488,6 +1602,13 @@ GST_START_TEST (test_considered_lost_packet_in_large_gap_arrives)
fail_unless_equals_int ((4 + seq_offset) & 0xffff, get_rtp_seq_num (buffer));
gst_buffer_unref (buffer);
/* we have lost 3, and one of them arrived eventually, but too late */
fail_unless (verify_jb_stats (h->element,
gst_structure_new ("application/x-rtp-jitterbuffer-stats",
"num-pushed", G_TYPE_UINT64, (guint64) 2,
"num-lost", G_TYPE_UINT64, (guint64) 3,
"num-late", G_TYPE_UINT64, (guint64) 1, NULL)));
gst_object_unref (testclock);
gst_harness_teardown (h);
}
......@@ -1510,6 +1631,8 @@ rtpjitterbuffer_suite (void)
tcase_add_test (tc_chain, test_two_lost_one_arrives_in_time);
tcase_add_test (tc_chain, test_late_packets_still_makes_lost_events);
tcase_add_test (tc_chain, test_all_packets_are_timestamped_zero);
tcase_add_loop_test (tc_chain, test_num_late_when_considered_lost_arrives, 0,
2);
tcase_add_test (tc_chain, test_rtx_expected_next);
tcase_add_test (tc_chain, test_rtx_two_missing);
tcase_add_test (tc_chain, test_rtx_packet_delay);
......
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