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_messages (GstBus * bus, int count)
32 GST_DEBUG ("popping %d messages", count);
33 for (i = 0; i < count; ++i) {
34 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
36 fail_unless (message && GST_MESSAGE_TYPE (message)
37 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
39 gst_message_unref (message);
41 GST_DEBUG ("popped %d messages", count);
44 GST_START_TEST (test_interface)
51 bin = GST_BIN (gst_bin_new (NULL));
52 fail_unless (bin != NULL, "Could not create bin");
54 filesrc = gst_element_factory_make ("filesrc", NULL);
55 fail_unless (filesrc != NULL, "Could not create filesrc");
56 fail_unless (GST_IS_URI_HANDLER (filesrc), "Filesrc not a URI handler");
57 gst_bin_add (bin, filesrc);
59 fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
60 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
61 fail_unless (it != NULL);
62 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
63 fail_unless (item == (gpointer) filesrc);
64 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
65 gst_iterator_free (it);
67 gst_bin_add_many (bin,
68 gst_element_factory_make ("identity", NULL),
69 gst_element_factory_make ("identity", NULL),
70 gst_element_factory_make ("identity", NULL), NULL);
71 fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
72 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
73 fail_unless (it != NULL);
74 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
75 fail_unless (item == (gpointer) filesrc);
76 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
77 gst_iterator_free (it);
80 bin = GST_BIN (gst_bin_new (NULL));
81 fail_unless (bin != NULL);
82 gst_bin_add_many (bin,
83 gst_element_factory_make ("identity", NULL),
84 gst_element_factory_make ("identity", NULL),
85 GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
86 fail_unless (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc);
87 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
88 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
89 fail_unless (item == (gpointer) filesrc);
90 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
91 gst_iterator_free (it);
93 gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL));
94 gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
95 it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
96 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
97 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
98 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
99 fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
100 gst_iterator_free (it);
102 gst_object_unref (bin);
107 GST_START_TEST (test_message_state_changed)
113 bin = GST_BIN (gst_bin_new (NULL));
114 fail_unless (bin != NULL, "Could not create bin");
115 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
117 bus = GST_ELEMENT_BUS (bin);
119 /* change state, spawning a message, causing an incref on the bin */
120 gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
122 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
124 /* get and unref the message, causing a decref on the bin */
125 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
127 fail_unless (message && GST_MESSAGE_TYPE (message)
128 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
130 gst_message_unref (message);
132 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
135 gst_object_unref (bin);
140 GST_START_TEST (test_message_state_changed_child)
147 bin = GST_BIN (gst_bin_new (NULL));
148 fail_unless (bin != NULL, "Could not create bin");
149 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
151 src = gst_element_factory_make ("fakesrc", NULL);
152 fail_if (src == NULL, "Could not create fakesrc");
153 gst_bin_add (bin, src);
154 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
155 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
157 bus = GST_ELEMENT_BUS (bin);
159 /* change state, spawning two messages:
160 * - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
161 * - second for bin, causing an incref on the bin */
162 GST_DEBUG ("setting bin to READY");
163 fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY)
164 == GST_STATE_CHANGE_SUCCESS);
166 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
167 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
169 /* get and unref the message, causing a decref on the src */
170 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
171 fail_unless (message && GST_MESSAGE_TYPE (message)
172 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
174 fail_unless (message->src == GST_OBJECT (src));
175 gst_message_unref (message);
177 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
178 ASSERT_OBJECT_REFCOUNT (bin, "bin", 2);
180 /* get and unref message 2, causing a decref on the bin */
181 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
182 fail_unless (message && GST_MESSAGE_TYPE (message)
183 == GST_MESSAGE_STATE_CHANGED, "did not get GST_MESSAGE_STATE_CHANGED");
185 fail_unless (message->src == GST_OBJECT (bin));
186 gst_message_unref (message);
188 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
189 ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
192 gst_object_unref (bin);
197 GST_START_TEST (test_message_state_changed_children)
199 GstPipeline *pipeline;
200 GstElement *src, *sink;
203 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
204 fail_unless (pipeline != NULL, "Could not create pipeline");
205 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
207 src = gst_element_factory_make ("fakesrc", NULL);
208 fail_if (src == NULL, "Could not create fakesrc");
209 /* need to silence the element as the deep_notify refcounts the
210 * parents while running */
211 g_object_set (G_OBJECT (src), "silent", TRUE, NULL);
212 gst_bin_add (GST_BIN (pipeline), src);
214 sink = gst_element_factory_make ("fakesink", NULL);
215 /* need to silence the element as the deep_notify refcounts the
216 * parents while running */
217 g_object_set (G_OBJECT (sink), "silent", TRUE, NULL);
218 fail_if (sink == NULL, "Could not create fakesink");
219 gst_bin_add (GST_BIN (pipeline), sink);
221 fail_unless (gst_element_link (src, sink), "could not link src and sink");
223 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
224 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
225 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
227 bus = GST_ELEMENT_BUS (pipeline);
229 /* change state to READY, spawning three messages */
230 GST_DEBUG ("setting pipeline to READY");
231 fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
232 == GST_STATE_CHANGE_SUCCESS);
234 /* each object is referenced by a message */
235 ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
236 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
237 ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
238 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
240 pop_messages (bus, 3);
241 fail_if ((gst_bus_pop (bus)) != NULL);
243 ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
244 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
245 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
246 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
248 /* change state to PAUSED, spawning three messages */
249 GST_DEBUG ("setting pipeline to PAUSED");
250 fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED)
251 == GST_STATE_CHANGE_SUCCESS);
253 /* each object is referenced by a message;
254 * base_sink_chain has taken a refcount on the sink, and is blocked on
256 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
257 ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
258 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
260 pop_messages (bus, 3);
261 fail_if ((gst_bus_pop (bus)) != NULL);
263 ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
264 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
265 ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
266 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
268 /* change state to PLAYING, spawning three messages */
269 GST_DEBUG ("setting pipeline to PLAYING");
270 fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING)
271 == GST_STATE_CHANGE_SUCCESS);
273 /* each object is referenced by one message
274 * sink might have an extra reference if it's still blocked on preroll */
275 ASSERT_OBJECT_REFCOUNT (src, "src", 2);
276 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3);
277 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
279 pop_messages (bus, 3);
280 fail_if ((gst_bus_pop (bus)) != NULL);
282 ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
283 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
284 /* sink might have an extra reference if it's still blocked on preroll */
285 ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
286 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
288 /* go back to READY, spawning six messages */
289 GST_DEBUG ("setting pipeline to READY");
290 fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY)
291 == GST_STATE_CHANGE_SUCCESS);
293 /* each object is referenced by two messages */
294 ASSERT_OBJECT_REFCOUNT (src, "src", 3);
295 ASSERT_OBJECT_REFCOUNT (sink, "sink", 3);
296 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3);
298 pop_messages (bus, 6);
299 fail_if ((gst_bus_pop (bus)) != NULL);
301 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
302 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
303 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
305 /* setting pipeline to NULL flushes the bus automatically */
306 fail_unless (gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL)
307 == GST_STATE_CHANGE_SUCCESS);
309 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
310 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
311 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
314 gst_object_unref (pipeline);
319 GST_START_TEST (test_watch_for_state_change)
321 GstElement *src, *sink, *bin;
324 bin = gst_element_factory_make ("bin", NULL);
325 fail_unless (bin != NULL, "Could not create bin");
327 src = gst_element_factory_make ("fakesrc", NULL);
328 fail_if (src == NULL, "Could not create fakesrc");
329 sink = gst_element_factory_make ("fakesink", NULL);
330 fail_if (sink == NULL, "Could not create fakesink");
332 gst_bin_add (GST_BIN (bin), sink);
333 gst_bin_add (GST_BIN (bin), src);
335 fail_unless (gst_element_link (src, sink), "could not link src and sink");
337 bus = GST_ELEMENT_BUS (bin);
339 /* change state, spawning two times three messages, minus one async */
340 fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED)
341 == GST_STATE_CHANGE_ASYNC);
343 pop_messages (bus, 5);
345 fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
346 "Unexpected messages on bus");
348 gst_bin_watch_for_state_change (GST_BIN (bin));
350 /* should get the bin's state change message now */
351 pop_messages (bus, 1);
353 fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
354 "Unexpected messages on bus");
356 fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING)
357 == GST_STATE_CHANGE_SUCCESS);
359 pop_messages (bus, 3);
361 /* this one might return either SUCCESS or ASYNC, likely SUCCESS */
362 gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
364 gst_bin_watch_for_state_change (GST_BIN (bin));
366 pop_messages (bus, 3);
368 fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
369 "Unexpected messages on bus");
371 /* setting bin to NULL flushes the bus automatically */
372 fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL)
373 == GST_STATE_CHANGE_SUCCESS);
376 gst_object_unref (bin);
381 /* adding an element with linked pads to a bin unlinks the
383 GST_START_TEST (test_add_linked)
385 GstElement *src, *sink;
386 GstPad *srcpad, *sinkpad;
387 GstElement *pipeline;
389 pipeline = gst_pipeline_new (NULL);
390 fail_unless (pipeline != NULL, "Could not create pipeline");
392 src = gst_element_factory_make ("fakesrc", NULL);
393 fail_if (src == NULL, "Could not create fakesrc");
394 sink = gst_element_factory_make ("fakesink", NULL);
395 fail_if (sink == NULL, "Could not create fakesink");
397 srcpad = gst_element_get_pad (src, "src");
398 fail_unless (srcpad != NULL);
399 sinkpad = gst_element_get_pad (sink, "sink");
400 fail_unless (sinkpad != NULL);
402 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
404 /* pads are linked now */
405 fail_unless (gst_pad_is_linked (srcpad));
406 fail_unless (gst_pad_is_linked (sinkpad));
408 /* adding element to bin voids hierarchy so pads are unlinked */
409 gst_bin_add (GST_BIN (pipeline), src);
411 /* check if pads really are unlinked */
412 fail_unless (!gst_pad_is_linked (srcpad));
413 fail_unless (!gst_pad_is_linked (sinkpad));
415 /* cannot link pads in wrong hierarchy */
416 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_WRONG_HIERARCHY);
418 /* adding other element to bin as well */
419 gst_bin_add (GST_BIN (pipeline), sink);
421 /* now we can link again */
422 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
424 /* check if pads really are linked */
425 fail_unless (gst_pad_is_linked (srcpad));
426 fail_unless (gst_pad_is_linked (sinkpad));
428 gst_object_unref (srcpad);
429 gst_object_unref (sinkpad);
430 gst_object_unref (pipeline);
435 /* g_print ("%10s: %4d => %4d\n", GST_OBJECT_NAME (msg->src), old, new); */
437 #define ASSERT_STATE_CHANGE_MSG(bus,element,old_state,new_state,num) \
440 GstState old = 0, new = 0; \
441 msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); \
442 fail_if (msg == NULL, "No state change message within 1 second (#" \
443 G_STRINGIFY (num) ")"); \
444 gst_message_parse_state_changed (msg, &old, &new); \
445 fail_if (msg->src != GST_OBJECT (element), G_STRINGIFY(element) \
446 " should have changed state next (#" G_STRINGIFY (num) ")"); \
447 fail_if (old != old_state || new != new_state, "state change is not " \
448 G_STRINGIFY (old_state) " => " G_STRINGIFY (new_state)); \
449 gst_message_unref (msg); \
452 GST_START_TEST (test_children_state_change_order_flagged_sink)
454 GstElement *src, *identity, *sink, *pipeline;
455 GstStateChangeReturn ret;
458 pipeline = gst_pipeline_new (NULL);
459 fail_unless (pipeline != NULL, "Could not create pipeline");
461 bus = GST_ELEMENT_BUS (pipeline);
462 fail_unless (bus != NULL, "Pipeline has no bus?!");
464 src = gst_element_factory_make ("fakesrc", NULL);
465 fail_if (src == NULL, "Could not create fakesrc");
467 identity = gst_element_factory_make ("identity", NULL);
468 fail_if (identity == NULL, "Could not create identity");
470 sink = gst_element_factory_make ("fakesink", NULL);
471 fail_if (sink == NULL, "Could not create fakesink");
473 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
475 fail_unless (gst_element_link (src, identity) == TRUE);
476 fail_unless (gst_element_link (identity, sink) == TRUE);
478 /* (1) Test state change with fakesink being a regular sink */
479 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
480 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
483 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 101);
484 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 102);
485 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 103);
486 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 104);
488 /* READY => PAUSED */
489 /* because of pre-rolling, sink will return ASYNC on state
490 * change and change state later when it has a buffer */
491 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
493 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 106);
494 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
495 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
498 /* PAUSED => PLAYING */
499 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 109);
500 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
502 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 111);
503 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
506 /* don't set to NULL that will set the bus flushing and kill our messages */
507 ret = gst_element_set_state (pipeline, GST_STATE_READY);
508 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
510 /* TODO: do we need to check downwards state change order as well? */
511 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
512 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
514 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
515 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
516 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
518 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
519 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
521 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
522 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
523 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
525 gst_object_unref (pipeline);
531 GST_START_TEST (test_children_state_change_order_semi_sink)
533 GstElement *src, *identity, *sink, *pipeline;
534 GstStateChangeReturn ret;
537 /* (2) Now again, but check other code path where we don't have
538 * a proper sink correctly flagged as such, but a 'semi-sink' */
539 pipeline = gst_pipeline_new (NULL);
540 fail_unless (pipeline != NULL, "Could not create pipeline");
542 bus = GST_ELEMENT_BUS (pipeline);
543 fail_unless (bus != NULL, "Pipeline has no bus?!");
545 src = gst_element_factory_make ("fakesrc", NULL);
546 fail_if (src == NULL, "Could not create fakesrc");
548 identity = gst_element_factory_make ("identity", NULL);
549 fail_if (identity == NULL, "Could not create identity");
551 sink = gst_element_factory_make ("fakesink", NULL);
552 fail_if (sink == NULL, "Could not create fakesink");
554 gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
556 fail_unless (gst_element_link (src, identity) == TRUE);
557 fail_unless (gst_element_link (identity, sink) == TRUE);
559 GST_FLAG_UNSET (sink, GST_ELEMENT_IS_SINK); /* <======== */
561 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
562 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
565 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 201);
566 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 202);
567 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 203);
568 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 204);
570 /* READY => PAUSED */
571 /* because of pre-rolling, sink will return ASYNC on state
572 * change and change state later when it has a buffer */
573 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
575 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
576 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
577 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
580 /* PAUSED => PLAYING */
581 ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 209);
582 ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
584 ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 211);
585 ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
588 /* don't set to NULL that will set the bus flushing and kill our messages */
589 ret = gst_element_set_state (pipeline, GST_STATE_READY);
590 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
592 /* TODO: do we need to check downwards state change order as well? */
593 pop_messages (bus, 4); /* pop playing => paused messages off the bus */
594 pop_messages (bus, 4); /* pop paused => ready messages off the bus */
596 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
597 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
598 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
600 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
601 fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
603 ASSERT_OBJECT_REFCOUNT (src, "src", 1);
604 ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
605 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
607 gst_object_unref (pipeline);
615 Suite *s = suite_create ("GstBin");
616 TCase *tc_chain = tcase_create ("bin tests");
618 suite_add_tcase (s, tc_chain);
619 tcase_add_test (tc_chain, test_interface);
620 tcase_add_test (tc_chain, test_children_state_change_order_flagged_sink);
621 tcase_add_test (tc_chain, test_children_state_change_order_semi_sink);
622 tcase_add_test (tc_chain, test_message_state_changed);
623 tcase_add_test (tc_chain, test_message_state_changed_child);
624 tcase_add_test (tc_chain, test_message_state_changed_children);
625 tcase_add_test (tc_chain, test_watch_for_state_change);
626 tcase_add_test (tc_chain, test_add_linked);
632 main (int argc, char **argv)
636 Suite *s = gst_bin_suite ();
637 SRunner *sr = srunner_create (s);
639 gst_check_init (&argc, &argv);
641 srunner_run_all (sr, CK_NORMAL);
642 nf = srunner_ntests_failed (sr);