tests/check/generic/sinks.c: Fix leak in unit test (bus sync handler must unref the...
[platform/upstream/gstreamer.git] / tests / check / generic / sinks.c
1 /* GStreamer
2  *
3  * unit test for sinks
4  *
5  * Copyright (C) <2005> Wim Taymans <wim at fluendo dot com>
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include <gst/check/gstcheck.h>
24
25 static void
26 pop_state_change_message (GstBus * bus, GstElement * src, GstState old,
27     GstState new, GstState pending)
28 {
29   GstMessage *message = NULL;
30   GstState _old, _new, _pending;
31
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");
35
36   gst_message_parse_state_changed (message, &_old, &_new, &_pending);
37
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");
43
44   gst_message_unref (message);
45 }
46
47 /* a sink should go ASYNC to PAUSE. forcing PLAYING is possible */
48 GST_START_TEST (test_sink)
49 {
50   GstElement *sink;
51   GstStateChangeReturn ret;
52   GstState current, pending;
53
54   sink = gst_element_factory_make ("fakesink", "sink");
55
56   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
57   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
58
59   ret = gst_element_set_state (sink, GST_STATE_PLAYING);
60   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no forced async state change");
61
62   ret = gst_element_get_state (sink, &current, &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");
66
67   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
68   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async going back to paused");
69
70   ret = gst_element_set_state (sink, GST_STATE_READY);
71   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to ready");
72
73   ret = gst_element_set_state (sink, GST_STATE_NULL);
74   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
75
76   gst_object_unref (sink);
77 }
78
79 GST_END_TEST
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)
83 {
84   GstElement *sink, *src;
85   GstStateChangeReturn ret;
86   GstState current, pending;
87
88   sink = gst_element_factory_make ("fakesink", "sink");
89   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
90
91   ret = gst_element_set_state (sink, GST_STATE_PLAYING);
92   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
93
94   ret = gst_element_get_state (sink, &current, &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");
98
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);
102
103   ret = gst_element_set_state (src, GST_STATE_PLAYING);
104   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
105
106   /* now wait for final state */
107   ret = gst_element_get_state (sink, &current, &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");
111
112   ret = gst_element_set_state (sink, GST_STATE_NULL);
113   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
114
115   ret = gst_element_set_state (src, GST_STATE_NULL);
116   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "failed to go to null");
117
118   gst_object_unref (sink);
119   gst_object_unref (src);
120 }
121
122 GST_END_TEST
123 /* a sink should go ASYNC to PAUSE. PAUSE should complete when
124  * prerolled. */
125 GST_START_TEST (test_src_sink)
126 {
127   GstElement *sink, *src, *pipeline;
128   GstStateChangeReturn ret;
129   GstState current, pending;
130   GstPad *srcpad, *sinkpad;
131
132   pipeline = gst_pipeline_new ("pipeline");
133   src = gst_element_factory_make ("fakesrc", "src");
134   sink = gst_element_factory_make ("fakesink", "sink");
135
136   gst_bin_add (GST_BIN (pipeline), src);
137   gst_bin_add (GST_BIN (pipeline), sink);
138
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);
144
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");
149
150   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
151   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot start play");
152
153   ret =
154       gst_element_get_state (pipeline, &current, &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");
160
161   gst_object_unref (pipeline);
162
163 }
164
165 GST_END_TEST
166 /* a pipeline with live source should return NO_PREROLL in
167  * PAUSE. When removing the live source it should return ASYNC
168  * from the sink */
169 GST_START_TEST (test_livesrc_remove)
170 {
171   GstElement *sink, *src, *pipeline;
172   GstStateChangeReturn ret;
173   GstState current, pending;
174   GstPad *srcpad, *sinkpad;
175
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");
180
181   gst_object_ref (src);
182   gst_bin_add (GST_BIN (pipeline), src);
183   gst_bin_add (GST_BIN (pipeline), sink);
184
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);
190
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");
194
195   ret = gst_element_get_state (src, &current, &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");
199
200   gst_bin_remove (GST_BIN (pipeline), src);
201
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);
205
206   ret = gst_element_get_state (pipeline, &current, &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");
210
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);
214 }
215
216 GST_END_TEST
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
221  * PLAYING. */
222 GST_START_TEST (test_livesrc_sink)
223 {
224   GstElement *sink, *src, *pipeline;
225   GstStateChangeReturn ret;
226   GstState current, pending;
227   GstPad *srcpad, *sinkpad;
228   GstBus *bus;
229
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");
234
235   gst_bin_add (GST_BIN (pipeline), src);
236   gst_bin_add (GST_BIN (pipeline), sink);
237
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);
243
244   bus = gst_element_get_bus (pipeline);
245
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");
249
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,
255       GST_STATE_PAUSED);
256
257   /* this order only holds true for live sources because they do not push
258      buffers in PAUSED */
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);
263
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");
267
268   ret = gst_element_get_state (src, &current, &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");
272
273   /* don't block here */
274   ret = gst_element_get_state (sink, &current, &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");
278
279   ret =
280       gst_element_get_state (pipeline, &current, &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");
284
285   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
286   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
287   ret =
288       gst_element_get_state (pipeline, &current, &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");
292
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. */
297   {
298     GstMessage *m;
299     GstState old, new, pending;
300     gint n_src = 1, n_sink = 2;
301
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");
308         n_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) {
313         if (n_sink == 2) {
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");
321         } else {
322           g_assert_not_reached ();
323         }
324         n_sink--;
325       } else {
326         g_critical
327             ("Unexpected state change message src %s (%d src %d sink pending)",
328             GST_OBJECT_NAME (GST_MESSAGE_SRC (m)), n_src, n_sink);
329       }
330       gst_message_unref (m);
331     }
332   }
333
334   pop_state_change_message (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
335       GST_STATE_VOID_PENDING);
336
337   gst_object_unref (bus);
338   gst_element_set_state (pipeline, GST_STATE_NULL);
339   gst_object_unref (pipeline);
340 }
341
342 GST_END_TEST;
343
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)
347 {
348   GstElement *sink, *src, *pipeline;
349   GstStateChangeReturn ret;
350   GstState current, pending;
351   GstPad *srcpad, *sinkpad;
352
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");
357
358   gst_bin_add (GST_BIN (pipeline), src);
359   gst_bin_add (GST_BIN (pipeline), sink);
360
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);
366
367   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
368   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
369
370   ret = gst_element_get_state (src, &current, &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");
374
375   ret =
376       gst_element_get_state (pipeline, &current, &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");
380
381   /* and back down */
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");
385
386   ret = gst_element_get_state (src, &current, &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");
390
391   /* sink state is not known.. it might be prerolled or not */
392
393   /* and to READY */
394   ret = gst_element_set_state (pipeline, GST_STATE_READY);
395   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
396
397   ret = gst_element_get_state (src, &current, &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");
401
402   ret = gst_element_get_state (sink, &current, &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");
406
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);
411 }
412
413 GST_END_TEST;
414
415 GST_START_TEST (test_livesrc3_sink)
416 {
417   GstElement *sink, *src, *pipeline;
418   GstStateChangeReturn ret;
419   GstState current, pending;
420   GstPad *srcpad, *sinkpad;
421
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");
426
427   gst_bin_add (GST_BIN (pipeline), src);
428   gst_bin_add (GST_BIN (pipeline), sink);
429
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);
435
436   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
437   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
438
439   ret =
440       gst_element_get_state (pipeline, &current, &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");
444
445   /* and back down */
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);
449 }
450
451 GST_END_TEST;
452
453 GST_START_TEST (test_locked_sink)
454 {
455   GstElement *sink, *src, *pipeline;
456   GstStateChangeReturn ret;
457   GstState current, pending;
458
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");
463
464   gst_bin_add (GST_BIN (pipeline), src);
465   gst_bin_add (GST_BIN (pipeline), sink);
466
467   /* we don't link the elements */
468
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");
472
473   ret =
474       gst_element_get_state (pipeline, &current, &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");
478
479   /* the sink is now async going from ready to paused */
480   ret = gst_element_get_state (sink, &current, &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");
484
485   /* lock the sink */
486   gst_element_set_locked_state (sink, TRUE);
487
488   /* move to PlAYING, the sink should remain ASYNC. The pipeline
489    * returns ASYNC */
490   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
491   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
492
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");
497
498   /* unlock the sink */
499   gst_element_set_locked_state (sink, FALSE);
500
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);
505 }
506
507 GST_END_TEST;
508
509 GST_START_TEST (test_unlinked_live)
510 {
511   GstElement *sink, *src, *lsrc, *pipeline;
512   GstStateChangeReturn ret;
513   GstState current, pending;
514   GstPad *srcpad, *sinkpad;
515
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");
521
522   gst_bin_add (GST_BIN (pipeline), src);
523   gst_bin_add (GST_BIN (pipeline), lsrc);
524   gst_bin_add (GST_BIN (pipeline), sink);
525
526   /* link non live source to sink */
527   srcpad = gst_element_get_pad (src, "src");
528   sinkpad = gst_element_get_pad (sink, "sink");
529   gst_pad_link (srcpad, sinkpad);
530   gst_object_unref (srcpad);
531   gst_object_unref (sinkpad);
532
533   /* we don't link the srcpad of the live source, it will not contribute to the
534    * NO_PREROLL. */
535
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");
542
543   /* wait till the sink is prerolled */
544   ret = gst_element_get_state (sink, &current, &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");
548
549   /* the pipeline should still return NO_PREROLL */
550   ret =
551       gst_element_get_state (pipeline, &current, &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");
555
556   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
557   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
558
559   gst_object_unref (pipeline);
560 }
561
562 GST_END_TEST;
563
564 GST_START_TEST (test_delayed_async)
565 {
566   GstElement *sink, *src, *pipeline;
567   GstStateChangeReturn ret;
568   GstState current, pending;
569   GstPad *srcpad, *sinkpad;
570
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");
575
576   /* add source, don't add sink yet */
577   gst_bin_add (GST_BIN (pipeline), src);
578
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");
582
583   /* add sink now and set to PAUSED */
584   gst_bin_add (GST_BIN (pipeline), sink);
585
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");
589
590   /* we should still be NO_PREROLL now although there is an async element in the
591    * pipeline. */
592   ret =
593       gst_element_get_state (pipeline, &current, &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");
597
598   /* link live source to sink */
599   srcpad = gst_element_get_pad (src, "src");
600   sinkpad = gst_element_get_pad (sink, "sink");
601   gst_pad_link (srcpad, sinkpad);
602   gst_object_unref (srcpad);
603   gst_object_unref (sinkpad);
604
605   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
606   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
607
608   /* we should get SUCCESS now */
609   ret =
610       gst_element_get_state (pipeline, &current, &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");
614
615   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
616   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
617
618   gst_object_unref (pipeline);
619 }
620
621 GST_END_TEST;
622
623 GST_START_TEST (test_added_async)
624 {
625   GstElement *sink, *src, *pipeline;
626   GstStateChangeReturn ret;
627   GstState current, pending;
628   GstPad *srcpad, *sinkpad;
629
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");
634
635   /* add source, don't add sink yet */
636   gst_bin_add (GST_BIN (pipeline), src);
637
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");
641
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");
645
646   /* add sink now, pipeline should notice the async element */
647   gst_bin_add (GST_BIN (pipeline), sink);
648
649   /* we should still be NO_PREROLL now although there is an async element in the
650    * pipeline. */
651   ret =
652       gst_element_get_state (pipeline, &current, &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");
656
657   /* link live source to sink */
658   srcpad = gst_element_get_pad (src, "src");
659   sinkpad = gst_element_get_pad (sink, "sink");
660   gst_pad_link (srcpad, sinkpad);
661   gst_object_unref (srcpad);
662   gst_object_unref (sinkpad);
663
664   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
665   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
666
667   /* we should get SUCCESS now */
668   ret =
669       gst_element_get_state (pipeline, &current, &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");
673
674   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
675   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
676
677   gst_object_unref (pipeline);
678 }
679
680 GST_END_TEST;
681
682 GST_START_TEST (test_added_async2)
683 {
684   GstElement *sink, *src, *pipeline;
685   GstStateChangeReturn ret;
686   GstState current, pending;
687
688   pipeline = gst_pipeline_new ("pipeline");
689   src = gst_element_factory_make ("fakesrc", "src");
690   sink = gst_element_factory_make ("fakesink", "sink");
691
692   /* add source, don't add sink yet */
693   gst_bin_add (GST_BIN (pipeline), src);
694
695   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
696   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
697
698   /* set sink to PAUSED without adding it to the pipeline */
699   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
700   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
701
702   /* add sink now, pipeline should notice the async element */
703   gst_bin_add (GST_BIN (pipeline), sink);
704
705   /* we should be ASYNC now because there is an async element in the
706    * pipeline. */
707   ret = gst_element_get_state (pipeline, &current, &pending, 0);
708   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not ASYNC");
709   fail_unless (current == GST_STATE_PAUSED, "not paused");
710   fail_unless (pending == GST_STATE_PAUSED, "not paused");
711
712   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
713   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
714
715   gst_object_unref (pipeline);
716 }
717
718 GST_END_TEST;
719
720 GST_START_TEST (test_add_live)
721 {
722   GstElement *sink, *src, *pipeline;
723   GstStateChangeReturn ret;
724   GstState current, pending;
725
726   pipeline = gst_pipeline_new ("pipeline");
727   src = gst_element_factory_make ("fakesrc", "src");
728   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
729   sink = gst_element_factory_make ("fakesink", "sink");
730
731   /* add sink, don't add sourc3 yet */
732   gst_bin_add (GST_BIN (pipeline), sink);
733
734   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
735   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
736
737   /* set source to PAUSED without adding it to the pipeline */
738   ret = gst_element_set_state (src, GST_STATE_PAUSED);
739   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
740       "no NO_PREROLL state return");
741
742   /* add source now, pipeline should notice the NO_PREROLL element */
743   gst_bin_add (GST_BIN (pipeline), src);
744
745   /* we should be NO_PREROLL now because there is a NO_PREROLL element in the
746    * pipeline. */
747   ret =
748       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
749   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
750   fail_unless (current == GST_STATE_PAUSED, "not paused");
751   fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
752
753   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
754   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
755
756   gst_object_unref (pipeline);
757 }
758
759 GST_END_TEST;
760
761 static GMutex *blocked_lock;
762 static GCond *blocked_cond;
763
764 static void
765 pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
766 {
767   g_mutex_lock (blocked_lock);
768   GST_DEBUG ("srcpad blocked: %d, sending signal", blocked);
769   g_cond_signal (blocked_cond);
770   g_mutex_unlock (blocked_lock);
771 }
772
773 GST_START_TEST (test_add_live2)
774 {
775   GstElement *sink, *src, *pipeline;
776   GstStateChangeReturn ret;
777   GstState current, pending;
778   GstPad *srcpad, *sinkpad;
779
780   blocked_lock = g_mutex_new ();
781   blocked_cond = g_cond_new ();
782
783   pipeline = gst_pipeline_new ("pipeline");
784   src = gst_element_factory_make ("fakesrc", "src");
785   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
786   sink = gst_element_factory_make ("fakesink", "sink");
787
788   /* add sink, don't add source yet */
789   gst_bin_add (GST_BIN (pipeline), sink);
790
791   /* set the pipeline to PLAYING. This will return ASYNC on READY->PAUSED */
792   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
793   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
794
795   g_mutex_lock (blocked_lock);
796
797   GST_DEBUG ("blocking srcpad");
798   /* block source pad */
799   srcpad = gst_element_get_pad (src, "src");
800   gst_pad_set_blocked_async (srcpad, TRUE, pad_blocked_cb, NULL);
801
802   /* set source to PAUSED without adding it to the pipeline */
803   ret = gst_element_set_state (src, GST_STATE_PAUSED);
804   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
805       "no NO_PREROLL state return");
806
807   /* add source now, pipeline should notice the NO_PREROLL element. This
808    * should trigger as commit of the ASYNC pipeline and make it continue
809    * to PLAYING. We blocked the source pad so that we don't get an unlinked
810    * error. */
811   gst_bin_add (GST_BIN (pipeline), src);
812
813   /* wait for pad blocked, this means the source is now PLAYING. */
814   g_cond_wait (blocked_cond, blocked_lock);
815   g_mutex_unlock (blocked_lock);
816
817   GST_DEBUG ("linking pads");
818
819   /* link to sink */
820   sinkpad = gst_element_get_pad (sink, "sink");
821   gst_pad_link (srcpad, sinkpad);
822   gst_object_unref (srcpad);
823   gst_object_unref (sinkpad);
824
825   GST_DEBUG ("unblocking srcpad");
826
827   /* and unblock */
828   gst_pad_set_blocked_async (srcpad, FALSE, pad_blocked_cb, NULL);
829
830   GST_DEBUG ("getting state");
831
832   /* we should be SUCCESS now and PLAYING */
833   ret =
834       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
835   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
836   fail_unless (current == GST_STATE_PLAYING, "not PLAYING");
837   fail_unless (pending == GST_STATE_VOID_PENDING, "have pending");
838
839   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
840   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
841
842   g_cond_free (blocked_cond);
843   g_mutex_free (blocked_lock);
844   gst_object_unref (pipeline);
845 }
846
847 GST_END_TEST;
848
849 GST_START_TEST (test_bin_live)
850 {
851   GstElement *sink, *src, *pipeline, *bin;
852   GstStateChangeReturn ret;
853   GstState current, pending;
854   GstPad *srcpad, *sinkpad;
855
856   pipeline = gst_pipeline_new ("pipeline");
857   bin = gst_bin_new ("bin");
858   src = gst_element_factory_make ("fakesrc", "src");
859   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
860   sink = gst_element_factory_make ("fakesink", "sink");
861
862   gst_bin_add (GST_BIN (bin), src);
863   gst_bin_add (GST_BIN (bin), sink);
864   gst_bin_add (GST_BIN (pipeline), bin);
865
866   srcpad = gst_element_get_pad (src, "src");
867   sinkpad = gst_element_get_pad (sink, "sink");
868   gst_pad_link (srcpad, sinkpad);
869   gst_object_unref (srcpad);
870   gst_object_unref (sinkpad);
871
872   /* PAUSED returns NO_PREROLL because of the live source */
873   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
874   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
875       "no NO_PREROLL state return");
876   ret =
877       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
878   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not NO_PREROLL");
879   fail_unless (current == GST_STATE_PAUSED, "not paused");
880   fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
881
882   /* when going to PLAYING, the sink should go to PLAYING ASYNC */
883   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
884   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not ASYNC");
885
886   /* now wait for PLAYING to complete */
887   ret =
888       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
889   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
890   fail_unless (current == GST_STATE_PLAYING, "not playing");
891   fail_unless (pending == GST_STATE_VOID_PENDING, "not void pending");
892
893   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
894   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
895
896   gst_object_unref (pipeline);
897 }
898
899 GST_END_TEST static void
900 send_eos (GstPad * sinkpad)
901 {
902   gst_pad_send_event (sinkpad, gst_event_new_eos ());
903 }
904
905 /* push a buffer with a very long duration in a fakesink, then push an EOS
906  * event. fakesink should emit EOS after the duration of the buffer expired.
907  * Going to PAUSED, however should not return ASYNC while processing the
908  * buffer. */
909 GST_START_TEST (test_fake_eos)
910 {
911   GstElement *sink, *pipeline;
912   GstBuffer *buffer;
913   GstStateChangeReturn ret;
914   GstPad *sinkpad;
915   GstFlowReturn res;
916   GThread *thread;
917
918   pipeline = gst_pipeline_new ("pipeline");
919
920   sink = gst_element_factory_make ("fakesink", "sink");
921   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
922
923   sinkpad = gst_element_get_pad (sink, "sink");
924
925   gst_bin_add (GST_BIN_CAST (pipeline), sink);
926
927   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
928   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
929
930   /* push buffer of 100 seconds, since it has a timestamp of 0, it should be
931    * rendered immediatly and the chain function should return immediatly */
932   buffer = gst_buffer_new_and_alloc (10);
933   GST_BUFFER_TIMESTAMP (buffer) = 0;
934   GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
935   res = gst_pad_chain (sinkpad, buffer);
936   fail_unless (res == GST_FLOW_OK, "no OK flow return");
937
938   /* wait for preroll, this should happen really soon. */
939   ret = gst_element_get_state (pipeline, NULL, NULL, -1);
940   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
941
942   /* push EOS, this will block for up to 100 seconds, until the previous
943    * buffer has finished. We therefore push it in another thread so we can do
944    * something else while it blocks. */
945   thread = g_thread_create ((GThreadFunc) send_eos, sinkpad, TRUE, NULL);
946   fail_if (thread == NULL, "no thread");
947
948   /* wait a while so that the thread manages to start and push the EOS */
949   g_usleep (G_USEC_PER_SEC);
950
951   /* this should cancel rendering of the EOS event and should return SUCCESS
952    * because the sink is now prerolled on the EOS. */
953   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
954   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
955
956   /* we can unref the sinkpad now, we're done with it */
957   gst_object_unref (sinkpad);
958
959   /* wait for a second, use the debug log to see that basesink does not discard
960    * the EOS */
961   g_usleep (G_USEC_PER_SEC);
962
963   /* go back to PLAYING, which means waiting some more in EOS, check debug log
964    * to see this happen. */
965   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
966   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
967   g_usleep (G_USEC_PER_SEC);
968
969   /* teardown and cleanup */
970   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
971   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
972
973   gst_object_unref (pipeline);
974 }
975
976 GST_END_TEST;
977
978 /* this variable is updated in the same thread, first it is set by the
979  * handoff-preroll signal, then it is checked when the ASYNC_DONE is posted on
980  * the bus */
981 static gboolean have_preroll = FALSE;
982
983 static void
984 async_done_handoff (GstElement * element, GstBuffer * buf, GstPad * pad,
985     GstElement * sink)
986 {
987   GST_DEBUG ("we have the preroll buffer");
988   have_preroll = TRUE;
989 }
990
991 /* when we get the ASYNC_DONE, query the position */
992 static GstBusSyncReply
993 async_done_func (GstBus * bus, GstMessage * msg, GstElement * sink)
994 {
995   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
996     GstFormat format;
997     gint64 position;
998
999     GST_DEBUG ("we have ASYNC_DONE now");
1000     fail_unless (have_preroll == TRUE, "no preroll buffer received");
1001
1002     /* get the position now */
1003     format = GST_FORMAT_TIME;
1004     gst_element_query_position (sink, &format, &position);
1005
1006     GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1007
1008     fail_unless (position == 10 * GST_SECOND, "position is wrong");
1009   }
1010
1011   /* we must unref the message if we return DROP */
1012   gst_message_unref (msg);
1013
1014   /* we can drop the message, nothing is listening for it. */
1015   return GST_BUS_DROP;
1016 }
1017
1018 static void
1019 send_buffer (GstPad * sinkpad)
1020 {
1021   GstBuffer *buffer;
1022   GstStateChangeReturn ret;
1023
1024   /* push a second buffer */
1025   GST_DEBUG ("pushing last buffer");
1026   buffer = gst_buffer_new_and_alloc (10);
1027   GST_BUFFER_TIMESTAMP (buffer) = 200 * GST_SECOND;
1028   GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1029
1030   /* this function will initially block */
1031   ret = gst_pad_chain (sinkpad, buffer);
1032   fail_unless (ret == GST_FLOW_OK, "no OK flow return");
1033 }
1034
1035 /* when we get the ASYNC_DONE message from a sink, we want the sink to be able
1036  * to report the duration and position. The sink should also have called the
1037  * render method. */
1038 GST_START_TEST (test_async_done)
1039 {
1040   GstElement *sink;
1041   GstBuffer *buffer;
1042   GstEvent *event;
1043   GstStateChangeReturn ret;
1044   GstPad *sinkpad;
1045   GstFlowReturn res;
1046   GstBus *bus;
1047   GThread *thread;
1048   GstFormat format;
1049   gint64 position;
1050   gboolean qret;
1051
1052   sink = gst_element_factory_make ("fakesink", "sink");
1053   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
1054   g_object_set (G_OBJECT (sink), "preroll-queue-len", 2, NULL);
1055   g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
1056
1057   g_signal_connect (sink, "preroll-handoff", (GCallback) async_done_handoff,
1058       sink);
1059
1060   sinkpad = gst_element_get_pad (sink, "sink");
1061
1062   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1063   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1064
1065   /* set bus on element synchronously listen for ASYNC_DONE */
1066   bus = gst_bus_new ();
1067   gst_element_set_bus (sink, bus);
1068   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) async_done_func, sink);
1069
1070   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1071   GST_DEBUG ("sending segment");
1072   event =
1073       gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
1074       10 * GST_SECOND);
1075   res = gst_pad_send_event (sinkpad, event);
1076
1077   /* We have not yet received any buffers so we are still in the READY state,
1078    * the position is therefore still not queryable. */
1079   format = GST_FORMAT_TIME;
1080   position = -1;
1081   qret = gst_element_query_position (sink, &format, &position);
1082   fail_unless (qret == FALSE, "position wrong");
1083   fail_unless (position == -1, "position is wrong");
1084
1085   /* Since we are paused and the preroll queue has a length of 2, this function
1086    * will return immediatly, the preroll handoff will be called and the stream
1087    * position should now be 10 seconds. */
1088   GST_DEBUG ("pushing first buffer");
1089   buffer = gst_buffer_new_and_alloc (10);
1090   GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
1091   GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1092   res = gst_pad_chain (sinkpad, buffer);
1093   fail_unless (res == GST_FLOW_OK, "no OK flow return");
1094
1095   /* scond buffer, will not block either but position should still be 10
1096    * seconds */
1097   GST_DEBUG ("pushing second buffer");
1098   buffer = gst_buffer_new_and_alloc (10);
1099   GST_BUFFER_TIMESTAMP (buffer) = 100 * GST_SECOND;
1100   GST_BUFFER_DURATION (buffer) = 100 * GST_SECOND;
1101   res = gst_pad_chain (sinkpad, buffer);
1102   fail_unless (res == GST_FLOW_OK, "no OK flow return");
1103
1104   /* check if position is still 10 seconds */
1105   format = GST_FORMAT_TIME;
1106   gst_element_query_position (sink, &format, &position);
1107   GST_DEBUG ("first buffer position %" GST_TIME_FORMAT,
1108       GST_TIME_ARGS (position));
1109   fail_unless (position == 10 * GST_SECOND, "position is wrong");
1110
1111   /* last buffer, blocks because preroll queue is filled. Start the push in a
1112    * new thread so that we can check the position */
1113   GST_DEBUG ("starting thread");
1114   thread = g_thread_create ((GThreadFunc) send_buffer, sinkpad, TRUE, NULL);
1115   fail_if (thread == NULL, "no thread");
1116
1117   GST_DEBUG ("waiting 1 second");
1118   g_usleep (G_USEC_PER_SEC);
1119   GST_DEBUG ("waiting done");
1120
1121   /* check if position is still 10 seconds. This is racy because  the above
1122    * thread might not yet have started the push, because of the above sleep,
1123    * this is very unlikely, though. */
1124   format = GST_FORMAT_TIME;
1125   gst_element_query_position (sink, &format, &position);
1126   GST_DEBUG ("second buffer position %" GST_TIME_FORMAT,
1127       GST_TIME_ARGS (position));
1128   fail_unless (position == 10 * GST_SECOND, "position is wrong");
1129
1130   /* now we go to playing. This should unlock and stop the above thread. */
1131   GST_DEBUG ("going to PLAYING");
1132   ret = gst_element_set_state (sink, GST_STATE_PLAYING);
1133
1134   /* join the thread. At this point we know the sink processed the last buffer
1135    * and the position should now be 210 seconds; the time of the last buffer we
1136    * pushed */
1137   GST_DEBUG ("joining thread");
1138   g_thread_join (thread);
1139
1140   format = GST_FORMAT_TIME;
1141   gst_element_query_position (sink, &format, &position);
1142   GST_DEBUG ("last buffer position %" GST_TIME_FORMAT,
1143       GST_TIME_ARGS (position));
1144   fail_unless (position == 210 * GST_SECOND, "position is wrong");
1145
1146   gst_object_unref (sinkpad);
1147
1148   gst_element_set_state (sink, GST_STATE_NULL);
1149   gst_object_unref (sink);
1150   gst_object_unref (bus);
1151 }
1152
1153 GST_END_TEST;
1154
1155 /* when we get the ASYNC_DONE, query the position */
1156 static GstBusSyncReply
1157 async_done_eos_func (GstBus * bus, GstMessage * msg, GstElement * sink)
1158 {
1159   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
1160     GstFormat format;
1161     gint64 position;
1162
1163     GST_DEBUG ("we have ASYNC_DONE now");
1164
1165     /* get the position now */
1166     format = GST_FORMAT_TIME;
1167     gst_element_query_position (sink, &format, &position);
1168
1169     GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1170
1171     fail_unless (position == 10 * GST_SECOND, "position is wrong");
1172   }
1173   /* we must unref the message if we return DROP */
1174   gst_message_unref (msg);
1175   /* we can drop the message, nothing is listening for it. */
1176   return GST_BUS_DROP;
1177 }
1178
1179 /* when we get the ASYNC_DONE message from a sink, we want the sink to be able
1180  * to report the duration and position. The sink should also have called the
1181  * render method. */
1182 GST_START_TEST (test_async_done_eos)
1183 {
1184   GstElement *sink;
1185   GstEvent *event;
1186   GstStateChangeReturn ret;
1187   GstPad *sinkpad;
1188   gboolean res;
1189   GstBus *bus;
1190   GstFormat format;
1191   gint64 position;
1192   gboolean qret;
1193
1194   sink = gst_element_factory_make ("fakesink", "sink");
1195   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
1196   g_object_set (G_OBJECT (sink), "preroll-queue-len", 1, NULL);
1197
1198   sinkpad = gst_element_get_pad (sink, "sink");
1199
1200   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1201   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1202
1203   /* set bus on element synchronously listen for ASYNC_DONE */
1204   bus = gst_bus_new ();
1205   gst_element_set_bus (sink, bus);
1206   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) async_done_eos_func, sink);
1207
1208   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1209   GST_DEBUG ("sending segment");
1210   event =
1211       gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
1212       10 * GST_SECOND);
1213   res = gst_pad_send_event (sinkpad, event);
1214
1215   /* We have not yet received any buffers so we are still in the READY state,
1216    * the position is therefore still not queryable. */
1217   format = GST_FORMAT_TIME;
1218   position = -1;
1219   qret = gst_element_query_position (sink, &format, &position);
1220   fail_unless (qret == FALSE, "position wrong");
1221   fail_unless (position == -1, "position is wrong");
1222
1223   /* Since we are paused and the preroll queue has a length of 1, this function
1224    * will return immediatly. The EOS will complete the preroll and the  
1225    * position should now be 10 seconds. */
1226   GST_DEBUG ("pushing EOS");
1227   event = gst_event_new_eos ();
1228   res = gst_pad_send_event (sinkpad, event);
1229   fail_unless (res == TRUE, "no TRUE return");
1230
1231   /* check if position is still 10 seconds */
1232   format = GST_FORMAT_TIME;
1233   gst_element_query_position (sink, &format, &position);
1234   GST_DEBUG ("EOS position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1235   fail_unless (position == 10 * GST_SECOND, "position is wrong");
1236
1237   gst_object_unref (sinkpad);
1238
1239   gst_element_set_state (sink, GST_STATE_NULL);
1240   gst_object_unref (sink);
1241   gst_object_unref (bus);
1242 }
1243
1244 GST_END_TEST;
1245
1246 /* test: try changing state of sinks */
1247 Suite *
1248 gst_sinks_suite (void)
1249 {
1250   Suite *s = suite_create ("Sinks");
1251   TCase *tc_chain = tcase_create ("general");
1252
1253   suite_add_tcase (s, tc_chain);
1254   tcase_add_test (tc_chain, test_sink);
1255   tcase_add_test (tc_chain, test_sink_completion);
1256   tcase_add_test (tc_chain, test_src_sink);
1257   tcase_add_test (tc_chain, test_livesrc_remove);
1258   tcase_add_test (tc_chain, test_livesrc_sink);
1259   tcase_add_test (tc_chain, test_livesrc2_sink);
1260   tcase_add_test (tc_chain, test_livesrc3_sink);
1261   tcase_add_test (tc_chain, test_locked_sink);
1262   tcase_add_test (tc_chain, test_unlinked_live);
1263   tcase_add_test (tc_chain, test_delayed_async);
1264   tcase_add_test (tc_chain, test_added_async);
1265   tcase_add_test (tc_chain, test_added_async2);
1266   tcase_add_test (tc_chain, test_add_live);
1267   tcase_add_test (tc_chain, test_add_live2);
1268   tcase_add_test (tc_chain, test_bin_live);
1269   tcase_add_test (tc_chain, test_fake_eos);
1270   tcase_add_test (tc_chain, test_async_done);
1271   tcase_add_test (tc_chain, test_async_done_eos);
1272
1273   return s;
1274 }
1275
1276 GST_CHECK_MAIN (gst_sinks);