372faede2017ed9391fdef9fe7ac27f1bb19de02
[platform/upstream/gst-plugins-good.git] / tests / check / elements / rtpbin.c
1 /* GStreamer
2  *
3  * unit test for gstrtpbin
4  *
5  * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 GST_START_TEST (test_pads)
26 {
27   GstElement *element;
28   GstPad *pad;
29
30   element = gst_element_factory_make ("rtpsession", NULL);
31
32   pad = gst_element_get_request_pad (element, "recv_rtcp_sink");
33   gst_object_unref (pad);
34   gst_object_unref (element);
35 }
36
37 GST_END_TEST;
38
39 GST_START_TEST (test_cleanup_send)
40 {
41   GstElement *rtpbin;
42   GstPad *rtp_sink, *rtp_src, *rtcp_src;
43   GObject *session;
44   gint count = 2;
45
46   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
47
48   while (count--) {
49     /* request session 0 */
50     rtp_sink = gst_element_get_request_pad (rtpbin, "send_rtp_sink_0");
51     fail_unless (rtp_sink != NULL);
52     ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);
53
54     /* this static pad should be created automatically now */
55     rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_0");
56     fail_unless (rtp_src != NULL);
57     ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 2);
58
59     /* we should be able to get an internal session 0 now */
60     g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
61     fail_unless (session != NULL);
62     g_object_unref (session);
63
64     /* get the send RTCP pad too */
65     rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_0");
66     fail_unless (rtcp_src != NULL);
67     ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtcp_src", 2);
68
69     gst_element_release_request_pad (rtpbin, rtp_sink);
70     /* we should only have our refs to the pads now */
71     ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1);
72     ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1);
73     ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 2);
74
75     /* the other pad should be gone now */
76     fail_unless (gst_element_get_static_pad (rtpbin, "send_rtp_src_0") == NULL);
77
78     /* internal session should still be there */
79     g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
80     fail_unless (session != NULL);
81     g_object_unref (session);
82
83     /* release the RTCP pad */
84     gst_element_release_request_pad (rtpbin, rtcp_src);
85     /* we should only have our refs to the pads now */
86     ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 1);
87     ASSERT_OBJECT_REFCOUNT (rtp_src, "rtp_src", 1);
88     ASSERT_OBJECT_REFCOUNT (rtcp_src, "rtp_src", 1);
89
90     /* the session should be gone now */
91     g_signal_emit_by_name (rtpbin, "get-internal-session", 0, &session);
92     fail_unless (session == NULL);
93
94     /* unref the request pad and the static pad */
95     gst_object_unref (rtp_sink);
96     gst_object_unref (rtp_src);
97     gst_object_unref (rtcp_src);
98   }
99
100   gst_object_unref (rtpbin);
101 }
102
103 GST_END_TEST;
104
105 typedef struct
106 {
107   guint16 seqnum;
108   gboolean pad_added;
109   GstPad *pad;
110   GMutex lock;
111   GCond cond;
112   GstPad *sinkpad;
113   GList *pads;
114 } CleanupData;
115
116 static void
117 init_data (CleanupData * data)
118 {
119   data->seqnum = 10;
120   data->pad_added = FALSE;
121   g_mutex_init (&data->lock);
122   g_cond_init (&data->cond);
123   data->pads = NULL;
124 }
125
126 static void
127 clean_data (CleanupData * data)
128 {
129   g_list_foreach (data->pads, (GFunc) gst_object_unref, NULL);
130   g_list_free (data->pads);
131   g_mutex_clear (&data->lock);
132   g_cond_clear (&data->cond);
133 }
134
135 static guint8 rtp_packet[] = { 0x80, 0x60, 0x94, 0xbc, 0x8f, 0x37, 0x4e, 0xb8,
136   0x44, 0xa8, 0xf3, 0x7c, 0x06, 0x6a, 0x0c, 0xce,
137   0x13, 0x25, 0x19, 0x69, 0x1f, 0x93, 0x25, 0x9d,
138   0x2b, 0x82, 0x31, 0x3b, 0x36, 0xc1, 0x3c, 0x13
139 };
140
141 static GstFlowReturn
142 chain_rtp_packet (GstPad * pad, CleanupData * data)
143 {
144   GstFlowReturn res;
145   static GstCaps *caps = NULL;
146   GstSegment segment;
147   GstBuffer *buffer;
148   GstMapInfo map;
149
150   if (caps == NULL) {
151     caps = gst_caps_from_string ("application/x-rtp,"
152         "media=(string)audio, clock-rate=(int)44100, "
153         "encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1");
154     data->seqnum = 0;
155   }
156
157   gst_pad_send_event (pad, gst_event_new_stream_start (GST_OBJECT_NAME (pad)));
158   gst_pad_send_event (pad, gst_event_new_caps (caps));
159   gst_segment_init (&segment, GST_FORMAT_TIME);
160   gst_pad_send_event (pad, gst_event_new_segment (&segment));
161
162   buffer = gst_buffer_new_and_alloc (sizeof (rtp_packet));
163   gst_buffer_map (buffer, &map, GST_MAP_WRITE);
164   memcpy (map.data, rtp_packet, sizeof (rtp_packet));
165
166   map.data[2] = (data->seqnum >> 8) & 0xff;
167   map.data[3] = data->seqnum & 0xff;
168
169   data->seqnum++;
170   gst_buffer_unmap (buffer, &map);
171
172   res = gst_pad_chain (pad, buffer);
173
174   return res;
175 }
176
177 static GstFlowReturn
178 dummy_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
179 {
180   gst_buffer_unref (buffer);
181
182   return GST_FLOW_OK;
183 }
184
185 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
186     GST_PAD_SINK,
187     GST_PAD_ALWAYS,
188     GST_STATIC_CAPS ("application/x-rtp"));
189
190
191 static GstPad *
192 make_sinkpad (CleanupData * data)
193 {
194   GstPad *pad;
195
196   pad = gst_pad_new_from_static_template (&sink_factory, "sink");
197
198   gst_pad_set_chain_function (pad, dummy_chain);
199   gst_pad_set_active (pad, TRUE);
200
201   data->pads = g_list_prepend (data->pads, pad);
202
203   return pad;
204 }
205
206 static void
207 pad_added_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
208 {
209   GstPad *sinkpad;
210
211   GST_DEBUG ("pad added %s:%s\n", GST_DEBUG_PAD_NAME (pad));
212
213   if (GST_PAD_IS_SINK (pad))
214     return;
215
216   fail_unless (data->pad_added == FALSE);
217
218   sinkpad = make_sinkpad (data);
219   fail_unless (gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK);
220
221   g_mutex_lock (&data->lock);
222   data->pad_added = TRUE;
223   data->pad = pad;
224   g_cond_signal (&data->cond);
225   g_mutex_unlock (&data->lock);
226 }
227
228 static void
229 pad_removed_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
230 {
231   GST_DEBUG ("pad removed %s:%s\n", GST_DEBUG_PAD_NAME (pad));
232
233   if (data->pad != pad)
234     return;
235
236   fail_unless (data->pad_added == TRUE);
237
238   g_mutex_lock (&data->lock);
239   data->pad_added = FALSE;
240   g_cond_signal (&data->cond);
241   g_mutex_unlock (&data->lock);
242 }
243
244 GST_START_TEST (test_cleanup_recv)
245 {
246   GstElement *rtpbin;
247   GstPad *rtp_sink;
248   CleanupData data;
249   GstStateChangeReturn ret;
250   GstFlowReturn res;
251   gint count = 2;
252
253   init_data (&data);
254
255   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
256
257   g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
258   g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);
259
260   ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
261   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
262
263   while (count--) {
264     /* request session 0 */
265     rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
266     fail_unless (rtp_sink != NULL);
267     ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);
268
269     /* no sourcepads are created yet */
270     fail_unless (rtpbin->numsinkpads == 1);
271     fail_unless (rtpbin->numsrcpads == 0);
272
273     res = chain_rtp_packet (rtp_sink, &data);
274     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
275     fail_unless (res == GST_FLOW_OK);
276
277     res = chain_rtp_packet (rtp_sink, &data);
278     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
279     fail_unless (res == GST_FLOW_OK);
280
281     /* we wait for the new pad to appear now */
282     g_mutex_lock (&data.lock);
283     while (!data.pad_added)
284       g_cond_wait (&data.cond, &data.lock);
285     g_mutex_unlock (&data.lock);
286
287     /* sourcepad created now */
288     fail_unless (rtpbin->numsinkpads == 1);
289     fail_unless (rtpbin->numsrcpads == 1);
290
291     /* remove the session */
292     gst_element_release_request_pad (rtpbin, rtp_sink);
293     gst_object_unref (rtp_sink);
294
295     /* pad should be gone now */
296     g_mutex_lock (&data.lock);
297     while (data.pad_added)
298       g_cond_wait (&data.cond, &data.lock);
299     g_mutex_unlock (&data.lock);
300
301     /* nothing left anymore now */
302     fail_unless (rtpbin->numsinkpads == 0);
303     fail_unless (rtpbin->numsrcpads == 0);
304   }
305
306   ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
307   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
308
309   gst_object_unref (rtpbin);
310
311   clean_data (&data);
312 }
313
314 GST_END_TEST;
315
316 GST_START_TEST (test_cleanup_recv2)
317 {
318   GstElement *rtpbin;
319   GstPad *rtp_sink;
320   CleanupData data;
321   GstStateChangeReturn ret;
322   GstFlowReturn res;
323   gint count = 2;
324
325   init_data (&data);
326
327   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
328
329   g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
330   g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);
331
332   ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
333   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
334
335   /* request session 0 */
336   rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
337   fail_unless (rtp_sink != NULL);
338   ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);
339
340   while (count--) {
341     /* no sourcepads are created yet */
342     fail_unless (rtpbin->numsinkpads == 1);
343     fail_unless (rtpbin->numsrcpads == 0);
344
345     res = chain_rtp_packet (rtp_sink, &data);
346     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
347     fail_unless (res == GST_FLOW_OK);
348
349     res = chain_rtp_packet (rtp_sink, &data);
350     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
351     fail_unless (res == GST_FLOW_OK);
352
353     /* we wait for the new pad to appear now */
354     g_mutex_lock (&data.lock);
355     while (!data.pad_added)
356       g_cond_wait (&data.cond, &data.lock);
357     g_mutex_unlock (&data.lock);
358
359     /* sourcepad created now */
360     fail_unless (rtpbin->numsinkpads == 1);
361     fail_unless (rtpbin->numsrcpads == 1);
362
363     /* change state */
364     ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
365     fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
366
367     /* pad should be gone now */
368     g_mutex_lock (&data.lock);
369     while (data.pad_added)
370       g_cond_wait (&data.cond, &data.lock);
371     g_mutex_unlock (&data.lock);
372
373     /* back to playing for the next round */
374     ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
375     fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
376   }
377
378   /* remove the session */
379   gst_element_release_request_pad (rtpbin, rtp_sink);
380   gst_object_unref (rtp_sink);
381
382   /* nothing left anymore now */
383   fail_unless (rtpbin->numsinkpads == 0);
384   fail_unless (rtpbin->numsrcpads == 0);
385
386   ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
387   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
388
389   gst_object_unref (rtpbin);
390
391   clean_data (&data);
392 }
393
394 GST_END_TEST;
395
396 GST_START_TEST (test_request_pad_by_template_name)
397 {
398   GstElement *rtpbin;
399   GstPad *rtp_sink1, *rtp_sink2, *rtp_sink3;
400
401   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
402   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
403   fail_unless (rtp_sink1 != NULL);
404   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_0");
405   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
406
407   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
408   fail_unless (rtp_sink2 != NULL);
409   fail_unless_equals_string (GST_PAD_NAME (rtp_sink2), "recv_rtp_sink_1");
410   ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 2);
411
412   rtp_sink3 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
413   fail_unless (rtp_sink3 != NULL);
414   fail_unless_equals_string (GST_PAD_NAME (rtp_sink3), "recv_rtp_sink_2");
415   ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 2);
416
417
418   gst_element_release_request_pad (rtpbin, rtp_sink2);
419   gst_element_release_request_pad (rtpbin, rtp_sink1);
420   gst_element_release_request_pad (rtpbin, rtp_sink3);
421   ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 1);
422   ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 1);
423   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink", 1);
424   gst_object_unref (rtp_sink1);
425   gst_object_unref (rtp_sink2);
426   gst_object_unref (rtp_sink3);
427
428   gst_object_unref (rtpbin);
429 }
430
431 GST_END_TEST;
432
433 static GstElement *
434 encoder_cb (GstElement * rtpbin, guint sessid, GstElement * bin)
435 {
436   GstPad *srcpad, *sinkpad;
437
438   fail_unless (sessid == 2);
439
440   GST_DEBUG ("making encoder");
441   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_2", GST_PAD_SINK);
442   srcpad = gst_ghost_pad_new_no_target ("rtp_src_2", GST_PAD_SRC);
443
444   gst_element_add_pad (bin, sinkpad);
445   gst_element_add_pad (bin, srcpad);
446
447   return gst_object_ref (bin);
448 }
449
450 static GstElement *
451 encoder_cb2 (GstElement * rtpbin, guint sessid, GstElement * bin)
452 {
453   GstPad *srcpad, *sinkpad;
454
455   fail_unless (sessid == 3);
456
457   GST_DEBUG ("making encoder");
458   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_3", GST_PAD_SINK);
459   srcpad = gst_ghost_pad_new_no_target ("rtp_src_3", GST_PAD_SRC);
460
461   gst_element_add_pad (bin, sinkpad);
462   gst_element_add_pad (bin, srcpad);
463
464   return gst_object_ref (bin);
465 }
466
467 GST_START_TEST (test_encoder)
468 {
469   GstElement *rtpbin, *bin;
470   GstPad *rtp_sink1, *rtp_sink2;
471   gulong id;
472
473   bin = gst_bin_new ("rtpenc");
474
475   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
476
477   id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb,
478       bin);
479
480   rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
481   fail_unless (rtp_sink1 != NULL);
482   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
483   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
484
485   g_signal_handler_disconnect (rtpbin, id);
486
487   id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb2,
488       bin);
489
490   rtp_sink2 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_3");
491   fail_unless (rtp_sink2 != NULL);
492
493   /* remove the session */
494   gst_element_release_request_pad (rtpbin, rtp_sink1);
495   gst_object_unref (rtp_sink1);
496
497   gst_element_release_request_pad (rtpbin, rtp_sink2);
498   gst_object_unref (rtp_sink2);
499
500   /* nothing left anymore now */
501   fail_unless (rtpbin->numsinkpads == 0);
502   fail_unless (rtpbin->numsrcpads == 0);
503
504   gst_object_unref (rtpbin);
505   gst_object_unref (bin);
506 }
507
508 GST_END_TEST;
509
510 static GstElement *
511 decoder_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
512 {
513   GstElement *bin;
514   GstPad *srcpad, *sinkpad;
515
516   bin = gst_bin_new (NULL);
517
518   GST_DEBUG ("making decoder");
519   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink", GST_PAD_SINK);
520   srcpad = gst_ghost_pad_new_no_target ("rtp_src", GST_PAD_SRC);
521
522   gst_element_add_pad (bin, sinkpad);
523   gst_element_add_pad (bin, srcpad);
524
525   return bin;
526 }
527
528 GST_START_TEST (test_decoder)
529 {
530   GstElement *rtpbin;
531   GstPad *rtp_sink1, *rtp_sink2;
532   gulong id;
533
534
535   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
536
537   id = g_signal_connect (rtpbin, "request-rtp-decoder", (GCallback) decoder_cb,
538       NULL);
539
540   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
541   fail_unless (rtp_sink1 != NULL);
542   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_2");
543   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
544
545   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_3");
546   fail_unless (rtp_sink2 != NULL);
547
548   g_signal_handler_disconnect (rtpbin, id);
549
550   /* remove the session */
551   gst_element_release_request_pad (rtpbin, rtp_sink1);
552   gst_object_unref (rtp_sink1);
553
554   gst_element_release_request_pad (rtpbin, rtp_sink2);
555   gst_object_unref (rtp_sink2);
556
557   /* nothing left anymore now */
558   fail_unless (rtpbin->numsinkpads == 0);
559   fail_unless (rtpbin->numsrcpads == 0);
560
561   gst_object_unref (rtpbin);
562 }
563
564 GST_END_TEST;
565
566 static GstElement *
567 aux_sender_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
568 {
569   GstElement *bin;
570   GstPad *srcpad, *sinkpad;
571
572   bin = gst_bin_new (NULL);
573
574   GST_DEBUG ("making AUX sender");
575   sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
576   gst_element_add_pad (bin, sinkpad);
577
578   srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
579   gst_element_add_pad (bin, srcpad);
580   srcpad = gst_ghost_pad_new_no_target ("src_1", GST_PAD_SRC);
581   gst_element_add_pad (bin, srcpad);
582   srcpad = gst_ghost_pad_new_no_target ("src_3", GST_PAD_SRC);
583   gst_element_add_pad (bin, srcpad);
584
585   return bin;
586 }
587
588 GST_START_TEST (test_aux_sender)
589 {
590   GstElement *rtpbin;
591   GstPad *rtp_sink1, *rtp_src, *rtcp_src;
592   gulong id;
593
594   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
595
596   id = g_signal_connect (rtpbin, "request-aux-sender",
597       (GCallback) aux_sender_cb, NULL);
598
599   rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
600   fail_unless (rtp_sink1 != NULL);
601   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
602   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
603
604   g_signal_handler_disconnect (rtpbin, id);
605
606   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_2");
607   fail_unless (rtp_src != NULL);
608   gst_object_unref (rtp_src);
609
610   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_1");
611   fail_unless (rtp_src != NULL);
612   gst_object_unref (rtp_src);
613
614   rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_1");
615   fail_unless (rtcp_src != NULL);
616   gst_element_release_request_pad (rtpbin, rtcp_src);
617   gst_object_unref (rtcp_src);
618
619   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_3");
620   fail_unless (rtp_src != NULL);
621   gst_object_unref (rtp_src);
622
623   /* remove the session */
624   gst_element_release_request_pad (rtpbin, rtp_sink1);
625   gst_object_unref (rtp_sink1);
626
627   gst_object_unref (rtpbin);
628 }
629
630 GST_END_TEST;
631
632 static GstElement *
633 aux_receiver_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
634 {
635   GstElement *bin;
636   GstPad *srcpad, *sinkpad;
637
638   bin = gst_bin_new (NULL);
639
640   GST_DEBUG ("making AUX receiver");
641   srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
642   gst_element_add_pad (bin, srcpad);
643
644   sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
645   gst_element_add_pad (bin, sinkpad);
646   sinkpad = gst_ghost_pad_new_no_target ("sink_1", GST_PAD_SINK);
647   gst_element_add_pad (bin, sinkpad);
648   sinkpad = gst_ghost_pad_new_no_target ("sink_3", GST_PAD_SINK);
649   gst_element_add_pad (bin, sinkpad);
650
651   return bin;
652 }
653
654 GST_START_TEST (test_aux_receiver)
655 {
656   GstElement *rtpbin;
657   GstPad *rtp_sink1, *rtp_sink2, *rtcp_sink;
658   gulong id;
659
660   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
661
662   id = g_signal_connect (rtpbin, "request-aux-receiver",
663       (GCallback) aux_receiver_cb, NULL);
664
665   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
666   fail_unless (rtp_sink1 != NULL);
667
668   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_1");
669   fail_unless (rtp_sink2 != NULL);
670
671   g_signal_handler_disconnect (rtpbin, id);
672
673   rtcp_sink = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_1");
674   fail_unless (rtcp_sink != NULL);
675   gst_element_release_request_pad (rtpbin, rtcp_sink);
676   gst_object_unref (rtcp_sink);
677
678   /* remove the session */
679   gst_element_release_request_pad (rtpbin, rtp_sink1);
680   gst_object_unref (rtp_sink1);
681   gst_element_release_request_pad (rtpbin, rtp_sink2);
682   gst_object_unref (rtp_sink2);
683
684   gst_object_unref (rtpbin);
685 }
686
687 GST_END_TEST;
688
689 static Suite *
690 rtpbin_suite (void)
691 {
692   Suite *s = suite_create ("rtpbin");
693   TCase *tc_chain = tcase_create ("general");
694
695   suite_add_tcase (s, tc_chain);
696   tcase_add_test (tc_chain, test_pads);
697   tcase_add_test (tc_chain, test_cleanup_send);
698   tcase_add_test (tc_chain, test_cleanup_recv);
699   tcase_add_test (tc_chain, test_cleanup_recv2);
700   tcase_add_test (tc_chain, test_request_pad_by_template_name);
701   tcase_add_test (tc_chain, test_encoder);
702   tcase_add_test (tc_chain, test_decoder);
703   tcase_add_test (tc_chain, test_aux_sender);
704   tcase_add_test (tc_chain, test_aux_receiver);
705
706   return s;
707 }
708
709 GST_CHECK_MAIN (rtpbin);