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_static_pad (src, "src");
140 sinkpad = gst_element_get_static_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_static_pad (src, "src");
186 sinkpad = gst_element_get_static_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_static_pad (src, "src");
239 sinkpad = gst_element_get_static_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_VOID_PENDING, "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_static_pad (src, "src");
362 sinkpad = gst_element_get_static_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_static_pad (src, "src");
431 sinkpad = gst_element_get_static_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 GST_START_TEST (test_locked_sink)
455 GstElement *sink, *src, *pipeline;
456 GstStateChangeReturn ret;
457 GstState current, pending;
459 pipeline = gst_pipeline_new ("pipeline");
460 src = gst_element_factory_make ("fakesrc", "src");
461 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
462 sink = gst_element_factory_make ("fakesink", "sink");
464 gst_bin_add (GST_BIN (pipeline), src);
465 gst_bin_add (GST_BIN (pipeline), sink);
467 /* we don't link the elements */
469 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
470 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
471 "no NO_PREROLL state return");
474 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
475 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
476 fail_unless (current == GST_STATE_PAUSED, "not paused");
477 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
479 /* the sink is now async going from ready to paused */
480 ret = gst_element_get_state (sink, ¤t, &pending, 0);
481 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
482 fail_unless (current == GST_STATE_READY, "not ready");
483 fail_unless (pending == GST_STATE_PAUSED, "not paused");
486 gst_element_set_locked_state (sink, TRUE);
488 /* move to PlAYING, the sink should remain ASYNC. The pipeline
490 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
491 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
493 /* back to PAUSED, we should get NO_PREROLL again */
494 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
495 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
496 "no NO_PREROLL state return");
498 /* unlock the sink */
499 gst_element_set_locked_state (sink, FALSE);
501 /* and now everything back down */
502 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
503 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
504 gst_object_unref (pipeline);
509 GST_START_TEST (test_unlinked_live)
511 GstElement *sink, *src, *lsrc, *pipeline;
512 GstStateChangeReturn ret;
513 GstState current, pending;
514 GstPad *srcpad, *sinkpad;
516 pipeline = gst_pipeline_new ("pipeline");
517 src = gst_element_factory_make ("fakesrc", "src");
518 lsrc = gst_element_factory_make ("fakesrc", "lsrc");
519 g_object_set (G_OBJECT (lsrc), "is-live", TRUE, NULL);
520 sink = gst_element_factory_make ("fakesink", "sink");
522 gst_bin_add (GST_BIN (pipeline), src);
523 gst_bin_add (GST_BIN (pipeline), lsrc);
524 gst_bin_add (GST_BIN (pipeline), sink);
526 /* link non live source to sink */
527 srcpad = gst_element_get_static_pad (src, "src");
528 sinkpad = gst_element_get_static_pad (sink, "sink");
529 gst_pad_link (srcpad, sinkpad);
530 gst_object_unref (srcpad);
531 gst_object_unref (sinkpad);
533 /* we don't link the srcpad of the live source, it will not contribute to the
536 /* set state to PAUSED, this should return NO_PREROLL because there is a live
537 * source. since the only sink in this pipeline is linked to a non-live
538 * source, it will preroll eventually. */
539 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
540 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
541 "no NO_PREROLL state return");
543 /* wait till the sink is prerolled */
544 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
545 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
546 fail_unless (current == GST_STATE_PAUSED, "not paused");
547 fail_unless (pending == GST_STATE_VOID_PENDING, "have playing");
549 /* the pipeline should still return NO_PREROLL */
551 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
552 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
553 fail_unless (current == GST_STATE_PAUSED, "not paused");
554 fail_unless (pending == GST_STATE_VOID_PENDING, "have playing");
556 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
557 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
559 gst_object_unref (pipeline);
564 GST_START_TEST (test_delayed_async)
566 GstElement *sink, *src, *pipeline;
567 GstStateChangeReturn ret;
568 GstState current, pending;
569 GstPad *srcpad, *sinkpad;
571 pipeline = gst_pipeline_new ("pipeline");
572 src = gst_element_factory_make ("fakesrc", "src");
573 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
574 sink = gst_element_factory_make ("fakesink", "sink");
576 /* add source, don't add sink yet */
577 gst_bin_add (GST_BIN (pipeline), src);
579 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
580 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
581 "no NO_PREROLL state return");
583 /* add sink now and set to PAUSED */
584 gst_bin_add (GST_BIN (pipeline), sink);
586 /* This will make the bin notice an ASYNC element. */
587 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
588 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
590 /* we should still be NO_PREROLL now although there is an async element in the
593 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
594 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
595 fail_unless (current == GST_STATE_PAUSED, "not paused");
596 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
598 /* link live source to sink */
599 srcpad = gst_element_get_static_pad (src, "src");
600 sinkpad = gst_element_get_static_pad (sink, "sink");
601 gst_pad_link (srcpad, sinkpad);
602 gst_object_unref (srcpad);
603 gst_object_unref (sinkpad);
605 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
606 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
608 /* we should get SUCCESS now */
610 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
611 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not NO_PREROLL");
612 fail_unless (current == GST_STATE_PLAYING, "not PLAYING");
613 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
615 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
616 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
618 gst_object_unref (pipeline);
623 GST_START_TEST (test_added_async)
625 GstElement *sink, *src, *pipeline;
626 GstStateChangeReturn ret;
627 GstState current, pending;
628 GstPad *srcpad, *sinkpad;
630 pipeline = gst_pipeline_new ("pipeline");
631 src = gst_element_factory_make ("fakesrc", "src");
632 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
633 sink = gst_element_factory_make ("fakesink", "sink");
635 /* add source, don't add sink yet */
636 gst_bin_add (GST_BIN (pipeline), src);
638 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
639 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
640 "no NO_PREROLL state return");
642 /* set sink to PAUSED without adding it to the pipeline */
643 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
644 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
646 /* add sink now, pipeline should notice the async element */
647 gst_bin_add (GST_BIN (pipeline), sink);
649 /* we should still be NO_PREROLL now although there is an async element in the
652 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
653 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
654 fail_unless (current == GST_STATE_PAUSED, "not paused");
655 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
657 /* link live source to sink */
658 srcpad = gst_element_get_static_pad (src, "src");
659 sinkpad = gst_element_get_static_pad (sink, "sink");
660 gst_pad_link (srcpad, sinkpad);
661 gst_object_unref (srcpad);
662 gst_object_unref (sinkpad);
664 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
665 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
667 /* we should get SUCCESS now */
669 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
670 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not NO_PREROLL");
671 fail_unless (current == GST_STATE_PLAYING, "not PLAYING");
672 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
674 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
675 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
677 gst_object_unref (pipeline);
682 GST_START_TEST (test_added_async2)
684 GstElement *sink, *src, *pipeline;
685 GstStateChangeReturn ret;
686 GstState current, pending;
688 pipeline = gst_pipeline_new ("pipeline");
689 src = gst_element_factory_make ("fakesrc", "src");
690 sink = gst_element_factory_make ("fakesink", "sink");
692 /* add source, don't add sink yet */
693 gst_bin_add (GST_BIN (pipeline), src);
694 /* need to lock state here or the pipeline might go in error */
695 gst_element_set_locked_state (src, TRUE);
697 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
698 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
700 /* set sink to PAUSED without adding it to the pipeline */
701 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
702 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
704 /* add sink now, pipeline should notice the async element */
705 gst_bin_add (GST_BIN (pipeline), sink);
707 /* we should be ASYNC now because there is an async element in the
709 ret = gst_element_get_state (pipeline, ¤t, &pending, 0);
710 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not ASYNC");
711 fail_unless (current == GST_STATE_PAUSED, "not paused");
712 fail_unless (pending == GST_STATE_PAUSED, "not paused");
714 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
715 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
717 gst_object_unref (pipeline);
722 GST_START_TEST (test_add_live)
724 GstElement *sink, *src, *pipeline;
725 GstStateChangeReturn ret;
726 GstState current, pending;
728 pipeline = gst_pipeline_new ("pipeline");
729 src = gst_element_factory_make ("fakesrc", "src");
730 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
731 sink = gst_element_factory_make ("fakesink", "sink");
733 /* add sink, don't add sourc3 yet */
734 gst_bin_add (GST_BIN (pipeline), sink);
736 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
737 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
739 /* set source to PAUSED without adding it to the pipeline */
740 ret = gst_element_set_state (src, GST_STATE_PAUSED);
741 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
742 "no NO_PREROLL state return");
744 /* add source now, pipeline should notice the NO_PREROLL element */
745 gst_bin_add (GST_BIN (pipeline), src);
747 /* we should be NO_PREROLL now because there is a NO_PREROLL element in the
750 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
751 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
752 fail_unless (current == GST_STATE_PAUSED, "not paused");
753 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
755 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
756 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
758 gst_object_unref (pipeline);
763 static GMutex *blocked_lock;
764 static GCond *blocked_cond;
767 pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
769 g_mutex_lock (blocked_lock);
770 GST_DEBUG ("srcpad blocked: %d, sending signal", blocked);
771 g_cond_signal (blocked_cond);
772 g_mutex_unlock (blocked_lock);
775 GST_START_TEST (test_add_live2)
777 GstElement *sink, *src, *pipeline;
778 GstStateChangeReturn ret;
779 GstState current, pending;
780 GstPad *srcpad, *sinkpad;
782 blocked_lock = g_mutex_new ();
783 blocked_cond = g_cond_new ();
785 pipeline = gst_pipeline_new ("pipeline");
786 src = gst_element_factory_make ("fakesrc", "src");
787 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
788 sink = gst_element_factory_make ("fakesink", "sink");
790 /* add sink, don't add source yet */
791 gst_bin_add (GST_BIN (pipeline), sink);
793 /* set the pipeline to PLAYING. This will return ASYNC on READY->PAUSED */
794 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
795 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
797 g_mutex_lock (blocked_lock);
799 GST_DEBUG ("blocking srcpad");
800 /* block source pad */
801 srcpad = gst_element_get_static_pad (src, "src");
802 gst_pad_set_blocked_async (srcpad, TRUE, pad_blocked_cb, NULL);
804 /* set source to PAUSED without adding it to the pipeline */
805 ret = gst_element_set_state (src, GST_STATE_PAUSED);
806 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
807 "no NO_PREROLL state return");
809 /* add source now, pipeline should notice the NO_PREROLL element. This
810 * should trigger as commit of the ASYNC pipeline and make it continue
811 * to PLAYING. We blocked the source pad so that we don't get an unlinked
813 gst_bin_add (GST_BIN (pipeline), src);
815 /* wait for pad blocked, this means the source is now PLAYING. */
816 g_cond_wait (blocked_cond, blocked_lock);
817 g_mutex_unlock (blocked_lock);
819 GST_DEBUG ("linking pads");
822 sinkpad = gst_element_get_static_pad (sink, "sink");
823 gst_pad_link (srcpad, sinkpad);
824 gst_object_unref (srcpad);
825 gst_object_unref (sinkpad);
827 GST_DEBUG ("unblocking srcpad");
830 gst_pad_set_blocked_async (srcpad, FALSE, pad_blocked_cb, NULL);
832 GST_DEBUG ("getting state");
834 /* we should be SUCCESS now and PLAYING */
836 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
837 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
838 fail_unless (current == GST_STATE_PLAYING, "not PLAYING");
839 fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
841 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
842 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
844 g_cond_free (blocked_cond);
845 g_mutex_free (blocked_lock);
846 gst_object_unref (pipeline);
851 GST_START_TEST (test_bin_live)
853 GstElement *sink, *src, *pipeline, *bin;
854 GstStateChangeReturn ret;
855 GstState current, pending;
856 GstPad *srcpad, *sinkpad;
858 pipeline = gst_pipeline_new ("pipeline");
859 bin = gst_bin_new ("bin");
860 src = gst_element_factory_make ("fakesrc", "src");
861 g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
862 sink = gst_element_factory_make ("fakesink", "sink");
864 gst_bin_add (GST_BIN (bin), src);
865 gst_bin_add (GST_BIN (bin), sink);
866 gst_bin_add (GST_BIN (pipeline), bin);
868 srcpad = gst_element_get_static_pad (src, "src");
869 sinkpad = gst_element_get_static_pad (sink, "sink");
870 gst_pad_link (srcpad, sinkpad);
871 gst_object_unref (srcpad);
872 gst_object_unref (sinkpad);
874 /* PAUSED returns NO_PREROLL because of the live source */
875 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
876 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
877 "no NO_PREROLL state return");
879 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
880 fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
881 fail_unless (current == GST_STATE_PAUSED, "not paused");
882 fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
884 /* when going to PLAYING, the sink should go to PLAYING ASYNC */
885 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
886 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not ASYNC");
888 /* now wait for PLAYING to complete */
890 gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE);
891 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
892 fail_unless (current == GST_STATE_PLAYING, "not playing");
893 fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
895 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
896 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
898 gst_object_unref (pipeline);
901 GST_END_TEST static void
902 send_eos (GstPad * sinkpad)
904 gst_pad_send_event (sinkpad, gst_event_new_eos ());
907 /* push a buffer with a very long duration in a fakesink, then push an EOS
908 * event. fakesink should emit EOS after the duration of the buffer expired.
909 * Going to PAUSED, however should not return ASYNC while processing the
911 GST_START_TEST (test_fake_eos)
913 GstElement *sink, *pipeline;
915 GstStateChangeReturn ret;
920 pipeline = gst_pipeline_new ("pipeline");
922 sink = gst_element_factory_make ("fakesink", "sink");
923 g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
925 sinkpad = gst_element_get_static_pad (sink, "sink");
927 gst_bin_add (GST_BIN_CAST (pipeline), sink);
929 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
930 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
932 /* push buffer of 100 seconds, since it has a timestamp of 0, it should be
933 * rendered immediatly and the chain function should return immediatly */
934 buffer = gst_buffer_new_and_alloc (10);
935 GST_BUFFER_TIMESTAMP (buffer) = 0;
936 GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
937 res = gst_pad_chain (sinkpad, buffer);
938 fail_unless (res == GST_FLOW_OK, "no OK flow return");
940 /* wait for preroll, this should happen really soon. */
941 ret = gst_element_get_state (pipeline, NULL, NULL, -1);
942 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
944 /* push EOS, this will block for up to 100 seconds, until the previous
945 * buffer has finished. We therefore push it in another thread so we can do
946 * something else while it blocks. */
947 thread = g_thread_create ((GThreadFunc) send_eos, sinkpad, TRUE, NULL);
948 fail_if (thread == NULL, "no thread");
950 /* wait a while so that the thread manages to start and push the EOS */
951 g_usleep (G_USEC_PER_SEC);
953 /* this should cancel rendering of the EOS event and should return SUCCESS
954 * because the sink is now prerolled on the EOS. */
955 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
956 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
958 /* we can unref the sinkpad now, we're done with it */
959 gst_object_unref (sinkpad);
961 /* wait for a second, use the debug log to see that basesink does not discard
963 g_usleep (G_USEC_PER_SEC);
965 /* go back to PLAYING, which means waiting some more in EOS, check debug log
966 * to see this happen. */
967 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
968 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
969 g_usleep (G_USEC_PER_SEC);
971 /* teardown and cleanup */
972 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
973 fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
975 gst_object_unref (pipeline);
980 /* this variable is updated in the same thread, first it is set by the
981 * handoff-preroll signal, then it is checked when the ASYNC_DONE is posted on
983 static gboolean have_preroll = FALSE;
986 async_done_handoff (GstElement * element, GstBuffer * buf, GstPad * pad,
989 GST_DEBUG ("we have the preroll buffer");
993 /* when we get the ASYNC_DONE, query the position */
994 static GstBusSyncReply
995 async_done_func (GstBus * bus, GstMessage * msg, GstElement * sink)
997 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
1001 GST_DEBUG ("we have ASYNC_DONE now");
1002 fail_unless (have_preroll == TRUE, "no preroll buffer received");
1004 /* get the position now */
1005 format = GST_FORMAT_TIME;
1006 gst_element_query_position (sink, &format, &position);
1008 GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1010 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1013 /* we must unref the message if we return DROP */
1014 gst_message_unref (msg);
1016 /* we can drop the message, nothing is listening for it. */
1017 return GST_BUS_DROP;
1021 send_buffer (GstPad * sinkpad)
1026 /* push a second buffer */
1027 GST_DEBUG ("pushing last buffer");
1028 buffer = gst_buffer_new_and_alloc (10);
1029 GST_BUFFER_TIMESTAMP (buffer) = 200 * GST_SECOND;
1030 GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1032 /* this function will initially block */
1033 ret = gst_pad_chain (sinkpad, buffer);
1034 fail_unless (ret == GST_FLOW_OK, "no OK flow return");
1037 /* when we get the ASYNC_DONE message from a sink, we want the sink to be able
1038 * to report the duration and position. The sink should also have called the
1040 GST_START_TEST (test_async_done)
1045 GstStateChangeReturn ret;
1054 sink = gst_element_factory_make ("fakesink", "sink");
1055 g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
1056 g_object_set (G_OBJECT (sink), "preroll-queue-len", 2, NULL);
1057 g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
1059 g_signal_connect (sink, "preroll-handoff", (GCallback) async_done_handoff,
1062 sinkpad = gst_element_get_static_pad (sink, "sink");
1064 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1065 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1067 /* set bus on element synchronously listen for ASYNC_DONE */
1068 bus = gst_bus_new ();
1069 gst_element_set_bus (sink, bus);
1070 gst_bus_set_sync_handler (bus, (GstBusSyncHandler) async_done_func, sink);
1072 /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1073 GST_DEBUG ("sending segment");
1075 gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
1077 res = gst_pad_send_event (sinkpad, event);
1079 /* We have not yet received any buffers so we are still in the READY state,
1080 * the position is therefore still not queryable. */
1081 format = GST_FORMAT_TIME;
1083 qret = gst_element_query_position (sink, &format, &position);
1084 fail_unless (qret == TRUE, "position wrong");
1085 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1087 /* Since we are paused and the preroll queue has a length of 2, this function
1088 * will return immediatly, the preroll handoff will be called and the stream
1089 * position should now be 10 seconds. */
1090 GST_DEBUG ("pushing first buffer");
1091 buffer = gst_buffer_new_and_alloc (10);
1092 GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
1093 GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1094 res = gst_pad_chain (sinkpad, buffer);
1095 fail_unless (res == GST_FLOW_OK, "no OK flow return");
1097 /* scond buffer, will not block either but position should still be 10
1099 GST_DEBUG ("pushing second buffer");
1100 buffer = gst_buffer_new_and_alloc (10);
1101 GST_BUFFER_TIMESTAMP (buffer) = 100 * GST_SECOND;
1102 GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1103 res = gst_pad_chain (sinkpad, buffer);
1104 fail_unless (res == GST_FLOW_OK, "no OK flow return");
1106 /* check if position is still 10 seconds */
1107 format = GST_FORMAT_TIME;
1108 gst_element_query_position (sink, &format, &position);
1109 GST_DEBUG ("first buffer position %" GST_TIME_FORMAT,
1110 GST_TIME_ARGS (position));
1111 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1113 /* last buffer, blocks because preroll queue is filled. Start the push in a
1114 * new thread so that we can check the position */
1115 GST_DEBUG ("starting thread");
1116 thread = g_thread_create ((GThreadFunc) send_buffer, sinkpad, TRUE, NULL);
1117 fail_if (thread == NULL, "no thread");
1119 GST_DEBUG ("waiting 1 second");
1120 g_usleep (G_USEC_PER_SEC);
1121 GST_DEBUG ("waiting done");
1123 /* check if position is still 10 seconds. This is racy because the above
1124 * thread might not yet have started the push, because of the above sleep,
1125 * this is very unlikely, though. */
1126 format = GST_FORMAT_TIME;
1127 gst_element_query_position (sink, &format, &position);
1128 GST_DEBUG ("second buffer position %" GST_TIME_FORMAT,
1129 GST_TIME_ARGS (position));
1130 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1132 /* now we go to playing. This should unlock and stop the above thread. */
1133 GST_DEBUG ("going to PLAYING");
1134 ret = gst_element_set_state (sink, GST_STATE_PLAYING);
1136 /* join the thread. At this point we know the sink processed the last buffer
1137 * and the position should now be 210 seconds; the time of the last buffer we
1139 GST_DEBUG ("joining thread");
1140 g_thread_join (thread);
1142 format = GST_FORMAT_TIME;
1143 gst_element_query_position (sink, &format, &position);
1144 GST_DEBUG ("last buffer position %" GST_TIME_FORMAT,
1145 GST_TIME_ARGS (position));
1146 fail_unless (position == 210 * GST_SECOND, "position is wrong");
1148 gst_object_unref (sinkpad);
1150 gst_element_set_state (sink, GST_STATE_NULL);
1151 gst_object_unref (sink);
1152 gst_object_unref (bus);
1157 /* when we get the ASYNC_DONE, query the position */
1158 static GstBusSyncReply
1159 async_done_eos_func (GstBus * bus, GstMessage * msg, GstElement * sink)
1161 if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
1165 GST_DEBUG ("we have ASYNC_DONE now");
1167 /* get the position now */
1168 format = GST_FORMAT_TIME;
1169 gst_element_query_position (sink, &format, &position);
1171 GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1173 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1175 /* we must unref the message if we return DROP */
1176 gst_message_unref (msg);
1177 /* we can drop the message, nothing is listening for it. */
1178 return GST_BUS_DROP;
1181 /* when we get the ASYNC_DONE message from a sink, we want the sink to be able
1182 * to report the duration and position. The sink should also have called the
1184 GST_START_TEST (test_async_done_eos)
1188 GstStateChangeReturn ret;
1196 sink = gst_element_factory_make ("fakesink", "sink");
1197 g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
1198 g_object_set (G_OBJECT (sink), "preroll-queue-len", 1, NULL);
1200 sinkpad = gst_element_get_static_pad (sink, "sink");
1202 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1203 fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1205 /* set bus on element synchronously listen for ASYNC_DONE */
1206 bus = gst_bus_new ();
1207 gst_element_set_bus (sink, bus);
1208 gst_bus_set_sync_handler (bus, (GstBusSyncHandler) async_done_eos_func, sink);
1210 /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1211 GST_DEBUG ("sending segment");
1213 gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
1215 res = gst_pad_send_event (sinkpad, event);
1217 /* We have not yet received any buffers so we are still in the READY state,
1218 * the position is therefore still not queryable. */
1219 format = GST_FORMAT_TIME;
1221 qret = gst_element_query_position (sink, &format, &position);
1222 fail_unless (qret == TRUE, "position wrong");
1223 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1225 /* Since we are paused and the preroll queue has a length of 1, this function
1226 * will return immediatly. The EOS will complete the preroll and the
1227 * position should now be 10 seconds. */
1228 GST_DEBUG ("pushing EOS");
1229 event = gst_event_new_eos ();
1230 res = gst_pad_send_event (sinkpad, event);
1231 fail_unless (res == TRUE, "no TRUE return");
1233 /* check if position is still 10 seconds */
1234 format = GST_FORMAT_TIME;
1235 gst_element_query_position (sink, &format, &position);
1236 GST_DEBUG ("EOS position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1237 fail_unless (position == 10 * GST_SECOND, "position is wrong");
1239 gst_object_unref (sinkpad);
1241 gst_element_set_state (sink, GST_STATE_NULL);
1242 gst_object_unref (sink);
1243 gst_object_unref (bus);
1248 /* test: try changing state of sinks */
1250 gst_sinks_suite (void)
1252 Suite *s = suite_create ("Sinks");
1253 TCase *tc_chain = tcase_create ("general");
1256 /* time out after 10s, not the default 3, we need this for the last test.
1257 * We need a longer timeout when running under valgrind though. */
1258 if (g_getenv ("CK_DEFAULT_TIMEOUT") != NULL)
1259 timeout = MAX (10, atoi (g_getenv ("CK_DEFAULT_TIMEOUT")));
1260 tcase_set_timeout (tc_chain, timeout);
1262 suite_add_tcase (s, tc_chain);
1263 tcase_add_test (tc_chain, test_sink);
1264 tcase_add_test (tc_chain, test_sink_completion);
1265 tcase_add_test (tc_chain, test_src_sink);
1266 tcase_add_test (tc_chain, test_livesrc_remove);
1267 tcase_add_test (tc_chain, test_livesrc_sink);
1268 tcase_add_test (tc_chain, test_livesrc2_sink);
1269 tcase_add_test (tc_chain, test_livesrc3_sink);
1270 tcase_add_test (tc_chain, test_locked_sink);
1271 tcase_add_test (tc_chain, test_unlinked_live);
1272 tcase_add_test (tc_chain, test_delayed_async);
1273 tcase_add_test (tc_chain, test_added_async);
1274 tcase_add_test (tc_chain, test_added_async2);
1275 tcase_add_test (tc_chain, test_add_live);
1276 tcase_add_test (tc_chain, test_add_live2);
1277 tcase_add_test (tc_chain, test_bin_live);
1278 tcase_add_test (tc_chain, test_fake_eos);
1279 tcase_add_test (tc_chain, test_async_done);
1280 tcase_add_test (tc_chain, test_async_done_eos);
1285 GST_CHECK_MAIN (gst_sinks);