caps: improve _do_simplify
[platform/upstream/gstreamer.git] / tests / check / gst / gstelement.c
1 /* GStreamer
2  * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
3  *
4  * gstelement.c: Unit test for GstElement
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 GST_START_TEST (test_add_remove_pad)
25 {
26   GstElement *e;
27   GstPad *p;
28
29   /* getting an existing element class is cheating, but easier */
30   e = gst_element_factory_make ("fakesrc", "source");
31
32   /* create a new floating pad with refcount 1 */
33   p = gst_pad_new ("source", GST_PAD_SRC);
34   ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
35   /* ref it for ourselves */
36   gst_object_ref (p);
37   ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
38   /* adding it sinks the pad -> not floating, same refcount */
39   gst_element_add_pad (e, p);
40   ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
41
42   /* removing it reduces the refcount */
43   gst_element_remove_pad (e, p);
44   ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
45
46   /* clean up our own reference */
47   gst_object_unref (p);
48   gst_object_unref (e);
49 }
50
51 GST_END_TEST;
52
53 GST_START_TEST (test_add_pad_unref_element)
54 {
55   GstElement *e;
56   GstPad *p;
57
58   /* getting an existing element class is cheating, but easier */
59   e = gst_element_factory_make ("fakesrc", "source");
60
61   /* create a new floating pad with refcount 1 */
62   p = gst_pad_new ("source", GST_PAD_SRC);
63   ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
64   /* ref it for ourselves */
65   gst_object_ref (p);
66   ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
67   /* adding it sinks the pad -> not floating, same refcount */
68   gst_element_add_pad (e, p);
69   ASSERT_OBJECT_REFCOUNT (p, "pad", 2);
70
71   /* unreffing the element should clean it up */
72   gst_object_unref (GST_OBJECT (e));
73
74   ASSERT_OBJECT_REFCOUNT (p, "pad", 1);
75
76   /* clean up our own reference */
77   gst_object_unref (p);
78 }
79
80 GST_END_TEST;
81
82 GST_START_TEST (test_error_no_bus)
83 {
84   GstElement *e;
85   GstBus *bus;
86
87   e = gst_element_factory_make ("fakesrc", "source");
88
89   /* get the bus, should be NULL */
90   bus = gst_element_get_bus (e);
91   fail_if (bus != NULL);
92
93   /* I don't want errors shown */
94   gst_debug_set_default_threshold (GST_LEVEL_NONE);
95
96   GST_ELEMENT_ERROR (e, RESOURCE, OPEN_READ, ("I could not read"), ("debug"));
97
98   gst_object_unref (e);
99 }
100
101 GST_END_TEST;
102
103 /* link and run two elements without putting them in a pipeline */
104 GST_START_TEST (test_link)
105 {
106   GstElement *src, *sink;
107
108   src = gst_element_factory_make ("fakesrc", "source");
109   sink = gst_element_factory_make ("fakesink", "sink");
110
111   fail_unless (gst_element_link_pads (src, "src", sink, "sink"));
112
113   /* do sink to source state change */
114   gst_element_set_state (sink, GST_STATE_PAUSED);
115   gst_element_set_state (src, GST_STATE_PAUSED);
116
117   /* wait for preroll */
118   gst_element_get_state (sink, NULL, NULL, GST_CLOCK_TIME_NONE);
119
120   /* play some more */
121   gst_element_set_state (sink, GST_STATE_PLAYING);
122   gst_element_set_state (src, GST_STATE_PLAYING);
123
124   g_usleep (G_USEC_PER_SEC);
125
126   /* and stop */
127   gst_element_set_state (sink, GST_STATE_PAUSED);
128   gst_element_set_state (src, GST_STATE_PAUSED);
129
130   /* wait for preroll */
131   gst_element_get_state (sink, NULL, NULL, GST_CLOCK_TIME_NONE);
132
133   gst_element_set_state (sink, GST_STATE_NULL);
134   gst_element_set_state (src, GST_STATE_NULL);
135
136   gst_element_get_state (sink, NULL, NULL, GST_CLOCK_TIME_NONE);
137   g_usleep (G_USEC_PER_SEC / 2);
138
139   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
140   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
141   gst_element_unlink_pads (src, "src", sink, "sink");
142   ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
143   ASSERT_OBJECT_REFCOUNT (src, "src", 1);
144
145   gst_object_unref (src);
146   gst_object_unref (sink);
147 }
148
149 GST_END_TEST;
150
151 /* linking two elements without pads should fail */
152 GST_START_TEST (test_link_no_pads)
153 {
154   GstElement *src, *sink;
155
156   src = gst_bin_new ("src");
157   sink = gst_bin_new ("sink");
158
159   fail_if (gst_element_link (src, sink));
160
161   gst_object_unref (src);
162   gst_object_unref (sink);
163 }
164
165 GST_END_TEST;
166
167 typedef struct _GstTestElement
168 {
169   GstElement parent;
170
171 } GstTestElement;
172
173 typedef struct _GstTestElementClass
174 {
175   GstElementClass parent;
176
177 } GstTestElementClass;
178
179 static void
180 gst_test_element_class_init (GstTestElementClass * klass)
181 {
182   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
183   GstPadTemplate *templ;
184
185   gst_element_class_set_metadata (element_class, "Test element",
186       "Element", "Does nothing", "Foo Bar <foo@bar.com>");
187
188   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
189           (element_class)), 0);
190
191   fail_unless (gst_element_class_get_pad_template (element_class,
192           "test") == NULL);
193
194   gst_element_class_add_pad_template (element_class,
195       gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_ANY));
196
197   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
198           (element_class)), 1);
199
200   fail_unless ((templ =
201           gst_element_class_get_pad_template (element_class, "test")) != NULL);
202   fail_unless (gst_caps_is_any (templ->caps));
203
204   gst_element_class_add_pad_template (element_class,
205       gst_pad_template_new ("test2", GST_PAD_SRC, GST_PAD_ALWAYS,
206           GST_CAPS_ANY));
207
208   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
209           (element_class)), 2);
210
211   fail_unless ((templ =
212           gst_element_class_get_pad_template (element_class, "test2")) != NULL);
213   fail_unless (gst_caps_is_any (templ->caps));
214
215   /* Add "test" again, with NONE caps this time */
216   gst_element_class_add_pad_template (element_class,
217       gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS,
218           GST_CAPS_NONE));
219
220   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
221           (element_class)), 2);
222
223   fail_unless ((templ =
224           gst_element_class_get_pad_template (element_class, "test")) != NULL);
225   fail_unless (gst_caps_is_empty (templ->caps));
226 }
227
228 static GType
229 gst_test_element_get_type (void)
230 {
231   static GType gst_test_element_type = G_TYPE_NONE;
232
233   if (gst_test_element_type == G_TYPE_NONE) {
234     static const GTypeInfo gst_test_element_info = {
235       sizeof (GstTestElementClass),
236       NULL,                     /* base_init */
237       NULL,                     /* base_finalize */
238       (GClassInitFunc) gst_test_element_class_init,
239       NULL,
240       NULL,
241       sizeof (GstTestElement),
242       0,
243       NULL,                     /* instance_init */
244       NULL
245     };
246
247     gst_test_element_type = g_type_register_static (GST_TYPE_ELEMENT,
248         "GstTestElement", &gst_test_element_info, 0);
249   }
250   return gst_test_element_type;
251 }
252
253 typedef struct _GstTestElement2
254 {
255   GstTestElement parent;
256
257 } GstTestElement2;
258
259 typedef struct _GstTestElement2Class
260 {
261   GstTestElementClass parent;
262
263 } GstTestElement2Class;
264
265 static void
266 gst_test_element2_class_init (GstTestElement2Class * klass)
267 {
268   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
269   GstPadTemplate *templ;
270
271   gst_element_class_set_metadata (element_class, "Test element 2",
272       "Element", "Does nothing", "Foo Bar <foo@bar.com>");
273
274   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
275           (element_class)), 2);
276
277   fail_unless ((templ =
278           gst_element_class_get_pad_template (element_class, "test")) != NULL);
279   fail_unless (gst_caps_is_empty (templ->caps));
280
281   fail_unless ((templ =
282           gst_element_class_get_pad_template (element_class, "test2")) != NULL);
283   fail_unless (gst_caps_is_any (templ->caps));
284
285   /* Add "test" pad with ANY caps, should have "test" pad with EMPTY caps before */
286   gst_element_class_add_pad_template (element_class,
287       gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_ANY));
288
289   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
290           (element_class)), 2);
291
292   fail_unless ((templ =
293           gst_element_class_get_pad_template (element_class, "test")) != NULL);
294   fail_unless (gst_caps_is_any (templ->caps));
295
296
297   gst_element_class_add_pad_template (element_class,
298       gst_pad_template_new ("test4", GST_PAD_SRC, GST_PAD_ALWAYS,
299           GST_CAPS_ANY));
300
301   fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
302           (element_class)), 3);
303
304   fail_unless ((templ =
305           gst_element_class_get_pad_template (element_class, "test4")) != NULL);
306   fail_unless (gst_caps_is_any (templ->caps));
307 }
308
309 static GType
310 gst_test_element2_get_type (void)
311 {
312   static GType gst_test_element2_type = G_TYPE_NONE;
313
314   if (gst_test_element2_type == G_TYPE_NONE) {
315     static const GTypeInfo gst_test_element2_info = {
316       sizeof (GstTestElement2Class),
317       NULL,                     /* base_init */
318       NULL,                     /* base_finalize */
319       (GClassInitFunc) gst_test_element2_class_init,
320       NULL,
321       NULL,
322       sizeof (GstTestElement2),
323       0,
324       NULL,                     /* instance_init */
325       NULL
326     };
327
328     gst_test_element2_type =
329         g_type_register_static (gst_test_element_get_type (), "GstTestElement2",
330         &gst_test_element2_info, 0);
331   }
332   return gst_test_element2_type;
333 }
334
335
336 GST_START_TEST (test_pad_templates)
337 {
338   GstTestElement *test;
339   GstTestElement2 *test2;
340
341   test = g_object_new (gst_test_element_get_type (), NULL);
342   test2 = g_object_new (gst_test_element2_get_type (), NULL);
343
344   g_object_unref (test);
345   g_object_unref (test2);
346 }
347
348 GST_END_TEST;
349
350 static Suite *
351 gst_element_suite (void)
352 {
353   Suite *s = suite_create ("GstElement");
354   TCase *tc_chain = tcase_create ("element tests");
355
356   suite_add_tcase (s, tc_chain);
357   tcase_add_test (tc_chain, test_add_remove_pad);
358   tcase_add_test (tc_chain, test_add_pad_unref_element);
359   tcase_add_test (tc_chain, test_error_no_bus);
360   tcase_add_test (tc_chain, test_link);
361   tcase_add_test (tc_chain, test_link_no_pads);
362   tcase_add_test (tc_chain, test_pad_templates);
363
364   return s;
365 }
366
367 GST_CHECK_MAIN (gst_element);