mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-23 23:58:17 +00:00
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
This commit is contained in:
parent
531199d5c4
commit
1b868cc9b1
2 changed files with 180 additions and 20 deletions
|
@ -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>"num-pushed"</classname>:
|
||||
* the number of packets pushed out.
|
||||
* </para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>
|
||||
* #guint64
|
||||
* <classname>"num-lost"</classname>:
|
||||
* the number of packets considered lost.
|
||||
* </para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>
|
||||
* #guint64
|
||||
* <classname>"num-late"</classname>:
|
||||
* the number of packets arriving too late.
|
||||
* </para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>
|
||||
* #guint64
|
||||
* <classname>"num-duplicates"</classname>:
|
||||
* the number of duplicate packets.
|
||||
* </para>
|
||||
* </listitem>
|
||||
* <listitem>
|
||||
* <para>
|
||||
* #guint64
|
||||
* <classname>"rtx-count"</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);
|
||||
|
|
Loading…
Reference in a new issue