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_object_ref (src);
182 gst_bin_add (GST_BIN (pipeline), src);
183 gst_bin_add (GST_BIN (pipeline), sink);
185 srcpad = gst_element_get_pad (src, "src");
186 sinkpad = gst_element_get_pad (sink, "sink");
187 gst_pad_link (srcpad, sinkpad);
188 gst_object_unref (srcpad);
189 gst_object_unref (sinkpad);
191 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
192 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
193 "no no_preroll state return");
195 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
196 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
197 fail_unless (current == GST_STATE_PAUSED, "not paused");
198 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
200 gst_bin_remove (GST_BIN (pipeline), src);
202 ret = gst_element_set_state (src, GST_STATE_NULL);
203 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "async going to null");
204 gst_object_unref (src);
206 ret = gst_element_get_state (pipeline, ¤t, &pending, 0);
207 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
208 fail_unless (current == GST_STATE_PAUSED, "not paused");
209 fail_unless (pending == GST_STATE_PAUSED, "not paused");
211 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
212 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "async going to null");
213 gst_object_unref (pipeline);
217 /* the sink should go ASYNC to PAUSE. The live source should go
218 * NO_PREROLL to PAUSE. the pipeline returns NO_PREROLL. An
219 * attempt to go to PLAYING will return ASYNC. polling state
220 * completion should return SUCCESS when the sink is gone to
222 GST_START_TEST (test_livesrc_sink)
224 GstElement *sink, *src, *pipeline;
225 GstStateChangeReturn ret;
226 GstState current, pending;
227 GstPad *srcpad, *sinkpad;
230 pipeline = gst_pipeline_new ("pipeline");
231 src = gst_element_factory_make ("fakesrc", "src");
232 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
233 sink = gst_element_factory_make ("fakesink", "sink");
235 gst_bin_add (GST_BIN (pipeline), src);
236 gst_bin_add (GST_BIN (pipeline), sink);
238 srcpad = gst_element_get_pad (src, "src");
239 sinkpad = gst_element_get_pad (sink, "sink");
240 gst_pad_link (srcpad, sinkpad);
241 gst_object_unref (srcpad);
242 gst_object_unref (sinkpad);
244 bus = gst_element_get_bus (pipeline);
246 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
247 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
248 "no no_preroll state return");
250 pop_state_change_message (bus, sink, GST_STATE_NULL, GST_STATE_READY,
251 GST_STATE_VOID_PENDING);
252 pop_state_change_message (bus, src, GST_STATE_NULL, GST_STATE_READY,
253 GST_STATE_VOID_PENDING);
254 pop_state_change_message (bus, pipeline, GST_STATE_NULL, GST_STATE_READY,
257 /* this order only holds true for live sources because they do not push
259 pop_state_change_message (bus, src, GST_STATE_READY, GST_STATE_PAUSED,
260 GST_STATE_VOID_PENDING);
261 pop_state_change_message (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
262 GST_STATE_VOID_PENDING);
264 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
265 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
266 "no no_preroll state return the second time");
268 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
269 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
270 fail_unless (current == GST_STATE_PAUSED, "not paused");
271 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
273 /* don't block here */
274 ret = gst_element_get_state (sink, ¤t, &pending, 0);
275 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
276 fail_unless (current == GST_STATE_READY, "not ready");
277 fail_unless (pending == GST_STATE_PAUSED, "not paused");
280 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
281 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
282 fail_unless (current == GST_STATE_PAUSED, "not paused");
283 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
285 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
286 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
288 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
289 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
290 fail_unless (current == GST_STATE_PLAYING, "not playing");
291 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
293 /* now we have four messages on the bus: src from paused to playing, sink from
294 ready to paused and paused to playing, and pipeline from paused to playing.
295 the pipeline message should be last, and the sink messages should go in
296 order, but the src message can be interleaved with the sink one. */
299 GstState old, new, pending;
300 gint n_src = 1, n_sink = 2;
302 while (n_src + n_sink > 0) {
303 m = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
304 fail_unless (m != NULL, "expected state change message");
305 gst_message_parse_state_changed (m, &old, &new, &pending);
306 if (GST_MESSAGE_SRC (m) == (GstObject *) src) {
307 fail_unless (n_src == 1, "already got one message from the src");
309 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
310 fail_unless (new == GST_STATE_PLAYING, "unexpected new (got %d)", new);
311 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
312 } else if (GST_MESSAGE_SRC (m) == (GstObject *) sink) {
314 fail_unless (old == GST_STATE_READY, "unexpected old");
315 fail_unless (new == GST_STATE_PAUSED, "unexpected new");
316 fail_unless (pending == GST_STATE_PLAYING, "unexpected pending");
317 } else if (n_sink == 1) {
318 fail_unless (old == GST_STATE_PAUSED, "unexpected old");
319 fail_unless (new == GST_STATE_PLAYING, "unexpected new");
320 fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
322 g_assert_not_reached ();
327 ("Unexpected state change message src %s (%d src %d sink pending)",
328 GST_OBJECT_NAME (GST_MESSAGE_SRC (m)), n_src, n_sink);
330 gst_message_unref (m);
334 pop_state_change_message (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
335 GST_STATE_VOID_PENDING);
337 gst_object_unref (bus);
338 gst_element_set_state (pipeline, GST_STATE_NULL);
339 gst_object_unref (pipeline);
344 /* The sink should go ASYNC to PLAYING. The source should go
345 * to PLAYING with SUCCESS. The pipeline returns ASYNC. */
346 GST_START_TEST (test_livesrc2_sink)
348 GstElement *sink, *src, *pipeline;
349 GstStateChangeReturn ret;
350 GstState current, pending;
351 GstPad *srcpad, *sinkpad;
353 pipeline = gst_pipeline_new ("pipeline");
354 src = gst_element_factory_make ("fakesrc", "src");
355 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
356 sink = gst_element_factory_make ("fakesink", "sink");
358 gst_bin_add (GST_BIN (pipeline), src);
359 gst_bin_add (GST_BIN (pipeline), sink);
361 srcpad = gst_element_get_pad (src, "src");
362 sinkpad = gst_element_get_pad (sink, "sink");
363 gst_pad_link (srcpad, sinkpad);
364 gst_object_unref (srcpad);
365 gst_object_unref (sinkpad);
367 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
368 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
370 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
371 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
372 fail_unless (current == GST_STATE_PLAYING, "not playing");
373 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
376 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
377 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
378 fail_unless (current == GST_STATE_PLAYING, "not playing");
379 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
382 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
383 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
384 "no no_preroll state return");
386 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
387 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
388 fail_unless (current == GST_STATE_PAUSED, "not paused");
389 fail_unless (pending == GST_STATE_VOID_PENDING, "not paused");
391 /* sink state is not known.. it might be prerolled or not */
394 ret = gst_element_set_state (pipeline, GST_STATE_READY);
395 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
397 ret = gst_element_get_state (src, ¤t, &pending, GST_CLOCK_TIME_NONE);
398 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
399 fail_unless (current == GST_STATE_READY, "not ready");
400 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
402 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
403 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
404 fail_unless (current == GST_STATE_READY, "not ready");
405 fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
407 /* And destroy. Must be NULL */
408 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
409 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
410 gst_object_unref (pipeline);
415 GST_START_TEST (test_livesrc3_sink)
417 GstElement *sink, *src, *pipeline;
418 GstStateChangeReturn ret;
419 GstState current, pending;
420 GstPad *srcpad, *sinkpad;
422 pipeline = gst_pipeline_new ("pipeline");
423 src = gst_element_factory_make ("fakesrc", "src");
424 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
425 sink = gst_element_factory_make ("fakesink", "sink");
427 gst_bin_add (GST_BIN (pipeline), src);
428 gst_bin_add (GST_BIN (pipeline), sink);
430 srcpad = gst_element_get_pad (src, "src");
431 sinkpad = gst_element_get_pad (sink, "sink");
432 gst_pad_link (srcpad, sinkpad);
433 gst_object_unref (srcpad);
434 gst_object_unref (sinkpad);
436 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
437 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
440 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
441 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
442 fail_unless (current == GST_STATE_PLAYING, "not playing");
443 fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
446 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
447 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
448 gst_object_unref (pipeline);
453 /* test: try changing state of sinks */
455 gst_sinks_suite (void)
457 Suite *s = suite_create ("Sinks");
458 TCase *tc_chain = tcase_create ("general");
460 suite_add_tcase (s, tc_chain);
461 tcase_add_test (tc_chain, test_sink);
462 tcase_add_test (tc_chain, test_sink_completion);
463 tcase_add_test (tc_chain, test_src_sink);
464 tcase_add_test (tc_chain, test_livesrc_remove);
465 tcase_add_test (tc_chain, test_livesrc_sink);
466 tcase_add_test (tc_chain, test_livesrc2_sink);
467 tcase_add_test (tc_chain, test_livesrc3_sink);
472 GST_CHECK_MAIN (gst_sinks);