3 * unit test for gstrtpsession
5 * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
6 * Copyright (C) 2013 Collabora Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
23 #define GLIB_DISABLE_DEPRECATION_WARNINGS
25 #include <gst/check/gstharness.h>
26 #include <gst/check/gstcheck.h>
27 #include <gst/check/gsttestclock.h>
28 #include <gst/check/gstharness.h>
30 #include <gst/rtp/gstrtpbuffer.h>
31 #include <gst/rtp/gstrtcpbuffer.h>
32 #include <gst/net/gstnetaddressmeta.h>
33 #include <gst/video/video.h>
35 #define TEST_BUF_CLOCK_RATE 8000
37 #define TEST_BUF_SSRC 0x01BADBAD
38 #define TEST_BUF_MS 20
39 #define TEST_BUF_DURATION (TEST_BUF_MS * GST_MSECOND)
40 #define TEST_BUF_SIZE (64000 * TEST_BUF_MS / 1000)
41 #define TEST_RTP_TS_DURATION (TEST_BUF_CLOCK_RATE * TEST_BUF_MS / 1000)
46 return gst_caps_new_simple ("application/x-rtp",
47 "clock-rate", G_TYPE_INT, TEST_BUF_CLOCK_RATE,
48 "payload", G_TYPE_INT, TEST_BUF_PT, NULL);
52 generate_test_buffer_full (GstClockTime dts,
53 guint seq_num, guint32 rtp_ts, guint ssrc)
58 GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
60 buf = gst_rtp_buffer_new_allocate (TEST_BUF_SIZE, 0, 0);
61 GST_BUFFER_DTS (buf) = dts;
63 gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
64 gst_rtp_buffer_set_payload_type (&rtp, TEST_BUF_PT);
65 gst_rtp_buffer_set_seq (&rtp, seq_num);
66 gst_rtp_buffer_set_timestamp (&rtp, rtp_ts);
67 gst_rtp_buffer_set_ssrc (&rtp, ssrc);
69 payload = gst_rtp_buffer_get_payload (&rtp);
70 for (i = 0; i < TEST_BUF_SIZE; i++)
73 gst_rtp_buffer_unmap (&rtp);
79 generate_test_buffer (guint seq_num, guint ssrc)
81 return generate_test_buffer_full (seq_num * TEST_BUF_DURATION,
82 seq_num, seq_num * TEST_RTP_TS_DURATION, ssrc);
87 GstHarness *send_rtp_h;
88 GstHarness *recv_rtp_h;
92 GObject *internal_session;
93 GstTestClock *testclock;
98 _pt_map_requested (GstElement * element, guint pt, gpointer data)
100 SessionHarness *h = data;
101 return gst_caps_copy (h->caps);
104 static SessionHarness *
105 session_harness_new (void)
107 SessionHarness *h = g_new0 (SessionHarness, 1);
108 h->caps = generate_caps ();
110 h->testclock = GST_TEST_CLOCK_CAST (gst_test_clock_new ());
111 gst_system_clock_set_default (GST_CLOCK_CAST (h->testclock));
113 h->session = gst_element_factory_make ("rtpsession", NULL);
114 gst_element_set_clock (h->session, GST_CLOCK_CAST (h->testclock));
116 h->send_rtp_h = gst_harness_new_with_element (h->session,
117 "send_rtp_sink", "send_rtp_src");
118 gst_harness_set_src_caps (h->send_rtp_h, gst_caps_copy (h->caps));
120 h->recv_rtp_h = gst_harness_new_with_element (h->session,
121 "recv_rtp_sink", "recv_rtp_src");
122 gst_harness_set_src_caps (h->recv_rtp_h, gst_caps_copy (h->caps));
124 h->rtcp_h = gst_harness_new_with_element (h->session,
125 "recv_rtcp_sink", "send_rtcp_src");
126 gst_harness_set_src_caps_str (h->rtcp_h, "application/x-rtcp");
128 g_signal_connect (h->session, "request-pt-map",
129 (GCallback) _pt_map_requested, h);
131 g_object_get (h->session, "internal-session", &h->internal_session, NULL);
137 session_harness_free (SessionHarness * h)
139 gst_system_clock_set_default (NULL);
141 gst_caps_unref (h->caps);
142 gst_object_unref (h->testclock);
144 gst_harness_teardown (h->rtcp_h);
145 gst_harness_teardown (h->recv_rtp_h);
146 gst_harness_teardown (h->send_rtp_h);
148 g_object_unref (h->internal_session);
149 gst_object_unref (h->session);
154 session_harness_send_rtp (SessionHarness * h, GstBuffer * buf)
156 return gst_harness_push (h->send_rtp_h, buf);
160 session_harness_recv_rtp (SessionHarness * h, GstBuffer * buf)
162 return gst_harness_push (h->recv_rtp_h, buf);
166 session_harness_recv_rtcp (SessionHarness * h, GstBuffer * buf)
168 return gst_harness_push (h->rtcp_h, buf);
172 session_harness_pull_rtcp (SessionHarness * h)
174 return gst_harness_pull (h->rtcp_h);
178 session_harness_crank_clock (SessionHarness * h)
180 gst_test_clock_crank (h->testclock);
184 session_harness_advance_and_crank (SessionHarness * h, GstClockTime delta)
186 GstClockID res, pending;
188 gst_test_clock_wait_for_next_pending_id (h->testclock, &pending);
189 gst_test_clock_advance_time (h->testclock, delta);
190 res = gst_test_clock_process_next_clock_id (h->testclock);
196 gst_clock_id_unref (res);
197 gst_clock_id_unref (pending);
202 session_harness_produce_rtcp (SessionHarness * h, gint num_rtcp_packets)
204 /* due to randomness in rescheduling of RTCP timeout, we need to
205 keep cranking until we have the desired amount of packets */
206 while (gst_harness_buffers_in_queue (h->rtcp_h) < num_rtcp_packets) {
207 session_harness_crank_clock (h);
208 /* allow the rtcp-thread to settle before checking the queue */
209 gst_test_clock_wait_for_next_pending_id (h->testclock, NULL);
214 session_harness_force_key_unit (SessionHarness * h,
215 guint count, guint ssrc, guint payload, gint * reqid, guint64 * sfr)
217 GstClockTime running_time = GST_CLOCK_TIME_NONE;
218 gboolean all_headers = TRUE;
220 GstStructure *s = gst_structure_new ("GstForceKeyUnit",
221 "running-time", GST_TYPE_CLOCK_TIME, running_time,
222 "all-headers", G_TYPE_BOOLEAN, all_headers,
223 "count", G_TYPE_UINT, count,
224 "ssrc", G_TYPE_UINT, ssrc,
225 "payload", G_TYPE_UINT, payload,
229 gst_structure_set (s, "reqid", G_TYPE_INT, *reqid, NULL);
231 gst_structure_set (s, "sfr", G_TYPE_UINT64, *sfr, NULL);
233 gst_harness_push_upstream_event (h->recv_rtp_h,
234 gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s));
238 session_harness_rtp_retransmission_request (SessionHarness * h,
239 guint ssrc, guint seqnum, guint delay, guint deadline, guint avg_rtt)
241 GstClockTime running_time = GST_CLOCK_TIME_NONE;
243 GstStructure *s = gst_structure_new ("GstRTPRetransmissionRequest",
244 "running-time", GST_TYPE_CLOCK_TIME, running_time,
245 "ssrc", G_TYPE_UINT, ssrc,
246 "seqnum", G_TYPE_UINT, seqnum,
247 "delay", G_TYPE_UINT, delay,
248 "deadline", G_TYPE_UINT, deadline,
249 "avg-rtt", G_TYPE_UINT, avg_rtt,
251 gst_harness_push_upstream_event (h->recv_rtp_h,
252 gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, s));
255 GST_START_TEST (test_multiple_ssrc_rr)
257 SessionHarness *h = session_harness_new ();
259 GstBuffer *in_buf, *out_buf;
260 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
261 GstRTCPPacket rtcp_packet;
270 /* receive buffers with multiple ssrcs */
271 for (i = 0; i < 2; i++) {
272 for (j = 0; j < G_N_ELEMENTS (ssrcs); j++) {
273 in_buf = generate_test_buffer (i, ssrcs[j]);
274 res = session_harness_recv_rtp (h, in_buf);
275 fail_unless_equals_int (GST_FLOW_OK, res);
279 /* crank the rtcp-thread and pull out the rtcp-packet we have generated */
280 session_harness_crank_clock (h);
281 out_buf = session_harness_pull_rtcp (h);
283 /* verify we have report blocks for both ssrcs */
284 g_assert (out_buf != NULL);
285 fail_unless (gst_rtcp_buffer_validate (out_buf));
286 gst_rtcp_buffer_map (out_buf, GST_MAP_READ, &rtcp);
287 g_assert (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
288 fail_unless_equals_int (GST_RTCP_TYPE_RR,
289 gst_rtcp_packet_get_type (&rtcp_packet));
291 fail_unless_equals_int (G_N_ELEMENTS (ssrcs),
292 gst_rtcp_packet_get_rb_count (&rtcp_packet));
295 for (i = 0; i < G_N_ELEMENTS (ssrcs); i++) {
297 gst_rtcp_packet_get_rb (&rtcp_packet, i, &ssrc,
298 NULL, NULL, NULL, NULL, NULL, NULL);
299 for (j = 0; j < G_N_ELEMENTS (ssrcs); j++) {
300 if (ssrcs[j] == ssrc)
304 fail_unless_equals_int (G_N_ELEMENTS (ssrcs), ssrc_match);
306 gst_rtcp_buffer_unmap (&rtcp);
307 gst_buffer_unref (out_buf);
309 session_harness_free (h);
314 /* This verifies that rtpsession will correctly place RBs round-robin
315 * across multiple RRs when there are too many senders that their RBs
316 * do not fit in one RR */
317 GST_START_TEST (test_multiple_senders_roundrobin_rbs)
319 SessionHarness *h = session_harness_new ();
322 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
323 GstRTCPPacket rtcp_packet;
326 GHashTable *rb_ssrcs, *tmp_set;
328 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
330 for (i = 0; i < 2; i++) { /* cycles between RR reports */
331 for (j = 0; j < 5; j++) { /* packets per ssrc */
332 gint seq = (i * 5) + j;
333 for (k = 0; k < 35; k++) { /* number of ssrcs */
334 buf = generate_test_buffer (seq, 10000 + k);
335 res = session_harness_recv_rtp (h, buf);
336 fail_unless_equals_int (GST_FLOW_OK, res);
341 rb_ssrcs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
342 (GDestroyNotify) g_hash_table_unref);
344 /* verify the rtcp packets */
345 for (i = 0; i < 2; i++) {
346 guint expected_rb_count = (i < 1) ? GST_RTCP_MAX_RB_COUNT :
347 (35 - GST_RTCP_MAX_RB_COUNT);
349 session_harness_produce_rtcp (h, 1);
350 buf = session_harness_pull_rtcp (h);
351 g_assert (buf != NULL);
352 fail_unless (gst_rtcp_buffer_validate (buf));
354 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
355 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
356 fail_unless_equals_int (GST_RTCP_TYPE_RR,
357 gst_rtcp_packet_get_type (&rtcp_packet));
359 ssrc = gst_rtcp_packet_rr_get_ssrc (&rtcp_packet);
360 fail_unless_equals_int (0xDEADBEEF, ssrc);
362 /* inspect the RBs */
363 fail_unless_equals_int (expected_rb_count,
364 gst_rtcp_packet_get_rb_count (&rtcp_packet));
367 tmp_set = g_hash_table_new (g_direct_hash, g_direct_equal);
368 g_hash_table_insert (rb_ssrcs, GUINT_TO_POINTER (ssrc), tmp_set);
370 tmp_set = g_hash_table_lookup (rb_ssrcs, GUINT_TO_POINTER (ssrc));
374 for (j = 0; j < expected_rb_count; j++) {
375 gst_rtcp_packet_get_rb (&rtcp_packet, j, &ssrc, NULL, NULL,
376 NULL, NULL, NULL, NULL);
377 g_assert_cmpint (ssrc, >=, 10000);
378 g_assert_cmpint (ssrc, <=, 10035);
379 g_hash_table_add (tmp_set, GUINT_TO_POINTER (ssrc));
382 gst_rtcp_buffer_unmap (&rtcp);
383 gst_buffer_unref (buf);
386 /* now verify all received ssrcs have been reported */
387 fail_unless_equals_int (1, g_hash_table_size (rb_ssrcs));
388 tmp_set = g_hash_table_lookup (rb_ssrcs, GUINT_TO_POINTER (0xDEADBEEF));
390 fail_unless_equals_int (35, g_hash_table_size (tmp_set));
392 g_hash_table_unref (rb_ssrcs);
393 session_harness_free (h);
398 GST_START_TEST (test_no_rbs_for_internal_senders)
400 SessionHarness *h = session_harness_new ();
403 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
404 GstRTCPPacket rtcp_packet;
407 GHashTable *sr_ssrcs;
408 GHashTable *rb_ssrcs, *tmp_set;
410 /* Push RTP from our send SSRCs */
411 for (j = 0; j < 5; j++) { /* packets per ssrc */
412 for (k = 0; k < 2; k++) { /* number of ssrcs */
413 buf = generate_test_buffer (j, 10000 + k);
414 res = session_harness_send_rtp (h, buf);
415 fail_unless_equals_int (GST_FLOW_OK, res);
419 /* crank the RTCP pad thread */
420 session_harness_crank_clock (h);
422 sr_ssrcs = g_hash_table_new (g_direct_hash, g_direct_equal);
424 /* verify the rtcp packets */
425 for (i = 0; i < 2; i++) {
426 buf = session_harness_pull_rtcp (h);
427 g_assert (buf != NULL);
428 g_assert (gst_rtcp_buffer_validate (buf));
430 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
431 g_assert (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
432 fail_unless_equals_int (GST_RTCP_TYPE_SR,
433 gst_rtcp_packet_get_type (&rtcp_packet));
435 gst_rtcp_packet_sr_get_sender_info (&rtcp_packet, &ssrc, NULL, NULL,
437 g_assert_cmpint (ssrc, >=, 10000);
438 g_assert_cmpint (ssrc, <=, 10001);
439 g_hash_table_add (sr_ssrcs, GUINT_TO_POINTER (ssrc));
441 /* There should be no RBs as there are no remote senders */
442 fail_unless_equals_int (0, gst_rtcp_packet_get_rb_count (&rtcp_packet));
444 gst_rtcp_buffer_unmap (&rtcp);
445 gst_buffer_unref (buf);
448 /* Ensure both internal senders generated RTCP */
449 fail_unless_equals_int (2, g_hash_table_size (sr_ssrcs));
450 g_hash_table_unref (sr_ssrcs);
452 /* Generate RTP from remote side */
453 for (j = 0; j < 5; j++) { /* packets per ssrc */
454 for (k = 0; k < 2; k++) { /* number of ssrcs */
455 buf = generate_test_buffer (j, 20000 + k);
456 res = session_harness_recv_rtp (h, buf);
457 fail_unless_equals_int (GST_FLOW_OK, res);
461 sr_ssrcs = g_hash_table_new (g_direct_hash, g_direct_equal);
462 rb_ssrcs = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL,
463 (GDestroyNotify) g_hash_table_unref);
465 /* verify the rtcp packets */
466 for (i = 0; i < 2; i++) {
467 session_harness_produce_rtcp (h, 1);
468 buf = session_harness_pull_rtcp (h);
469 g_assert (buf != NULL);
470 g_assert (gst_rtcp_buffer_validate (buf));
472 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
473 g_assert (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
474 fail_unless_equals_int (GST_RTCP_TYPE_SR,
475 gst_rtcp_packet_get_type (&rtcp_packet));
477 gst_rtcp_packet_sr_get_sender_info (&rtcp_packet, &ssrc, NULL, NULL,
479 g_assert_cmpint (ssrc, >=, 10000);
480 g_assert_cmpint (ssrc, <=, 10001);
481 g_hash_table_add (sr_ssrcs, GUINT_TO_POINTER (ssrc));
483 /* There should be 2 RBs: one for each remote sender */
484 fail_unless_equals_int (2, gst_rtcp_packet_get_rb_count (&rtcp_packet));
486 tmp_set = g_hash_table_new (g_direct_hash, g_direct_equal);
487 g_hash_table_insert (rb_ssrcs, GUINT_TO_POINTER (ssrc), tmp_set);
489 for (j = 0; j < 2; j++) {
490 gst_rtcp_packet_get_rb (&rtcp_packet, j, &ssrc, NULL, NULL,
491 NULL, NULL, NULL, NULL);
492 g_assert_cmpint (ssrc, >=, 20000);
493 g_assert_cmpint (ssrc, <=, 20001);
494 g_hash_table_add (tmp_set, GUINT_TO_POINTER (ssrc));
497 gst_rtcp_buffer_unmap (&rtcp);
498 gst_buffer_unref (buf);
501 /* now verify all received ssrcs have been reported */
502 fail_unless_equals_int (2, g_hash_table_size (sr_ssrcs));
503 fail_unless_equals_int (2, g_hash_table_size (rb_ssrcs));
504 for (i = 10000; i < 10002; i++) {
505 tmp_set = g_hash_table_lookup (rb_ssrcs, GUINT_TO_POINTER (i));
507 fail_unless_equals_int (2, g_hash_table_size (tmp_set));
510 g_hash_table_unref (rb_ssrcs);
511 g_hash_table_unref (sr_ssrcs);
513 session_harness_free (h);
518 GST_START_TEST (test_internal_sources_timeout)
520 SessionHarness *h = session_harness_new ();
524 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
525 GstRTCPPacket rtcp_packet;
526 GstRTCPType rtcp_type;
532 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
533 g_object_get (h->internal_session, "internal-ssrc", &internal_ssrc, NULL);
534 fail_unless_equals_int (0xDEADBEEF, internal_ssrc);
536 for (i = 1; i < 4; i++) {
537 buf = generate_test_buffer (i, 0xBEEFDEAD);
538 res = session_harness_recv_rtp (h, buf);
539 fail_unless_equals_int (GST_FLOW_OK, res);
542 /* verify that rtpsession has sent RR for an internally-created
543 * RTPSource that is using the internal-ssrc */
544 session_harness_produce_rtcp (h, 1);
545 buf = session_harness_pull_rtcp (h);
547 fail_unless (buf != NULL);
548 fail_unless (gst_rtcp_buffer_validate (buf));
549 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
550 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
551 fail_unless_equals_int (GST_RTCP_TYPE_RR,
552 gst_rtcp_packet_get_type (&rtcp_packet));
553 ssrc = gst_rtcp_packet_rr_get_ssrc (&rtcp_packet);
554 fail_unless_equals_int (ssrc, internal_ssrc);
555 gst_rtcp_buffer_unmap (&rtcp);
556 gst_buffer_unref (buf);
558 /* ok, now let's push some RTP packets */
559 caps = gst_caps_new_simple ("application/x-rtp",
560 "ssrc", G_TYPE_UINT, 0x01BADBAD, NULL);
561 gst_harness_set_src_caps (h->send_rtp_h, caps);
563 for (i = 1; i < 4; i++) {
564 buf = generate_test_buffer (i, 0x01BADBAD);
565 res = session_harness_send_rtp (h, buf);
566 fail_unless_equals_int (GST_FLOW_OK, res);
569 /* internal ssrc must have changed already */
570 g_object_get (h->internal_session, "internal-ssrc", &internal_ssrc, NULL);
571 fail_unless (internal_ssrc != ssrc);
572 fail_unless_equals_int (0x01BADBAD, internal_ssrc);
574 /* verify SR and RR */
576 for (i = 0; i < 5; i++) {
577 session_harness_produce_rtcp (h, 1);
578 buf = session_harness_pull_rtcp (h);
579 g_assert (buf != NULL);
580 fail_unless (gst_rtcp_buffer_validate (buf));
581 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
582 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
583 rtcp_type = gst_rtcp_packet_get_type (&rtcp_packet);
585 if (rtcp_type == GST_RTCP_TYPE_SR) {
586 gst_rtcp_packet_sr_get_sender_info (&rtcp_packet, &ssrc, NULL, NULL, NULL,
588 fail_unless_equals_int (internal_ssrc, ssrc);
589 fail_unless_equals_int (0x01BADBAD, ssrc);
591 } else if (rtcp_type == GST_RTCP_TYPE_RR) {
592 ssrc = gst_rtcp_packet_rr_get_ssrc (&rtcp_packet);
593 if (internal_ssrc != ssrc)
596 gst_rtcp_buffer_unmap (&rtcp);
597 gst_buffer_unref (buf);
599 fail_unless_equals_int (0x3, j); /* verify we got both SR and RR */
601 /* go 30 seconds in the future and observe both sources timing out:
602 * 0xDEADBEEF -> BYE, 0x01BADBAD -> becomes receiver only */
603 fail_unless (session_harness_advance_and_crank (h, 30 * GST_SECOND));
605 /* verify BYE and RR */
609 session_harness_produce_rtcp (h, 1);
610 buf = session_harness_pull_rtcp (h);
611 fail_unless (buf != NULL);
612 fail_unless (gst_rtcp_buffer_validate (buf));
613 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
614 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
615 rtcp_type = gst_rtcp_packet_get_type (&rtcp_packet);
617 if (rtcp_type == GST_RTCP_TYPE_RR) {
618 ssrc = gst_rtcp_packet_rr_get_ssrc (&rtcp_packet);
619 if (ssrc == 0x01BADBAD) {
621 fail_unless_equals_int (internal_ssrc, ssrc);
622 /* 2 => RR, SDES. There is no BYE here */
623 fail_unless_equals_int (2, gst_rtcp_buffer_get_packet_count (&rtcp));
624 } else if (ssrc == 0xDEADBEEF) {
626 g_assert_cmpint (ssrc, !=, internal_ssrc);
627 /* 3 => RR, SDES, BYE */
628 if (gst_rtcp_buffer_get_packet_count (&rtcp) == 3) {
629 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
630 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
631 fail_unless_equals_int (GST_RTCP_TYPE_BYE,
632 gst_rtcp_packet_get_type (&rtcp_packet));
637 gst_rtcp_buffer_unmap (&rtcp);
638 gst_buffer_unref (buf);
640 fail_unless_equals_int (0x3, j); /* verify we got both BYE and RR */
642 session_harness_free (h);
656 on_app_rtcp_cb (GObject * session, guint subtype, guint ssrc,
657 const gchar * name, GstBuffer * data, RTCPAppResult * result)
659 result->subtype = subtype;
661 result->name = g_strdup (name);
662 result->data = data ? gst_buffer_ref (data) : NULL;
665 GST_START_TEST (test_receive_rtcp_app_packet)
667 SessionHarness *h = session_harness_new ();
669 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
670 GstRTCPPacket packet;
671 RTCPAppResult result = { 0 };
672 guint8 data[] = { 0x11, 0x22, 0x33, 0x44 };
674 g_signal_connect (h->internal_session, "on-app-rtcp",
675 G_CALLBACK (on_app_rtcp_cb), &result);
677 /* Push APP buffer with no data */
678 buf = gst_rtcp_buffer_new (1000);
679 fail_unless (gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp));
680 fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
681 gst_rtcp_packet_app_set_subtype (&packet, 21);
682 gst_rtcp_packet_app_set_ssrc (&packet, 0x11111111);
683 gst_rtcp_packet_app_set_name (&packet, "Test");
684 gst_rtcp_buffer_unmap (&rtcp);
686 fail_unless_equals_int (GST_FLOW_OK, session_harness_recv_rtcp (h, buf));
688 fail_unless_equals_int (21, result.subtype);
689 fail_unless_equals_int (0x11111111, result.ssrc);
690 fail_unless_equals_string ("Test", result.name);
691 fail_unless_equals_pointer (NULL, result.data);
693 g_free (result.name);
695 /* Push APP buffer with data */
696 memset (&result, 0, sizeof (result));
697 buf = gst_rtcp_buffer_new (1000);
698 fail_unless (gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp));
699 fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
700 gst_rtcp_packet_app_set_subtype (&packet, 22);
701 gst_rtcp_packet_app_set_ssrc (&packet, 0x22222222);
702 gst_rtcp_packet_app_set_name (&packet, "Test");
703 gst_rtcp_packet_app_set_data_length (&packet, sizeof (data) / 4);
704 memcpy (gst_rtcp_packet_app_get_data (&packet), data, sizeof (data));
705 gst_rtcp_buffer_unmap (&rtcp);
707 fail_unless_equals_int (GST_FLOW_OK, session_harness_recv_rtcp (h, buf));
709 fail_unless_equals_int (22, result.subtype);
710 fail_unless_equals_int (0x22222222, result.ssrc);
711 fail_unless_equals_string ("Test", result.name);
712 fail_unless (gst_buffer_memcmp (result.data, 0, data, sizeof (data)) == 0);
714 g_free (result.name);
715 gst_buffer_unref (result.data);
717 session_harness_free (h);
723 stats_test_cb (GObject * object, GParamSpec * spec, gpointer data)
725 guint num_sources = 0;
726 gboolean *cb_called = data;
727 g_assert (*cb_called == FALSE);
729 /* We should be able to get a rtpsession property
730 without introducing the deadlock */
731 g_object_get (object, "num-sources", &num_sources, NULL);
736 GST_START_TEST (test_dont_lock_on_stats)
738 SessionHarness *h = session_harness_new ();
739 gboolean cb_called = FALSE;
741 /* connect to the stats-reporting */
742 g_signal_connect (h->session, "notify::stats",
743 G_CALLBACK (stats_test_cb), &cb_called);
745 /* Push RTP buffer to make sure RTCP-thread have started */
746 fail_unless_equals_int (GST_FLOW_OK,
747 session_harness_send_rtp (h, generate_test_buffer (0, 0xDEADBEEF)));
749 /* crank the RTCP-thread and pull out rtcp, generating a stats-callback */
750 session_harness_crank_clock (h);
751 gst_buffer_unref (session_harness_pull_rtcp (h));
752 fail_unless (cb_called);
754 session_harness_free (h);
760 suspicious_bye_cb (GObject * object, GParamSpec * spec, gpointer data)
762 GValueArray *stats_arr;
763 GstStructure *stats, *internal_stats;
764 gboolean *cb_called = data;
765 gboolean internal = FALSE, sent_bye = TRUE;
769 g_assert (*cb_called == FALSE);
772 g_object_get (object, "stats", &stats, NULL);
774 g_value_get_boxed (gst_structure_get_value (stats, "source-stats"));
775 g_assert (stats_arr != NULL);
776 fail_unless (stats_arr->n_values >= 1);
778 for (i = 0; i < stats_arr->n_values; i++) {
779 internal_stats = g_value_get_boxed (g_value_array_get_nth (stats_arr, i));
780 g_assert (internal_stats != NULL);
782 gst_structure_get (internal_stats,
783 "ssrc", G_TYPE_UINT, &ssrc,
784 "internal", G_TYPE_BOOLEAN, &internal,
785 "received-bye", G_TYPE_BOOLEAN, &sent_bye, NULL);
787 if (ssrc == 0xDEADBEEF) {
788 fail_unless (internal);
789 fail_unless (!sent_bye);
793 fail_unless_equals_int (ssrc, 0xDEADBEEF);
795 gst_structure_free (stats);
799 create_bye_rtcp (guint32 ssrc)
801 GstRTCPPacket packet;
802 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
803 GSocketAddress *saddr;
804 GstBuffer *buffer = gst_rtcp_buffer_new (1000);
806 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
807 fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_BYE, &packet));
808 gst_rtcp_packet_bye_add_ssrc (&packet, ssrc);
809 gst_rtcp_buffer_unmap (&rtcp);
811 /* Need to add meta to trigger collision detection */
812 saddr = g_inet_socket_address_new_from_string ("127.0.0.1", 3490);
813 gst_buffer_add_net_address_meta (buffer, saddr);
814 g_object_unref (saddr);
818 GST_START_TEST (test_ignore_suspicious_bye)
820 SessionHarness *h = session_harness_new ();
821 gboolean cb_called = FALSE;
823 /* connect to the stats-reporting */
824 g_signal_connect (h->session, "notify::stats",
825 G_CALLBACK (suspicious_bye_cb), &cb_called);
827 /* Push RTP buffer making our internal SSRC=0xDEADBEEF */
828 fail_unless_equals_int (GST_FLOW_OK,
829 session_harness_send_rtp (h, generate_test_buffer (0, 0xDEADBEEF)));
831 /* Receive BYE RTCP referencing our internal SSRC(!?!) (0xDEADBEEF) */
832 fail_unless_equals_int (GST_FLOW_OK,
833 session_harness_recv_rtcp (h, create_bye_rtcp (0xDEADBEEF)));
835 /* "crank" and check the stats */
836 session_harness_crank_clock (h);
837 gst_buffer_unref (session_harness_pull_rtcp (h));
838 fail_unless (cb_called);
840 session_harness_free (h);
846 create_buffer (guint8 * data, gsize size)
848 return gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY,
849 data, size, 0, size, NULL, NULL);
852 GST_START_TEST (test_receive_regular_pli)
854 SessionHarness *h = session_harness_new ();
858 guint8 rtcp_pkt[] = {
860 0xce, /* Type 206 Application layer feedback */
861 0x00, 0x02, /* Length */
862 0x37, 0x56, 0x93, 0xed, /* Sender SSRC */
863 0x37, 0x56, 0x93, 0xed /* Media SSRC */
866 fail_unless_equals_int (GST_FLOW_OK,
867 session_harness_send_rtp (h, generate_test_buffer (0, 928420845)));
869 session_harness_recv_rtcp (h, create_buffer (rtcp_pkt, sizeof (rtcp_pkt)));
870 fail_unless_equals_int (3,
871 gst_harness_upstream_events_received (h->send_rtp_h));
873 /* Remove the first 2 reconfigure events */
874 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
875 fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev));
876 gst_event_unref (ev);
877 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
878 fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev));
879 gst_event_unref (ev);
881 /* Then pull and check the force key-unit event */
882 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
883 fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
884 fail_unless (gst_video_event_is_force_key_unit (ev));
885 gst_event_unref (ev);
887 session_harness_free (h);
892 GST_START_TEST (test_receive_pli_no_sender_ssrc)
894 SessionHarness *h = session_harness_new ();
898 guint8 rtcp_pkt[] = {
900 0xce, /* Type 206 Application layer feedback */
901 0x00, 0x02, /* Length */
902 0x00, 0x00, 0x00, 0x00, /* Sender SSRC */
903 0x37, 0x56, 0x93, 0xed /* Media SSRC */
906 fail_unless_equals_int (GST_FLOW_OK,
907 session_harness_send_rtp (h, generate_test_buffer (0, 928420845)));
909 session_harness_recv_rtcp (h, create_buffer (rtcp_pkt, sizeof (rtcp_pkt)));
910 fail_unless_equals_int (3,
911 gst_harness_upstream_events_received (h->send_rtp_h));
913 /* Remove the first 2 reconfigure events */
914 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
915 fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev));
916 gst_event_unref (ev);
917 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
918 fail_unless_equals_int (GST_EVENT_RECONFIGURE, GST_EVENT_TYPE (ev));
919 gst_event_unref (ev);
921 /* Then pull and check the force key-unit event */
922 fail_unless ((ev = gst_harness_pull_upstream_event (h->send_rtp_h)) != NULL);
923 fail_unless_equals_int (GST_EVENT_CUSTOM_UPSTREAM, GST_EVENT_TYPE (ev));
924 fail_unless (gst_video_event_is_force_key_unit (ev));
925 gst_event_unref (ev);
927 session_harness_free (h);
933 add_rtcp_sdes_packet (GstBuffer * gstbuf, guint32 ssrc, const char *cname)
935 GstRTCPPacket packet;
936 GstRTCPBuffer buffer = GST_RTCP_BUFFER_INIT;
938 gst_rtcp_buffer_map (gstbuf, GST_MAP_READWRITE, &buffer);
940 fail_unless (gst_rtcp_buffer_add_packet (&buffer, GST_RTCP_TYPE_SDES,
942 fail_unless (gst_rtcp_packet_sdes_add_item (&packet, ssrc) == TRUE);
943 fail_unless (gst_rtcp_packet_sdes_add_entry (&packet, GST_RTCP_SDES_CNAME,
944 strlen (cname), (const guint8 *) cname));
946 gst_rtcp_buffer_unmap (&buffer);
949 GST_START_TEST (test_ssrc_collision_when_sending)
951 SessionHarness *h = session_harness_new ();
952 GstBuffer *buf = gst_rtcp_buffer_new (1400);
954 /* Push SDES with identical SSRC as what we will use for sending RTP,
955 establishing this as a non-internal SSRC */
956 add_rtcp_sdes_packet (buf, 0x12345678, "test@foo.bar");
957 session_harness_recv_rtcp (h, buf);
959 /* Push RTP buffer making our internal SSRC=0x12345678 */
960 fail_unless_equals_int (GST_FLOW_OK,
961 session_harness_send_rtp (h, generate_test_buffer (0, 0x12345678)));
963 /* Verify the packet we just sent is not being boomeranged back to us
964 as a received packet! */
965 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h->recv_rtp_h));
967 /* FIXME: verify a Collision event coming upstream! */
969 session_harness_free (h);
974 GST_START_TEST (test_request_fir)
976 SessionHarness *h = session_harness_new ();
978 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
979 GstRTCPPacket rtcp_packet;
982 /* add FIR-capabilites to our caps */
983 gst_caps_set_simple (h->caps, "rtcp-fb-ccm-fir", G_TYPE_BOOLEAN, TRUE, NULL);
984 /* clear pt-map to removed the cached caps without fir */
985 g_signal_emit_by_name (h->session, "clear-pt-map");
987 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
989 /* Receive a RTP buffer from the wire from 2 different ssrcs */
990 fail_unless_equals_int (GST_FLOW_OK,
991 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
992 fail_unless_equals_int (GST_FLOW_OK,
993 session_harness_recv_rtp (h, generate_test_buffer (0, 0x87654321)));
995 /* fix to make the test deterministic: We need to wait for the RTCP-thread
996 to have settled to ensure the key-unit will considered once released */
997 gst_test_clock_wait_for_next_pending_id (h->testclock, NULL);
999 /* request FIR for both SSRCs */
1000 session_harness_force_key_unit (h, 0, 0x12345678, TEST_BUF_PT, NULL, NULL);
1001 session_harness_force_key_unit (h, 0, 0x87654321, TEST_BUF_PT, NULL, NULL);
1003 session_harness_produce_rtcp (h, 1);
1004 buf = session_harness_pull_rtcp (h);
1006 fail_unless (gst_rtcp_buffer_validate (buf));
1007 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1008 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1009 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1011 /* first a Receiver Report */
1012 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1013 gst_rtcp_packet_get_type (&rtcp_packet));
1014 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1017 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1018 gst_rtcp_packet_get_type (&rtcp_packet));
1019 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1021 /* and then our FIR */
1022 fail_unless_equals_int (GST_RTCP_TYPE_PSFB,
1023 gst_rtcp_packet_get_type (&rtcp_packet));
1024 fail_unless_equals_int (GST_RTCP_PSFB_TYPE_FIR,
1025 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1027 /* FIR has sender-ssrc as normal, but media-ssrc set to 0, because
1028 it can have multiple media-ssrcs in its fci-data */
1029 fail_unless_equals_int (0xDEADBEEF,
1030 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1031 fail_unless_equals_int (0, gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1032 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1034 fail_unless_equals_int (16,
1035 gst_rtcp_packet_fb_get_fci_length (&rtcp_packet) * sizeof (guint32));
1037 /* verify the FIR contains both SSRCs */
1038 fail_unless_equals_int (0x87654321, GST_READ_UINT32_BE (fci_data));
1039 fail_unless_equals_int (1, fci_data[4]);
1040 fail_unless_equals_int (0, fci_data[5]);
1041 fail_unless_equals_int (0, fci_data[6]);
1042 fail_unless_equals_int (0, fci_data[7]);
1045 fail_unless_equals_int (0x12345678, GST_READ_UINT32_BE (fci_data));
1046 fail_unless_equals_int (1, fci_data[4]);
1047 fail_unless_equals_int (0, fci_data[5]);
1048 fail_unless_equals_int (0, fci_data[6]);
1049 fail_unless_equals_int (0, fci_data[7]);
1051 gst_rtcp_buffer_unmap (&rtcp);
1052 gst_buffer_unref (buf);
1053 session_harness_free (h);
1058 GST_START_TEST (test_request_pli)
1060 SessionHarness *h = session_harness_new ();
1062 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1063 GstRTCPPacket rtcp_packet;
1065 /* add PLI-capabilites to our caps */
1066 gst_caps_set_simple (h->caps, "rtcp-fb-nack-pli", G_TYPE_BOOLEAN, TRUE, NULL);
1067 /* clear pt-map to removed the cached caps without PLI */
1068 g_signal_emit_by_name (h->session, "clear-pt-map");
1070 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1072 /* Receive a RTP buffer from the wire */
1073 fail_unless_equals_int (GST_FLOW_OK,
1074 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1076 /* Wait for first regular RTCP to be sent so that we are clear to send early RTCP */
1077 session_harness_produce_rtcp (h, 1);
1078 gst_buffer_unref (session_harness_pull_rtcp (h));
1081 session_harness_force_key_unit (h, 0, 0x12345678, TEST_BUF_PT, NULL, NULL);
1083 /* PLI should be produced immediately as early RTCP is allowed. Pull buffer
1084 without advancing the clock to ensure this is the case */
1085 buf = session_harness_pull_rtcp (h);
1086 fail_unless (gst_rtcp_buffer_validate (buf));
1087 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1088 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1089 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1091 /* first a Receiver Report */
1092 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1093 gst_rtcp_packet_get_type (&rtcp_packet));
1094 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1097 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1098 gst_rtcp_packet_get_type (&rtcp_packet));
1099 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1101 /* and then our PLI */
1102 fail_unless_equals_int (GST_RTCP_TYPE_PSFB,
1103 gst_rtcp_packet_get_type (&rtcp_packet));
1104 fail_unless_equals_int (GST_RTCP_PSFB_TYPE_PLI,
1105 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1107 fail_unless_equals_int (0xDEADBEEF,
1108 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1109 fail_unless_equals_int (0x12345678,
1110 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1111 fail_unless_equals_int (0, gst_rtcp_packet_fb_get_fci_length (&rtcp_packet));
1113 gst_rtcp_buffer_unmap (&rtcp);
1114 gst_buffer_unref (buf);
1115 session_harness_free (h);
1120 GST_START_TEST (test_illegal_rtcp_fb_packet)
1122 SessionHarness *h = session_harness_new ();
1124 /* Zero length RTCP feedback packet (reduced size) */
1125 const guint8 rtcp_zero_fb_pkt[] = { 0x8f, 0xce, 0x00, 0x00 };
1127 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1129 buf = gst_buffer_new_and_alloc (sizeof (rtcp_zero_fb_pkt));
1130 gst_buffer_fill (buf, 0, rtcp_zero_fb_pkt, sizeof (rtcp_zero_fb_pkt));
1131 GST_BUFFER_DTS (buf) = GST_BUFFER_PTS (buf) = G_GUINT64_CONSTANT (0);
1133 /* Push the packet, this did previously crash because length of packet was
1134 * never validated. */
1135 fail_unless_equals_int (GST_FLOW_OK, session_harness_recv_rtcp (h, buf));
1137 session_harness_free (h);
1147 } FeedbackRTCPCallbackData;
1150 feedback_rtcp_cb (GstElement * element, guint fbtype, guint fmt,
1151 guint sender_ssrc, guint media_ssrc, GstBuffer * fci,
1152 FeedbackRTCPCallbackData * cb_data)
1154 g_mutex_lock (cb_data->mutex);
1155 cb_data->fired = TRUE;
1156 g_cond_wait (cb_data->cond, cb_data->mutex);
1157 g_mutex_unlock (cb_data->mutex);
1161 send_feedback_rtcp (SessionHarness * h)
1163 GstRTCPPacket packet;
1164 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1165 GstBuffer *buffer = gst_rtcp_buffer_new (1000);
1167 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
1168 fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_PSFB, &packet));
1169 gst_rtcp_packet_fb_set_type (&packet, GST_RTCP_PSFB_TYPE_PLI);
1170 gst_rtcp_packet_fb_set_fci_length (&packet, 0);
1171 gst_rtcp_packet_fb_set_media_ssrc (&packet, 0xABE2B0B);
1172 gst_rtcp_packet_fb_set_media_ssrc (&packet, 0xDEADBEEF);
1173 gst_rtcp_buffer_unmap (&rtcp);
1174 fail_unless_equals_int (GST_FLOW_OK, session_harness_recv_rtcp (h, buffer));
1179 GST_START_TEST (test_feedback_rtcp_race)
1181 SessionHarness *h = session_harness_new ();
1185 FeedbackRTCPCallbackData cb_data;
1186 GThread *send_rtcp_thread;
1188 g_cond_init (&cond);
1189 g_mutex_init (&mutex);
1190 cb_data.cond = &cond;
1191 cb_data.mutex = &mutex;
1192 cb_data.fired = FALSE;
1193 g_signal_connect (h->internal_session, "on-feedback-rtcp",
1194 G_CALLBACK (feedback_rtcp_cb), &cb_data);
1196 /* Push RTP buffer making external source with SSRC=0xDEADBEEF */
1197 fail_unless_equals_int (GST_FLOW_OK, session_harness_recv_rtp (h,
1198 generate_test_buffer (0, 0xDEADBEEF)));
1200 /* Push feedback RTCP with media SSRC=0xDEADBEEF */
1201 send_rtcp_thread = g_thread_new (NULL, (GThreadFunc) send_feedback_rtcp, h);
1203 /* Waiting for feedback RTCP callback to fire */
1204 while (!cb_data.fired)
1205 g_usleep (G_USEC_PER_SEC / 100);
1207 /* While send_rtcp_thread thread is waiting for our signal
1208 advance the clock by 30sec triggering removal of 0xDEADBEEF,
1209 as if the source was inactive for too long */
1210 session_harness_advance_and_crank (h, GST_SECOND * 30);
1211 gst_buffer_unref (session_harness_pull_rtcp (h));
1213 /* Let send_rtcp_thread finish */
1214 g_mutex_lock (&mutex);
1215 g_cond_signal (&cond);
1216 g_mutex_unlock (&mutex);
1217 g_thread_join (send_rtcp_thread);
1219 session_harness_free (h);
1224 GST_START_TEST (test_dont_send_rtcp_while_idle)
1226 SessionHarness *h = session_harness_new ();
1228 /* verify the RTCP thread has not started */
1229 fail_unless_equals_int (0, gst_test_clock_peek_id_count (h->testclock));
1230 /* and that no RTCP has been pushed */
1231 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h->rtcp_h));
1233 session_harness_free (h);
1238 GST_START_TEST (test_send_rtcp_when_signalled)
1240 SessionHarness *h = session_harness_new ();
1243 /* verify the RTCP thread has not started */
1244 fail_unless_equals_int (0, gst_test_clock_peek_id_count (h->testclock));
1245 /* and that no RTCP has been pushed */
1246 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h->rtcp_h));
1248 /* then ask explicitly to send RTCP */
1249 g_signal_emit_by_name (h->internal_session,
1250 "send-rtcp-full", GST_SECOND, &ret);
1251 /* this is FALSE due to no next RTCP check time */
1252 fail_unless (ret == FALSE);
1254 /* "crank" and verify RTCP now was sent */
1255 session_harness_crank_clock (h);
1256 gst_buffer_unref (session_harness_pull_rtcp (h));
1258 session_harness_free (h);
1264 validate_sdes_priv (GstBuffer * buf, const char *name_ref, const char *value)
1266 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1269 fail_unless (gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp));
1271 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &pkt));
1274 if (gst_rtcp_packet_get_type (&pkt) == GST_RTCP_TYPE_SDES) {
1275 fail_unless (gst_rtcp_packet_sdes_first_entry (&pkt));
1278 GstRTCPSDESType type;
1282 fail_unless (gst_rtcp_packet_sdes_get_entry (&pkt, &type, &len, &data));
1284 if (type == GST_RTCP_SDES_PRIV) {
1285 char *name = g_strndup ((const gchar *) &data[1], data[0]);
1287 data += data[0] + 1;
1289 fail_unless_equals_int (len, strlen (value));
1290 fail_unless (!strncmp (value, (char *) data, len));
1291 fail_unless_equals_string (name, name_ref);
1295 } while (gst_rtcp_packet_sdes_next_entry (&pkt));
1297 g_assert_not_reached ();
1299 } while (gst_rtcp_packet_move_to_next (&pkt));
1301 g_assert_not_reached ();
1305 fail_unless (gst_rtcp_buffer_unmap (&rtcp));
1309 GST_START_TEST (test_change_sent_sdes)
1311 SessionHarness *h = session_harness_new ();
1317 /* verify the RTCP thread has not started */
1318 fail_unless_equals_int (0, gst_test_clock_peek_id_count (h->testclock));
1319 /* and that no RTCP has been pushed */
1320 fail_unless_equals_int (0, gst_harness_buffers_in_queue (h->rtcp_h));
1322 s = gst_structure_new ("application/x-rtp-source-sdes",
1323 "other", G_TYPE_STRING, "first", NULL);
1324 g_object_set (h->internal_session, "sdes", s, NULL);
1325 gst_structure_free (s);
1327 /* then ask explicitly to send RTCP */
1328 g_signal_emit_by_name (h->internal_session,
1329 "send-rtcp-full", GST_SECOND, &ret);
1330 /* this is FALSE due to no next RTCP check time */
1331 fail_unless (ret == FALSE);
1333 /* "crank" and verify RTCP now was sent */
1334 session_harness_crank_clock (h);
1335 buf = session_harness_pull_rtcp (h);
1337 validate_sdes_priv (buf, "other", "first");
1338 gst_buffer_unref (buf);
1340 /* Change the SDES */
1341 s = gst_structure_new ("application/x-rtp-source-sdes",
1342 "other", G_TYPE_STRING, "second", NULL);
1343 g_object_set (h->internal_session, "sdes", s, NULL);
1344 gst_structure_free (s);
1346 /* Send an RTP packet */
1347 buf = generate_test_buffer (22, 10000);
1348 res = session_harness_send_rtp (h, buf);
1349 fail_unless_equals_int (GST_FLOW_OK, res);
1351 /* "crank" enough to ensure a RTCP packet has been produced ! */
1352 session_harness_crank_clock (h);
1353 session_harness_crank_clock (h);
1354 session_harness_crank_clock (h);
1355 session_harness_crank_clock (h);
1356 session_harness_crank_clock (h);
1357 session_harness_crank_clock (h);
1358 session_harness_crank_clock (h);
1359 session_harness_crank_clock (h);
1360 session_harness_crank_clock (h);
1361 session_harness_crank_clock (h);
1363 /* and verify RTCP now was sent with new SDES */
1364 buf = session_harness_pull_rtcp (h);
1365 validate_sdes_priv (buf, "other", "second");
1366 gst_buffer_unref (buf);
1368 session_harness_free (h);
1373 GST_START_TEST (test_request_nack)
1375 SessionHarness *h = session_harness_new ();
1377 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1378 GstRTCPPacket rtcp_packet;
1382 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1384 /* Receive a RTP buffer from the wire */
1385 fail_unless_equals_int (GST_FLOW_OK,
1386 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1388 /* Wait for first regular RTCP to be sent so that we are clear to send early RTCP */
1389 session_harness_produce_rtcp (h, 1);
1390 gst_buffer_unref (session_harness_pull_rtcp (h));
1392 /* request NACK immediately */
1393 session_harness_rtp_retransmission_request (h, 0x12345678, 1234, 0, 0, 0);
1395 /* NACK should be produced immediately as early RTCP is allowed. Pull buffer
1396 without advancing the clock to ensure this is the case */
1397 buf = session_harness_pull_rtcp (h);
1399 fail_unless (gst_rtcp_buffer_validate (buf));
1400 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1401 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1402 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1404 /* first a Receiver Report */
1405 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1406 gst_rtcp_packet_get_type (&rtcp_packet));
1407 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1410 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1411 gst_rtcp_packet_get_type (&rtcp_packet));
1412 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1414 /* and then our NACK */
1415 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1416 gst_rtcp_packet_get_type (&rtcp_packet));
1417 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1418 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1420 fail_unless_equals_int (0xDEADBEEF,
1421 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1422 fail_unless_equals_int (0x12345678,
1423 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1425 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1427 gst_rtcp_packet_fb_get_fci_length (&rtcp_packet) * sizeof (guint32);
1428 fail_unless_equals_int (4, fci_length);
1429 fail_unless_equals_int (GST_READ_UINT32_BE (fci_data), 1234L << 16);
1431 gst_rtcp_buffer_unmap (&rtcp);
1432 gst_buffer_unref (buf);
1434 session_harness_free (h);
1446 } BlockingProbeData;
1448 static GstPadProbeReturn
1449 on_rtcp_pad_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
1451 BlockingProbeData *probe = user_data;
1453 g_mutex_lock (&probe->mutex);
1454 probe->blocked = TRUE;
1455 g_cond_signal (&probe->cond);
1456 g_mutex_unlock (&probe->mutex);
1458 return GST_PAD_PROBE_OK;
1462 session_harness_block_rtcp (SessionHarness * h, BlockingProbeData * probe)
1464 probe->pad = gst_element_get_static_pad (h->session, "send_rtcp_src");
1465 fail_unless (probe->pad);
1467 g_mutex_init (&probe->mutex);
1468 g_cond_init (&probe->cond);
1469 probe->blocked = FALSE;
1470 probe->id = gst_pad_add_probe (probe->pad,
1471 GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_BUFFER |
1472 GST_PAD_PROBE_TYPE_BUFFER_LIST, on_rtcp_pad_blocked, probe, NULL);
1474 g_mutex_lock (&probe->mutex);
1475 while (!probe->blocked) {
1476 session_harness_crank_clock (h);
1477 g_cond_wait (&probe->cond, &probe->mutex);
1479 g_mutex_unlock (&probe->mutex);
1483 session_harness_unblock_rtcp (SessionHarness * h, BlockingProbeData * probe)
1485 gst_pad_remove_probe (probe->pad, probe->id);
1486 gst_object_unref (probe->pad);
1487 g_mutex_clear (&probe->mutex);
1490 GST_START_TEST (test_request_nack_surplus)
1492 SessionHarness *h = session_harness_new ();
1493 GstRTCPPacket rtcp_packet;
1494 BlockingProbeData probe;
1496 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1501 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1503 /* sdes cname has variable size, fix it */
1504 g_object_get (h->internal_session, "sdes", &sdes, NULL);
1505 gst_structure_set (sdes, "cname", G_TYPE_STRING, "user@test", NULL);
1506 g_object_set (h->internal_session, "sdes", sdes, NULL);
1507 gst_structure_free (sdes);
1509 /* Receive a RTP buffer from the wire */
1510 fail_unless_equals_int (GST_FLOW_OK,
1511 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1513 /* Block on first regular RTCP so we can fill the nack list */
1514 session_harness_block_rtcp (h, &probe);
1516 /* request 400 NACK with 17 seqnum distance to optain the worst possible
1518 for (i = 0; i < 350; i++)
1519 session_harness_rtp_retransmission_request (h, 0x12345678, 1234 + i * 17,
1521 /* and the last 50 with a 2s deadline */
1522 for (i = 350; i < 400; i++)
1523 session_harness_rtp_retransmission_request (h, 0x12345678, 1234 + i * 17,
1526 /* Unblock and wait for the regular and first early packet */
1527 session_harness_unblock_rtcp (h, &probe);
1528 session_harness_produce_rtcp (h, 2);
1530 /* Move time forward, so that only the remaining 50 are still up to date */
1531 session_harness_advance_and_crank (h, GST_SECOND);
1532 session_harness_produce_rtcp (h, 3);
1534 /* ignore the regular RTCP packet */
1535 buf = session_harness_pull_rtcp (h);
1536 gst_buffer_unref (buf);
1538 /* validate the first early RTCP which should hold 335 Nack */
1539 buf = session_harness_pull_rtcp (h);
1541 fail_unless (gst_rtcp_buffer_validate (buf));
1542 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1543 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1544 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1546 /* first a Receiver Report */
1547 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1548 gst_rtcp_packet_get_type (&rtcp_packet));
1549 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1552 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1553 gst_rtcp_packet_get_type (&rtcp_packet));
1554 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1556 /* and then our NACK */
1557 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1558 gst_rtcp_packet_get_type (&rtcp_packet));
1559 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1560 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1562 fail_unless_equals_int (0xDEADBEEF,
1563 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1564 fail_unless_equals_int (0x12345678,
1565 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1567 fail_unless_equals_int (340,
1568 gst_rtcp_packet_fb_get_fci_length (&rtcp_packet));
1569 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1570 fail_unless_equals_int (GST_READ_UINT32_BE (fci_data), 1234L << 16);
1572 gst_rtcp_buffer_unmap (&rtcp);
1573 gst_buffer_unref (buf);
1575 /* validate the second early RTCP which should hold 50 Nack */
1576 buf = session_harness_pull_rtcp (h);
1578 fail_unless (gst_rtcp_buffer_validate (buf));
1579 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1580 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1581 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1583 /* first a Receiver Report */
1584 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1585 gst_rtcp_packet_get_type (&rtcp_packet));
1586 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1589 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1590 gst_rtcp_packet_get_type (&rtcp_packet));
1591 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1593 /* and then our NACK */
1594 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1595 gst_rtcp_packet_get_type (&rtcp_packet));
1596 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1597 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1599 fail_unless_equals_int (0xDEADBEEF,
1600 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1601 fail_unless_equals_int (0x12345678,
1602 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1604 fail_unless_equals_int (50, gst_rtcp_packet_fb_get_fci_length (&rtcp_packet));
1605 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1606 fail_unless_equals_int (GST_READ_UINT32_BE (fci_data),
1607 (guint16) (1234 + 350 * 17) << 16);
1609 gst_rtcp_buffer_unmap (&rtcp);
1610 gst_buffer_unref (buf);
1612 session_harness_free (h);
1617 GST_START_TEST (test_request_nack_packing)
1619 SessionHarness *h = session_harness_new ();
1620 GstRTCPPacket rtcp_packet;
1621 BlockingProbeData probe;
1623 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1627 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1629 /* Receive a RTP buffer from the wire */
1630 fail_unless_equals_int (GST_FLOW_OK,
1631 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1633 /* Block on first regular RTCP so we can fill the nack list */
1634 session_harness_block_rtcp (h, &probe);
1636 /* append 16 consecutive seqnum */
1637 for (i = 1; i < 17; i++)
1638 session_harness_rtp_retransmission_request (h, 0x12345678, 1234 + i,
1640 /* prepend one, still consecutive */
1641 session_harness_rtp_retransmission_request (h, 0x12345678, 1234, 0, 0, 0);
1643 session_harness_rtp_retransmission_request (h, 0x12345678, 1234, 0, 0, 0);
1645 /* Unblock and wait for the regular and first early packet */
1646 session_harness_unblock_rtcp (h, &probe);
1647 session_harness_produce_rtcp (h, 2);
1649 /* ignore the regular RTCP packet */
1650 buf = session_harness_pull_rtcp (h);
1651 gst_buffer_unref (buf);
1653 /* validate the early RTCP which should hold 1 Nack */
1654 buf = session_harness_pull_rtcp (h);
1656 fail_unless (gst_rtcp_buffer_validate (buf));
1657 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1658 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1659 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1661 /* first a Receiver Report */
1662 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1663 gst_rtcp_packet_get_type (&rtcp_packet));
1664 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1667 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1668 gst_rtcp_packet_get_type (&rtcp_packet));
1669 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1671 /* and then our NACK */
1672 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1673 gst_rtcp_packet_get_type (&rtcp_packet));
1674 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1675 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1677 fail_unless_equals_int (0xDEADBEEF,
1678 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1679 fail_unless_equals_int (0x12345678,
1680 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1682 fail_unless_equals_int (1, gst_rtcp_packet_fb_get_fci_length (&rtcp_packet));
1683 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1684 fail_unless_equals_int (GST_READ_UINT32_BE (fci_data), 1234L << 16 | 0xFFFF);
1686 gst_rtcp_buffer_unmap (&rtcp);
1687 gst_buffer_unref (buf);
1689 session_harness_free (h);
1694 GST_START_TEST (test_disable_sr_timestamp)
1696 SessionHarness *h = session_harness_new ();
1698 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1699 GstRTCPPacket rtcp_packet;
1703 g_object_set (h->internal_session, "disable-sr-timestamp", TRUE, NULL);
1705 /* Push RTP buffer to make sure RTCP-thread have started */
1706 fail_unless_equals_int (GST_FLOW_OK,
1707 session_harness_send_rtp (h, generate_test_buffer (0, 0xDEADBEEF)));
1709 /* crank the RTCP-thread and pull out rtcp, generating a stats-callback */
1710 session_harness_crank_clock (h);
1711 buf = session_harness_pull_rtcp (h);
1713 gst_rtcp_buffer_map (buf, GST_MAP_READWRITE, &rtcp);
1715 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1717 fail_unless_equals_int (GST_RTCP_TYPE_SR,
1718 gst_rtcp_packet_get_type (&rtcp_packet));
1720 gst_rtcp_packet_sr_get_sender_info (&rtcp_packet, NULL, &ntptime, &rtptime,
1723 fail_unless_equals_uint64 (ntptime, 0);
1724 fail_unless (rtptime == 0);
1726 gst_rtcp_buffer_unmap (&rtcp);
1727 gst_buffer_unref (buf);
1729 session_harness_free (h);
1735 on_sending_nacks (GObject * internal_session, guint sender_ssrc,
1736 guint media_ssrc, GArray * nacks, GstBuffer * buffer)
1738 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1739 GstRTCPPacket packet;
1740 guint16 seqnum = g_array_index (nacks, guint16, 0);
1746 fail_unless (gst_rtcp_buffer_map (buffer, GST_MAP_READWRITE, &rtcp));
1747 fail_unless (gst_rtcp_buffer_add_packet (&rtcp, GST_RTCP_TYPE_APP, &packet));
1749 gst_rtcp_packet_app_set_ssrc (&packet, media_ssrc);
1750 gst_rtcp_packet_app_set_name (&packet, "TEST");
1752 fail_unless (gst_rtcp_packet_app_set_data_length (&packet, 1));
1753 data = gst_rtcp_packet_app_get_data (&packet);
1754 GST_WRITE_UINT32_BE (data, seqnum);
1756 gst_rtcp_buffer_unmap (&rtcp);
1760 GST_START_TEST (test_on_sending_nacks)
1762 SessionHarness *h = session_harness_new ();
1763 BlockingProbeData probe;
1765 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1766 GstRTCPPacket rtcp_packet;
1769 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1771 /* Receive a RTP buffer from the wire */
1772 fail_unless_equals_int (GST_FLOW_OK,
1773 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1775 /* Block on first regular RTCP so we can fill the nack list */
1776 session_harness_block_rtcp (h, &probe);
1777 g_signal_connect (h->internal_session, "on-sending-nacks",
1778 G_CALLBACK (on_sending_nacks), NULL);
1780 /* request NACK immediately */
1781 session_harness_rtp_retransmission_request (h, 0x12345678, 1234, 0, 0, 0);
1782 session_harness_rtp_retransmission_request (h, 0x12345678, 1235, 0, 0, 0);
1784 session_harness_unblock_rtcp (h, &probe);
1785 gst_buffer_unref (session_harness_pull_rtcp (h));
1786 session_harness_produce_rtcp (h, 2);
1788 /* first packet only includes seqnum 1234 in an APP FB */
1789 buf = session_harness_pull_rtcp (h);
1791 fail_unless (gst_rtcp_buffer_validate (buf));
1792 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1793 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1794 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1796 /* first a Receiver Report */
1797 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1798 gst_rtcp_packet_get_type (&rtcp_packet));
1799 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1802 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1803 gst_rtcp_packet_get_type (&rtcp_packet));
1804 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1806 /* and then our NACK */
1807 fail_unless_equals_int (GST_RTCP_TYPE_APP,
1808 gst_rtcp_packet_get_type (&rtcp_packet));
1809 fail_unless_equals_string ("TEST",
1810 gst_rtcp_packet_app_get_name (&rtcp_packet));
1812 fail_unless_equals_int (0x12345678,
1813 gst_rtcp_packet_app_get_ssrc (&rtcp_packet));
1815 fail_unless_equals_int (1,
1816 gst_rtcp_packet_app_get_data_length (&rtcp_packet));
1817 data = gst_rtcp_packet_app_get_data (&rtcp_packet);
1818 fail_unless_equals_int (GST_READ_UINT32_BE (data), 1234L);
1820 gst_rtcp_buffer_unmap (&rtcp);
1821 gst_buffer_unref (buf);
1823 /* second will contain seqnum 1235 in a generic nack packet */
1824 buf = session_harness_pull_rtcp (h);
1826 fail_unless (gst_rtcp_buffer_validate (buf));
1827 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1828 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1829 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1831 /* first a Receiver Report */
1832 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1833 gst_rtcp_packet_get_type (&rtcp_packet));
1834 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1837 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1838 gst_rtcp_packet_get_type (&rtcp_packet));
1839 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1841 /* and then our NACK */
1842 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1843 gst_rtcp_packet_get_type (&rtcp_packet));
1844 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1845 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1847 fail_unless_equals_int (0xDEADBEEF,
1848 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1849 fail_unless_equals_int (0x12345678,
1850 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1852 fail_unless_equals_int (1, gst_rtcp_packet_fb_get_fci_length (&rtcp_packet));
1853 data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1854 fail_unless_equals_int (GST_READ_UINT32_BE (data), 1235L << 16);
1856 gst_rtcp_buffer_unmap (&rtcp);
1857 gst_buffer_unref (buf);
1859 session_harness_free (h);
1865 disable_probation_on_new_ssrc (GObject * session, GObject * source)
1867 g_object_set (source, "probation", 0, NULL);
1870 GST_START_TEST (test_disable_probation)
1872 SessionHarness *h = session_harness_new ();
1874 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1875 g_signal_connect (h->internal_session, "on-new-ssrc",
1876 G_CALLBACK (disable_probation_on_new_ssrc), NULL);
1878 /* Receive a RTP buffer from the wire */
1879 fail_unless_equals_int (GST_FLOW_OK,
1880 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1882 /* When probation is disable, the packet should be produced immediatly */
1883 fail_unless_equals_int (1, gst_harness_buffers_in_queue (h->recv_rtp_h));
1885 session_harness_free (h);
1890 GST_START_TEST (test_request_late_nack)
1892 SessionHarness *h = session_harness_new ();
1894 GstRTCPBuffer rtcp = GST_RTCP_BUFFER_INIT;
1895 GstRTCPPacket rtcp_packet;
1899 g_object_set (h->internal_session, "internal-ssrc", 0xDEADBEEF, NULL);
1901 /* Receive a RTP buffer from the wire */
1902 fail_unless_equals_int (GST_FLOW_OK,
1903 session_harness_recv_rtp (h, generate_test_buffer (0, 0x12345678)));
1905 /* Wait for first regular RTCP to be sent so that we are clear to send early RTCP */
1906 session_harness_produce_rtcp (h, 1);
1907 gst_buffer_unref (session_harness_pull_rtcp (h));
1909 /* request NACK immediately, but also advance the clock, so the request is
1910 * now late, but it should be kept to avoid sendign an early rtcp without
1911 * NACK. This would otherwise lead to a stall if the late packet was cause
1912 * by high RTT, we need to send some RTX in order to update that statistic. */
1913 session_harness_rtp_retransmission_request (h, 0x12345678, 1234, 0, 0, 0);
1914 gst_test_clock_advance_time (h->testclock, 100 * GST_USECOND);
1916 /* NACK should be produced immediately as early RTCP is allowed. Pull buffer
1917 without advancing the clock to ensure this is the case */
1918 buf = session_harness_pull_rtcp (h);
1920 fail_unless (gst_rtcp_buffer_validate (buf));
1921 gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcp);
1922 fail_unless_equals_int (3, gst_rtcp_buffer_get_packet_count (&rtcp));
1923 fail_unless (gst_rtcp_buffer_get_first_packet (&rtcp, &rtcp_packet));
1925 /* first a Receiver Report */
1926 fail_unless_equals_int (GST_RTCP_TYPE_RR,
1927 gst_rtcp_packet_get_type (&rtcp_packet));
1928 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1931 fail_unless_equals_int (GST_RTCP_TYPE_SDES,
1932 gst_rtcp_packet_get_type (&rtcp_packet));
1933 fail_unless (gst_rtcp_packet_move_to_next (&rtcp_packet));
1935 /* and then our NACK */
1936 fail_unless_equals_int (GST_RTCP_TYPE_RTPFB,
1937 gst_rtcp_packet_get_type (&rtcp_packet));
1938 fail_unless_equals_int (GST_RTCP_RTPFB_TYPE_NACK,
1939 gst_rtcp_packet_fb_get_type (&rtcp_packet));
1941 fail_unless_equals_int (0xDEADBEEF,
1942 gst_rtcp_packet_fb_get_sender_ssrc (&rtcp_packet));
1943 fail_unless_equals_int (0x12345678,
1944 gst_rtcp_packet_fb_get_media_ssrc (&rtcp_packet));
1946 fci_data = gst_rtcp_packet_fb_get_fci (&rtcp_packet);
1948 gst_rtcp_packet_fb_get_fci_length (&rtcp_packet) * sizeof (guint32);
1949 fail_unless_equals_int (4, fci_length);
1950 fail_unless_equals_int (GST_READ_UINT32_BE (fci_data), 1234L << 16);
1952 gst_rtcp_buffer_unmap (&rtcp);
1953 gst_buffer_unref (buf);
1955 session_harness_free (h);
1961 rtpsession_suite (void)
1963 Suite *s = suite_create ("rtpsession");
1964 TCase *tc_chain = tcase_create ("general");
1966 suite_add_tcase (s, tc_chain);
1967 tcase_add_test (tc_chain, test_multiple_ssrc_rr);
1968 tcase_add_test (tc_chain, test_multiple_senders_roundrobin_rbs);
1969 tcase_add_test (tc_chain, test_no_rbs_for_internal_senders);
1970 tcase_add_test (tc_chain, test_internal_sources_timeout);
1971 tcase_add_test (tc_chain, test_receive_rtcp_app_packet);
1972 tcase_add_test (tc_chain, test_dont_lock_on_stats);
1973 tcase_add_test (tc_chain, test_ignore_suspicious_bye);
1974 tcase_add_test (tc_chain, test_ssrc_collision_when_sending);
1975 tcase_add_test (tc_chain, test_request_fir);
1976 tcase_add_test (tc_chain, test_request_pli);
1977 tcase_add_test (tc_chain, test_request_nack);
1978 tcase_add_test (tc_chain, test_request_nack_surplus);
1979 tcase_add_test (tc_chain, test_request_nack_packing);
1980 tcase_add_test (tc_chain, test_illegal_rtcp_fb_packet);
1981 tcase_add_test (tc_chain, test_feedback_rtcp_race);
1982 tcase_add_test (tc_chain, test_receive_regular_pli);
1983 tcase_add_test (tc_chain, test_receive_pli_no_sender_ssrc);
1984 tcase_add_test (tc_chain, test_dont_send_rtcp_while_idle);
1985 tcase_add_test (tc_chain, test_send_rtcp_when_signalled);
1986 tcase_add_test (tc_chain, test_change_sent_sdes);
1987 tcase_add_test (tc_chain, test_disable_sr_timestamp);
1988 tcase_add_test (tc_chain, test_on_sending_nacks);
1989 tcase_add_test (tc_chain, test_disable_probation);
1990 tcase_add_test (tc_chain, test_request_late_nack);
1994 GST_CHECK_MAIN (rtpsession);