2 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
4 * gstghostpad.c: Unit test for GstGhostPad
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.
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.
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.
22 #include <gst/check/gstcheck.h>
25 assert_gstrefcount (gpointer p, gint i)
27 if (GST_OBJECT_REFCOUNT_VALUE (p) != i)
28 g_critical ("Expected refcount %d for %s, got %d", i, GST_OBJECT_NAME (p),
29 GST_OBJECT_REFCOUNT_VALUE (p));
32 /* test if removing a bin also cleans up the ghostpads
34 GST_START_TEST (test_remove1)
36 GstElement *b1, *b2, *src, *sink;
37 GstPad *srcpad, *sinkpad;
40 b1 = gst_element_factory_make ("pipeline", NULL);
41 b2 = gst_element_factory_make ("bin", NULL);
42 src = gst_element_factory_make ("fakesrc", NULL);
43 sink = gst_element_factory_make ("fakesink", NULL);
45 fail_unless (gst_bin_add (GST_BIN (b2), sink));
46 fail_unless (gst_bin_add (GST_BIN (b1), src));
47 fail_unless (gst_bin_add (GST_BIN (b1), b2));
49 sinkpad = gst_element_get_pad (sink, "sink");
50 gst_element_add_pad (b2, gst_ghost_pad_new ("sink", sinkpad));
51 gst_object_unref (sinkpad);
53 srcpad = gst_element_get_pad (src, "src");
54 /* get the ghostpad */
55 sinkpad = gst_element_get_pad (b2, "sink");
57 ret = gst_pad_link (srcpad, sinkpad);
58 fail_unless (ret == GST_PAD_LINK_OK);
59 gst_object_unref (srcpad);
60 gst_object_unref (sinkpad);
62 /* now remove the bin with the ghostpad, b2 is disposed
64 gst_bin_remove (GST_BIN (b1), b2);
66 srcpad = gst_element_get_pad (src, "src");
67 /* pad cannot be linked now */
68 fail_if (gst_pad_is_linked (srcpad));
73 /* test if removing a bin also cleans up the ghostpads
75 GST_START_TEST (test_remove2)
77 GstElement *b1, *b2, *src, *sink;
78 GstPad *srcpad, *sinkpad;
81 b1 = gst_element_factory_make ("pipeline", NULL);
82 b2 = gst_element_factory_make ("bin", NULL);
83 src = gst_element_factory_make ("fakesrc", NULL);
84 sink = gst_element_factory_make ("fakesink", NULL);
86 fail_unless (gst_bin_add (GST_BIN (b2), sink));
87 fail_unless (gst_bin_add (GST_BIN (b1), src));
88 fail_unless (gst_bin_add (GST_BIN (b1), b2));
90 sinkpad = gst_element_get_pad (sink, "sink");
91 gst_element_add_pad (b2, gst_ghost_pad_new ("sink", sinkpad));
92 gst_object_unref (sinkpad);
94 srcpad = gst_element_get_pad (src, "src");
95 /* get the ghostpad */
96 sinkpad = gst_element_get_pad (b2, "sink");
98 ret = gst_pad_link (srcpad, sinkpad);
99 fail_unless (ret == GST_PAD_LINK_OK);
100 gst_object_unref (srcpad);
101 gst_object_unref (sinkpad);
103 /* now remove the sink from the bin */
104 gst_bin_remove (GST_BIN (b2), sink);
106 srcpad = gst_element_get_pad (src, "src");
107 /* pad is still linked to ghostpad */
108 fail_if (!gst_pad_is_linked (srcpad));
114 /* test if a ghost pad without a target can be linked
117 GST_START_TEST (test_ghost_pad_notarget)
119 GstElement *b1, *b2, *sink;
120 GstPad *srcpad, *sinkpad;
121 GstPadLinkReturn ret;
123 b1 = gst_element_factory_make ("pipeline", NULL);
124 b2 = gst_element_factory_make ("bin", NULL);
125 sink = gst_element_factory_make ("fakesink", NULL);
127 fail_unless (gst_bin_add (GST_BIN (b1), sink));
128 fail_unless (gst_bin_add (GST_BIN (b1), b2));
130 srcpad = gst_ghost_pad_new_notarget ("src", GST_PAD_SRC);
131 fail_unless (srcpad != NULL);
132 sinkpad = gst_element_get_pad (sink, "sink");
133 fail_unless (sinkpad != NULL);
135 ret = gst_pad_link (srcpad, sinkpad);
136 fail_unless (ret == GST_PAD_LINK_OK);
142 /* test if linking fails over different bins using a pipeline
145 * fakesrc num_buffers=10 ! ( fakesink )
148 GST_START_TEST (test_link)
150 GstElement *b1, *b2, *src, *sink;
151 GstPad *srcpad, *sinkpad, *gpad;
152 GstPadLinkReturn ret;
154 b1 = gst_element_factory_make ("pipeline", NULL);
155 b2 = gst_element_factory_make ("bin", NULL);
156 src = gst_element_factory_make ("fakesrc", NULL);
157 sink = gst_element_factory_make ("fakesink", NULL);
159 fail_unless (gst_bin_add (GST_BIN (b2), sink));
160 fail_unless (gst_bin_add (GST_BIN (b1), src));
161 fail_unless (gst_bin_add (GST_BIN (b1), b2));
163 srcpad = gst_element_get_pad (src, "src");
164 fail_unless (srcpad != NULL);
165 sinkpad = gst_element_get_pad (sink, "sink");
166 fail_unless (sinkpad != NULL);
168 /* linking in different hierarchies should fail */
169 ret = gst_pad_link (srcpad, sinkpad);
170 fail_unless (ret == GST_PAD_LINK_WRONG_HIERARCHY);
172 /* now setup a ghostpad */
173 gpad = gst_ghost_pad_new ("sink", sinkpad);
174 gst_object_unref (sinkpad);
175 /* need to ref as _add_pad takes ownership */
176 gst_object_ref (gpad);
177 gst_element_add_pad (b2, gpad);
179 /* our new sinkpad */
182 /* and linking should work now */
183 ret = gst_pad_link (srcpad, sinkpad);
184 fail_unless (ret == GST_PAD_LINK_OK);
189 /* test if ghostpads are created automagically when using
190 * gst_element_link_pads.
192 * fakesrc num_buffers=10 ! ( identity ) ! fakesink
194 GST_START_TEST (test_ghost_pads)
196 GstElement *b1, *b2, *src, *i1, *sink;
197 GstPad *gsink, *gsrc, *gisrc, *gisink, *isink, *isrc, *fsrc, *fsink;
199 b1 = gst_element_factory_make ("pipeline", NULL);
200 b2 = gst_element_factory_make ("bin", NULL);
201 src = gst_element_factory_make ("fakesrc", NULL);
202 g_object_set (src, "num-buffers", (int) 10, NULL);
203 i1 = gst_element_factory_make ("identity", NULL);
204 sink = gst_element_factory_make ("fakesink", NULL);
206 fail_unless (gst_bin_add (GST_BIN (b2), i1));
207 fail_unless (gst_bin_add (GST_BIN (b1), src));
208 fail_unless (gst_bin_add (GST_BIN (b1), b2));
209 fail_unless (gst_bin_add (GST_BIN (b1), sink));
210 fail_unless (gst_element_link_pads (src, NULL, i1, NULL));
211 fail_unless (gst_element_link_pads (i1, NULL, sink, NULL));
213 fail_unless (b2->numsinkpads == 1);
214 fail_unless (GST_IS_GHOST_PAD (b2->sinkpads->data));
215 fail_unless (b2->numsrcpads == 1);
216 fail_unless (GST_IS_GHOST_PAD (b2->srcpads->data));
219 fsrc = gst_element_get_pad (src, "src");
220 fail_unless (fsrc != NULL);
221 gsink = GST_PAD (gst_object_ref (b2->sinkpads->data));
222 fail_unless (gsink != NULL);
223 gsrc = GST_PAD (gst_object_ref (b2->srcpads->data));
224 fail_unless (gsrc != NULL);
225 fsink = gst_element_get_pad (sink, "sink");
226 fail_unless (fsink != NULL);
228 isink = gst_element_get_pad (i1, "sink");
229 fail_unless (isink != NULL);
230 isrc = gst_element_get_pad (i1, "src");
231 fail_unless (isrc != NULL);
232 gisrc = gst_pad_get_peer (isink);
233 fail_unless (gisrc != NULL);
234 gisink = gst_pad_get_peer (isrc);
235 fail_unless (gisink != NULL);
237 /* all objects above have one refcount owned by us as well */
239 assert_gstrefcount (fsrc, 3); /* parent and gisrc */
240 assert_gstrefcount (gsink, 2); /* parent */
241 assert_gstrefcount (gsrc, 2); /* parent */
242 assert_gstrefcount (fsink, 3); /* parent and gisink */
244 assert_gstrefcount (gisrc, 2); /* parent */
245 assert_gstrefcount (isink, 3); /* parent and gsink */
246 assert_gstrefcount (gisink, 2); /* parent */
247 assert_gstrefcount (isrc, 3); /* parent and gsrc */
249 fail_unless (gst_element_set_state (b1,
250 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
252 fail_unless (gst_element_set_state (b1,
253 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
255 gst_object_unref (b1);
256 /* unreffing the bin will unref all elements, which will unlink and unparent
259 assert_gstrefcount (fsrc, 2); /* gisrc */
260 assert_gstrefcount (gsink, 1);
261 assert_gstrefcount (gsrc, 1);
262 assert_gstrefcount (fsink, 2); /* gisink */
264 assert_gstrefcount (gisrc, 1); /* gsink */
265 assert_gstrefcount (isink, 2); /* gsink */
266 assert_gstrefcount (gisink, 1); /* gsrc */
267 assert_gstrefcount (isrc, 2); /* gsrc */
269 gst_object_unref (gsink);
270 assert_gstrefcount (isink, 1);
271 assert_gstrefcount (gisrc, 1);
272 assert_gstrefcount (fsrc, 2); /* gisrc */
273 gst_object_unref (gisrc);
274 assert_gstrefcount (fsrc, 1);
276 gst_object_unref (gsrc);
277 assert_gstrefcount (isrc, 1);
278 assert_gstrefcount (gisink, 1);
279 assert_gstrefcount (fsink, 2); /* gisrc */
280 gst_object_unref (gisink);
281 assert_gstrefcount (fsink, 1);
283 gst_object_unref (fsrc);
284 gst_object_unref (isrc);
285 gst_object_unref (isink);
286 gst_object_unref (fsink);
292 gst_ghost_pad_suite (void)
294 Suite *s = suite_create ("GstGhostPad");
295 TCase *tc_chain = tcase_create ("ghost pad tests");
297 suite_add_tcase (s, tc_chain);
298 tcase_add_test (tc_chain, test_remove1);
299 tcase_add_test (tc_chain, test_remove2);
300 tcase_add_test (tc_chain, test_link);
301 tcase_add_test (tc_chain, test_ghost_pads);
302 /* tcase_add_test (tc_chain, test_ghost_pad_notarget); */
308 main (int argc, char **argv)
312 Suite *s = gst_ghost_pad_suite ();
313 SRunner *sr = srunner_create (s);
315 gst_check_init (&argc, &argv);
317 srunner_run_all (sr, CK_NORMAL);
318 nf = srunner_ntests_failed (sr);