And correct even more valid sparse warnings.
[platform/upstream/gstreamer.git] / tests / check / gst / gstghostpad.c
1 /* GStreamer
2  * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3  *
4  * gstghostpad.c: Unit test for GstGhostPad
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <gst/check/gstcheck.h>
23
24 /* test if removing a bin also cleans up the ghostpads
25  */
26 GST_START_TEST (test_remove1)
27 {
28   GstElement *b1, *b2, *src, *sink;
29   GstPad *srcpad, *sinkpad;
30   GstPadLinkReturn ret;
31
32   b1 = gst_element_factory_make ("pipeline", NULL);
33   b2 = gst_element_factory_make ("bin", NULL);
34   src = gst_element_factory_make ("fakesrc", NULL);
35   sink = gst_element_factory_make ("fakesink", NULL);
36   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
37   ASSERT_OBJECT_REFCOUNT (b2, "bin", 1);
38
39   fail_unless (gst_bin_add (GST_BIN (b2), sink));
40   fail_unless (gst_bin_add (GST_BIN (b1), src));
41   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
42   ASSERT_OBJECT_REFCOUNT (b2, "bin", 1);
43   fail_unless (gst_bin_add (GST_BIN (b1), b2));
44   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
45   ASSERT_OBJECT_REFCOUNT (b2, "bin", 1);
46
47   sinkpad = gst_element_get_pad (sink, "sink");
48   gst_element_add_pad (b2, gst_ghost_pad_new ("sink", sinkpad));
49   gst_object_unref (sinkpad);
50
51   srcpad = gst_element_get_pad (src, "src");
52   /* get the ghostpad */
53   sinkpad = gst_element_get_pad (b2, "sink");
54
55   ret = gst_pad_link (srcpad, sinkpad);
56   fail_unless (ret == GST_PAD_LINK_OK);
57   gst_object_unref (srcpad);
58   gst_object_unref (sinkpad);
59
60   /* now remove the bin with the ghostpad, b2 is disposed now. */
61   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
62   ASSERT_OBJECT_REFCOUNT (b2, "bin", 1);
63   gst_bin_remove (GST_BIN (b1), b2);
64
65   srcpad = gst_element_get_pad (src, "src");
66   /* pad cannot be linked now */
67   fail_if (gst_pad_is_linked (srcpad));
68   gst_object_unref (srcpad);
69
70   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
71   gst_object_unref (b1);
72 }
73
74 GST_END_TEST;
75
76 /* test if removing a bin also cleans up the ghostpads
77  */
78 GST_START_TEST (test_remove2)
79 {
80   GstElement *b1, *b2, *src, *sink;
81   GstPad *srcpad, *sinkpad;
82   GstPadLinkReturn ret;
83
84   b1 = gst_element_factory_make ("pipeline", NULL);
85   b2 = gst_element_factory_make ("bin", NULL);
86   src = gst_element_factory_make ("fakesrc", NULL);
87   sink = gst_element_factory_make ("fakesink", NULL);
88   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
89
90   fail_unless (gst_bin_add (GST_BIN (b2), sink));
91   fail_unless (gst_bin_add (GST_BIN (b1), src));
92   fail_unless (gst_bin_add (GST_BIN (b1), b2));
93   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
94
95   sinkpad = gst_element_get_pad (sink, "sink");
96   gst_element_add_pad (b2, gst_ghost_pad_new ("sink", sinkpad));
97   gst_object_unref (sinkpad);
98
99   srcpad = gst_element_get_pad (src, "src");
100   ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 2); /* since we got one */
101   /* get the ghostpad */
102   sinkpad = gst_element_get_pad (b2, "sink");
103   ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 2);       /* since we got one */
104
105   GST_DEBUG ("linking srcpad and sinkpad");
106   ret = gst_pad_link (srcpad, sinkpad);
107   GST_DEBUG ("linked srcpad and sinkpad");
108   fail_unless (ret == GST_PAD_LINK_OK);
109   /* the linking causes a proxypad to be created for srcpad,
110    * to which sinkpad gets linked.  This proxypad has a ref to srcpad */
111   ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 3);
112   ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 2);
113   gst_object_unref (srcpad);
114   gst_object_unref (sinkpad);
115
116   /* now remove the sink from the bin */
117   gst_bin_remove (GST_BIN (b2), sink);
118
119   srcpad = gst_element_get_pad (src, "src");
120   /* pad is still linked to ghostpad */
121   fail_if (!gst_pad_is_linked (srcpad));
122   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
123   ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 3);
124   gst_object_unref (srcpad);
125   ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 1);
126
127   /* cleanup */
128   /* now unlink the pads */
129   gst_pad_unlink (srcpad, sinkpad);
130   ASSERT_OBJECT_REFCOUNT (srcpad, "srcpad", 1); /* proxy has dropped ref */
131   ASSERT_OBJECT_REFCOUNT (sinkpad, "sinkpad", 1);
132
133   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
134   ASSERT_OBJECT_REFCOUNT (b2, "bin", 1);
135   /* remove b2 from b1 */
136   gst_bin_remove (GST_BIN (b1), b2);
137
138   /* flush the message, dropping the b1 refcount to 1 */
139   gst_element_set_state (b1, GST_STATE_READY);
140   gst_element_set_state (b1, GST_STATE_NULL);
141   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
142   gst_object_unref (b1);
143 }
144
145 GST_END_TEST;
146
147 /* test if a ghost pad without a target can be linked and
148  * unlinked. An untargeted ghostpad has a default ANY caps unless there 
149  * is a padtemplate that says something else.
150  */
151 GST_START_TEST (test_ghost_pads_notarget)
152 {
153   GstElement *b1, *b2, *sink;
154   GstPad *srcpad, *sinkpad, *peer;
155   GstPadLinkReturn ret;
156   gboolean bret;
157   GstBus *bus;
158   GstCaps *caps;
159
160   b1 = gst_element_factory_make ("pipeline", NULL);
161
162   /* make sure all messages are discarded */
163   bus = gst_pipeline_get_bus (GST_PIPELINE (b1));
164   gst_bus_set_flushing (bus, TRUE);
165   gst_object_unref (bus);
166
167   b2 = gst_element_factory_make ("bin", NULL);
168   sink = gst_element_factory_make ("fakesink", NULL);
169
170   fail_unless (gst_bin_add (GST_BIN (b1), sink));
171   fail_unless (gst_bin_add (GST_BIN (b1), b2));
172
173   srcpad = gst_ghost_pad_new_no_target ("src", GST_PAD_SRC);
174   fail_unless (srcpad != NULL);
175   sinkpad = gst_element_get_pad (sink, "sink");
176   fail_unless (sinkpad != NULL);
177
178   ret = gst_pad_link (srcpad, sinkpad);
179   fail_unless (ret == GST_PAD_LINK_OK);
180
181   /* check if the peers are ok */
182   peer = gst_pad_get_peer (srcpad);
183   fail_unless (peer == sinkpad);
184   gst_object_unref (peer);
185
186   peer = gst_pad_get_peer (sinkpad);
187   fail_unless (peer == srcpad);
188   gst_object_unref (peer);
189
190   /* check caps, untargetted pad should return ANY or the padtemplate caps 
191    * when it was created from a template */
192   caps = gst_pad_get_caps (srcpad);
193   fail_unless (gst_caps_is_any (caps));
194   gst_caps_unref (caps);
195
196   /* unlink */
197   bret = gst_pad_unlink (srcpad, sinkpad);
198   fail_unless (bret == TRUE);
199
200   /* cleanup */
201   gst_object_unref (srcpad);
202   gst_object_unref (sinkpad);
203   gst_object_unref (b1);
204 }
205
206 GST_END_TEST;
207
208 /* test if linking fails over different bins using a pipeline
209  * like this:
210  *
211  * fakesrc num_buffers=10 ! ( fakesink )
212  *
213  */
214 GST_START_TEST (test_link)
215 {
216   GstElement *b1, *b2, *src, *sink;
217   GstPad *srcpad, *sinkpad, *gpad;
218   GstPadLinkReturn ret;
219
220   b1 = gst_element_factory_make ("pipeline", NULL);
221   b2 = gst_element_factory_make ("bin", NULL);
222   src = gst_element_factory_make ("fakesrc", NULL);
223   sink = gst_element_factory_make ("fakesink", NULL);
224
225   fail_unless (gst_bin_add (GST_BIN (b2), sink));
226   fail_unless (gst_bin_add (GST_BIN (b1), src));
227   fail_unless (gst_bin_add (GST_BIN (b1), b2));
228
229   srcpad = gst_element_get_pad (src, "src");
230   fail_unless (srcpad != NULL);
231   sinkpad = gst_element_get_pad (sink, "sink");
232   fail_unless (sinkpad != NULL);
233
234   /* linking in different hierarchies should fail */
235   ret = gst_pad_link (srcpad, sinkpad);
236   fail_unless (ret == GST_PAD_LINK_WRONG_HIERARCHY);
237
238   /* now setup a ghostpad */
239   gpad = gst_ghost_pad_new ("sink", sinkpad);
240   gst_object_unref (sinkpad);
241   /* need to ref as _add_pad takes ownership */
242   gst_object_ref (gpad);
243   gst_element_add_pad (b2, gpad);
244
245   /* our new sinkpad */
246   sinkpad = gpad;
247
248   /* and linking should work now */
249   ret = gst_pad_link (srcpad, sinkpad);
250   fail_unless (ret == GST_PAD_LINK_OK);
251
252   /* flush the message, dropping the b1 refcount to 1 */
253   gst_element_set_state (b1, GST_STATE_READY);
254   gst_element_set_state (b1, GST_STATE_NULL);
255   ASSERT_OBJECT_REFCOUNT (b1, "pipeline", 1);
256
257   gst_object_unref (srcpad);
258   gst_object_unref (sinkpad);
259   gst_object_unref (b1);
260 }
261
262 GST_END_TEST;
263
264 /* test if ghostpads are created automagically when using
265  * gst_element_link_pads.
266  *
267  * fakesrc num_buffers=10 ! ( identity ) ! fakesink
268  */
269 GST_START_TEST (test_ghost_pads)
270 {
271   GstElement *b1, *b2, *src, *i1, *sink;
272   GstPad *gsink, *gsrc, *gisrc, *gisink, *isink, *isrc, *fsrc, *fsink;
273   GstStateChangeReturn ret;
274
275   b1 = gst_element_factory_make ("pipeline", NULL);
276   b2 = gst_element_factory_make ("bin", NULL);
277   src = gst_element_factory_make ("fakesrc", NULL);
278   g_object_set (src, "num-buffers", (int) 10, NULL);
279   i1 = gst_element_factory_make ("identity", NULL);
280   sink = gst_element_factory_make ("fakesink", NULL);
281
282   fail_unless (gst_bin_add (GST_BIN (b2), i1));
283   fail_unless (gst_bin_add (GST_BIN (b1), src));
284   fail_unless (gst_bin_add (GST_BIN (b1), b2));
285   fail_unless (gst_bin_add (GST_BIN (b1), sink));
286   fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
287   fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
288   GST_OBJECT_LOCK (b2);
289   fail_unless (b2->numsinkpads == 1);
290   fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
291   fail_unless (b2->numsrcpads == 1);
292   fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
293   GST_OBJECT_UNLOCK (b2);
294
295   fsrc = gst_element_get_pad (src, "src");
296   fail_unless (fsrc != NULL);
297   gsink = GST_PAD (gst_object_ref (b2->sinkpads->data));
298   fail_unless (gsink != NULL);
299   gsrc = GST_PAD (gst_object_ref (b2->srcpads->data));
300   fail_unless (gsrc != NULL);
301   fsink = gst_element_get_pad (sink, "sink");
302   fail_unless (fsink != NULL);
303
304   isink = gst_element_get_pad (i1, "sink");
305   fail_unless (isink != NULL);
306   isrc = gst_element_get_pad (i1, "src");
307   fail_unless (isrc != NULL);
308   gisrc = gst_pad_get_peer (isink);
309   fail_unless (gisrc != NULL);
310   gisink = gst_pad_get_peer (isrc);
311   fail_unless (gisink != NULL);
312
313   /* all objects above have one refcount owned by us as well */
314
315   ASSERT_OBJECT_REFCOUNT (fsrc, "fsrc", 3);     /* parent and gisrc */
316   ASSERT_OBJECT_REFCOUNT (gsink, "gsink", 2);   /* parent */
317   ASSERT_OBJECT_REFCOUNT (gsrc, "gsrc", 2);     /* parent */
318   ASSERT_OBJECT_REFCOUNT (fsink, "fsink", 3);   /* parent and gisink */
319
320   ASSERT_OBJECT_REFCOUNT (gisrc, "gisrc", 2);   /* parent */
321   ASSERT_OBJECT_REFCOUNT (isink, "isink", 3);   /* parent and gsink */
322   ASSERT_OBJECT_REFCOUNT (gisink, "gisink", 2); /* parent */
323   ASSERT_OBJECT_REFCOUNT (isrc, "isrc", 3);     /* parent and gsrc */
324
325   ret = gst_element_set_state (b1, GST_STATE_PLAYING);
326   ret = gst_element_get_state (b1, NULL, NULL, GST_CLOCK_TIME_NONE);
327   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
328
329   ret = gst_element_set_state (b1, GST_STATE_NULL);
330   ret = gst_element_get_state (b1, NULL, NULL, GST_CLOCK_TIME_NONE);
331   fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
332
333   gst_object_unref (b1);
334   /* unreffing the bin will unref all elements, which will unlink and unparent
335    * all pads */
336
337   /* wait for thread to settle down */
338   while (GST_OBJECT_REFCOUNT_VALUE (fsrc) > 2)
339     THREAD_SWITCH ();
340
341   ASSERT_OBJECT_REFCOUNT (fsrc, "fsrc", 1);
342   ASSERT_OBJECT_REFCOUNT (gsink, "gsink", 1);
343   ASSERT_OBJECT_REFCOUNT (gsrc, "gsink", 1);
344   ASSERT_OBJECT_REFCOUNT (fsink, "fsink", 1);
345
346   ASSERT_OBJECT_REFCOUNT (gisrc, "gisrc", 2);   /* gsink */
347   ASSERT_OBJECT_REFCOUNT (isink, "isink", 2);   /* gsink */
348   ASSERT_OBJECT_REFCOUNT (gisink, "gisink", 2); /* gsrc */
349   ASSERT_OBJECT_REFCOUNT (isrc, "isrc", 2);     /* gsrc */
350
351   gst_object_unref (gsink);
352   ASSERT_OBJECT_REFCOUNT (isink, "isink", 1);
353   ASSERT_OBJECT_REFCOUNT (gisrc, "gisrc", 1);
354   ASSERT_OBJECT_REFCOUNT (fsrc, "fsrc", 1);
355   gst_object_unref (gisrc);
356   ASSERT_OBJECT_REFCOUNT (fsrc, "fsrc", 1);
357
358   gst_object_unref (gsrc);
359   ASSERT_OBJECT_REFCOUNT (isrc, "isrc", 1);
360   ASSERT_OBJECT_REFCOUNT (gisink, "gisink", 1);
361   ASSERT_OBJECT_REFCOUNT (fsink, "fsink", 1);
362   gst_object_unref (gisink);
363   ASSERT_OBJECT_REFCOUNT (fsink, "fsink", 1);
364
365   gst_object_unref (fsrc);
366   gst_object_unref (isrc);
367   gst_object_unref (isink);
368   gst_object_unref (fsink);
369 }
370
371 GST_END_TEST;
372
373 GST_START_TEST (test_ghost_pads_bin)
374 {
375   GstBin *pipeline;
376   GstBin *srcbin;
377   GstBin *sinkbin;
378   GstElement *src;
379   GstElement *sink;
380   GstPad *srcpad, *srcghost, *target;
381   GstPad *sinkpad, *sinkghost;
382
383   pipeline = GST_BIN (gst_pipeline_new ("pipe"));
384   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
385
386   srcbin = GST_BIN (gst_bin_new ("srcbin"));
387   gst_bin_add (pipeline, GST_ELEMENT (srcbin));
388   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
389
390   sinkbin = GST_BIN (gst_bin_new ("sinkbin"));
391   gst_bin_add (pipeline, GST_ELEMENT (sinkbin));
392   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
393
394   src = gst_element_factory_make ("fakesrc", "src");
395   gst_bin_add (srcbin, src);
396   srcpad = gst_element_get_pad (src, "src");
397   srcghost = gst_ghost_pad_new ("src", srcpad);
398   gst_object_unref (srcpad);
399   gst_element_add_pad (GST_ELEMENT (srcbin), srcghost);
400
401   sink = gst_element_factory_make ("fakesink", "sink");
402   gst_bin_add (sinkbin, sink);
403   sinkpad = gst_element_get_pad (sink, "sink");
404   sinkghost = gst_ghost_pad_new ("sink", sinkpad);
405   gst_object_unref (sinkpad);
406   gst_element_add_pad (GST_ELEMENT (sinkbin), sinkghost);
407
408   gst_element_link (GST_ELEMENT (srcbin), GST_ELEMENT (sinkbin));
409
410   fail_unless (GST_PAD_PEER (srcghost) != NULL);
411   fail_unless (GST_PAD_PEER (sinkghost) != NULL);
412   target = gst_ghost_pad_get_target (GST_GHOST_PAD (srcghost));
413   fail_unless (GST_PAD_PEER (target) != NULL);
414   gst_object_unref (target);
415   target = gst_ghost_pad_get_target (GST_GHOST_PAD (sinkghost));
416   fail_unless (GST_PAD_PEER (target) != NULL);
417   gst_object_unref (target);
418
419   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
420
421   gst_object_unref (pipeline);
422 }
423
424 GST_END_TEST;
425
426 typedef struct
427 {
428   GMutex *mutex;
429   GCond *cond;
430 } BlockData;
431
432 static void
433 block_callback (GstPad * pad, gboolean blocked, gpointer user_data)
434 {
435   BlockData *block_data = (BlockData *) user_data;
436
437   g_mutex_lock (block_data->mutex);
438   GST_DEBUG ("blocked\n");
439   g_cond_signal (block_data->cond);
440   g_mutex_unlock (block_data->mutex);
441 }
442
443 GST_START_TEST (test_ghost_pads_block)
444 {
445   GstBin *pipeline;
446   GstBin *srcbin;
447   GstElement *src;
448   GstPad *srcpad;
449   GstPad *srcghost;
450   BlockData block_data;
451
452   pipeline = GST_BIN (gst_pipeline_new ("pipeline"));
453
454   srcbin = GST_BIN (gst_bin_new ("srcbin"));
455   gst_bin_add (pipeline, GST_ELEMENT (srcbin));
456
457   src = gst_element_factory_make ("fakesrc", "src");
458   gst_bin_add (srcbin, src);
459   srcpad = gst_element_get_pad (src, "src");
460   srcghost = gst_ghost_pad_new ("src", srcpad);
461   gst_element_add_pad (GST_ELEMENT (srcbin), srcghost);
462   gst_object_unref (srcpad);
463
464   block_data.mutex = g_mutex_new ();
465   block_data.cond = g_cond_new ();
466
467   g_mutex_lock (block_data.mutex);
468   gst_pad_set_blocked_async (srcghost, TRUE, block_callback, &block_data);
469   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
470   /* and wait now */
471   g_cond_wait (block_data.cond, block_data.mutex);
472   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
473   g_mutex_unlock (block_data.mutex);
474
475   g_mutex_free (block_data.mutex);
476   g_cond_free (block_data.cond);
477
478   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
479   gst_object_unref (pipeline);
480 }
481
482 GST_END_TEST;
483
484 GST_START_TEST (test_ghost_pads_probes)
485 {
486   GstBin *pipeline;
487   GstBin *srcbin;
488   GstElement *src;
489   GstPad *srcpad;
490   GstPad *srcghost;
491   BlockData block_data;
492
493   pipeline = GST_BIN (gst_pipeline_new ("pipeline"));
494
495   srcbin = GST_BIN (gst_bin_new ("srcbin"));
496   gst_bin_add (pipeline, GST_ELEMENT (srcbin));
497
498   src = gst_element_factory_make ("fakesrc", "src");
499   gst_bin_add (srcbin, src);
500   srcpad = gst_element_get_pad (src, "src");
501   srcghost = gst_ghost_pad_new ("src", srcpad);
502   gst_element_add_pad (GST_ELEMENT (srcbin), srcghost);
503   gst_object_unref (srcpad);
504
505   block_data.mutex = g_mutex_new ();
506   block_data.cond = g_cond_new ();
507
508   g_mutex_lock (block_data.mutex);
509   gst_pad_set_blocked_async (srcghost, TRUE, block_callback, &block_data);
510   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
511   /* and wait now */
512   g_cond_wait (block_data.cond, block_data.mutex);
513   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
514   g_mutex_unlock (block_data.mutex);
515
516   g_mutex_free (block_data.mutex);
517   g_cond_free (block_data.cond);
518
519   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
520   gst_object_unref (pipeline);
521 }
522
523 GST_END_TEST;
524
525 GST_START_TEST (test_ghost_pads_new_from_template)
526 {
527   GstPad *sinkpad, *ghostpad;
528   GstPadTemplate *padtempl, *ghosttempl;
529   GstCaps *padcaps, *ghostcaps, *newcaps;
530
531   padcaps = gst_caps_from_string ("some/caps");
532   fail_unless (padcaps != NULL);
533   ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
534   fail_unless (ghostcaps != NULL);
535
536   padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
537       GST_PAD_ALWAYS, padcaps);
538   fail_unless (padtempl != NULL);
539   ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
540       GST_PAD_ALWAYS, ghostcaps);
541
542   sinkpad = gst_pad_new_from_template (padtempl, "sinkpad");
543   fail_unless (sinkpad != NULL);
544
545   ghostpad = gst_ghost_pad_new_from_template ("ghostpad", sinkpad, ghosttempl);
546   fail_unless (ghostpad != NULL);
547
548   /* check template is properly set */
549   fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
550
551   /* check ghostpad caps are from the sinkpad */
552   newcaps = gst_pad_get_caps (ghostpad);
553   fail_unless (newcaps != NULL);
554   fail_unless (gst_caps_is_equal (newcaps, padcaps));
555   gst_caps_unref (newcaps);
556   gst_caps_unref (padcaps);
557 }
558
559 GST_END_TEST;
560
561 GST_START_TEST (test_ghost_pads_new_no_target_from_template)
562 {
563   GstPad *sinkpad, *ghostpad;
564   GstPadTemplate *padtempl, *ghosttempl;
565   GstCaps *padcaps, *ghostcaps, *newcaps;
566
567   padcaps = gst_caps_from_string ("some/caps");
568   fail_unless (padcaps != NULL);
569   ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
570   fail_unless (ghostcaps != NULL);
571
572   padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
573       GST_PAD_ALWAYS, padcaps);
574   fail_unless (padtempl != NULL);
575   ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
576       GST_PAD_ALWAYS, ghostcaps);
577
578   sinkpad = gst_pad_new_from_template (padtempl, "sinkpad");
579   fail_unless (sinkpad != NULL);
580
581   ghostpad = gst_ghost_pad_new_no_target_from_template ("ghostpad", ghosttempl);
582   fail_unless (ghostpad != NULL);
583
584   /* check template is properly set */
585   fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
586
587   /* check ghostpad caps are from the ghostpad template */
588   newcaps = gst_pad_get_caps (ghostpad);
589   fail_unless (newcaps != NULL);
590   fail_unless (gst_caps_is_equal (newcaps, ghostcaps));
591   gst_caps_unref (newcaps);
592
593   fail_unless (gst_ghost_pad_set_target ((GstGhostPad *) ghostpad, sinkpad));
594
595   /* check ghostpad caps are now from the target pad */
596   newcaps = gst_pad_get_caps (ghostpad);
597   fail_unless (newcaps != NULL);
598   fail_unless (gst_caps_is_equal (newcaps, padcaps));
599   gst_caps_unref (newcaps);
600
601 }
602
603 GST_END_TEST;
604
605 static Suite *
606 gst_ghost_pad_suite (void)
607 {
608   Suite *s = suite_create ("GstGhostPad");
609   TCase *tc_chain = tcase_create ("ghost pad tests");
610
611   suite_add_tcase (s, tc_chain);
612   tcase_add_test (tc_chain, test_remove1);
613   tcase_add_test (tc_chain, test_remove2);
614   tcase_add_test (tc_chain, test_link);
615   tcase_add_test (tc_chain, test_ghost_pads);
616   tcase_add_test (tc_chain, test_ghost_pads_bin);
617   tcase_add_test (tc_chain, test_ghost_pads_notarget);
618   tcase_add_test (tc_chain, test_ghost_pads_block);
619   tcase_add_test (tc_chain, test_ghost_pads_probes);
620   tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
621   tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
622
623   return s;
624 }
625
626 GST_CHECK_MAIN (gst_ghost_pad);