tests: rtpbin: fix caps leak
[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   GstCaps *caps;
115 } CleanupData;
116
117 static void
118 init_data (CleanupData * data)
119 {
120   data->seqnum = 10;
121   data->pad_added = FALSE;
122   g_mutex_init (&data->lock);
123   g_cond_init (&data->cond);
124   data->pads = NULL;
125   data->caps = NULL;
126 }
127
128 static void
129 clean_data (CleanupData * data)
130 {
131   g_list_foreach (data->pads, (GFunc) gst_object_unref, NULL);
132   g_list_free (data->pads);
133   g_mutex_clear (&data->lock);
134   g_cond_clear (&data->cond);
135   if (data->caps)
136     gst_caps_unref (data->caps);
137 }
138
139 static guint8 rtp_packet[] = { 0x80, 0x60, 0x94, 0xbc, 0x8f, 0x37, 0x4e, 0xb8,
140   0x44, 0xa8, 0xf3, 0x7c, 0x06, 0x6a, 0x0c, 0xce,
141   0x13, 0x25, 0x19, 0x69, 0x1f, 0x93, 0x25, 0x9d,
142   0x2b, 0x82, 0x31, 0x3b, 0x36, 0xc1, 0x3c, 0x13
143 };
144
145 static GstFlowReturn
146 chain_rtp_packet (GstPad * pad, CleanupData * data)
147 {
148   GstFlowReturn res;
149   GstSegment segment;
150   GstBuffer *buffer;
151   GstMapInfo map;
152
153   if (data->caps == NULL) {
154     data->caps = gst_caps_from_string ("application/x-rtp,"
155         "media=(string)audio, clock-rate=(int)44100, "
156         "encoding-name=(string)L16, encoding-params=(string)1, channels=(int)1");
157     data->seqnum = 0;
158   }
159
160   gst_pad_send_event (pad, gst_event_new_stream_start (GST_OBJECT_NAME (pad)));
161   gst_pad_send_event (pad, gst_event_new_caps (data->caps));
162   gst_segment_init (&segment, GST_FORMAT_TIME);
163   gst_pad_send_event (pad, gst_event_new_segment (&segment));
164
165   buffer = gst_buffer_new_and_alloc (sizeof (rtp_packet));
166   gst_buffer_map (buffer, &map, GST_MAP_WRITE);
167   memcpy (map.data, rtp_packet, sizeof (rtp_packet));
168
169   map.data[2] = (data->seqnum >> 8) & 0xff;
170   map.data[3] = data->seqnum & 0xff;
171
172   data->seqnum++;
173   gst_buffer_unmap (buffer, &map);
174
175   res = gst_pad_chain (pad, buffer);
176
177   return res;
178 }
179
180 static GstFlowReturn
181 dummy_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
182 {
183   gst_buffer_unref (buffer);
184
185   return GST_FLOW_OK;
186 }
187
188 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
189     GST_PAD_SINK,
190     GST_PAD_ALWAYS,
191     GST_STATIC_CAPS ("application/x-rtp"));
192
193
194 static GstPad *
195 make_sinkpad (CleanupData * data)
196 {
197   GstPad *pad;
198
199   pad = gst_pad_new_from_static_template (&sink_factory, "sink");
200
201   gst_pad_set_chain_function (pad, dummy_chain);
202   gst_pad_set_active (pad, TRUE);
203
204   data->pads = g_list_prepend (data->pads, pad);
205
206   return pad;
207 }
208
209 static void
210 pad_added_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
211 {
212   GstPad *sinkpad;
213
214   GST_DEBUG ("pad added %s:%s\n", GST_DEBUG_PAD_NAME (pad));
215
216   if (GST_PAD_IS_SINK (pad))
217     return;
218
219   fail_unless (data->pad_added == FALSE);
220
221   sinkpad = make_sinkpad (data);
222   fail_unless (gst_pad_link (pad, sinkpad) == GST_PAD_LINK_OK);
223
224   g_mutex_lock (&data->lock);
225   data->pad_added = TRUE;
226   data->pad = pad;
227   g_cond_signal (&data->cond);
228   g_mutex_unlock (&data->lock);
229 }
230
231 static void
232 pad_removed_cb (GstElement * rtpbin, GstPad * pad, CleanupData * data)
233 {
234   GST_DEBUG ("pad removed %s:%s\n", GST_DEBUG_PAD_NAME (pad));
235
236   if (data->pad != pad)
237     return;
238
239   fail_unless (data->pad_added == TRUE);
240
241   g_mutex_lock (&data->lock);
242   data->pad_added = FALSE;
243   g_cond_signal (&data->cond);
244   g_mutex_unlock (&data->lock);
245 }
246
247 GST_START_TEST (test_cleanup_recv)
248 {
249   GstElement *rtpbin;
250   GstPad *rtp_sink;
251   CleanupData data;
252   GstStateChangeReturn ret;
253   GstFlowReturn res;
254   gint count = 2;
255
256   init_data (&data);
257
258   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
259
260   g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
261   g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);
262
263   ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
264   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
265
266   while (count--) {
267     /* request session 0 */
268     rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
269     fail_unless (rtp_sink != NULL);
270     ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);
271
272     /* no sourcepads are created yet */
273     fail_unless (rtpbin->numsinkpads == 1);
274     fail_unless (rtpbin->numsrcpads == 0);
275
276     res = chain_rtp_packet (rtp_sink, &data);
277     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
278     fail_unless (res == GST_FLOW_OK);
279
280     res = chain_rtp_packet (rtp_sink, &data);
281     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
282     fail_unless (res == GST_FLOW_OK);
283
284     /* we wait for the new pad to appear now */
285     g_mutex_lock (&data.lock);
286     while (!data.pad_added)
287       g_cond_wait (&data.cond, &data.lock);
288     g_mutex_unlock (&data.lock);
289
290     /* sourcepad created now */
291     fail_unless (rtpbin->numsinkpads == 1);
292     fail_unless (rtpbin->numsrcpads == 1);
293
294     /* remove the session */
295     gst_element_release_request_pad (rtpbin, rtp_sink);
296     gst_object_unref (rtp_sink);
297
298     /* pad should be gone now */
299     g_mutex_lock (&data.lock);
300     while (data.pad_added)
301       g_cond_wait (&data.cond, &data.lock);
302     g_mutex_unlock (&data.lock);
303
304     /* nothing left anymore now */
305     fail_unless (rtpbin->numsinkpads == 0);
306     fail_unless (rtpbin->numsrcpads == 0);
307   }
308
309   ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
310   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
311
312   gst_object_unref (rtpbin);
313
314   clean_data (&data);
315 }
316
317 GST_END_TEST;
318
319 GST_START_TEST (test_cleanup_recv2)
320 {
321   GstElement *rtpbin;
322   GstPad *rtp_sink;
323   CleanupData data;
324   GstStateChangeReturn ret;
325   GstFlowReturn res;
326   gint count = 2;
327
328   init_data (&data);
329
330   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
331
332   g_signal_connect (rtpbin, "pad-added", (GCallback) pad_added_cb, &data);
333   g_signal_connect (rtpbin, "pad-removed", (GCallback) pad_removed_cb, &data);
334
335   ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
336   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
337
338   /* request session 0 */
339   rtp_sink = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_0");
340   fail_unless (rtp_sink != NULL);
341   ASSERT_OBJECT_REFCOUNT (rtp_sink, "rtp_sink", 2);
342
343   while (count--) {
344     /* no sourcepads are created yet */
345     fail_unless (rtpbin->numsinkpads == 1);
346     fail_unless (rtpbin->numsrcpads == 0);
347
348     res = chain_rtp_packet (rtp_sink, &data);
349     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
350     fail_unless (res == GST_FLOW_OK);
351
352     res = chain_rtp_packet (rtp_sink, &data);
353     GST_DEBUG ("res %d, %s\n", res, gst_flow_get_name (res));
354     fail_unless (res == GST_FLOW_OK);
355
356     /* we wait for the new pad to appear now */
357     g_mutex_lock (&data.lock);
358     while (!data.pad_added)
359       g_cond_wait (&data.cond, &data.lock);
360     g_mutex_unlock (&data.lock);
361
362     /* sourcepad created now */
363     fail_unless (rtpbin->numsinkpads == 1);
364     fail_unless (rtpbin->numsrcpads == 1);
365
366     /* change state */
367     ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
368     fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
369
370     /* pad should be gone now */
371     g_mutex_lock (&data.lock);
372     while (data.pad_added)
373       g_cond_wait (&data.cond, &data.lock);
374     g_mutex_unlock (&data.lock);
375
376     /* back to playing for the next round */
377     ret = gst_element_set_state (rtpbin, GST_STATE_PLAYING);
378     fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
379   }
380
381   /* remove the session */
382   gst_element_release_request_pad (rtpbin, rtp_sink);
383   gst_object_unref (rtp_sink);
384
385   /* nothing left anymore now */
386   fail_unless (rtpbin->numsinkpads == 0);
387   fail_unless (rtpbin->numsrcpads == 0);
388
389   ret = gst_element_set_state (rtpbin, GST_STATE_NULL);
390   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
391
392   gst_object_unref (rtpbin);
393
394   clean_data (&data);
395 }
396
397 GST_END_TEST;
398
399 GST_START_TEST (test_request_pad_by_template_name)
400 {
401   GstElement *rtpbin;
402   GstPad *rtp_sink1, *rtp_sink2, *rtp_sink3;
403
404   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
405   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
406   fail_unless (rtp_sink1 != NULL);
407   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_0");
408   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
409
410   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
411   fail_unless (rtp_sink2 != NULL);
412   fail_unless_equals_string (GST_PAD_NAME (rtp_sink2), "recv_rtp_sink_1");
413   ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 2);
414
415   rtp_sink3 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_%u");
416   fail_unless (rtp_sink3 != NULL);
417   fail_unless_equals_string (GST_PAD_NAME (rtp_sink3), "recv_rtp_sink_2");
418   ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 2);
419
420
421   gst_element_release_request_pad (rtpbin, rtp_sink2);
422   gst_element_release_request_pad (rtpbin, rtp_sink1);
423   gst_element_release_request_pad (rtpbin, rtp_sink3);
424   ASSERT_OBJECT_REFCOUNT (rtp_sink3, "rtp_sink3", 1);
425   ASSERT_OBJECT_REFCOUNT (rtp_sink2, "rtp_sink2", 1);
426   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink", 1);
427   gst_object_unref (rtp_sink1);
428   gst_object_unref (rtp_sink2);
429   gst_object_unref (rtp_sink3);
430
431   gst_object_unref (rtpbin);
432 }
433
434 GST_END_TEST;
435
436 static GstElement *
437 encoder_cb (GstElement * rtpbin, guint sessid, GstElement * bin)
438 {
439   GstPad *srcpad, *sinkpad;
440
441   fail_unless (sessid == 2);
442
443   GST_DEBUG ("making encoder");
444   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_2", GST_PAD_SINK);
445   srcpad = gst_ghost_pad_new_no_target ("rtp_src_2", GST_PAD_SRC);
446
447   gst_element_add_pad (bin, sinkpad);
448   gst_element_add_pad (bin, srcpad);
449
450   return gst_object_ref (bin);
451 }
452
453 static GstElement *
454 encoder_cb2 (GstElement * rtpbin, guint sessid, GstElement * bin)
455 {
456   GstPad *srcpad, *sinkpad;
457
458   fail_unless (sessid == 3);
459
460   GST_DEBUG ("making encoder");
461   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink_3", GST_PAD_SINK);
462   srcpad = gst_ghost_pad_new_no_target ("rtp_src_3", GST_PAD_SRC);
463
464   gst_element_add_pad (bin, sinkpad);
465   gst_element_add_pad (bin, srcpad);
466
467   return gst_object_ref (bin);
468 }
469
470 GST_START_TEST (test_encoder)
471 {
472   GstElement *rtpbin, *bin;
473   GstPad *rtp_sink1, *rtp_sink2;
474   gulong id;
475
476   bin = gst_bin_new ("rtpenc");
477
478   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
479
480   id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb,
481       bin);
482
483   rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
484   fail_unless (rtp_sink1 != NULL);
485   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
486   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
487
488   g_signal_handler_disconnect (rtpbin, id);
489
490   id = g_signal_connect (rtpbin, "request-rtp-encoder", (GCallback) encoder_cb2,
491       bin);
492
493   rtp_sink2 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_3");
494   fail_unless (rtp_sink2 != NULL);
495
496   /* remove the session */
497   gst_element_release_request_pad (rtpbin, rtp_sink1);
498   gst_object_unref (rtp_sink1);
499
500   gst_element_release_request_pad (rtpbin, rtp_sink2);
501   gst_object_unref (rtp_sink2);
502
503   /* nothing left anymore now */
504   fail_unless (rtpbin->numsinkpads == 0);
505   fail_unless (rtpbin->numsrcpads == 0);
506
507   gst_object_unref (rtpbin);
508   gst_object_unref (bin);
509 }
510
511 GST_END_TEST;
512
513 static GstElement *
514 decoder_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
515 {
516   GstElement *bin;
517   GstPad *srcpad, *sinkpad;
518
519   bin = gst_bin_new (NULL);
520
521   GST_DEBUG ("making decoder");
522   sinkpad = gst_ghost_pad_new_no_target ("rtp_sink", GST_PAD_SINK);
523   srcpad = gst_ghost_pad_new_no_target ("rtp_src", GST_PAD_SRC);
524
525   gst_element_add_pad (bin, sinkpad);
526   gst_element_add_pad (bin, srcpad);
527
528   return bin;
529 }
530
531 GST_START_TEST (test_decoder)
532 {
533   GstElement *rtpbin;
534   GstPad *rtp_sink1, *rtp_sink2;
535   gulong id;
536
537
538   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
539
540   id = g_signal_connect (rtpbin, "request-rtp-decoder", (GCallback) decoder_cb,
541       NULL);
542
543   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
544   fail_unless (rtp_sink1 != NULL);
545   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "recv_rtp_sink_2");
546   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
547
548   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_3");
549   fail_unless (rtp_sink2 != NULL);
550
551   g_signal_handler_disconnect (rtpbin, id);
552
553   /* remove the session */
554   gst_element_release_request_pad (rtpbin, rtp_sink1);
555   gst_object_unref (rtp_sink1);
556
557   gst_element_release_request_pad (rtpbin, rtp_sink2);
558   gst_object_unref (rtp_sink2);
559
560   /* nothing left anymore now */
561   fail_unless (rtpbin->numsinkpads == 0);
562   fail_unless (rtpbin->numsrcpads == 0);
563
564   gst_object_unref (rtpbin);
565 }
566
567 GST_END_TEST;
568
569 static GstElement *
570 aux_sender_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
571 {
572   GstElement *bin;
573   GstPad *srcpad, *sinkpad;
574
575   bin = gst_bin_new (NULL);
576
577   GST_DEBUG ("making AUX sender");
578   sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
579   gst_element_add_pad (bin, sinkpad);
580
581   srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
582   gst_element_add_pad (bin, srcpad);
583   srcpad = gst_ghost_pad_new_no_target ("src_1", GST_PAD_SRC);
584   gst_element_add_pad (bin, srcpad);
585   srcpad = gst_ghost_pad_new_no_target ("src_3", GST_PAD_SRC);
586   gst_element_add_pad (bin, srcpad);
587
588   return bin;
589 }
590
591 GST_START_TEST (test_aux_sender)
592 {
593   GstElement *rtpbin;
594   GstPad *rtp_sink1, *rtp_src, *rtcp_src;
595   gulong id;
596
597   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
598
599   id = g_signal_connect (rtpbin, "request-aux-sender",
600       (GCallback) aux_sender_cb, NULL);
601
602   rtp_sink1 = gst_element_get_request_pad (rtpbin, "send_rtp_sink_2");
603   fail_unless (rtp_sink1 != NULL);
604   fail_unless_equals_string (GST_PAD_NAME (rtp_sink1), "send_rtp_sink_2");
605   ASSERT_OBJECT_REFCOUNT (rtp_sink1, "rtp_sink1", 2);
606
607   g_signal_handler_disconnect (rtpbin, id);
608
609   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_2");
610   fail_unless (rtp_src != NULL);
611   gst_object_unref (rtp_src);
612
613   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_1");
614   fail_unless (rtp_src != NULL);
615   gst_object_unref (rtp_src);
616
617   rtcp_src = gst_element_get_request_pad (rtpbin, "send_rtcp_src_1");
618   fail_unless (rtcp_src != NULL);
619   gst_element_release_request_pad (rtpbin, rtcp_src);
620   gst_object_unref (rtcp_src);
621
622   rtp_src = gst_element_get_static_pad (rtpbin, "send_rtp_src_3");
623   fail_unless (rtp_src != NULL);
624   gst_object_unref (rtp_src);
625
626   /* remove the session */
627   gst_element_release_request_pad (rtpbin, rtp_sink1);
628   gst_object_unref (rtp_sink1);
629
630   gst_object_unref (rtpbin);
631 }
632
633 GST_END_TEST;
634
635 static GstElement *
636 aux_receiver_cb (GstElement * rtpbin, guint sessid, gpointer user_data)
637 {
638   GstElement *bin;
639   GstPad *srcpad, *sinkpad;
640
641   bin = gst_bin_new (NULL);
642
643   GST_DEBUG ("making AUX receiver");
644   srcpad = gst_ghost_pad_new_no_target ("src_2", GST_PAD_SRC);
645   gst_element_add_pad (bin, srcpad);
646
647   sinkpad = gst_ghost_pad_new_no_target ("sink_2", GST_PAD_SINK);
648   gst_element_add_pad (bin, sinkpad);
649   sinkpad = gst_ghost_pad_new_no_target ("sink_1", GST_PAD_SINK);
650   gst_element_add_pad (bin, sinkpad);
651   sinkpad = gst_ghost_pad_new_no_target ("sink_3", GST_PAD_SINK);
652   gst_element_add_pad (bin, sinkpad);
653
654   return bin;
655 }
656
657 GST_START_TEST (test_aux_receiver)
658 {
659   GstElement *rtpbin;
660   GstPad *rtp_sink1, *rtp_sink2, *rtcp_sink;
661   gulong id;
662
663   rtpbin = gst_element_factory_make ("rtpbin", "rtpbin");
664
665   id = g_signal_connect (rtpbin, "request-aux-receiver",
666       (GCallback) aux_receiver_cb, NULL);
667
668   rtp_sink1 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_2");
669   fail_unless (rtp_sink1 != NULL);
670
671   rtp_sink2 = gst_element_get_request_pad (rtpbin, "recv_rtp_sink_1");
672   fail_unless (rtp_sink2 != NULL);
673
674   g_signal_handler_disconnect (rtpbin, id);
675
676   rtcp_sink = gst_element_get_request_pad (rtpbin, "recv_rtcp_sink_1");
677   fail_unless (rtcp_sink != NULL);
678   gst_element_release_request_pad (rtpbin, rtcp_sink);
679   gst_object_unref (rtcp_sink);
680
681   /* remove the session */
682   gst_element_release_request_pad (rtpbin, rtp_sink1);
683   gst_object_unref (rtp_sink1);
684   gst_element_release_request_pad (rtpbin, rtp_sink2);
685   gst_object_unref (rtp_sink2);
686
687   gst_object_unref (rtpbin);
688 }
689
690 GST_END_TEST;
691
692 static Suite *
693 rtpbin_suite (void)
694 {
695   Suite *s = suite_create ("rtpbin");
696   TCase *tc_chain = tcase_create ("general");
697
698   suite_add_tcase (s, tc_chain);
699   tcase_add_test (tc_chain, test_pads);
700   tcase_add_test (tc_chain, test_cleanup_send);
701   tcase_add_test (tc_chain, test_cleanup_recv);
702   tcase_add_test (tc_chain, test_cleanup_recv2);
703   tcase_add_test (tc_chain, test_request_pad_by_template_name);
704   tcase_add_test (tc_chain, test_encoder);
705   tcase_add_test (tc_chain, test_decoder);
706   tcase_add_test (tc_chain, test_aux_sender);
707   tcase_add_test (tc_chain, test_aux_receiver);
708
709   return s;
710 }
711
712 GST_CHECK_MAIN (rtpbin);