1 /* GStreamer
2  *
3  * unit test for rtpmux elements
4  *
5  * Copyright 2009 Collabora Ltd.
6  *  @author: Olivier Crete <olivier.crete@collabora.co.uk>
7  * Copyright 2009 Nokia Corp.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24 
25 #include <gst/check/gstcheck.h>
26 #include <gst/check/gstharness.h>
27 #include <gst/rtp/gstrtpbuffer.h>
28 #include <gst/gst.h>
29 
30 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
31     GST_PAD_SINK,
32     GST_PAD_ALWAYS,
33     GST_STATIC_CAPS ("application/x-rtp"));
34 
35 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
36     GST_PAD_SRC,
37     GST_PAD_ALWAYS,
38     GST_STATIC_CAPS ("application/x-rtp"));
39 
40 typedef void (*check_cb) (GstPad * pad, int i);
41 
42 static gboolean
query_func(GstPad * pad,GstObject * noparent,GstQuery * query)43 query_func (GstPad * pad, GstObject * noparent, GstQuery * query)
44 {
45   switch (GST_QUERY_TYPE (query)) {
46     case GST_QUERY_CAPS:
47     {
48       GstCaps **caps = g_object_get_data (G_OBJECT (pad), "caps");
49 
50       fail_unless (caps != NULL && *caps != NULL);
51       gst_query_set_caps_result (query, *caps);
52       break;
53     }
54     case GST_QUERY_ACCEPT_CAPS:
55       gst_query_set_accept_caps_result (query, TRUE);
56       break;
57     default:
58       break;
59   }
60 
61   return TRUE;
62 }
63 
64 static GstCaps *
remove_ssrc_from_caps(GstCaps * caps)65 remove_ssrc_from_caps (GstCaps * caps)
66 {
67   GstCaps *copy = gst_caps_copy (caps);
68   GstStructure *s = gst_caps_get_structure (copy, 0);
69   gst_structure_remove_field (s, "ssrc");
70   return copy;
71 }
72 
73 static gboolean
event_func(GstPad * pad,GstObject * noparent,GstEvent * event)74 event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
75 {
76   switch (GST_EVENT_TYPE (event)) {
77     case GST_EVENT_CAPS:
78     {
79       GstCaps *caps;
80       GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
81       GstCaps *caps_no_ssrc;
82       GstCaps *caps2_no_ssrc;
83 
84       gst_event_parse_caps (event, &caps);
85       caps_no_ssrc = remove_ssrc_from_caps (caps);
86       caps2_no_ssrc = remove_ssrc_from_caps (*caps2);
87 
88       fail_unless (caps2 != NULL && *caps2 != NULL);
89       fail_unless (gst_caps_is_fixed (caps));
90       fail_unless (gst_caps_is_fixed (*caps2));
91 
92       fail_unless (gst_caps_is_equal_fixed (caps_no_ssrc, caps2_no_ssrc));
93       gst_caps_unref (caps_no_ssrc);
94       gst_caps_unref (caps2_no_ssrc);
95       break;
96     }
97     default:
98       break;
99   }
100 
101   gst_event_unref (event);
102 
103   return TRUE;
104 }
105 
106 static void
test_basic(const gchar * elem_name,const gchar * sink2,int count,check_cb cb)107 test_basic (const gchar * elem_name, const gchar * sink2, int count,
108     check_cb cb)
109 {
110   GstElement *rtpmux = NULL;
111   GstPad *reqpad1 = NULL;
112   GstPad *reqpad2 = NULL;
113   GstPad *src1 = NULL;
114   GstPad *src2 = NULL;
115   GstPad *sink = NULL;
116   GstBuffer *inbuf = NULL;
117   GstCaps *src1caps = NULL;
118   GstCaps *src2caps = NULL;
119   GstCaps *sinkcaps = NULL;
120   GstCaps *caps;
121   GstSegment segment;
122   int i;
123 
124   rtpmux = gst_check_setup_element (elem_name);
125 
126   reqpad1 = gst_element_get_request_pad (rtpmux, "sink_1");
127   fail_unless (reqpad1 != NULL);
128   reqpad2 = gst_element_get_request_pad (rtpmux, sink2);
129   fail_unless (reqpad2 != NULL);
130   sink = gst_check_setup_sink_pad_by_name (rtpmux, &sinktemplate, "src");
131 
132   src1 = gst_pad_new_from_static_template (&srctemplate, "src");
133   src2 = gst_pad_new_from_static_template (&srctemplate, "src");
134   fail_unless (gst_pad_link (src1, reqpad1) == GST_PAD_LINK_OK);
135   fail_unless (gst_pad_link (src2, reqpad2) == GST_PAD_LINK_OK);
136   gst_pad_set_query_function (src1, query_func);
137   gst_pad_set_query_function (src2, query_func);
138   gst_pad_set_query_function (sink, query_func);
139   gst_pad_set_event_function (sink, event_func);
140   g_object_set_data (G_OBJECT (src1), "caps", &src1caps);
141   g_object_set_data (G_OBJECT (src2), "caps", &src2caps);
142   g_object_set_data (G_OBJECT (sink), "caps", &sinkcaps);
143 
144   src1caps = gst_caps_new_simple ("application/x-rtp",
145       "clock-rate", G_TYPE_INT, 1, "ssrc", G_TYPE_UINT, 11, NULL);
146   src2caps = gst_caps_new_simple ("application/x-rtp",
147       "clock-rate", G_TYPE_INT, 2, "ssrc", G_TYPE_UINT, 12, NULL);
148   sinkcaps = gst_caps_new_simple ("application/x-rtp",
149       "clock-rate", G_TYPE_INT, 3, "ssrc", G_TYPE_UINT, 13, NULL);
150 
151   caps = gst_pad_peer_query_caps (src1, NULL);
152   fail_unless (gst_caps_is_empty (caps));
153   gst_caps_unref (caps);
154 
155   gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL);
156   caps = gst_pad_peer_query_caps (src1, NULL);
157   gst_caps_unref (caps);
158 
159   g_object_set (rtpmux, "seqnum-offset", 100, "timestamp-offset", 1000,
160       "ssrc", 55, NULL);
161 
162   fail_unless (gst_element_set_state (rtpmux,
163           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
164   gst_pad_set_active (sink, TRUE);
165   gst_pad_set_active (src1, TRUE);
166   gst_pad_set_active (src2, TRUE);
167 
168   fail_unless (gst_pad_push_event (src1,
169           gst_event_new_stream_start ("stream1")));
170   fail_unless (gst_pad_push_event (src2,
171           gst_event_new_stream_start ("stream2")));
172 
173   gst_caps_set_simple (sinkcaps,
174       "payload", G_TYPE_INT, 98, "seqnum-offset", G_TYPE_UINT, 100,
175       "timestamp-offset", G_TYPE_UINT, 1000, "ssrc", G_TYPE_UINT, 66, NULL);
176   caps = gst_caps_new_simple ("application/x-rtp",
177       "payload", G_TYPE_INT, 98, "clock-rate", G_TYPE_INT, 3,
178       "seqnum-offset", G_TYPE_UINT, 56, "timestamp-offset", G_TYPE_UINT, 57,
179       "ssrc", G_TYPE_UINT, 66, NULL);
180   fail_unless (gst_pad_set_caps (src1, caps));
181   gst_caps_unref (caps);
182 
183   caps = gst_pad_peer_query_caps (sink, NULL);
184   fail_if (gst_caps_is_empty (caps));
185 
186   gst_segment_init (&segment, GST_FORMAT_TIME);
187   segment.start = 100000;
188   fail_unless (gst_pad_push_event (src1, gst_event_new_segment (&segment)));
189   segment.start = 0;
190   fail_unless (gst_pad_push_event (src2, gst_event_new_segment (&segment)));
191 
192 
193   for (i = 0; i < count; i++) {
194     GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
195 
196     inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
197     GST_BUFFER_PTS (inbuf) = i * 1000 + 100000;
198     GST_BUFFER_DURATION (inbuf) = 1000;
199 
200     gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
201 
202     gst_rtp_buffer_set_version (&rtpbuffer, 2);
203     gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
204     gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
205     gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
206     gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
207     gst_rtp_buffer_unmap (&rtpbuffer);
208     fail_unless (gst_pad_push (src1, inbuf) == GST_FLOW_OK);
209 
210     if (buffers)
211       fail_unless (GST_BUFFER_PTS (buffers->data) == i * 1000, "%lld",
212           GST_BUFFER_PTS (buffers->data));
213 
214     cb (src2, i);
215 
216     g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
217     g_list_free (buffers);
218     buffers = NULL;
219   }
220 
221 
222   gst_pad_set_active (sink, FALSE);
223   gst_pad_set_active (src1, FALSE);
224   gst_pad_set_active (src2, FALSE);
225   fail_unless (gst_element_set_state (rtpmux,
226           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
227   gst_check_teardown_pad_by_name (rtpmux, "src");
228   gst_object_unref (reqpad1);
229   gst_object_unref (reqpad2);
230   gst_check_teardown_pad_by_name (rtpmux, "sink_1");
231   gst_check_teardown_pad_by_name (rtpmux, sink2);
232   gst_element_release_request_pad (rtpmux, reqpad1);
233   gst_element_release_request_pad (rtpmux, reqpad2);
234 
235   gst_caps_unref (caps);
236   gst_caps_replace (&src1caps, NULL);
237   gst_caps_replace (&src2caps, NULL);
238   gst_caps_replace (&sinkcaps, NULL);
239 
240   gst_check_teardown_element (rtpmux);
241 }
242 
243 static void
basic_check_cb(GstPad * pad,int i)244 basic_check_cb (GstPad * pad, int i)
245 {
246   GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
247   fail_unless (buffers && g_list_length (buffers) == 1);
248 
249   gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
250   fail_unless_equals_int (55, gst_rtp_buffer_get_ssrc (&rtpbuffer));
251   fail_unless_equals_int64 (200 - 57 + 1000 + i,
252       gst_rtp_buffer_get_timestamp (&rtpbuffer));
253   fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
254   gst_rtp_buffer_unmap (&rtpbuffer);
255 }
256 
257 
GST_START_TEST(test_rtpmux_basic)258 GST_START_TEST (test_rtpmux_basic)
259 {
260   test_basic ("rtpmux", "sink_2", 10, basic_check_cb);
261 }
262 
263 GST_END_TEST;
264 
GST_START_TEST(test_rtpdtmfmux_basic)265 GST_START_TEST (test_rtpdtmfmux_basic)
266 {
267   test_basic ("rtpdtmfmux", "sink_2", 10, basic_check_cb);
268 }
269 
270 GST_END_TEST;
271 
272 static void
lock_check_cb(GstPad * pad,int i)273 lock_check_cb (GstPad * pad, int i)
274 {
275   GstBuffer *inbuf;
276 
277   if (i % 2) {
278     fail_unless (buffers == NULL);
279   } else {
280     GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
281 
282     fail_unless (buffers && g_list_length (buffers) == 1);
283     gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
284     fail_unless_equals_int (55, gst_rtp_buffer_get_ssrc (&rtpbuffer));
285     fail_unless_equals_int64 (200 - 57 + 1000 + i,
286         gst_rtp_buffer_get_timestamp (&rtpbuffer));
287     fail_unless_equals_int (100 + 1 + i, gst_rtp_buffer_get_seq (&rtpbuffer));
288     gst_rtp_buffer_unmap (&rtpbuffer);
289 
290     inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
291     GST_BUFFER_PTS (inbuf) = i * 1000 + 500;
292     GST_BUFFER_DURATION (inbuf) = 1000;
293     gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
294     gst_rtp_buffer_set_version (&rtpbuffer, 2);
295     gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
296     gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
297     gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
298     gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
299     gst_rtp_buffer_unmap (&rtpbuffer);
300     fail_unless (gst_pad_push (pad, inbuf) == GST_FLOW_OK);
301 
302 
303     g_list_foreach (buffers, (GFunc) gst_buffer_unref, NULL);
304     g_list_free (buffers);
305     buffers = NULL;
306   }
307 }
308 
GST_START_TEST(test_rtpdtmfmux_lock)309 GST_START_TEST (test_rtpdtmfmux_lock)
310 {
311   test_basic ("rtpdtmfmux", "priority_sink_2", 10, lock_check_cb);
312 }
313 
314 GST_END_TEST;
315 
316 static GstBuffer *
generate_test_buffer(guint seq_num,guint ssrc)317 generate_test_buffer (guint seq_num, guint ssrc)
318 {
319   GstBuffer *buf;
320   guint8 *payload;
321   guint i;
322   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
323   gsize size = 10;
324 
325   buf = gst_rtp_buffer_new_allocate (size, 0, 0);
326   GST_BUFFER_DTS (buf) = GST_MSECOND * 20 * seq_num;
327   GST_BUFFER_PTS (buf) = GST_MSECOND * 20 * seq_num;
328 
329   gst_rtp_buffer_map (buf, GST_MAP_READWRITE, &rtp);
330   gst_rtp_buffer_set_payload_type (&rtp, 0);
331   gst_rtp_buffer_set_seq (&rtp, seq_num);
332   gst_rtp_buffer_set_timestamp (&rtp, 160 * seq_num);
333   gst_rtp_buffer_set_ssrc (&rtp, ssrc);
334 
335   payload = gst_rtp_buffer_get_payload (&rtp);
336   for (i = 0; i < size; i++)
337     payload[i] = 0xff;
338 
339   gst_rtp_buffer_unmap (&rtp);
340 
341   return buf;
342 }
343 
344 static guint32
_rtp_buffer_get_ssrc(GstBuffer * buf)345 _rtp_buffer_get_ssrc (GstBuffer * buf)
346 {
347   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
348   guint32 ret;
349   g_assert (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
350   ret = gst_rtp_buffer_get_ssrc (&rtp);
351   gst_rtp_buffer_unmap (&rtp);
352   return ret;
353 }
354 
355 static guint32
_rtp_buffer_get_ts(GstBuffer * buf)356 _rtp_buffer_get_ts (GstBuffer * buf)
357 {
358   GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
359   guint32 ret;
360   g_assert (gst_rtp_buffer_map (buf, GST_MAP_READ, &rtp));
361   ret = gst_rtp_buffer_get_timestamp (&rtp);
362   gst_rtp_buffer_unmap (&rtp);
363   return ret;
364 }
365 
GST_START_TEST(test_rtpmux_ssrc_property)366 GST_START_TEST (test_rtpmux_ssrc_property)
367 {
368   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
369   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
370   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
371   GstBuffer *buf0;
372   GstBuffer *buf1;
373 
374   /* set ssrc to 111111 */
375   g_object_set (h->element, "ssrc", 111111, NULL);
376 
377   /* both sinkpads have their own idea of what the ssrc should be */
378   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
379   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
380 
381   /* push on both sinkpads with different ssrc */
382   fail_unless_equals_int (GST_FLOW_OK,
383       gst_harness_push (h0, generate_test_buffer (0, 222222)));
384   fail_unless_equals_int (GST_FLOW_OK,
385       gst_harness_push (h1, generate_test_buffer (0, 333333)));
386 
387   buf0 = gst_harness_pull (h);
388   buf1 = gst_harness_pull (h);
389 
390   /* we expect the ssrc to be what we specified in the property */
391   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf0));
392   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf1));
393 
394   gst_buffer_unref (buf0);
395   gst_buffer_unref (buf1);
396 
397   gst_harness_teardown (h0);
398   gst_harness_teardown (h1);
399   gst_harness_teardown (h);
400 }
401 
402 GST_END_TEST;
403 
GST_START_TEST(test_rtpmux_ssrc_property_not_set)404 GST_START_TEST (test_rtpmux_ssrc_property_not_set)
405 {
406   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
407   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
408   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
409   GstBuffer *buf0;
410   GstBuffer *buf1;
411 
412   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
413   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
414 
415   fail_unless_equals_int (GST_FLOW_OK,
416       gst_harness_push (h0, generate_test_buffer (0, 222222)));
417   fail_unless_equals_int (GST_FLOW_OK,
418       gst_harness_push (h1, generate_test_buffer (0, 333333)));
419 
420   buf0 = gst_harness_pull (h);
421   buf1 = gst_harness_pull (h);
422 
423   /* we expect the ssrc to be the first ssrc that came in */
424   fail_unless_equals_int (222222, _rtp_buffer_get_ssrc (buf0));
425   fail_unless_equals_int (222222, _rtp_buffer_get_ssrc (buf1));
426 
427   gst_buffer_unref (buf0);
428   gst_buffer_unref (buf1);
429 
430   gst_harness_teardown (h0);
431   gst_harness_teardown (h1);
432   gst_harness_teardown (h);
433 }
434 
435 GST_END_TEST;
436 
GST_START_TEST(test_rtpmux_ssrc_downstream_overrules_upstream)437 GST_START_TEST (test_rtpmux_ssrc_downstream_overrules_upstream)
438 {
439   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
440   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
441   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
442   GstBuffer *buf0;
443   GstBuffer *buf1;
444 
445   /* downstream is specifying 444444 as ssrc */
446   gst_harness_set_sink_caps_str (h, "application/x-rtp, ssrc=(uint)444444");
447 
448   /* while upstream ssrc is 222222 and 333333 */
449   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
450   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
451 
452   fail_unless_equals_int (GST_FLOW_OK,
453       gst_harness_push (h0, generate_test_buffer (0, 222222)));
454   fail_unless_equals_int (GST_FLOW_OK,
455       gst_harness_push (h1, generate_test_buffer (0, 333333)));
456 
457   buf0 = gst_harness_pull (h);
458   buf1 = gst_harness_pull (h);
459 
460   /* we expect the ssrc to be downstream ssrc */
461   fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf0));
462   fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf1));
463 
464   gst_buffer_unref (buf0);
465   gst_buffer_unref (buf1);
466 
467   gst_harness_teardown (h0);
468   gst_harness_teardown (h1);
469   gst_harness_teardown (h);
470 }
471 
472 GST_END_TEST;
473 
GST_START_TEST(test_rtpmux_ssrc_property_overrules_downstream)474 GST_START_TEST (test_rtpmux_ssrc_property_overrules_downstream)
475 {
476   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
477   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
478   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
479   GstBuffer *buf0;
480   GstBuffer *buf1;
481 
482   /* downstream is specifying 444444 as ssrc */
483   gst_harness_set_sink_caps_str (h, "application/x-rtp, ssrc=(uint)444444");
484 
485   /* rtpmux ssrc is set to 111111 */
486   g_object_set (h->element, "ssrc", 111111, NULL);
487 
488   /* while upstream ssrc is 222222 and 333333 */
489   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
490   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
491 
492   /* pushing now should fail */
493   fail_unless_equals_int (GST_FLOW_NOT_NEGOTIATED,
494       gst_harness_push (h0, generate_test_buffer (0, 222222)));
495   fail_unless_equals_int (GST_FLOW_NOT_NEGOTIATED,
496       gst_harness_push (h1, generate_test_buffer (0, 333333)));
497 
498   /* open up the restriction on ssrc downstream */
499   gst_harness_set_sink_caps_str (h, "application/x-rtp");
500 
501   /* and push again */
502   fail_unless_equals_int (GST_FLOW_OK,
503       gst_harness_push (h0, generate_test_buffer (0, 222222)));
504   fail_unless_equals_int (GST_FLOW_OK,
505       gst_harness_push (h1, generate_test_buffer (0, 333333)));
506 
507   buf0 = gst_harness_pull (h);
508   buf1 = gst_harness_pull (h);
509 
510   /* we expect the ssrc to be property ssrc */
511   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf0));
512   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf1));
513 
514   gst_buffer_unref (buf0);
515   gst_buffer_unref (buf1);
516 
517   gst_harness_teardown (h0);
518   gst_harness_teardown (h1);
519   gst_harness_teardown (h);
520 }
521 
522 GST_END_TEST;
523 
GST_START_TEST(test_rtpmux_ssrc_property_survive_statechange)524 GST_START_TEST (test_rtpmux_ssrc_property_survive_statechange)
525 {
526   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
527   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
528   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
529   GstBuffer *buf0;
530   GstBuffer *buf1;
531 
532   gst_element_set_state (h->element, GST_STATE_NULL);
533   /* rtpmux ssrc is set to 111111 */
534   g_object_set (h->element, "ssrc", 111111, NULL);
535   gst_element_set_state (h->element, GST_STATE_PLAYING);
536 
537   /* upstream ssrc is 222222 and 333333 */
538   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
539   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
540 
541   /* downstream is specifying 444444 as ssrc */
542   gst_harness_set_sink_caps_str (h, "application/x-rtp, ssrc=(uint)444444");
543   gst_harness_set_sink_caps_str (h, "application/x-rtp");
544 
545   /* push */
546   fail_unless_equals_int (GST_FLOW_OK,
547       gst_harness_push (h0, generate_test_buffer (0, 222222)));
548   fail_unless_equals_int (GST_FLOW_OK,
549       gst_harness_push (h1, generate_test_buffer (0, 333333)));
550 
551   buf0 = gst_harness_pull (h);
552   buf1 = gst_harness_pull (h);
553 
554   /* we expect the ssrc to be property ssrc */
555   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf0));
556   fail_unless_equals_int (111111, _rtp_buffer_get_ssrc (buf1));
557 
558   gst_buffer_unref (buf0);
559   gst_buffer_unref (buf1);
560 
561   gst_harness_teardown (h0);
562   gst_harness_teardown (h1);
563   gst_harness_teardown (h);
564 }
565 
566 GST_END_TEST;
567 
GST_START_TEST(test_rtpmux_ssrc_downstream_dynamic)568 GST_START_TEST (test_rtpmux_ssrc_downstream_dynamic)
569 {
570   GstHarness *h = gst_harness_new_parse ("rtpmux ! capsfilter");
571   GstElement *rtpmux = gst_harness_find_element (h, "rtpmux");
572   GstElement *capsfilter = gst_harness_find_element (h, "capsfilter");
573 
574   GstHarness *h0 = gst_harness_new_with_element (rtpmux, "sink_0", NULL);
575   GstHarness *h1 = gst_harness_new_with_element (rtpmux, "sink_1", NULL);
576   GstCaps *caps;
577   GstBuffer *buf0;
578   GstBuffer *buf1;
579 
580   gst_harness_play (h);
581 
582   caps = gst_caps_from_string ("application/x-rtp, ssrc=(uint)444444");
583   g_object_set (capsfilter, "caps", caps, NULL);
584   gst_caps_unref (caps);
585 
586   gst_harness_set_src_caps_str (h0, "application/x-rtp, ssrc=(uint)222222");
587   gst_harness_set_src_caps_str (h1, "application/x-rtp, ssrc=(uint)333333");
588 
589   /* push on both sinkpads with different ssrc */
590   fail_unless_equals_int (GST_FLOW_OK,
591       gst_harness_push (h0, generate_test_buffer (0, 222222)));
592   fail_unless_equals_int (GST_FLOW_OK,
593       gst_harness_push (h1, generate_test_buffer (0, 333333)));
594 
595   /* we expect the ssrc to be downstream ssrc (444444) */
596   buf0 = gst_harness_pull (h);
597   buf1 = gst_harness_pull (h);
598   fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf0));
599   fail_unless_equals_int (444444, _rtp_buffer_get_ssrc (buf1));
600   gst_buffer_unref (buf0);
601   gst_buffer_unref (buf1);
602 
603   caps = gst_caps_from_string ("application/x-rtp, ssrc=(uint)555555");
604   g_object_set (capsfilter, "caps", caps, NULL);
605   gst_caps_unref (caps);
606 
607   fail_unless_equals_int (GST_FLOW_OK,
608       gst_harness_push (h0, generate_test_buffer (0, 222222)));
609   fail_unless_equals_int (GST_FLOW_OK,
610       gst_harness_push (h1, generate_test_buffer (0, 333333)));
611 
612   /* we expect the ssrc to be the new downstream ssrc (555555) */
613   buf0 = gst_harness_pull (h);
614   buf1 = gst_harness_pull (h);
615   fail_unless_equals_int (555555, _rtp_buffer_get_ssrc (buf0));
616   fail_unless_equals_int (555555, _rtp_buffer_get_ssrc (buf1));
617   gst_buffer_unref (buf0);
618   gst_buffer_unref (buf1);
619 
620   gst_object_unref (rtpmux);
621   gst_object_unref (capsfilter);
622   gst_harness_teardown (h0);
623   gst_harness_teardown (h1);
624   gst_harness_teardown (h);
625 }
626 
627 GST_END_TEST;
628 
629 
GST_START_TEST(test_rtpmux_caps_query_with_downsteam_ts_offset_and_ssrc)630 GST_START_TEST (test_rtpmux_caps_query_with_downsteam_ts_offset_and_ssrc)
631 {
632   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", "sink_0", "src");
633   GstCaps *caps;
634   const GstStructure *s;
635 
636   /* downstream is specifying 100 as ts-offset and 111 as ssrc */
637   gst_harness_set_sink_caps_str (h, "application/x-rtp, "
638       "timstamp-offset=(uint)100, ssrc=(uint)111");
639 
640   caps = gst_pad_peer_query_caps (h->srcpad, NULL);
641   s = gst_caps_get_structure (caps, 0);
642 
643   /* check that the query does not contain any of these fields */
644   fail_unless (!gst_structure_has_field (s, "timestamp-offset"));
645   fail_unless (!gst_structure_has_field (s, "ssrc"));
646 
647   gst_caps_unref (caps);
648   gst_harness_teardown (h);
649 }
650 
651 GST_END_TEST;
652 
GST_START_TEST(test_rtpmux_ts_offset_downstream_overrules_upstream)653 GST_START_TEST (test_rtpmux_ts_offset_downstream_overrules_upstream)
654 {
655   GstHarness *h = gst_harness_new_with_padnames ("rtpmux", NULL, "src");
656   GstHarness *h0 = gst_harness_new_with_element (h->element, "sink_0", NULL);
657   GstHarness *h1 = gst_harness_new_with_element (h->element, "sink_1", NULL);
658   GstBuffer *buf0;
659   GstBuffer *buf1;
660 
661   /* downstream is specifying 1234567 as ts-offset */
662   gst_harness_set_sink_caps_str (h,
663       "application/x-rtp, timestamp-offset=(uint)1234567");
664 
665   /* while upstream ts-offset is 1600 (10 * 160) and 16000 (100 * 160) */
666   gst_harness_set_src_caps_str (h0,
667       "application/x-rtp, timestamp-offset=(uint)1600");
668   gst_harness_set_src_caps_str (h1,
669       "application/x-rtp, timestamp-offset=(uint)16000");
670 
671   /* push a buffer starting with rtp-timestamp: 1600 (10 * 160) */
672   fail_unless_equals_int (GST_FLOW_OK,
673       gst_harness_push (h0, generate_test_buffer (10, 222222)));
674   /* push a buffer starting with rtp-timestamp: 16000 (100 * 160) */
675   fail_unless_equals_int (GST_FLOW_OK,
676       gst_harness_push (h1, generate_test_buffer (100, 333333)));
677 
678   buf0 = gst_harness_pull (h);
679   buf1 = gst_harness_pull (h);
680 
681   /* we expect the buffers to start from 1234567 */
682   fail_unless_equals_int (1234567, _rtp_buffer_get_ts (buf0));
683   fail_unless_equals_int (1234567, _rtp_buffer_get_ts (buf1));
684 
685   gst_buffer_unref (buf0);
686   gst_buffer_unref (buf1);
687 
688   gst_harness_teardown (h0);
689   gst_harness_teardown (h1);
690   gst_harness_teardown (h);
691 }
692 
693 GST_END_TEST;
694 
695 static Suite *
rtpmux_suite(void)696 rtpmux_suite (void)
697 {
698   Suite *s = suite_create ("rtpmux");
699   TCase *tc_chain;
700 
701   tc_chain = tcase_create ("rtpmux_basic");
702   suite_add_tcase (s, tc_chain);
703   tcase_add_test (tc_chain, test_rtpmux_basic);
704   tcase_add_test (tc_chain, test_rtpmux_ssrc_property);
705   tcase_add_test (tc_chain, test_rtpmux_ssrc_property_not_set);
706 
707   tcase_add_test (tc_chain, test_rtpmux_ssrc_downstream_overrules_upstream);
708   tcase_add_test (tc_chain, test_rtpmux_ssrc_property_overrules_downstream);
709   tcase_add_test (tc_chain, test_rtpmux_ssrc_property_survive_statechange);
710 
711   tcase_add_test (tc_chain, test_rtpmux_ssrc_downstream_dynamic);
712 
713   tcase_add_test (tc_chain,
714       test_rtpmux_caps_query_with_downsteam_ts_offset_and_ssrc);
715   tcase_add_test (tc_chain,
716       test_rtpmux_ts_offset_downstream_overrules_upstream);
717 
718   tc_chain = tcase_create ("rtpdtmfmux_basic");
719   tcase_add_test (tc_chain, test_rtpdtmfmux_basic);
720   suite_add_tcase (s, tc_chain);
721 
722   tc_chain = tcase_create ("rtpdtmfmux_lock");
723   tcase_add_test (tc_chain, test_rtpdtmfmux_lock);
724   suite_add_tcase (s, tc_chain);
725 
726   return s;
727 }
728 
729 GST_CHECK_MAIN (rtpmux)
730