5 * Copyright (C) <2005> Wim Taymans <wim at fluendo dot com>
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_state_change_message (GstBus * bus, GstElement * src, GstState old,
27 GstState new, GstState pending)
29 GstMessage *message = NULL;
30 GstState _old, _new, _pending;
32 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
33 fail_unless (message != NULL,
34 "Expected state change message, but got nothing");
36 gst_message_parse_state_changed (message, &_old, &_new, &_pending);
38 fail_unless (GST_MESSAGE_SRC (message) == (GstObject *) src,
39 "Unexpected state change order");
40 fail_unless (old == _old, "Unexpected old state");
41 fail_unless (new == _new, "Unexpected new state");
42 fail_unless (pending == _pending, "Unexpected pending state");
44 gst_message_unref (message);
47 /* a sink should go ASYNC to PAUSE. forcing PLAYING is possible */
48 GST_START_TEST (test_sink)
51 GstStateChangeReturn ret;
52 GstState current, pending;
54 sink = gst_element_factory_make ("fakesink", "sink");
56 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
57 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
59 ret = gst_element_set_state (sink, GST_STATE_PLAYING);
60 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no forced async state change");
62 ret = gst_element_get_state (sink, ¤t, &pending, 0);
63 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not changing state async");
64 fail_unless (current == GST_STATE_READY, "bad current state");
65 fail_unless (pending == GST_STATE_PLAYING, "bad pending state");
67 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
68 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async going back to paused");
70 ret = gst_element_set_state (sink, GST_STATE_READY);
71 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to ready");
73 ret = gst_element_set_state (sink, GST_STATE_NULL);
74 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
76 gst_object_unref (sink);
80 /* a sink should go ASYNC to PAUSE and PLAYING, when linking a src, it
81 * should complete the state change. */
82 GST_START_TEST (test_sink_completion)
84 GstElement *sink, *src;
85 GstStateChangeReturn ret;
86 GstState current, pending;
88 sink = gst_element_factory_make ("fakesink", "sink");
90 ret = gst_element_set_state (sink, GST_STATE_PLAYING);
91 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
93 ret = gst_element_get_state (sink, ¤t, &pending, 0);
94 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not changing state async");
95 fail_unless (current == GST_STATE_READY, "bad current state");
96 fail_unless (pending == GST_STATE_PLAYING, "bad pending state");
98 src = gst_element_factory_make ("fakesrc", "src");
99 gst_element_link (src, sink);
101 ret = gst_element_set_state (src, GST_STATE_PLAYING);
102 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
104 /* now wait for final state */
105 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
106 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to change state");
107 fail_unless (current == GST_STATE_PLAYING, "bad current state");
108 fail_unless (pending == GST_STATE_VOID_PENDING, "bad pending state");
110 ret = gst_element_set_state (sink, GST_STATE_NULL);
111 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
113 ret = gst_element_set_state (src, GST_STATE_NULL);
114 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
116 gst_object_unref (sink);
117 gst_object_unref (src);
121 /* a sink should go ASYNC to PAUSE. PAUSE should complete when
123 GST_START_TEST (test_src_sink)
125 GstElement *sink, *src, *pipeline;
126 GstStateChangeReturn ret;
127 GstState current, pending;
128 GstPad *srcpad, *sinkpad;
130 pipeline = gst_pipeline_new ("pipeline");
131 src = gst_element_factory_make ("fakesrc", "src");
132 sink = gst_element_factory_make ("fakesink", "sink");
134 gst_bin_add (GST_BIN (pipeline), src);
135 gst_bin_add (GST_BIN (pipeline), sink);
137 srcpad = gst_element_get_pad (src, "src");
138 sinkpad = gst_element_get_pad (sink, "sink");
139 gst_pad_link (srcpad, sinkpad);
140 gst_object_unref (srcpad);
141 gst_object_unref (sinkpad);
143 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
144 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
145 ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
146 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
148 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
149 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot start play");
152 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
153 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
154 fail_unless (current == GST_STATE_PLAYING, "not playing");
155 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
156 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
157 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
159 gst_object_unref (pipeline);
164 /* a pipeline with live source should return NO_PREROLL in
165 * PAUSE. When removing the live source it should return ASYNC
167 GST_START_TEST (test_livesrc_remove)
169 GstElement *sink, *src, *pipeline;
170 GstStateChangeReturn ret;
171 GstState current, pending;
172 GstPad *srcpad, *sinkpad;
174 pipeline = gst_pipeline_new ("pipeline");
175 src = gst_element_factory_make ("fakesrc", "src");
176 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
177 sink = gst_element_factory_make ("fakesink", "sink");
179 gst_bin_add (GST_BIN (pipeline), src);
180 gst_bin_add (GST_BIN (pipeline), sink);
182 srcpad = gst_element_get_pad (src, "src");
183 sinkpad = gst_element_get_pad (sink, "sink");
184 gst_pad_link (srcpad, sinkpad);
185 gst_object_unref (srcpad);
186 gst_object_unref (sinkpad);
188 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
189 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
190 "no no_preroll state return");
192 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
193 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
194 fail_unless (current == GST_STATE_PAUSED, "not paused");
195 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
197 gst_bin_remove (GST_BIN (pipeline), src);
199 ret = gst_element_get_state (pipeline, ¤t, &pending, 0);
200 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
201 fail_unless (current == GST_STATE_PAUSED, "not paused");
202 fail_unless (pending == GST_STATE_PAUSED, "not paused");
206 /* the sink should go ASYNC to PAUSE. The live source should go
207 * NO_PREROLL to PAUSE. the pipeline returns NO_PREROLL. An
208 * attempt to go to PLAYING will return ASYNC. polling state
209 * completion should return SUCCESS when the sink is gone to
211 GST_START_TEST (test_livesrc_sink)
213 GstElement *sink, *src, *pipeline;
214 GstStateChangeReturn ret;
215 GstState current, pending;
216 GstPad *srcpad, *sinkpad;
219 pipeline = gst_pipeline_new ("pipeline");
220 src = gst_element_factory_make ("fakesrc", "src");
221 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
222 sink = gst_element_factory_make ("fakesink", "sink");
224 gst_bin_add (GST_BIN (pipeline), src);
225 gst_bin_add (GST_BIN (pipeline), sink);
227 srcpad = gst_element_get_pad (src, "src");
228 sinkpad = gst_element_get_pad (sink, "sink");
229 gst_pad_link (srcpad, sinkpad);
230 gst_object_unref (srcpad);
231 gst_object_unref (sinkpad);
233 bus = gst_element_get_bus (pipeline);
235 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
236 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
237 "no no_preroll state return");
239 pop_state_change_message (bus, sink, GST_STATE_NULL, GST_STATE_READY,
240 GST_STATE_VOID_PENDING);
241 pop_state_change_message (bus, src, GST_STATE_NULL, GST_STATE_READY,
242 GST_STATE_VOID_PENDING);
243 pop_state_change_message (bus, pipeline, GST_STATE_NULL, GST_STATE_READY,
246 /* this order only holds true for live sources because they do not push
248 pop_state_change_message (bus, src, GST_STATE_READY, GST_STATE_PAUSED,
249 GST_STATE_VOID_PENDING);
250 pop_state_change_message (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
251 GST_STATE_VOID_PENDING);
253 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
254 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
255 "no no_preroll state return the second time");
257 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
258 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
259 fail_unless (current == GST_STATE_PAUSED, "not paused");
260 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
262 /* don't block here */
263 ret = gst_element_get_state (sink, ¤t, &pending, 0);
264 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
265 fail_unless (current == GST_STATE_READY, "not ready");
266 fail_unless (pending == GST_STATE_PAUSED, "not paused");
269 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
270 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
271 fail_unless (current == GST_STATE_PAUSED, "not paused");
272 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
274 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
275 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
277 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
278 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
279 fail_unless (current == GST_STATE_PLAYING, "not playing");
280 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
282 #ifdef WIM_EARNS_HIS_KEEP
283 /* now we have four messages on the bus: src from paused to playing, sink from
284 ready to paused and paused to playing, and pipeline from paused to playing.
285 the pipeline message should be last, and the sink messages should go in
286 order, but the src message can be interleaved with the sink one. */
289 GstState old, new, pending;
290 gint n_src = 1, n_sink = 2;
292 while (n_src + n_sink > 0) {
293 m = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
294 fail_unless (m != NULL, "expected state change message");
295 gst_message_parse_state_changed (m, &old, &new, &pending);
296 if (GST_MESSAGE_SRC (m) == (GstObject *) src) {
297 fail_unless (n_src == 1, "already got one message from the src");
299 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
300 fail_unless (new == GST_STATE_PLAYING, "unexpected new (got %d)", new);
301 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
302 } else if (GST_MESSAGE_SRC (m) == (GstObject *) sink) {
304 fail_unless (old == GST_STATE_READY, "unexpected old");
305 fail_unless (new == GST_STATE_PAUSED, "unexpected new");
306 fail_unless (pending == GST_STATE_PLAYING, "unexpected pending");
307 } else if (n_sink == 1) {
308 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
309 fail_unless (new == GST_STATE_PLAYING, "unexpected new");
310 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
312 g_assert_not_reached ();
317 ("Unexpected state change message src %s (%d src %d sink pending)",
318 GST_OBJECT_NAME (GST_MESSAGE_SRC (m)), n_src, n_sink);
320 gst_message_unref (m);
324 pop_state_change_message (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
325 GST_STATE_VOID_PENDING);
328 gst_object_unref (bus);
329 gst_element_set_state (pipeline, GST_STATE_NULL);
330 gst_object_unref (pipeline);
335 /* The sink should go ASYNC to PLAYING. The source should go
336 * to PLAYING with SUCCESS. The pipeline returns ASYNC. */
337 GST_START_TEST (test_livesrc2_sink)
339 GstElement *sink, *src, *pipeline;
340 GstStateChangeReturn ret;
341 GstState current, pending;
342 GstPad *srcpad, *sinkpad;
344 pipeline = gst_pipeline_new ("pipeline");
345 src = gst_element_factory_make ("fakesrc", "src");
346 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
347 sink = gst_element_factory_make ("fakesink", "sink");
349 gst_bin_add (GST_BIN (pipeline), src);
350 gst_bin_add (GST_BIN (pipeline), sink);
352 srcpad = gst_element_get_pad (src, "src");
353 sinkpad = gst_element_get_pad (sink, "sink");
354 gst_pad_link (srcpad, sinkpad);
355 gst_object_unref (srcpad);
356 gst_object_unref (sinkpad);
358 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
359 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
361 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
362 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
363 fail_unless (current == GST_STATE_PLAYING, "not playing");
364 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
367 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
368 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
369 fail_unless (current == GST_STATE_PLAYING, "not playing");
370 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
373 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
374 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
375 "no no_preroll state return");
377 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
378 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
379 fail_unless (current == GST_STATE_PAUSED, "not paused");
380 fail_unless (pending == GST_STATE_VOID_PENDING, "not paused");
382 /* sink state is not known.. it might be prerolled or not */
385 ret = gst_element_set_state (pipeline, GST_STATE_READY);
386 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
388 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
389 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
390 fail_unless (current == GST_STATE_READY, "not ready");
391 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
393 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
394 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
395 fail_unless (current == GST_STATE_READY, "not ready");
396 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
401 GST_START_TEST (test_livesrc3_sink)
403 GstElement *sink, *src, *pipeline;
404 GstStateChangeReturn ret;
405 GstState current, pending;
406 GstPad *srcpad, *sinkpad;
408 pipeline = gst_pipeline_new ("pipeline");
409 src = gst_element_factory_make ("fakesrc", "src");
410 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
411 sink = gst_element_factory_make ("fakesink", "sink");
413 gst_bin_add (GST_BIN (pipeline), src);
414 gst_bin_add (GST_BIN (pipeline), sink);
416 srcpad = gst_element_get_pad (src, "src");
417 sinkpad = gst_element_get_pad (sink, "sink");
418 gst_pad_link (srcpad, sinkpad);
419 gst_object_unref (srcpad);
420 gst_object_unref (sinkpad);
422 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
423 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
426 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
427 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
428 fail_unless (current == GST_STATE_PLAYING, "not playing");
429 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
432 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
433 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
438 /* test: try changing state of sinks */
440 gst_object_suite (void)
442 Suite *s = suite_create ("Sinks");
443 TCase *tc_chain = tcase_create ("general");
445 suite_add_tcase (s, tc_chain);
446 tcase_add_test (tc_chain, test_sink);
447 tcase_add_test (tc_chain, test_sink_completion);
448 tcase_add_test (tc_chain, test_src_sink);
449 tcase_add_test (tc_chain, test_livesrc_remove);
450 tcase_add_test (tc_chain, test_livesrc_sink);
451 tcase_add_test (tc_chain, test_livesrc2_sink);
452 tcase_add_test (tc_chain, test_livesrc3_sink);
458 main (int argc, char **argv)
462 Suite *s = gst_object_suite ();
463 SRunner *sr = srunner_create (s);
465 gst_check_init (&argc, &argv);
467 srunner_run_all (sr, CK_NORMAL);
468 nf = srunner_ntests_failed (sr);