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");
89 g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
91 ret = gst_element_set_state (sink, GST_STATE_PLAYING);
92 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
94 ret = gst_element_get_state (sink, ¤t, &pending, 0);
95 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not changing state async");
96 fail_unless (current == GST_STATE_READY, "bad current state");
97 fail_unless (pending == GST_STATE_PLAYING, "bad pending state");
99 src = gst_element_factory_make ("fakesrc", "src");
100 g_object_set (G_OBJECT (src), "datarate", 200, "sizetype", 2, NULL);
101 gst_element_link (src, sink);
103 ret = gst_element_set_state (src, GST_STATE_PLAYING);
104 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
106 /* now wait for final state */
107 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
108 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to change state");
109 fail_unless (current == GST_STATE_PLAYING, "bad current state");
110 fail_unless (pending == GST_STATE_VOID_PENDING, "bad pending state");
112 ret = gst_element_set_state (sink, GST_STATE_NULL);
113 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
115 ret = gst_element_set_state (src, GST_STATE_NULL);
116 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
118 gst_object_unref (sink);
119 gst_object_unref (src);
123 /* a sink should go ASYNC to PAUSE. PAUSE should complete when
125 GST_START_TEST (test_src_sink)
127 GstElement *sink, *src, *pipeline;
128 GstStateChangeReturn ret;
129 GstState current, pending;
130 GstPad *srcpad, *sinkpad;
132 pipeline = gst_pipeline_new ("pipeline");
133 src = gst_element_factory_make ("fakesrc", "src");
134 sink = gst_element_factory_make ("fakesink", "sink");
136 gst_bin_add (GST_BIN (pipeline), src);
137 gst_bin_add (GST_BIN (pipeline), sink);
139 srcpad = gst_element_get_pad (src, "src");
140 sinkpad = gst_element_get_pad (sink, "sink");
141 gst_pad_link (srcpad, sinkpad);
142 gst_object_unref (srcpad);
143 gst_object_unref (sinkpad);
145 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
146 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
147 ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
148 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
150 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
151 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot start play");
154 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
155 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
156 fail_unless (current == GST_STATE_PLAYING, "not playing");
157 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
158 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
159 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
161 gst_object_unref (pipeline);
166 /* a pipeline with live source should return NO_PREROLL in
167 * PAUSE. When removing the live source it should return ASYNC
169 GST_START_TEST (test_livesrc_remove)
171 GstElement *sink, *src, *pipeline;
172 GstStateChangeReturn ret;
173 GstState current, pending;
174 GstPad *srcpad, *sinkpad;
176 pipeline = gst_pipeline_new ("pipeline");
177 src = gst_element_factory_make ("fakesrc", "src");
178 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
179 sink = gst_element_factory_make ("fakesink", "sink");
181 gst_bin_add (GST_BIN (pipeline), src);
182 gst_bin_add (GST_BIN (pipeline), sink);
184 srcpad = gst_element_get_pad (src, "src");
185 sinkpad = gst_element_get_pad (sink, "sink");
186 gst_pad_link (srcpad, sinkpad);
187 gst_object_unref (srcpad);
188 gst_object_unref (sinkpad);
190 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
191 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
192 "no no_preroll state return");
194 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
195 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
196 fail_unless (current == GST_STATE_PAUSED, "not paused");
197 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
199 gst_bin_remove (GST_BIN (pipeline), src);
201 ret = gst_element_get_state (pipeline, ¤t, &pending, 0);
202 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
203 fail_unless (current == GST_STATE_PAUSED, "not paused");
204 fail_unless (pending == GST_STATE_PAUSED, "not paused");
206 gst_object_unref (pipeline);
210 /* the sink should go ASYNC to PAUSE. The live source should go
211 * NO_PREROLL to PAUSE. the pipeline returns NO_PREROLL. An
212 * attempt to go to PLAYING will return ASYNC. polling state
213 * completion should return SUCCESS when the sink is gone to
215 GST_START_TEST (test_livesrc_sink)
217 GstElement *sink, *src, *pipeline;
218 GstStateChangeReturn ret;
219 GstState current, pending;
220 GstPad *srcpad, *sinkpad;
223 pipeline = gst_pipeline_new ("pipeline");
224 src = gst_element_factory_make ("fakesrc", "src");
225 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
226 sink = gst_element_factory_make ("fakesink", "sink");
228 gst_bin_add (GST_BIN (pipeline), src);
229 gst_bin_add (GST_BIN (pipeline), sink);
231 srcpad = gst_element_get_pad (src, "src");
232 sinkpad = gst_element_get_pad (sink, "sink");
233 gst_pad_link (srcpad, sinkpad);
234 gst_object_unref (srcpad);
235 gst_object_unref (sinkpad);
237 bus = gst_element_get_bus (pipeline);
239 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
240 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
241 "no no_preroll state return");
243 pop_state_change_message (bus, sink, GST_STATE_NULL, GST_STATE_READY,
244 GST_STATE_VOID_PENDING);
245 pop_state_change_message (bus, src, GST_STATE_NULL, GST_STATE_READY,
246 GST_STATE_VOID_PENDING);
247 pop_state_change_message (bus, pipeline, GST_STATE_NULL, GST_STATE_READY,
250 /* this order only holds true for live sources because they do not push
252 pop_state_change_message (bus, src, GST_STATE_READY, GST_STATE_PAUSED,
253 GST_STATE_VOID_PENDING);
254 pop_state_change_message (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
255 GST_STATE_VOID_PENDING);
257 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
258 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
259 "no no_preroll state return the second time");
261 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
262 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
263 fail_unless (current == GST_STATE_PAUSED, "not paused");
264 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
266 /* don't block here */
267 ret = gst_element_get_state (sink, ¤t, &pending, 0);
268 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
269 fail_unless (current == GST_STATE_READY, "not ready");
270 fail_unless (pending == GST_STATE_PAUSED, "not paused");
273 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
274 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
275 fail_unless (current == GST_STATE_PAUSED, "not paused");
276 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
278 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
279 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
281 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
282 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
283 fail_unless (current == GST_STATE_PLAYING, "not playing");
284 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
286 /* now we have four messages on the bus: src from paused to playing, sink from
287 ready to paused and paused to playing, and pipeline from paused to playing.
288 the pipeline message should be last, and the sink messages should go in
289 order, but the src message can be interleaved with the sink one. */
292 GstState old, new, pending;
293 gint n_src = 1, n_sink = 2;
295 while (n_src + n_sink > 0) {
296 m = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
297 fail_unless (m != NULL, "expected state change message");
298 gst_message_parse_state_changed (m, &old, &new, &pending);
299 if (GST_MESSAGE_SRC (m) == (GstObject *) src) {
300 fail_unless (n_src == 1, "already got one message from the src");
302 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
303 fail_unless (new == GST_STATE_PLAYING, "unexpected new (got %d)", new);
304 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
305 } else if (GST_MESSAGE_SRC (m) == (GstObject *) sink) {
307 fail_unless (old == GST_STATE_READY, "unexpected old");
308 fail_unless (new == GST_STATE_PAUSED, "unexpected new");
309 fail_unless (pending == GST_STATE_PLAYING, "unexpected pending");
310 } else if (n_sink == 1) {
311 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
312 fail_unless (new == GST_STATE_PLAYING, "unexpected new");
313 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
315 g_assert_not_reached ();
320 ("Unexpected state change message src %s (%d src %d sink pending)",
321 GST_OBJECT_NAME (GST_MESSAGE_SRC (m)), n_src, n_sink);
323 gst_message_unref (m);
327 pop_state_change_message (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
328 GST_STATE_VOID_PENDING);
330 gst_object_unref (bus);
331 gst_element_set_state (pipeline, GST_STATE_NULL);
332 gst_object_unref (pipeline);
337 /* The sink should go ASYNC to PLAYING. The source should go
338 * to PLAYING with SUCCESS. The pipeline returns ASYNC. */
339 GST_START_TEST (test_livesrc2_sink)
341 GstElement *sink, *src, *pipeline;
342 GstStateChangeReturn ret;
343 GstState current, pending;
344 GstPad *srcpad, *sinkpad;
346 pipeline = gst_pipeline_new ("pipeline");
347 src = gst_element_factory_make ("fakesrc", "src");
348 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
349 sink = gst_element_factory_make ("fakesink", "sink");
351 gst_bin_add (GST_BIN (pipeline), src);
352 gst_bin_add (GST_BIN (pipeline), sink);
354 srcpad = gst_element_get_pad (src, "src");
355 sinkpad = gst_element_get_pad (sink, "sink");
356 gst_pad_link (srcpad, sinkpad);
357 gst_object_unref (srcpad);
358 gst_object_unref (sinkpad);
360 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
361 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
363 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
364 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
365 fail_unless (current == GST_STATE_PLAYING, "not playing");
366 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
369 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
370 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
371 fail_unless (current == GST_STATE_PLAYING, "not playing");
372 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
375 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
376 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
377 "no no_preroll state return");
379 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
380 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
381 fail_unless (current == GST_STATE_PAUSED, "not paused");
382 fail_unless (pending == GST_STATE_VOID_PENDING, "not paused");
384 /* sink state is not known.. it might be prerolled or not */
387 ret = gst_element_set_state (pipeline, GST_STATE_READY);
388 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
390 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
391 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
392 fail_unless (current == GST_STATE_READY, "not ready");
393 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
395 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
396 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
397 fail_unless (current == GST_STATE_READY, "not ready");
398 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
403 GST_START_TEST (test_livesrc3_sink)
405 GstElement *sink, *src, *pipeline;
406 GstStateChangeReturn ret;
407 GstState current, pending;
408 GstPad *srcpad, *sinkpad;
410 pipeline = gst_pipeline_new ("pipeline");
411 src = gst_element_factory_make ("fakesrc", "src");
412 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
413 sink = gst_element_factory_make ("fakesink", "sink");
415 gst_bin_add (GST_BIN (pipeline), src);
416 gst_bin_add (GST_BIN (pipeline), sink);
418 srcpad = gst_element_get_pad (src, "src");
419 sinkpad = gst_element_get_pad (sink, "sink");
420 gst_pad_link (srcpad, sinkpad);
421 gst_object_unref (srcpad);
422 gst_object_unref (sinkpad);
424 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
425 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
428 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
429 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
430 fail_unless (current == GST_STATE_PLAYING, "not playing");
431 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
434 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
435 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
440 /* test: try changing state of sinks */
442 gst_object_suite (void)
444 Suite *s = suite_create ("Sinks");
445 TCase *tc_chain = tcase_create ("general");
447 suite_add_tcase (s, tc_chain);
448 tcase_add_test (tc_chain, test_sink);
449 tcase_add_test (tc_chain, test_sink_completion);
450 tcase_add_test (tc_chain, test_src_sink);
451 tcase_add_test (tc_chain, test_livesrc_remove);
452 tcase_add_test (tc_chain, test_livesrc_sink);
453 tcase_add_test (tc_chain, test_livesrc2_sink);
454 tcase_add_test (tc_chain, test_livesrc3_sink);
460 main (int argc, char **argv)
464 Suite *s = gst_object_suite ();
465 SRunner *sr = srunner_create (s);
467 gst_check_init (&argc, &argv);
469 srunner_run_all (sr, CK_NORMAL);
470 nf = srunner_ntests_failed (sr);