2 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
3 * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
5 * gstbin.c: Unit test for GstBin
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.
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.
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., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #include <gst/check/gstcheck.h>
26 pop_async_done (GstBus * bus)
30 GST_DEBUG ("popping async-done message");
31 message = gst_bus_poll (bus, GST_MESSAGE_ASYNC_DONE, -1);
33 fail_unless (message && GST_MESSAGE_TYPE (message)
34 == GST_MESSAGE_ASYNC_DONE, "did not get GST_MESSAGE_ASYNC_DONE");
36 gst_message_unref (message);
37 GST_DEBUG ("popped message");
41 pop_messages (GstBus * bus, int count)
47 GST_DEBUG ("popping %d messages", count);
48 for (i = 0; i < count; ++i) {
49 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
51 fail_unless (message && GST_MESSAGE_TYPE (message)
52 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
54 gst_message_unref (message);
56 GST_DEBUG ("popped %d messages", count);
59 GST_START_TEST (test_interface)
66 bin = GST_BIN (gst_bin_new (NULL));
67 fail_unless (bin != NULL, "Could not create bin");
69 filesrc = gst_element_factory_make ("filesrc", NULL);
70 fail_unless (filesrc != NULL, "Could not create filesrc");
71 fail_unless (GST_IS_URI_HANDLER (filesrc), "Filesrc not a URI handler");
72 gst_bin_add (bin, filesrc);
74 fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
75 gst_object_unref (filesrc);
77 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
78 fail_unless (it != NULL);
79 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
80 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
81 g_value_reset (&item);
82 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
83 gst_iterator_free (it);
85 gst_bin_add_many (bin,
86 gst_element_factory_make ("identity", NULL),
87 gst_element_factory_make ("identity", NULL),
88 gst_element_factory_make ("identity", NULL), NULL);
89 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
90 fail_unless (it != NULL);
91 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
92 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
93 g_value_reset (&item);
94 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
95 gst_iterator_free (it);
98 bin = GST_BIN (gst_bin_new (NULL));
99 fail_unless (bin != NULL);
100 gst_bin_add_many (bin,
101 gst_element_factory_make ("identity", NULL),
102 gst_element_factory_make ("identity", NULL),
103 GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
104 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
105 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
106 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
107 g_value_reset (&item);
108 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
109 gst_iterator_free (it);
111 gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
112 gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
113 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
114 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
115 g_value_reset (&item);
116 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
117 g_value_reset (&item);
118 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
119 g_value_reset (&item);
120 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
121 g_value_unset (&item);
122 gst_iterator_free (it);
124 gst_object_unref (bin);
129 GST_START_TEST (test_message_state_changed)
134 GstStateChangeReturn ret;
136 bin = GST_BIN (gst_bin_new (NULL));
137 fail_unless (bin != NULL, "Could not create bin");
138 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
140 bus = g_object_new (gst_bus_get_type (), NULL);
141 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
143 /* change state, spawning a message, causing an incref on the bin */
144 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
145 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
147 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
149 /* get and unref the message, causing a decref on the bin */
150 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
152 fail_unless (message && GST_MESSAGE_TYPE (message)
153 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
155 gst_message_unref (message);
157 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
160 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
161 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
163 gst_object_unref (bus);
164 gst_object_unref (bin);
169 GST_START_TEST (test_message_state_changed_child)
175 GstStateChangeReturn ret;
177 bin = GST_BIN (gst_bin_new (NULL));
178 fail_unless (bin != NULL, "Could not create bin");
179 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
181 bus = g_object_new (gst_bus_get_type (), NULL);
182 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
184 src = gst_element_factory_make ("fakesrc", NULL);
185 fail_if (src == NULL, "Could not create fakesrc");
186 gst_bin_add (bin, src);
187 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
188 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
190 /* change state, spawning two messages:
191 * - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
192 * - second for bin, causing an incref on the bin */
193 GST_DEBUG ("setting bin to READY");
194 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
195 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
197 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
198 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
200 /* get and unref the message, causing a decref on the src */
201 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
202 fail_unless (message && GST_MESSAGE_TYPE (message)
203 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
205 fail_unless (message->src == GST_OBJECT (src));
206 gst_message_unref (message);
208 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
209 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
211 /* get and unref message 2, causing a decref on the bin */
212 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
213 fail_unless (message && GST_MESSAGE_TYPE (message)
214 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
216 fail_unless (message->src == GST_OBJECT (bin));
217 gst_message_unref (message);
219 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
220 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
223 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
224 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
225 gst_object_unref (bus);
226 gst_object_unref (bin);
231 GST_START_TEST (test_message_state_changed_children)
233 GstPipeline *pipeline;
234 GstElement *src, *sink;
236 GstStateChangeReturn ret;
237 GstState current, pending;
239 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
240 fail_unless (pipeline != NULL, "Could not create pipeline");
241 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
243 src = gst_element_factory_make ("fakesrc", NULL);
244 fail_if (src == NULL, "Could not create fakesrc");
245 /* need to silence the element as the deep_notify refcounts the
246 * parents while running */
247 g_object_set (G_OBJECT (src), "silent", TRUE, NULL);
248 gst_bin_add (GST_BIN (pipeline), src);
250 sink = gst_element_factory_make ("fakesink", NULL);
251 /* need to silence the element as the deep_notify refcounts the
252 * parents while running */
253 g_object_set (G_OBJECT (sink), "silent", TRUE, NULL);
254 fail_if (sink == NULL, "Could not create fakesink");
255 gst_bin_add (GST_BIN (pipeline), sink);
257 fail_unless (gst_element_link (src, sink), "could not link src and sink");
259 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
260 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
261 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
263 bus = gst_pipeline_get_bus (pipeline);
265 /* change state to READY, spawning three messages */
266 GST_DEBUG ("setting pipeline to READY");
267 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
268 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
270 /* each object is referenced by a message */
271 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
272 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
273 ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
274 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
276 pop_messages (bus, 3);
277 fail_if (gst_bus_have_pending (bus), "unexpected pending messages");
279 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
280 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
281 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
282 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
284 /* change state to PAUSED, spawning three messages */
285 GST_DEBUG ("setting pipeline to PAUSED");
286 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
287 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
289 gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending,
290 GST_CLOCK_TIME_NONE);
291 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
292 fail_unless (current == GST_STATE_PAUSED);
293 fail_unless (pending == GST_STATE_VOID_PENDING);
295 /* wait for async thread to settle down */
296 GST_DEBUG ("waiting for refcount");
297 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 3)
299 GST_DEBUG ("refcount <= 3 now");
301 /* each object is referenced by a message;
302 * base_src is blocked in the push and has an extra refcount.
303 * base_sink_chain has taken a refcount on the sink, and is blocked on
305 * The stream-status messages holds 2 more refs to the element */
306 ASSERT_OBJECT_REFCOUNT (src, "src", 4);
307 /* refcount can be 4 if the bin is still processing the async_done message of
309 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
310 /* 2 or 3 is valid, because the pipeline might still be posting
311 * its state_change message */
312 ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline", 2, 3);
314 pop_messages (bus, 3);
315 pop_async_done (bus);
316 fail_if ((gst_bus_pop (bus)) != NULL);
318 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
319 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
320 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
321 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
323 /* change state to PLAYING, spawning three messages */
324 GST_DEBUG ("setting pipeline to PLAYING");
325 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
326 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
328 gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending,
329 GST_CLOCK_TIME_NONE);
330 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
331 fail_unless (current == GST_STATE_PLAYING);
332 fail_unless (pending == GST_STATE_VOID_PENDING);
334 /* each object is referenced by one message
335 * src might have an extra reference if it's still pushing
336 * sink might have an extra reference if it's still blocked on preroll
337 * pipeline posted a new-clock message too. */
338 ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 2, 3);
339 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
340 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
342 pop_messages (bus, 3);
343 fail_if ((gst_bus_pop (bus)) != NULL);
345 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
346 /* src might have an extra reference if it's still pushing */
347 ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 1, 2);
348 /* sink might have an extra reference if it's still blocked on preroll */
349 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
350 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
352 /* go back to READY, spawning six messages */
353 GST_DEBUG ("setting pipeline to READY");
354 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
355 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
357 /* each object is referenced by two messages, the source also has the
358 * stream-status message referencing it */
359 ASSERT_OBJECT_REFCOUNT (src, "src", 4);
360 ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
361 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
363 pop_messages (bus, 6);
364 fail_if ((gst_bus_pop (bus)) != NULL);
366 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
367 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
368 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
370 /* setting pipeline to NULL flushes the bus automatically */
371 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
372 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
374 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
375 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
376 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
379 gst_object_unref (bus);
380 gst_object_unref (pipeline);
385 GST_START_TEST (test_watch_for_state_change)
387 GstElement *src, *sink, *bin;
389 GstStateChangeReturn ret;
391 bin = gst_element_factory_make ("bin", NULL);
392 fail_unless (bin != NULL, "Could not create bin");
394 bus = g_object_new (gst_bus_get_type (), NULL);
395 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
397 src = gst_element_factory_make ("fakesrc", NULL);
398 fail_if (src == NULL, "Could not create fakesrc");
399 sink = gst_element_factory_make ("fakesink", NULL);
400 fail_if (sink == NULL, "Could not create fakesink");
402 gst_bin_add (GST_BIN (bin), sink);
403 gst_bin_add (GST_BIN (bin), src);
405 fail_unless (gst_element_link (src, sink), "could not link src and sink");
407 /* change state, spawning two times three messages */
408 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
409 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
411 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
412 GST_CLOCK_TIME_NONE);
413 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
415 pop_messages (bus, 6);
416 pop_async_done (bus);
418 fail_unless (gst_bus_have_pending (bus) == FALSE,
419 "Unexpected messages on bus");
421 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
422 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
424 pop_messages (bus, 3);
426 /* this one might return either SUCCESS or ASYNC, likely SUCCESS */
427 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
428 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE);
430 pop_messages (bus, 3);
431 if (ret == GST_STATE_CHANGE_ASYNC)
432 pop_async_done (bus);
434 fail_unless (gst_bus_have_pending (bus) == FALSE,
435 "Unexpected messages on bus");
437 /* setting bin to NULL flushes the bus automatically */
438 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
439 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
442 gst_object_unref (bus);
443 gst_object_unref (bin);
448 GST_START_TEST (test_state_change_error_message)
450 GstElement *src, *sink, *bin;
452 GstStateChangeReturn ret;
454 bin = gst_element_factory_make ("bin", NULL);
455 fail_unless (bin != NULL, "Could not create bin");
457 bus = g_object_new (gst_bus_get_type (), NULL);
458 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
460 src = gst_element_factory_make ("fakesrc", NULL);
461 fail_if (src == NULL, "Could not create fakesrc");
462 sink = gst_element_factory_make ("fakesink", NULL);
463 fail_if (sink == NULL, "Could not create fakesink");
465 /* add but don't link elements */
466 gst_bin_add (GST_BIN (bin), sink);
467 gst_bin_add (GST_BIN (bin), src);
469 /* change state, this should succeed */
470 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
471 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
473 /* now wait, the streaming thread will error because the source is not
475 ret = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
476 GST_CLOCK_TIME_NONE);
477 fail_unless (ret == GST_STATE_CHANGE_FAILURE);
479 gst_bus_set_flushing (bus, TRUE);
481 /* setting bin to NULL flushes the bus automatically */
482 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
483 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
486 gst_object_unref (bus);
487 gst_object_unref (bin);
493 /* adding an element with linked pads to a bin unlinks the
495 GST_START_TEST (test_add_linked)
497 GstElement *src, *sink;
498 GstPad *srcpad, *sinkpad;
499 GstElement *pipeline;
501 pipeline = gst_pipeline_new (NULL);
502 fail_unless (pipeline != NULL, "Could not create pipeline");
504 src = gst_element_factory_make ("fakesrc", NULL);
505 fail_if (src == NULL, "Could not create fakesrc");
506 sink = gst_element_factory_make ("fakesink", NULL);
507 fail_if (sink == NULL, "Could not create fakesink");
509 srcpad = gst_element_get_static_pad (src, "src");
510 fail_unless (srcpad != NULL);
511 sinkpad = gst_element_get_static_pad (sink, "sink");
512 fail_unless (sinkpad != NULL);
514 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
516 /* pads are linked now */
517 fail_unless (gst_pad_is_linked (srcpad));
518 fail_unless (gst_pad_is_linked (sinkpad));
520 /* adding element to bin voids hierarchy so pads are unlinked */
521 gst_bin_add (GST_BIN (pipeline), src);
523 /* check if pads really are unlinked */
524 fail_unless (!gst_pad_is_linked (srcpad));
525 fail_unless (!gst_pad_is_linked (sinkpad));
527 /* cannot link pads in wrong hierarchy */
528 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_WRONG_HIERARCHY);
530 /* adding other element to bin as well */
531 gst_bin_add (GST_BIN (pipeline), sink);
533 /* now we can link again */
534 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
536 /* check if pads really are linked */
537 fail_unless (gst_pad_is_linked (srcpad));
538 fail_unless (gst_pad_is_linked (sinkpad));
540 gst_object_unref (srcpad);
541 gst_object_unref (sinkpad);
542 gst_object_unref (pipeline);
547 /* adding ourself should fail */
548 GST_START_TEST (test_add_self)
552 bin = gst_bin_new (NULL);
553 fail_unless (bin != NULL, "Could not create bin");
555 ASSERT_WARNING (gst_bin_add (GST_BIN (bin), bin));
557 gst_object_unref (bin);
563 /* g_print ("%10s: %4d => %4d\n", GST_OBJECT_NAME (msg->src), old, new); */
565 #define ASSERT_STATE_CHANGE_MSG(bus,element,old_state,new_state,num) \
568 GstState old = 0, new = 0, pending = 0; \
569 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); \
570 fail_if (msg == NULL, "No state change message within 1 second (#" \
571 G_STRINGIFY (num) ")"); \
572 gst_message_parse_state_changed (msg, &old, &new, &pending); \
573 fail_if (msg->src != GST_OBJECT (element), G_STRINGIFY(element) \
574 " should have changed state next (#" G_STRINGIFY (num) ")"); \
575 fail_if (old != old_state || new != new_state, "state change is not " \
576 G_STRINGIFY (old_state) " => " G_STRINGIFY (new_state)); \
577 gst_message_unref (msg); \
580 GST_START_TEST (test_children_state_change_order_flagged_sink)
582 GstElement *src, *identity, *sink, *pipeline;
583 GstStateChangeReturn ret;
584 GstState current, pending;
587 pipeline = gst_pipeline_new (NULL);
588 fail_unless (pipeline != NULL, "Could not create pipeline");
590 bus = gst_element_get_bus (pipeline);
591 fail_unless (bus != NULL, "Pipeline has no bus?!");
593 src = gst_element_factory_make ("fakesrc", NULL);
594 fail_if (src == NULL, "Could not create fakesrc");
595 g_object_set (src, "num-buffers", 5, NULL);
597 identity = gst_element_factory_make ("identity", NULL);
598 fail_if (identity == NULL, "Could not create identity");
600 sink = gst_element_factory_make ("fakesink", NULL);
601 fail_if (sink == NULL, "Could not create fakesink");
603 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
605 fail_unless (gst_element_link (src, identity) == TRUE);
606 fail_unless (gst_element_link (identity, sink) == TRUE);
608 /* (1) Test state change with fakesink being a regular sink */
609 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
610 fail_if (ret != GST_STATE_CHANGE_ASYNC,
611 "State change to PLAYING did not return ASYNC");
613 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
614 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
615 fail_if (current != GST_STATE_PLAYING, "State change to PLAYING failed");
616 fail_if (pending != GST_STATE_VOID_PENDING, "State change to PLAYING failed");
619 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 101);
620 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 102);
621 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 103);
622 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 104);
624 /* READY => PAUSED */
625 /* because of pre-rolling, sink will return ASYNC on state
626 * change and change state later when it has a buffer */
627 GST_DEBUG ("popping READY -> PAUSED messages");
628 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
631 /* From here on, all bets are off. Usually the source changes state next,
632 * but it might just as well be that the first buffer produced by the
633 * source reaches the sink before the source has finished its state change,
634 * in which case the sink will commit its new state before the source ... */
635 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 106);
636 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
639 pop_messages (bus, 2); /* pop remaining ready => paused messages off the bus */
640 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
642 pop_async_done (bus);
644 /* PAUSED => PLAYING */
645 GST_DEBUG ("popping PAUSED -> PLAYING messages");
646 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 109);
647 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
649 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 111);
650 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
653 /* don't set to NULL that will set the bus flushing and kill our messages */
654 ret = gst_element_set_state (pipeline, GST_STATE_READY);
655 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
656 ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
657 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
659 /* TODO: do we need to check downwards state change order as well? */
660 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
661 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
663 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
666 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
667 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
668 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
670 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
671 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
673 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
674 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
675 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
677 gst_object_unref (bus);
678 gst_object_unref (pipeline);
684 GST_START_TEST (test_children_state_change_order_semi_sink)
686 GstElement *src, *identity, *sink, *pipeline;
687 GstStateChangeReturn ret;
688 GstState current, pending;
691 /* (2) Now again, but check other code path where we don't have
692 * a proper sink correctly flagged as such, but a 'semi-sink' */
693 pipeline = gst_pipeline_new (NULL);
694 fail_unless (pipeline != NULL, "Could not create pipeline");
696 bus = gst_element_get_bus (pipeline);
697 fail_unless (bus != NULL, "Pipeline has no bus?!");
699 src = gst_element_factory_make ("fakesrc", NULL);
700 fail_if (src == NULL, "Could not create fakesrc");
702 identity = gst_element_factory_make ("identity", NULL);
703 fail_if (identity == NULL, "Could not create identity");
705 sink = gst_element_factory_make ("fakesink", NULL);
706 fail_if (sink == NULL, "Could not create fakesink");
708 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
710 fail_unless (gst_element_link (src, identity) == TRUE);
711 fail_unless (gst_element_link (identity, sink) == TRUE);
713 /* this is not very nice but should work just fine in this case. */
714 GST_OBJECT_FLAG_UNSET (sink, GST_ELEMENT_FLAG_SINK); /* <======== */
716 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
717 fail_if (ret != GST_STATE_CHANGE_ASYNC, "State change to PLAYING not ASYNC");
719 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
720 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
721 fail_if (current != GST_STATE_PLAYING, "State change to PLAYING failed");
722 fail_if (pending != GST_STATE_VOID_PENDING, "State change to PLAYING failed");
725 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 201);
726 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 202);
727 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 203);
728 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 204);
730 /* READY => PAUSED */
731 /* because of pre-rolling, sink will return ASYNC on state
732 * change and change state later when it has a buffer */
733 GST_DEBUG ("popping READY -> PAUSED messages");
734 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
737 /* From here on, all bets are off. Usually the source changes state next,
738 * but it might just as well be that the first buffer produced by the
739 * source reaches the sink before the source has finished its state change,
740 * in which case the sink will commit its new state before the source ... */
741 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
742 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
744 pop_messages (bus, 2); /* pop remaining ready => paused messages off the bus */
745 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
747 pop_async_done (bus);
749 /* PAUSED => PLAYING */
750 GST_DEBUG ("popping PAUSED -> PLAYING messages");
751 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 209);
752 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
754 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 211);
755 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
759 /* don't set to NULL that will set the bus flushing and kill our messages */
760 ret = gst_element_set_state (pipeline, GST_STATE_READY);
761 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
763 /* TODO: do we need to check downwards state change order as well? */
764 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
765 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
767 GST_DEBUG ("waiting for pipeline to reach refcount 1");
768 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
771 GST_DEBUG ("checking refcount");
772 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
773 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
774 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
776 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
777 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
779 GST_DEBUG ("checking refcount");
780 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
781 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
782 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
784 GST_DEBUG ("cleanup");
785 gst_object_unref (bus);
786 gst_object_unref (pipeline);
791 GST_START_TEST (test_children_state_change_order_two_sink)
793 GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline;
794 GstStateChangeReturn ret;
797 pipeline = gst_pipeline_new (NULL);
798 fail_unless (pipeline != NULL, "Could not create pipeline");
800 bus = gst_element_get_bus (pipeline);
801 fail_unless (bus != NULL, "Pipeline has no bus?!");
803 src = gst_element_factory_make ("fakesrc", NULL);
804 fail_if (src == NULL, "Could not create fakesrc");
806 tee = gst_element_factory_make ("tee", NULL);
807 fail_if (tee == NULL, "Could not create tee");
809 identity = gst_element_factory_make ("identity", NULL);
810 fail_if (identity == NULL, "Could not create identity");
812 sink1 = gst_element_factory_make ("fakesink", NULL);
813 fail_if (sink1 == NULL, "Could not create fakesink1");
815 sink2 = gst_element_factory_make ("fakesink", NULL);
816 fail_if (sink2 == NULL, "Could not create fakesink2");
818 gst_bin_add_many (GST_BIN (pipeline), src, tee, identity, sink1, sink2, NULL);
820 fail_unless (gst_element_link (src, tee) == TRUE);
821 fail_unless (gst_element_link (tee, identity) == TRUE);
822 fail_unless (gst_element_link (identity, sink1) == TRUE);
823 fail_unless (gst_element_link (tee, sink2) == TRUE);
825 ret = gst_element_set_state (pipeline, GST_STATE_READY);
826 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
831 GstState old = 0, new = 0, pending = 0;
832 GstObject *first, *second;
834 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
835 fail_if (msg == NULL, "No state change message within 1 second (#201)");
837 gst_message_parse_state_changed (msg, &old, &new, &pending);
838 first = gst_object_ref (msg->src);
840 fail_if (first != GST_OBJECT (sink1) && first != GST_OBJECT (sink2),
841 "sink1 or sink2 should have changed state next #(202)");
842 gst_message_unref (msg);
844 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
845 fail_if (msg == NULL, "No state change message within 1 second (#201)");
847 gst_message_parse_state_changed (msg, &old, &new, &pending);
848 second = gst_object_ref (msg->src);
850 fail_if (second != GST_OBJECT (sink1) && second != GST_OBJECT (sink2),
851 "sink1 or sink2 should have changed state next #(202)");
852 gst_message_unref (msg);
854 fail_if (second == first, "got state change from same object");
856 gst_object_unref (first);
857 gst_object_unref (second);
859 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 203);
860 ASSERT_STATE_CHANGE_MSG (bus, tee, GST_STATE_NULL, GST_STATE_READY, 204);
861 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 205);
862 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 206);
864 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
865 ASSERT_OBJECT_REFCOUNT (tee, "tee", 1);
866 ASSERT_OBJECT_REFCOUNT (identity, "identity", 1);
867 ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1);
868 ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
869 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
871 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
872 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
874 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
875 ASSERT_OBJECT_REFCOUNT (tee, "tee", 1);
876 ASSERT_OBJECT_REFCOUNT (identity, "identity", 1);
877 ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1);
878 ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
879 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
881 gst_object_unref (bus);
882 gst_object_unref (pipeline);
887 GST_START_TEST (test_iterate_sorted)
889 GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline, *bin;
891 GValue elem = { 0, };
893 pipeline = gst_pipeline_new (NULL);
894 fail_unless (pipeline != NULL, "Could not create pipeline");
896 bin = gst_bin_new (NULL);
897 fail_unless (bin != NULL, "Could not create bin");
899 src = gst_element_factory_make ("fakesrc", NULL);
900 fail_if (src == NULL, "Could not create fakesrc");
902 tee = gst_element_factory_make ("tee", NULL);
903 fail_if (tee == NULL, "Could not create tee");
905 sink1 = gst_element_factory_make ("fakesink", NULL);
906 fail_if (sink1 == NULL, "Could not create fakesink1");
908 gst_bin_add_many (GST_BIN (bin), src, tee, sink1, NULL);
910 fail_unless (gst_element_link (src, tee) == TRUE);
911 fail_unless (gst_element_link (tee, sink1) == TRUE);
913 identity = gst_element_factory_make ("identity", NULL);
914 fail_if (identity == NULL, "Could not create identity");
916 sink2 = gst_element_factory_make ("fakesink", NULL);
917 fail_if (sink2 == NULL, "Could not create fakesink2");
919 gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL);
921 fail_unless (gst_element_link (tee, identity) == TRUE);
922 fail_unless (gst_element_link (identity, sink2) == TRUE);
924 it = gst_bin_iterate_sorted (GST_BIN (pipeline));
925 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
926 fail_unless (g_value_get_object (&elem) == (gpointer) sink2);
927 g_value_reset (&elem);
929 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
930 fail_unless (g_value_get_object (&elem) == (gpointer) identity);
931 g_value_reset (&elem);
933 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
934 fail_unless (g_value_get_object (&elem) == (gpointer) bin);
935 g_value_reset (&elem);
937 g_value_unset (&elem);
938 gst_iterator_free (it);
940 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
941 gst_object_unref (pipeline);
947 test_link_structure_change_state_changed_sync_cb (GstBus * bus,
948 GstMessage * message, gpointer data)
950 GstPipeline *pipeline = GST_PIPELINE (data);
951 GstElement *src, *identity, *sink;
952 GstState old, snew, pending;
954 sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
955 fail_unless (sink != NULL, "Could not get sink");
957 gst_message_parse_state_changed (message, &old, &snew, &pending);
958 if (message->src != GST_OBJECT (sink) || snew != GST_STATE_READY) {
959 gst_object_unref (sink);
963 src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
964 fail_unless (src != NULL, "Could not get src");
966 identity = gst_bin_get_by_name (GST_BIN (pipeline), "identity");
967 fail_unless (identity != NULL, "Could not get identity");
969 /* link src to identity, the pipeline should detect the new link and
970 * resync the state change */
971 fail_unless (gst_element_link (src, identity) == TRUE);
973 gst_object_unref (src);
974 gst_object_unref (identity);
975 gst_object_unref (sink);
978 GST_START_TEST (test_link_structure_change)
980 GstElement *src, *identity, *sink, *pipeline;
984 pipeline = gst_pipeline_new (NULL);
985 fail_unless (pipeline != NULL, "Could not create pipeline");
987 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
988 fail_unless (bus != NULL, "Could not get bus");
990 /* use the sync signal handler to link elements while the pipeline is still
991 * doing the state change */
992 gst_bus_set_sync_handler (bus, gst_bus_sync_signal_handler, pipeline);
993 g_object_connect (bus, "signal::sync-message::state-changed",
994 G_CALLBACK (test_link_structure_change_state_changed_sync_cb), pipeline,
997 src = gst_element_factory_make ("fakesrc", "src");
998 fail_if (src == NULL, "Could not create fakesrc");
1000 identity = gst_element_factory_make ("identity", "identity");
1001 fail_if (identity == NULL, "Could not create identity");
1003 sink = gst_element_factory_make ("fakesink", "sink");
1004 fail_if (sink == NULL, "Could not create fakesink1");
1006 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
1008 gst_element_set_state (pipeline, GST_STATE_READY);
1009 gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
1011 /* the state change will be done on src only if the pipeline correctly resyncs
1012 * after that fakesrc has been linked to identity */
1013 gst_element_get_state (src, &state, NULL, 0);
1014 fail_unless_equals_int (state, GST_STATE_READY);
1017 gst_element_set_state (pipeline, GST_STATE_NULL);
1018 gst_object_unref (bus);
1019 gst_object_unref (pipeline);
1024 static GstBusSyncReply
1025 sync_handler_remove_sink (GstBus * bus, GstMessage * message, gpointer data)
1027 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
1030 child = gst_bin_get_by_name (GST_BIN (data), "fakesink");
1031 fail_unless (child != NULL, "Could not find fakesink");
1033 gst_bin_remove (GST_BIN (data), child);
1034 gst_object_unref (child);
1036 return GST_BUS_PASS;
1039 GST_START_TEST (test_state_failure_remove)
1041 GstElement *src, *sink, *pipeline;
1043 GstStateChangeReturn ret;
1045 pipeline = gst_pipeline_new (NULL);
1046 fail_unless (pipeline != NULL, "Could not create pipeline");
1048 src = gst_element_factory_make ("fakesrc", "fakesrc");
1049 fail_unless (src != NULL, "Could not create fakesrc");
1051 sink = gst_element_factory_make ("fakesink", "fakesink");
1052 fail_unless (sink != NULL, "Could not create fakesink");
1054 g_object_set (sink, "state-error", 1, NULL);
1056 gst_bin_add (GST_BIN (pipeline), src);
1057 gst_bin_add (GST_BIN (pipeline), sink);
1059 gst_element_link (src, sink);
1061 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1062 fail_unless (bus != NULL, "Could not get bus");
1064 gst_bus_set_sync_handler (bus, sync_handler_remove_sink, pipeline);
1066 ret = gst_element_set_state (pipeline, GST_STATE_READY);
1067 fail_unless (ret == GST_STATE_CHANGE_SUCCESS,
1068 "did not get state change success");
1070 gst_element_set_state (pipeline, GST_STATE_NULL);
1072 gst_object_unref (bus);
1073 gst_object_unref (pipeline);
1078 GST_START_TEST (test_many_bins)
1080 GstStateChangeReturn ret;
1081 GstElement *src, *sink, *pipeline, *last_bin = NULL;
1084 #define NUM_BINS 2000
1086 pipeline = gst_pipeline_new (NULL);
1087 fail_unless (pipeline != NULL, "Could not create pipeline");
1089 src = gst_element_factory_make ("fakesrc", "fakesrc");
1090 fail_unless (src != NULL, "Could not create fakesrc");
1091 g_object_set (src, "num-buffers", 3, NULL);
1093 sink = gst_element_factory_make ("fakesink", "fakesink");
1094 fail_unless (sink != NULL, "Could not create fakesink");
1096 gst_bin_add (GST_BIN (pipeline), src);
1097 gst_bin_add (GST_BIN (pipeline), sink);
1099 for (i = 0; i < NUM_BINS; ++i) {
1100 GstElement *bin, *identity;
1101 GstPad *srcpad, *sinkpad;
1103 bin = gst_bin_new (NULL);
1104 fail_unless (bin != NULL, "Could not create bin %d", i);
1105 identity = gst_element_factory_make ("identity", "identity");
1106 fail_unless (identity != NULL, "Could not create identity %d", i);
1107 g_object_set (identity, "silent", TRUE, NULL);
1108 gst_bin_add (GST_BIN (bin), identity);
1109 sinkpad = gst_element_get_static_pad (identity, "sink");
1110 srcpad = gst_element_get_static_pad (identity, "src");
1111 gst_element_add_pad (bin, gst_ghost_pad_new ("sink", sinkpad));
1112 gst_element_add_pad (bin, gst_ghost_pad_new ("src", srcpad));
1113 gst_object_unref (sinkpad);
1114 gst_object_unref (srcpad);
1116 gst_bin_add (GST_BIN (pipeline), bin);
1118 if (last_bin == NULL) {
1119 srcpad = gst_element_get_static_pad (src, "src");
1121 srcpad = gst_element_get_static_pad (last_bin, "src");
1123 sinkpad = gst_element_get_static_pad (bin, "sink");
1124 gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
1125 gst_object_unref (sinkpad);
1126 gst_object_unref (srcpad);
1131 /* insert some queues to limit the number of function calls in a row */
1132 if ((i % 100) == 0) {
1133 GstElement *q = gst_element_factory_make ("queue", NULL);
1135 GST_LOG ("bin #%d, inserting queue", i);
1136 gst_bin_add (GST_BIN (pipeline), q);
1137 fail_unless (gst_element_link (last_bin, q));
1142 fail_unless (gst_element_link (last_bin, sink));
1144 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
1145 fail_unless_equals_int (ret, GST_STATE_CHANGE_ASYNC);
1147 for (i = 0; i < 15; ++i) {
1148 GST_INFO ("waiting for preroll ...");
1149 ret = gst_element_get_state (pipeline, NULL, NULL, GST_SECOND);
1150 if (ret != GST_STATE_CHANGE_ASYNC)
1153 fail_unless_equals_int (ret, GST_STATE_CHANGE_SUCCESS);
1155 gst_element_set_state (pipeline, GST_STATE_NULL);
1156 gst_object_unref (pipeline);
1162 gst_bin_suite (void)
1164 Suite *s = suite_create ("GstBin");
1165 TCase *tc_chain = tcase_create ("bin tests");
1167 tcase_set_timeout (tc_chain, 0);
1169 suite_add_tcase (s, tc_chain);
1170 tcase_add_test (tc_chain, test_interface);
1171 tcase_add_test (tc_chain, test_children_state_change_order_flagged_sink);
1172 tcase_add_test (tc_chain, test_children_state_change_order_semi_sink);
1173 tcase_add_test (tc_chain, test_children_state_change_order_two_sink);
1174 tcase_add_test (tc_chain, test_message_state_changed);
1175 tcase_add_test (tc_chain, test_message_state_changed_child);
1176 tcase_add_test (tc_chain, test_message_state_changed_children);
1177 tcase_add_test (tc_chain, test_watch_for_state_change);
1178 tcase_add_test (tc_chain, test_state_change_error_message);
1179 tcase_add_test (tc_chain, test_add_linked);
1180 tcase_add_test (tc_chain, test_add_self);
1181 tcase_add_test (tc_chain, test_iterate_sorted);
1182 tcase_add_test (tc_chain, test_link_structure_change);
1183 tcase_add_test (tc_chain, test_state_failure_remove);
1185 /* fails on OSX build bot for some reason, and is a bit silly anyway */
1187 tcase_add_test (tc_chain, test_many_bins);
1192 GST_CHECK_MAIN (gst_bin);