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>
24 #include <gst/base/gstbasesrc.h>
27 pop_async_done (GstBus * bus)
31 GST_DEBUG ("popping async-done message");
32 message = gst_bus_poll (bus, GST_MESSAGE_ASYNC_DONE, -1);
34 fail_unless (message && GST_MESSAGE_TYPE (message)
35 == GST_MESSAGE_ASYNC_DONE, "did not get GST_MESSAGE_ASYNC_DONE");
37 gst_message_unref (message);
38 GST_DEBUG ("popped message");
42 pop_messages (GstBus * bus, int count)
48 GST_DEBUG ("popping %d messages", count);
49 for (i = 0; i < count; ++i) {
50 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
52 fail_unless (message && GST_MESSAGE_TYPE (message)
53 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
55 gst_message_unref (message);
57 GST_DEBUG ("popped %d messages", count);
60 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
66 push_one_eos (GstPad * pad)
68 GST_DEBUG_OBJECT (pad, "Pushing EOS event");
69 gst_pad_push_event (pad, gst_event_new_eos ());
75 push_one_stream_start (GstPad * pad)
77 GST_DEBUG_OBJECT (pad, "Pushing STREAM_START event");
78 gst_pad_push_event (pad, gst_event_new_stream_start ("test"));
83 GST_START_TEST (test_interface)
90 bin = GST_BIN (gst_bin_new (NULL));
91 fail_unless (bin != NULL, "Could not create bin");
93 filesrc = gst_element_factory_make ("filesrc", NULL);
94 fail_unless (filesrc != NULL, "Could not create filesrc");
95 fail_unless (GST_IS_URI_HANDLER (filesrc), "Filesrc not a URI handler");
96 gst_bin_add (bin, filesrc);
98 fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
99 gst_object_unref (filesrc);
101 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
102 fail_unless (it != NULL);
103 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
104 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
105 g_value_reset (&item);
106 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
107 gst_iterator_free (it);
109 gst_bin_add_many (bin,
110 gst_element_factory_make ("identity", NULL),
111 gst_element_factory_make ("identity", NULL),
112 gst_element_factory_make ("identity", NULL), NULL);
113 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
114 fail_unless (it != NULL);
115 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
116 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
117 g_value_reset (&item);
118 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
119 gst_iterator_free (it);
122 bin = GST_BIN (gst_bin_new (NULL));
123 fail_unless (bin != NULL);
124 gst_bin_add_many (bin,
125 gst_element_factory_make ("identity", NULL),
126 gst_element_factory_make ("identity", NULL),
127 GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
128 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
129 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
130 fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
131 g_value_reset (&item);
132 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
133 gst_iterator_free (it);
135 gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
136 gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
137 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
138 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
139 g_value_reset (&item);
140 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
141 g_value_reset (&item);
142 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
143 g_value_reset (&item);
144 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
145 g_value_unset (&item);
146 gst_iterator_free (it);
148 gst_object_unref (bin);
153 GST_START_TEST (test_eos)
156 GstElement *pipeline, *sink1, *sink2;
159 GThread *thread1, *thread2;
161 pipeline = gst_pipeline_new ("test_eos");
162 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
164 sink1 = gst_element_factory_make ("fakesink", "sink1");
165 sink2 = gst_element_factory_make ("fakesink", "sink2");
167 gst_bin_add_many (GST_BIN (pipeline), sink1, sink2, NULL);
169 pad1 = gst_check_setup_src_pad_by_name (sink1, &srctemplate, "sink");
170 pad2 = gst_check_setup_src_pad_by_name (sink2, &srctemplate, "sink");
172 gst_pad_set_active (pad1, TRUE);
173 gst_pad_set_active (pad2, TRUE);
175 fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
176 GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
178 /* Send one EOS to sink1 */
179 thread1 = g_thread_new ("thread1", (GThreadFunc) push_one_eos, pad1);
181 /* Make sure the EOS message is not sent */
183 gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, 2 * GST_SECOND);
184 fail_if (message != NULL);
186 /* Send one EOS to sink2 */
187 thread2 = g_thread_new ("thread2", (GThreadFunc) push_one_eos, pad2);
189 /* Make sure the EOS message is sent then */
190 message = gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_EOS, -1);
191 fail_if (message == NULL);
192 fail_unless (GST_MESSAGE_TYPE (message) == GST_MESSAGE_EOS);
193 gst_message_unref (message);
196 g_thread_join (thread1);
197 g_thread_join (thread2);
199 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
200 gst_pad_set_active (pad1, FALSE);
201 gst_pad_set_active (pad2, FALSE);
202 gst_check_teardown_src_pad (sink1);
203 gst_check_teardown_src_pad (sink2);
204 gst_object_unref (pipeline);
209 GST_START_TEST (test_stream_start)
212 GstElement *pipeline, *sink1, *sink2;
215 GThread *thread1, *thread2;
217 pipeline = gst_pipeline_new ("test_stream_start");
218 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
220 sink1 = gst_element_factory_make ("fakesink", "sink1");
221 sink2 = gst_element_factory_make ("fakesink", "sink2");
223 gst_bin_add_many (GST_BIN (pipeline), sink1, sink2, NULL);
225 pad1 = gst_check_setup_src_pad_by_name (sink1, &srctemplate, "sink");
226 pad2 = gst_check_setup_src_pad_by_name (sink2, &srctemplate, "sink");
228 gst_pad_set_active (pad1, TRUE);
229 gst_pad_set_active (pad2, TRUE);
231 fail_if (gst_element_set_state (GST_ELEMENT (pipeline),
232 GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE);
234 /* Send one STREAM_START to sink1 */
235 thread1 = g_thread_new ("thread1", (GThreadFunc) push_one_stream_start, pad1);
237 /* Make sure the STREAM_START message is not sent */
239 gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_STREAM_START,
241 fail_if (message != NULL);
243 /* Send one STREAM_START to sink2 */
244 thread2 = g_thread_new ("thread2", (GThreadFunc) push_one_stream_start, pad2);
246 /* Make sure the STREAM_START message is sent then */
248 gst_bus_poll (bus, GST_MESSAGE_ERROR | GST_MESSAGE_STREAM_START, -1);
249 fail_if (message == NULL);
250 fail_unless (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_START);
251 gst_message_unref (message);
254 g_thread_join (thread1);
255 g_thread_join (thread2);
257 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
258 gst_pad_set_active (pad1, FALSE);
259 gst_pad_set_active (pad2, FALSE);
260 gst_check_teardown_src_pad (sink1);
261 gst_check_teardown_src_pad (sink2);
262 gst_object_unref (pipeline);
267 GST_START_TEST (test_message_state_changed)
272 GstStateChangeReturn ret;
274 bin = GST_BIN (gst_bin_new (NULL));
275 fail_unless (bin != NULL, "Could not create bin");
276 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
278 bus = g_object_new (gst_bus_get_type (), NULL);
279 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
281 /* change state, spawning a message, causing an incref on the bin */
282 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
283 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
285 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
287 /* get and unref the message, causing a decref on the bin */
288 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
290 fail_unless (message && GST_MESSAGE_TYPE (message)
291 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
293 gst_message_unref (message);
295 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
298 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
299 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
301 gst_object_unref (bus);
302 gst_object_unref (bin);
307 GST_START_TEST (test_message_state_changed_child)
313 GstStateChangeReturn ret;
315 bin = GST_BIN (gst_bin_new (NULL));
316 fail_unless (bin != NULL, "Could not create bin");
317 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
319 bus = g_object_new (gst_bus_get_type (), NULL);
320 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
322 src = gst_element_factory_make ("fakesrc", NULL);
323 fail_if (src == NULL, "Could not create fakesrc");
324 gst_bin_add (bin, src);
325 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
326 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
328 /* change state, spawning two messages:
329 * - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
330 * - second for bin, causing an incref on the bin */
331 GST_DEBUG ("setting bin to READY");
332 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
333 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
335 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
336 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
338 /* get and unref the message, causing a decref on the src */
339 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
340 fail_unless (message && GST_MESSAGE_TYPE (message)
341 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
343 fail_unless (message->src == GST_OBJECT (src));
344 gst_message_unref (message);
346 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
347 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
349 /* get and unref message 2, causing a decref on the bin */
350 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
351 fail_unless (message && GST_MESSAGE_TYPE (message)
352 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
354 fail_unless (message->src == GST_OBJECT (bin));
355 gst_message_unref (message);
357 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
358 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
361 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
362 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
363 gst_object_unref (bus);
364 gst_object_unref (bin);
369 GST_START_TEST (test_message_state_changed_children)
371 GstPipeline *pipeline;
372 GstElement *src, *sink;
374 GstStateChangeReturn ret;
375 GstState current, pending;
377 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
378 fail_unless (pipeline != NULL, "Could not create pipeline");
379 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
381 src = gst_element_factory_make ("fakesrc", NULL);
382 fail_if (src == NULL, "Could not create fakesrc");
383 /* need to silence the element as the deep_notify refcounts the
384 * parents while running */
385 g_object_set (G_OBJECT (src), "silent", TRUE, NULL);
386 gst_bin_add (GST_BIN (pipeline), src);
388 sink = gst_element_factory_make ("fakesink", NULL);
389 /* need to silence the element as the deep_notify refcounts the
390 * parents while running */
391 g_object_set (G_OBJECT (sink), "silent", TRUE, NULL);
392 fail_if (sink == NULL, "Could not create fakesink");
393 gst_bin_add (GST_BIN (pipeline), sink);
395 fail_unless (gst_element_link (src, sink), "could not link src and sink");
397 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
398 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
399 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
401 bus = gst_pipeline_get_bus (pipeline);
403 /* change state to READY, spawning three messages */
404 GST_DEBUG ("setting pipeline to READY");
405 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
406 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
408 /* each object is referenced by a message */
409 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
410 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
411 ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
412 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
414 pop_messages (bus, 3);
415 fail_if (gst_bus_have_pending (bus), "unexpected pending messages");
417 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
418 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
419 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
420 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
422 /* change state to PAUSED, spawning four messages */
423 /* STATE_CHANGED (NULL => READY)
426 * STATE_CHANGED (READY => PAUSED)
428 GST_DEBUG ("setting pipeline to PAUSED");
429 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
430 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
432 gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending,
433 GST_CLOCK_TIME_NONE);
434 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
435 fail_unless (current == GST_STATE_PAUSED);
436 fail_unless (pending == GST_STATE_VOID_PENDING);
438 /* wait for async thread to settle down */
439 GST_DEBUG ("waiting for refcount");
440 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 4)
442 GST_DEBUG ("refcount <= 4 now");
444 /* each object is referenced by a message;
445 * base_src is blocked in the push and has an extra refcount.
446 * base_sink_chain has taken a refcount on the sink, and is blocked on
448 * The stream-status messages holds 2 more refs to the element */
449 ASSERT_OBJECT_REFCOUNT (src, "src", 4);
450 /* refcount can be 4 if the bin is still processing the async_done message of
452 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
453 /* 3 or 4 is valid, because the pipeline might still be posting
454 * its state_change message */
455 ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline", 3, 4);
457 pop_messages (bus, 3);
458 pop_async_done (bus);
459 fail_if ((gst_bus_pop (bus)) != NULL);
461 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
462 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
463 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
464 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
466 /* change state to PLAYING, spawning three messages */
467 GST_DEBUG ("setting pipeline to PLAYING");
468 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
469 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
471 gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending,
472 GST_CLOCK_TIME_NONE);
473 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
474 fail_unless (current == GST_STATE_PLAYING);
475 fail_unless (pending == GST_STATE_VOID_PENDING);
477 /* each object is referenced by one message
478 * src might have an extra reference if it's still pushing
479 * sink might have an extra reference if it's still blocked on preroll
480 * pipeline posted a new-clock message too. */
481 ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 2, 3);
482 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
483 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
485 pop_messages (bus, 3);
486 fail_if ((gst_bus_pop (bus)) != NULL);
488 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
489 /* src might have an extra reference if it's still pushing */
490 ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 1, 2);
491 /* sink might have an extra reference if it's still blocked on preroll */
492 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
493 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
495 /* go back to READY, spawning six messages */
496 GST_DEBUG ("setting pipeline to READY");
497 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY);
498 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
500 /* each object is referenced by two messages, the source also has the
501 * stream-status message referencing it */
502 ASSERT_OBJECT_REFCOUNT (src, "src", 4);
503 ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
504 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
506 pop_messages (bus, 6);
507 fail_if ((gst_bus_pop (bus)) != NULL);
509 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
510 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
511 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
513 /* setting pipeline to NULL flushes the bus automatically */
514 ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
515 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
517 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
518 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
519 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
522 gst_object_unref (bus);
523 gst_object_unref (pipeline);
528 GST_START_TEST (test_watch_for_state_change)
530 GstElement *src, *sink, *bin;
532 GstStateChangeReturn ret;
534 bin = gst_element_factory_make ("bin", NULL);
535 fail_unless (bin != NULL, "Could not create bin");
537 bus = g_object_new (gst_bus_get_type (), NULL);
538 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
540 src = gst_element_factory_make ("fakesrc", NULL);
541 fail_if (src == NULL, "Could not create fakesrc");
542 sink = gst_element_factory_make ("fakesink", NULL);
543 fail_if (sink == NULL, "Could not create fakesink");
545 gst_bin_add (GST_BIN (bin), sink);
546 gst_bin_add (GST_BIN (bin), src);
548 fail_unless (gst_element_link (src, sink), "could not link src and sink");
550 /* change state, spawning two times three messages */
551 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
552 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
554 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
555 GST_CLOCK_TIME_NONE);
556 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
558 pop_messages (bus, 6);
559 pop_async_done (bus);
561 fail_unless (gst_bus_have_pending (bus) == FALSE,
562 "Unexpected messages on bus");
564 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
565 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
567 pop_messages (bus, 3);
569 /* this one might return either SUCCESS or ASYNC, likely SUCCESS */
570 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
571 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE);
573 pop_messages (bus, 3);
574 if (ret == GST_STATE_CHANGE_ASYNC)
575 pop_async_done (bus);
577 fail_unless (gst_bus_have_pending (bus) == FALSE,
578 "Unexpected messages on bus");
580 /* setting bin to NULL flushes the bus automatically */
581 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
582 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
585 gst_object_unref (bus);
586 gst_object_unref (bin);
591 GST_START_TEST (test_state_change_error_message)
593 GstElement *src, *sink, *bin;
595 GstStateChangeReturn ret;
597 bin = gst_element_factory_make ("bin", NULL);
598 fail_unless (bin != NULL, "Could not create bin");
600 bus = g_object_new (gst_bus_get_type (), NULL);
601 gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
603 src = gst_element_factory_make ("fakesrc", NULL);
604 fail_if (src == NULL, "Could not create fakesrc");
605 sink = gst_element_factory_make ("fakesink", NULL);
606 fail_if (sink == NULL, "Could not create fakesink");
608 /* add but don't link elements */
609 gst_bin_add (GST_BIN (bin), sink);
610 gst_bin_add (GST_BIN (bin), src);
612 /* change state, this should succeed */
613 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
614 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
616 /* now wait, the streaming thread will error because the source is not
618 ret = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
619 GST_CLOCK_TIME_NONE);
620 fail_unless (ret == GST_STATE_CHANGE_FAILURE);
622 gst_bus_set_flushing (bus, TRUE);
624 /* setting bin to NULL flushes the bus automatically */
625 ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
626 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
629 gst_object_unref (bus);
630 gst_object_unref (bin);
636 /* adding an element with linked pads to a bin unlinks the
638 GST_START_TEST (test_add_linked)
640 GstElement *src, *sink;
641 GstPad *srcpad, *sinkpad;
642 GstElement *pipeline;
644 pipeline = gst_pipeline_new (NULL);
645 fail_unless (pipeline != NULL, "Could not create pipeline");
647 src = gst_element_factory_make ("fakesrc", NULL);
648 fail_if (src == NULL, "Could not create fakesrc");
649 sink = gst_element_factory_make ("fakesink", NULL);
650 fail_if (sink == NULL, "Could not create fakesink");
652 srcpad = gst_element_get_static_pad (src, "src");
653 fail_unless (srcpad != NULL);
654 sinkpad = gst_element_get_static_pad (sink, "sink");
655 fail_unless (sinkpad != NULL);
657 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
659 /* pads are linked now */
660 fail_unless (gst_pad_is_linked (srcpad));
661 fail_unless (gst_pad_is_linked (sinkpad));
663 /* adding element to bin voids hierarchy so pads are unlinked */
664 gst_bin_add (GST_BIN (pipeline), src);
666 /* check if pads really are unlinked */
667 fail_unless (!gst_pad_is_linked (srcpad));
668 fail_unless (!gst_pad_is_linked (sinkpad));
670 /* cannot link pads in wrong hierarchy */
671 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_WRONG_HIERARCHY);
673 /* adding other element to bin as well */
674 gst_bin_add (GST_BIN (pipeline), sink);
676 /* now we can link again */
677 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
679 /* check if pads really are linked */
680 fail_unless (gst_pad_is_linked (srcpad));
681 fail_unless (gst_pad_is_linked (sinkpad));
683 gst_object_unref (srcpad);
684 gst_object_unref (sinkpad);
685 gst_object_unref (pipeline);
690 /* adding ourself should fail */
691 GST_START_TEST (test_add_self)
695 bin = gst_bin_new (NULL);
696 fail_unless (bin != NULL, "Could not create bin");
698 ASSERT_WARNING (gst_bin_add (GST_BIN (bin), bin));
700 gst_object_unref (bin);
706 /* g_print ("%10s: %4d => %4d\n", GST_OBJECT_NAME (msg->src), old, new); */
708 #define ASSERT_STATE_CHANGE_MSG(bus,element,old_state,new_state,num) \
711 GstState old = 0, new = 0, pending = 0; \
712 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); \
713 fail_if (msg == NULL, "No state change message within 1 second (#" \
714 G_STRINGIFY (num) ")"); \
715 gst_message_parse_state_changed (msg, &old, &new, &pending); \
716 fail_if (msg->src != GST_OBJECT (element), G_STRINGIFY(element) \
717 " should have changed state next (#" G_STRINGIFY (num) ")"); \
718 fail_if (old != old_state || new != new_state, "state change is not " \
719 G_STRINGIFY (old_state) " => " G_STRINGIFY (new_state)); \
720 gst_message_unref (msg); \
723 GST_START_TEST (test_children_state_change_order_flagged_sink)
725 GstElement *src, *identity, *sink, *pipeline;
726 GstStateChangeReturn ret;
727 GstState current, pending;
730 pipeline = gst_pipeline_new (NULL);
731 fail_unless (pipeline != NULL, "Could not create pipeline");
733 bus = gst_element_get_bus (pipeline);
734 fail_unless (bus != NULL, "Pipeline has no bus?!");
736 src = gst_element_factory_make ("fakesrc", NULL);
737 fail_if (src == NULL, "Could not create fakesrc");
738 g_object_set (src, "num-buffers", 5, NULL);
740 identity = gst_element_factory_make ("identity", NULL);
741 fail_if (identity == NULL, "Could not create identity");
743 sink = gst_element_factory_make ("fakesink", NULL);
744 fail_if (sink == NULL, "Could not create fakesink");
746 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
748 fail_unless (gst_element_link (src, identity) == TRUE);
749 fail_unless (gst_element_link (identity, sink) == TRUE);
751 /* (1) Test state change with fakesink being a regular sink */
752 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
753 fail_if (ret != GST_STATE_CHANGE_ASYNC,
754 "State change to PLAYING did not return ASYNC");
756 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
757 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
758 fail_if (current != GST_STATE_PLAYING, "State change to PLAYING failed");
759 fail_if (pending != GST_STATE_VOID_PENDING, "State change to PLAYING failed");
762 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 101);
763 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 102);
764 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 103);
765 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 104);
767 /* READY => PAUSED */
768 /* because of pre-rolling, sink will return ASYNC on state
769 * change and change state later when it has a buffer */
770 GST_DEBUG ("popping READY -> PAUSED messages");
771 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
774 /* From here on, all bets are off. Usually the source changes state next,
775 * but it might just as well be that the first buffer produced by the
776 * source reaches the sink before the source has finished its state change,
777 * in which case the sink will commit its new state before the source ... */
778 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 106);
779 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
782 pop_messages (bus, 2); /* pop remaining ready => paused messages off the bus */
783 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
785 pop_async_done (bus);
787 /* PAUSED => PLAYING */
788 GST_DEBUG ("popping PAUSED -> PLAYING messages");
789 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 109);
790 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
792 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 111);
793 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
796 /* don't set to NULL that will set the bus flushing and kill our messages */
797 ret = gst_element_set_state (pipeline, GST_STATE_READY);
798 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
799 ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
800 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
802 /* TODO: do we need to check downwards state change order as well? */
803 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
804 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
806 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
809 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
810 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
811 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
813 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
814 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
816 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
817 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
818 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
820 gst_object_unref (bus);
821 gst_object_unref (pipeline);
827 GST_START_TEST (test_children_state_change_order_semi_sink)
829 GstElement *src, *identity, *sink, *pipeline;
830 GstStateChangeReturn ret;
831 GstState current, pending;
834 /* (2) Now again, but check other code path where we don't have
835 * a proper sink correctly flagged as such, but a 'semi-sink' */
836 pipeline = gst_pipeline_new (NULL);
837 fail_unless (pipeline != NULL, "Could not create pipeline");
839 bus = gst_element_get_bus (pipeline);
840 fail_unless (bus != NULL, "Pipeline has no bus?!");
842 src = gst_element_factory_make ("fakesrc", NULL);
843 fail_if (src == NULL, "Could not create fakesrc");
845 identity = gst_element_factory_make ("identity", NULL);
846 fail_if (identity == NULL, "Could not create identity");
848 sink = gst_element_factory_make ("fakesink", NULL);
849 fail_if (sink == NULL, "Could not create fakesink");
851 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
853 fail_unless (gst_element_link (src, identity) == TRUE);
854 fail_unless (gst_element_link (identity, sink) == TRUE);
856 /* this is not very nice but should work just fine in this case. */
857 GST_OBJECT_FLAG_UNSET (sink, GST_ELEMENT_FLAG_SINK); /* <======== */
859 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
860 fail_if (ret != GST_STATE_CHANGE_ASYNC, "State change to PLAYING not ASYNC");
862 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
863 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
864 fail_if (current != GST_STATE_PLAYING, "State change to PLAYING failed");
865 fail_if (pending != GST_STATE_VOID_PENDING, "State change to PLAYING failed");
868 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 201);
869 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 202);
870 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 203);
871 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 204);
873 /* READY => PAUSED */
874 /* because of pre-rolling, sink will return ASYNC on state
875 * change and change state later when it has a buffer */
876 GST_DEBUG ("popping READY -> PAUSED messages");
877 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
880 /* From here on, all bets are off. Usually the source changes state next,
881 * but it might just as well be that the first buffer produced by the
882 * source reaches the sink before the source has finished its state change,
883 * in which case the sink will commit its new state before the source ... */
884 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
885 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
887 pop_messages (bus, 2); /* pop remaining ready => paused messages off the bus */
888 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
890 pop_async_done (bus);
892 /* PAUSED => PLAYING */
893 GST_DEBUG ("popping PAUSED -> PLAYING messages");
894 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 209);
895 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
897 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 211);
898 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
902 /* don't set to NULL that will set the bus flushing and kill our messages */
903 ret = gst_element_set_state (pipeline, GST_STATE_READY);
904 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
906 /* TODO: do we need to check downwards state change order as well? */
907 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
908 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
910 GST_DEBUG ("waiting for pipeline to reach refcount 1");
911 while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1)
914 GST_DEBUG ("checking refcount");
915 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
916 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
917 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
919 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
920 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
922 GST_DEBUG ("checking refcount");
923 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
924 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
925 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
927 GST_DEBUG ("cleanup");
928 gst_object_unref (bus);
929 gst_object_unref (pipeline);
934 GST_START_TEST (test_children_state_change_order_two_sink)
936 GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline;
937 GstStateChangeReturn ret;
940 pipeline = gst_pipeline_new (NULL);
941 fail_unless (pipeline != NULL, "Could not create pipeline");
943 bus = gst_element_get_bus (pipeline);
944 fail_unless (bus != NULL, "Pipeline has no bus?!");
946 src = gst_element_factory_make ("fakesrc", NULL);
947 fail_if (src == NULL, "Could not create fakesrc");
949 tee = gst_element_factory_make ("tee", NULL);
950 fail_if (tee == NULL, "Could not create tee");
952 identity = gst_element_factory_make ("identity", NULL);
953 fail_if (identity == NULL, "Could not create identity");
955 sink1 = gst_element_factory_make ("fakesink", NULL);
956 fail_if (sink1 == NULL, "Could not create fakesink1");
958 sink2 = gst_element_factory_make ("fakesink", NULL);
959 fail_if (sink2 == NULL, "Could not create fakesink2");
961 gst_bin_add_many (GST_BIN (pipeline), src, tee, identity, sink1, sink2, NULL);
963 fail_unless (gst_element_link (src, tee) == TRUE);
964 fail_unless (gst_element_link (tee, identity) == TRUE);
965 fail_unless (gst_element_link (identity, sink1) == TRUE);
966 fail_unless (gst_element_link (tee, sink2) == TRUE);
968 ret = gst_element_set_state (pipeline, GST_STATE_READY);
969 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
974 GstState old = 0, new = 0, pending = 0;
975 GstObject *first, *second;
977 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
978 fail_if (msg == NULL, "No state change message within 1 second (#201)");
980 gst_message_parse_state_changed (msg, &old, &new, &pending);
981 first = gst_object_ref (msg->src);
983 fail_if (first != GST_OBJECT (sink1) && first != GST_OBJECT (sink2),
984 "sink1 or sink2 should have changed state next #(202)");
985 gst_message_unref (msg);
987 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
988 fail_if (msg == NULL, "No state change message within 1 second (#201)");
990 gst_message_parse_state_changed (msg, &old, &new, &pending);
991 second = gst_object_ref (msg->src);
993 fail_if (second != GST_OBJECT (sink1) && second != GST_OBJECT (sink2),
994 "sink1 or sink2 should have changed state next #(202)");
995 gst_message_unref (msg);
997 fail_if (second == first, "got state change from same object");
999 gst_object_unref (first);
1000 gst_object_unref (second);
1002 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 203);
1003 ASSERT_STATE_CHANGE_MSG (bus, tee, GST_STATE_NULL, GST_STATE_READY, 204);
1004 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 205);
1005 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 206);
1007 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
1008 ASSERT_OBJECT_REFCOUNT (tee, "tee", 1);
1009 ASSERT_OBJECT_REFCOUNT (identity, "identity", 1);
1010 ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1);
1011 ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
1012 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
1014 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
1015 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
1017 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
1018 ASSERT_OBJECT_REFCOUNT (tee, "tee", 1);
1019 ASSERT_OBJECT_REFCOUNT (identity, "identity", 1);
1020 ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1);
1021 ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
1022 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
1024 gst_object_unref (bus);
1025 gst_object_unref (pipeline);
1030 GST_START_TEST (test_iterate_sorted)
1032 GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline, *bin;
1034 GValue elem = { 0, };
1036 pipeline = gst_pipeline_new (NULL);
1037 fail_unless (pipeline != NULL, "Could not create pipeline");
1039 bin = gst_bin_new (NULL);
1040 fail_unless (bin != NULL, "Could not create bin");
1042 src = gst_element_factory_make ("fakesrc", NULL);
1043 fail_if (src == NULL, "Could not create fakesrc");
1045 tee = gst_element_factory_make ("tee", NULL);
1046 fail_if (tee == NULL, "Could not create tee");
1048 sink1 = gst_element_factory_make ("fakesink", NULL);
1049 fail_if (sink1 == NULL, "Could not create fakesink1");
1051 gst_bin_add_many (GST_BIN (bin), src, tee, sink1, NULL);
1053 fail_unless (gst_element_link (src, tee) == TRUE);
1054 fail_unless (gst_element_link (tee, sink1) == TRUE);
1056 identity = gst_element_factory_make ("identity", NULL);
1057 fail_if (identity == NULL, "Could not create identity");
1059 sink2 = gst_element_factory_make ("fakesink", NULL);
1060 fail_if (sink2 == NULL, "Could not create fakesink2");
1062 gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL);
1064 fail_unless (gst_element_link (tee, identity) == TRUE);
1065 fail_unless (gst_element_link (identity, sink2) == TRUE);
1067 it = gst_bin_iterate_sorted (GST_BIN (pipeline));
1068 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
1069 fail_unless (g_value_get_object (&elem) == (gpointer) sink2);
1070 g_value_reset (&elem);
1072 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
1073 fail_unless (g_value_get_object (&elem) == (gpointer) identity);
1074 g_value_reset (&elem);
1076 fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
1077 fail_unless (g_value_get_object (&elem) == (gpointer) bin);
1078 g_value_reset (&elem);
1080 g_value_unset (&elem);
1081 gst_iterator_free (it);
1083 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
1084 gst_object_unref (pipeline);
1090 test_link_structure_change_state_changed_sync_cb (GstBus * bus,
1091 GstMessage * message, gpointer data)
1093 GstPipeline *pipeline = GST_PIPELINE (data);
1094 GstElement *src, *identity, *sink;
1095 GstState old, snew, pending;
1097 sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink");
1098 fail_unless (sink != NULL, "Could not get sink");
1100 gst_message_parse_state_changed (message, &old, &snew, &pending);
1101 if (message->src != GST_OBJECT (sink) || snew != GST_STATE_READY) {
1102 gst_object_unref (sink);
1106 src = gst_bin_get_by_name (GST_BIN (pipeline), "src");
1107 fail_unless (src != NULL, "Could not get src");
1109 identity = gst_bin_get_by_name (GST_BIN (pipeline), "identity");
1110 fail_unless (identity != NULL, "Could not get identity");
1112 /* link src to identity, the pipeline should detect the new link and
1113 * resync the state change */
1114 fail_unless (gst_element_link (src, identity) == TRUE);
1116 gst_object_unref (src);
1117 gst_object_unref (identity);
1118 gst_object_unref (sink);
1121 GST_START_TEST (test_link_structure_change)
1123 GstElement *src, *identity, *sink, *pipeline;
1127 pipeline = gst_pipeline_new (NULL);
1128 fail_unless (pipeline != NULL, "Could not create pipeline");
1130 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1131 fail_unless (bus != NULL, "Could not get bus");
1133 /* use the sync signal handler to link elements while the pipeline is still
1134 * doing the state change */
1135 gst_bus_set_sync_handler (bus, gst_bus_sync_signal_handler, pipeline, NULL);
1136 g_object_connect (bus, "signal::sync-message::state-changed",
1137 G_CALLBACK (test_link_structure_change_state_changed_sync_cb), pipeline,
1140 src = gst_element_factory_make ("fakesrc", "src");
1141 fail_if (src == NULL, "Could not create fakesrc");
1143 identity = gst_element_factory_make ("identity", "identity");
1144 fail_if (identity == NULL, "Could not create identity");
1146 sink = gst_element_factory_make ("fakesink", "sink");
1147 fail_if (sink == NULL, "Could not create fakesink1");
1149 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
1151 gst_element_set_state (pipeline, GST_STATE_READY);
1152 gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
1154 /* the state change will be done on src only if the pipeline correctly resyncs
1155 * after that fakesrc has been linked to identity */
1156 gst_element_get_state (src, &state, NULL, 0);
1157 fail_unless_equals_int (state, GST_STATE_READY);
1160 gst_element_set_state (pipeline, GST_STATE_NULL);
1161 gst_object_unref (bus);
1162 gst_object_unref (pipeline);
1167 static GstBusSyncReply
1168 sync_handler_remove_sink (GstBus * bus, GstMessage * message, gpointer data)
1170 if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR) {
1173 child = gst_bin_get_by_name (GST_BIN (data), "fakesink");
1174 fail_unless (child != NULL, "Could not find fakesink");
1176 gst_bin_remove (GST_BIN (data), child);
1177 gst_object_unref (child);
1179 return GST_BUS_PASS;
1182 GST_START_TEST (test_state_failure_remove)
1184 GstElement *src, *sink, *pipeline;
1186 GstStateChangeReturn ret;
1188 pipeline = gst_pipeline_new (NULL);
1189 fail_unless (pipeline != NULL, "Could not create pipeline");
1191 src = gst_element_factory_make ("fakesrc", "fakesrc");
1192 fail_unless (src != NULL, "Could not create fakesrc");
1194 sink = gst_element_factory_make ("fakesink", "fakesink");
1195 fail_unless (sink != NULL, "Could not create fakesink");
1197 g_object_set (sink, "state-error", 1, NULL);
1199 gst_bin_add (GST_BIN (pipeline), src);
1200 gst_bin_add (GST_BIN (pipeline), sink);
1202 gst_element_link (src, sink);
1204 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1205 fail_unless (bus != NULL, "Could not get bus");
1207 gst_bus_set_sync_handler (bus, sync_handler_remove_sink, pipeline, NULL);
1209 ret = gst_element_set_state (pipeline, GST_STATE_READY);
1210 fail_unless (ret == GST_STATE_CHANGE_SUCCESS,
1211 "did not get state change success");
1213 gst_element_set_state (pipeline, GST_STATE_NULL);
1215 gst_object_unref (bus);
1216 gst_object_unref (pipeline);
1221 GST_START_TEST (test_many_bins)
1223 GstStateChangeReturn ret;
1224 GstElement *src, *sink, *pipeline, *last_bin = NULL;
1227 #define NUM_BINS 2000
1229 pipeline = gst_pipeline_new (NULL);
1230 fail_unless (pipeline != NULL, "Could not create pipeline");
1232 src = gst_element_factory_make ("fakesrc", "fakesrc");
1233 fail_unless (src != NULL, "Could not create fakesrc");
1234 g_object_set (src, "num-buffers", 3, NULL);
1236 sink = gst_element_factory_make ("fakesink", "fakesink");
1237 fail_unless (sink != NULL, "Could not create fakesink");
1239 gst_bin_add (GST_BIN (pipeline), src);
1240 gst_bin_add (GST_BIN (pipeline), sink);
1242 for (i = 0; i < NUM_BINS; ++i) {
1243 GstElement *bin, *identity;
1244 GstPad *srcpad, *sinkpad;
1246 bin = gst_bin_new (NULL);
1247 fail_unless (bin != NULL, "Could not create bin %d", i);
1248 identity = gst_element_factory_make ("identity", "identity");
1249 fail_unless (identity != NULL, "Could not create identity %d", i);
1250 g_object_set (identity, "silent", TRUE, NULL);
1251 gst_bin_add (GST_BIN (bin), identity);
1252 sinkpad = gst_element_get_static_pad (identity, "sink");
1253 srcpad = gst_element_get_static_pad (identity, "src");
1254 gst_element_add_pad (bin, gst_ghost_pad_new ("sink", sinkpad));
1255 gst_element_add_pad (bin, gst_ghost_pad_new ("src", srcpad));
1256 gst_object_unref (sinkpad);
1257 gst_object_unref (srcpad);
1259 gst_bin_add (GST_BIN (pipeline), bin);
1261 if (last_bin == NULL) {
1262 srcpad = gst_element_get_static_pad (src, "src");
1264 srcpad = gst_element_get_static_pad (last_bin, "src");
1266 sinkpad = gst_element_get_static_pad (bin, "sink");
1267 gst_pad_link_full (srcpad, sinkpad, GST_PAD_LINK_CHECK_NOTHING);
1268 gst_object_unref (sinkpad);
1269 gst_object_unref (srcpad);
1274 /* insert some queues to limit the number of function calls in a row */
1275 if ((i % 100) == 0) {
1276 GstElement *q = gst_element_factory_make ("queue", NULL);
1278 GST_LOG ("bin #%d, inserting queue", i);
1279 gst_bin_add (GST_BIN (pipeline), q);
1280 fail_unless (gst_element_link (last_bin, q));
1285 fail_unless (gst_element_link (last_bin, sink));
1287 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
1288 fail_unless_equals_int (ret, GST_STATE_CHANGE_ASYNC);
1290 for (i = 0; i < 15; ++i) {
1291 GST_INFO ("waiting for preroll ...");
1292 ret = gst_element_get_state (pipeline, NULL, NULL, GST_SECOND);
1293 if (ret != GST_STATE_CHANGE_ASYNC)
1296 fail_unless_equals_int (ret, GST_STATE_CHANGE_SUCCESS);
1298 gst_element_set_state (pipeline, GST_STATE_NULL);
1299 gst_object_unref (pipeline);
1304 static GstPadProbeReturn
1305 fakesrc_pad_blocked_cb (GstPad * pad, GstPadProbeInfo * info, void *arg)
1307 GstPipeline *pipeline = (GstPipeline *) arg;
1308 GstElement *src, *sink;
1310 src = gst_bin_get_by_name (GST_BIN (pipeline), "fakesrc");
1311 fail_unless (src != NULL, "Could not get fakesrc");
1313 sink = gst_element_factory_make ("fakesink", "fakesink");
1314 fail_unless (sink != NULL, "Could not create fakesink");
1316 g_object_set (sink, "state-error", 1, NULL);
1317 gst_bin_add (GST_BIN (pipeline), sink);
1319 gst_element_link (src, sink);
1320 gst_element_sync_state_with_parent (sink);
1321 gst_object_unref (src);
1323 return GST_PAD_PROBE_REMOVE;
1326 GST_START_TEST (test_state_failure_unref)
1328 GstElement *src, *pipeline;
1331 GstStateChangeReturn ret;
1334 pipeline = gst_pipeline_new (NULL);
1335 fail_unless (pipeline != NULL, "Could not create pipeline");
1337 src = gst_element_factory_make ("fakesrc", "fakesrc");
1338 fail_unless (src != NULL, "Could not create fakesrc");
1340 srcpad = gst_element_get_static_pad (src, "src");
1341 fail_unless (srcpad != NULL, "Could not get fakesrc srcpad");
1343 gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
1344 fakesrc_pad_blocked_cb, pipeline, NULL);
1345 gst_object_unref (srcpad);
1347 gst_bin_add (GST_BIN (pipeline), src);
1349 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1350 fail_unless (bus != NULL, "Could not get bus");
1352 gst_element_set_state (pipeline, GST_STATE_PLAYING);
1354 /* Wait for an error message from our fakesink (added from the
1355 pad block callback). */
1356 msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, GST_SECOND);
1357 fail_if (msg == NULL, "No error message within 1 second");
1358 gst_message_unref (msg);
1360 /* Check that after this failure, we can still stop, and then unref, the
1361 pipeline. This should always be possible. */
1362 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
1363 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "downward state change failed");
1365 gst_object_unref (bus);
1366 gst_object_unref (pipeline);
1372 on_sync_bus_error (GstBus * bus, GstMessage * msg)
1374 fail_if (msg != NULL);
1377 GST_START_TEST (test_state_change_skip)
1379 GstElement *sink, *pipeline;
1380 GstStateChangeReturn ret;
1383 pipeline = gst_pipeline_new (NULL);
1384 fail_unless (pipeline != NULL, "Could not create pipeline");
1386 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
1387 fail_unless (bus != NULL, "Could not get bus");
1390 gst_bus_enable_sync_message_emission (bus);
1391 g_signal_connect (bus, "sync-message::error", (GCallback) on_sync_bus_error,
1394 sink = gst_element_factory_make ("fakesink", "fakesink");
1395 fail_unless (sink != NULL, "Could not create fakesink");
1396 gst_element_set_state (sink, GST_STATE_PAUSED);
1398 g_object_set (sink, "state-error", 5, NULL);
1400 gst_bin_add (GST_BIN (pipeline), sink);
1401 gst_element_set_state (pipeline, GST_STATE_PLAYING);
1403 g_object_set (sink, "state-error", 0, NULL);
1405 /* Check that after this failure, we can still stop, and then unref, the
1406 pipeline. This should always be possible. */
1407 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
1408 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "downward state change failed");
1410 gst_object_unref (pipeline);
1411 gst_object_unref (bus);
1416 GST_START_TEST (test_duration_is_max)
1418 GstElement *bin, *src[3], *sink[3];
1419 GstStateChangeReturn state_res;
1420 GstFormat format = GST_FORMAT_BYTES;
1424 GST_INFO ("preparing test");
1426 /* build pipeline */
1427 bin = gst_pipeline_new ("pipeline");
1429 /* 3 sources, an adder and a fakesink */
1430 src[0] = gst_element_factory_make ("fakesrc", NULL);
1431 src[1] = gst_element_factory_make ("fakesrc", NULL);
1432 src[2] = gst_element_factory_make ("fakesrc", NULL);
1433 sink[0] = gst_element_factory_make ("fakesink", NULL);
1434 sink[1] = gst_element_factory_make ("fakesink", NULL);
1435 sink[2] = gst_element_factory_make ("fakesink", NULL);
1436 gst_bin_add_many (GST_BIN (bin), src[0], src[1], src[2], sink[0], sink[1],
1439 gst_element_link (src[0], sink[0]);
1440 gst_element_link (src[1], sink[1]);
1441 gst_element_link (src[2], sink[2]);
1443 /* irks, duration is reset on basesrc */
1444 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
1445 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1447 /* set durations on src */
1448 GST_BASE_SRC (src[0])->segment.duration = 1000;
1449 GST_BASE_SRC (src[1])->segment.duration = 3000;
1450 GST_BASE_SRC (src[2])->segment.duration = 2000;
1452 /* set to playing */
1453 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
1454 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1456 /* wait for completion */
1458 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
1459 GST_CLOCK_TIME_NONE);
1460 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1462 res = gst_element_query_duration (GST_ELEMENT (bin), format, &duration);
1463 fail_unless (res, NULL);
1465 ck_assert_int_eq (duration, 3000);
1467 gst_element_set_state (bin, GST_STATE_NULL);
1468 gst_object_unref (bin);
1473 GST_START_TEST (test_duration_unknown_overrides)
1475 GstElement *bin, *src[3], *sink[3];
1476 GstStateChangeReturn state_res;
1477 GstFormat format = GST_FORMAT_BYTES;
1481 GST_INFO ("preparing test");
1483 /* build pipeline */
1484 bin = gst_pipeline_new ("pipeline");
1486 /* 3 sources, an adder and a fakesink */
1487 src[0] = gst_element_factory_make ("fakesrc", NULL);
1488 src[1] = gst_element_factory_make ("fakesrc", NULL);
1489 src[2] = gst_element_factory_make ("fakesrc", NULL);
1490 sink[0] = gst_element_factory_make ("fakesink", NULL);
1491 sink[1] = gst_element_factory_make ("fakesink", NULL);
1492 sink[2] = gst_element_factory_make ("fakesink", NULL);
1493 gst_bin_add_many (GST_BIN (bin), src[0], src[1], src[2], sink[0], sink[1],
1496 gst_element_link (src[0], sink[0]);
1497 gst_element_link (src[1], sink[1]);
1498 gst_element_link (src[2], sink[2]);
1500 /* irks, duration is reset on basesrc */
1501 state_res = gst_element_set_state (bin, GST_STATE_PAUSED);
1502 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1504 /* set durations on src */
1505 GST_BASE_SRC (src[0])->segment.duration = GST_CLOCK_TIME_NONE;
1506 GST_BASE_SRC (src[1])->segment.duration = 3000;
1507 GST_BASE_SRC (src[2])->segment.duration = 2000;
1509 /* set to playing */
1510 state_res = gst_element_set_state (bin, GST_STATE_PLAYING);
1511 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1513 /* wait for completion */
1515 gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
1516 GST_CLOCK_TIME_NONE);
1517 fail_unless (state_res != GST_STATE_CHANGE_FAILURE, NULL);
1519 res = gst_element_query_duration (GST_ELEMENT (bin), format, &duration);
1520 fail_unless (res, NULL);
1522 ck_assert_int_eq (duration, GST_CLOCK_TIME_NONE);
1524 gst_element_set_state (bin, GST_STATE_NULL);
1525 gst_object_unref (bin);
1533 gst_bin_suite (void)
1535 Suite *s = suite_create ("GstBin");
1536 TCase *tc_chain = tcase_create ("bin tests");
1538 tcase_set_timeout (tc_chain, 0);
1540 suite_add_tcase (s, tc_chain);
1541 tcase_add_test (tc_chain, test_interface);
1542 tcase_add_test (tc_chain, test_eos);
1543 tcase_add_test (tc_chain, test_stream_start);
1544 tcase_add_test (tc_chain, test_children_state_change_order_flagged_sink);
1545 tcase_add_test (tc_chain, test_children_state_change_order_semi_sink);
1546 tcase_add_test (tc_chain, test_children_state_change_order_two_sink);
1547 tcase_add_test (tc_chain, test_message_state_changed);
1548 tcase_add_test (tc_chain, test_message_state_changed_child);
1549 tcase_add_test (tc_chain, test_message_state_changed_children);
1550 tcase_add_test (tc_chain, test_watch_for_state_change);
1551 tcase_add_test (tc_chain, test_state_change_error_message);
1552 tcase_add_test (tc_chain, test_add_linked);
1553 tcase_add_test (tc_chain, test_add_self);
1554 tcase_add_test (tc_chain, test_iterate_sorted);
1555 tcase_add_test (tc_chain, test_link_structure_change);
1556 tcase_add_test (tc_chain, test_state_failure_remove);
1557 tcase_add_test (tc_chain, test_state_failure_unref);
1558 tcase_add_test (tc_chain, test_state_change_skip);
1559 tcase_add_test (tc_chain, test_duration_is_max);
1560 tcase_add_test (tc_chain, test_duration_unknown_overrides);
1562 /* fails on OSX build bot for some reason, and is a bit silly anyway */
1564 tcase_add_test (tc_chain, test_many_bins);
1569 GST_CHECK_MAIN (gst_bin);