2c485084a812e2ca2a53e85564af5e93cfb63c0b
[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_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);
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_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);
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_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);
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_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);
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_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);
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_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);
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_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);
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_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);
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   /* need to lock state here or the pipeline might go in error */
695   gst_element_set_locked_state (src, TRUE);
696
697   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
698   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no SUCCESS state return");
699
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");
703
704   /* add sink now, pipeline should notice the async element */
705   gst_bin_add (GST_BIN (pipeline), sink);
706
707   /* we should be ASYNC now because there is an async element in the
708    * pipeline. */
709   ret = gst_element_get_state (pipeline, &current, &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");
713
714   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
715   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
716
717   gst_object_unref (pipeline);
718 }
719
720 GST_END_TEST;
721
722 GST_START_TEST (test_add_live)
723 {
724   GstElement *sink, *src, *pipeline;
725   GstStateChangeReturn ret;
726   GstState current, pending;
727
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");
732
733   /* add sink, don't add sourc3 yet */
734   gst_bin_add (GST_BIN (pipeline), sink);
735
736   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
737   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
738
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");
743
744   /* add source now, pipeline should notice the NO_PREROLL element */
745   gst_bin_add (GST_BIN (pipeline), src);
746
747   /* we should be NO_PREROLL now because there is a NO_PREROLL element in the
748    * pipeline. */
749   ret =
750       gst_element_get_state (pipeline, &current, &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");
754
755   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
756   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
757
758   gst_object_unref (pipeline);
759 }
760
761 GST_END_TEST;
762
763 static GMutex *blocked_lock;
764 static GCond *blocked_cond;
765
766 static void
767 pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
768 {
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);
773 }
774
775 GST_START_TEST (test_add_live2)
776 {
777   GstElement *sink, *src, *pipeline;
778   GstStateChangeReturn ret;
779   GstState current, pending;
780   GstPad *srcpad, *sinkpad;
781
782   blocked_lock = g_mutex_new ();
783   blocked_cond = g_cond_new ();
784
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");
789
790   /* add sink, don't add source yet */
791   gst_bin_add (GST_BIN (pipeline), sink);
792
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");
796
797   g_mutex_lock (blocked_lock);
798
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);
803
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");
808
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
812    * error. */
813   gst_bin_add (GST_BIN (pipeline), src);
814
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);
818
819   GST_DEBUG ("linking pads");
820
821   /* link to sink */
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);
826
827   GST_DEBUG ("unblocking srcpad");
828
829   /* and unblock */
830   gst_pad_set_blocked_async (srcpad, FALSE, pad_blocked_cb, NULL);
831
832   GST_DEBUG ("getting state");
833
834   /* we should be SUCCESS now and PLAYING */
835   ret =
836       gst_element_get_state (pipeline, &current, &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");
840
841   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
842   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not SUCCESS");
843
844   g_cond_free (blocked_cond);
845   g_mutex_free (blocked_lock);
846   gst_object_unref (pipeline);
847 }
848
849 GST_END_TEST;
850
851 GST_START_TEST (test_bin_live)
852 {
853   GstElement *sink, *src, *pipeline, *bin;
854   GstStateChangeReturn ret;
855   GstState current, pending;
856   GstPad *srcpad, *sinkpad;
857
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");
863
864   gst_bin_add (GST_BIN (bin), src);
865   gst_bin_add (GST_BIN (bin), sink);
866   gst_bin_add (GST_BIN (pipeline), bin);
867
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);
873
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");
878   ret =
879       gst_element_get_state (pipeline, &current, &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");
883
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");
887
888   /* now wait for PLAYING to complete */
889   ret =
890       gst_element_get_state (pipeline, &current, &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");
894
895   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
896   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "cannot null pipeline");
897
898   gst_object_unref (pipeline);
899 }
900
901 GST_END_TEST static void
902 send_eos (GstPad * sinkpad)
903 {
904   gst_pad_send_event (sinkpad, gst_event_new_eos ());
905 }
906
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
910  * buffer. */
911 GST_START_TEST (test_fake_eos)
912 {
913   GstElement *sink, *pipeline;
914   GstBuffer *buffer;
915   GstStateChangeReturn ret;
916   GstPad *sinkpad;
917   GstFlowReturn res;
918   GThread *thread;
919
920   pipeline = gst_pipeline_new ("pipeline");
921
922   sink = gst_element_factory_make ("fakesink", "sink");
923   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
924
925   sinkpad = gst_element_get_static_pad (sink, "sink");
926
927   gst_bin_add (GST_BIN_CAST (pipeline), sink);
928
929   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
930   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
931
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");
939
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");
943
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");
949
950   /* wait a while so that the thread manages to start and push the EOS */
951   g_usleep (G_USEC_PER_SEC);
952
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");
957
958   /* we can unref the sinkpad now, we're done with it */
959   gst_object_unref (sinkpad);
960
961   /* wait for a second, use the debug log to see that basesink does not discard
962    * the EOS */
963   g_usleep (G_USEC_PER_SEC);
964
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);
970
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");
974
975   gst_object_unref (pipeline);
976 }
977
978 GST_END_TEST;
979
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
982  * the bus */
983 static gboolean have_preroll = FALSE;
984
985 static void
986 async_done_handoff (GstElement * element, GstBuffer * buf, GstPad * pad,
987     GstElement * sink)
988 {
989   GST_DEBUG ("we have the preroll buffer");
990   have_preroll = TRUE;
991 }
992
993 /* when we get the ASYNC_DONE, query the position */
994 static GstBusSyncReply
995 async_done_func (GstBus * bus, GstMessage * msg, GstElement * sink)
996 {
997   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
998     GstFormat format;
999     gint64 position;
1000
1001     GST_DEBUG ("we have ASYNC_DONE now");
1002     fail_unless (have_preroll == TRUE, "no preroll buffer received");
1003
1004     /* get the position now */
1005     format = GST_FORMAT_TIME;
1006     gst_element_query_position (sink, &format, &position);
1007
1008     GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1009
1010     fail_unless (position == 10 * GST_SECOND, "position is wrong");
1011   }
1012
1013   /* we must unref the message if we return DROP */
1014   gst_message_unref (msg);
1015
1016   /* we can drop the message, nothing is listening for it. */
1017   return GST_BUS_DROP;
1018 }
1019
1020 static void
1021 send_buffer (GstPad * sinkpad)
1022 {
1023   GstBuffer *buffer;
1024   GstFlowReturn ret;
1025
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;
1031
1032   /* this function will initially block */
1033   ret = gst_pad_chain (sinkpad, buffer);
1034   fail_unless (ret == GST_FLOW_OK, "no OK flow return");
1035 }
1036
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
1039  * render method. */
1040 GST_START_TEST (test_async_done)
1041 {
1042   GstElement *sink;
1043   GstBuffer *buffer;
1044   GstEvent *event;
1045   GstStateChangeReturn ret;
1046   GstPad *sinkpad;
1047   GstFlowReturn res;
1048   GstBus *bus;
1049   GThread *thread;
1050   GstFormat format;
1051   gint64 position;
1052   gboolean qret;
1053
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);
1058
1059   g_signal_connect (sink, "preroll-handoff", (GCallback) async_done_handoff,
1060       sink);
1061
1062   sinkpad = gst_element_get_static_pad (sink, "sink");
1063
1064   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1065   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1066
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);
1071
1072   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1073   GST_DEBUG ("sending segment");
1074   event =
1075       gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
1076       10 * GST_SECOND);
1077   res = gst_pad_send_event (sinkpad, event);
1078
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;
1082   position = -1;
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");
1086
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");
1096
1097   /* scond buffer, will not block either but position should still be 10
1098    * seconds */
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");
1105
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");
1112
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");
1118
1119   GST_DEBUG ("waiting 1 second");
1120   g_usleep (G_USEC_PER_SEC);
1121   GST_DEBUG ("waiting done");
1122
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");
1131
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);
1135
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
1138    * pushed */
1139   GST_DEBUG ("joining thread");
1140   g_thread_join (thread);
1141
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 == 310 * GST_SECOND, "position is wrong");
1147
1148   gst_object_unref (sinkpad);
1149
1150   gst_element_set_state (sink, GST_STATE_NULL);
1151   gst_object_unref (sink);
1152   gst_object_unref (bus);
1153 }
1154
1155 GST_END_TEST;
1156
1157 /* when we get the ASYNC_DONE, query the position */
1158 static GstBusSyncReply
1159 async_done_eos_func (GstBus * bus, GstMessage * msg, GstElement * sink)
1160 {
1161   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
1162     GstFormat format;
1163     gint64 position;
1164
1165     GST_DEBUG ("we have ASYNC_DONE now");
1166
1167     /* get the position now */
1168     format = GST_FORMAT_TIME;
1169     gst_element_query_position (sink, &format, &position);
1170
1171     GST_DEBUG ("we have position %" GST_TIME_FORMAT, GST_TIME_ARGS (position));
1172
1173     fail_unless (position == 10 * GST_SECOND, "position is wrong");
1174   }
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;
1179 }
1180
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
1183  * render method. */
1184 GST_START_TEST (test_async_done_eos)
1185 {
1186   GstElement *sink;
1187   GstEvent *event;
1188   GstStateChangeReturn ret;
1189   GstPad *sinkpad;
1190   gboolean res;
1191   GstBus *bus;
1192   GstFormat format;
1193   gint64 position;
1194   gboolean qret;
1195
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);
1199
1200   sinkpad = gst_element_get_static_pad (sink, "sink");
1201
1202   ret = gst_element_set_state (sink, GST_STATE_PAUSED);
1203   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no ASYNC state return");
1204
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);
1209
1210   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
1211   GST_DEBUG ("sending segment");
1212   event =
1213       gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
1214       10 * GST_SECOND);
1215   res = gst_pad_send_event (sinkpad, event);
1216
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;
1220   position = -1;
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");
1224
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");
1232
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");
1238
1239   gst_object_unref (sinkpad);
1240
1241   gst_element_set_state (sink, GST_STATE_NULL);
1242   gst_object_unref (sink);
1243   gst_object_unref (bus);
1244 }
1245
1246 GST_END_TEST;
1247
1248 static GMutex *preroll_lock;
1249 static GCond *preroll_cond;
1250
1251 static void
1252 test_async_false_seek_preroll (GstElement * elem, GstBuffer * buf,
1253     GstPad * pad, gpointer data)
1254 {
1255   g_mutex_lock (preroll_lock);
1256   GST_DEBUG ("Got preroll buffer %p", buf);
1257   g_cond_signal (preroll_cond);
1258   g_mutex_unlock (preroll_lock);
1259 }
1260
1261 static void
1262 test_async_false_seek_handoff (GstElement * elem, GstBuffer * buf,
1263     GstPad * pad, gpointer data)
1264 {
1265   /* should never be reached, we never go to PLAYING */
1266   GST_DEBUG ("Got handoff buffer %p", buf);
1267   fail_unless (FALSE);
1268 }
1269
1270 GST_START_TEST (test_async_false_seek)
1271 {
1272   GstElement *pipeline, *source, *sink;
1273
1274   preroll_lock = g_mutex_new ();
1275   preroll_cond = g_cond_new ();
1276
1277   /* Create gstreamer elements */
1278   pipeline = gst_pipeline_new ("test-pipeline");
1279   source = gst_element_factory_make ("fakesrc", "file-source");
1280   sink = gst_element_factory_make ("fakesink", "audio-output");
1281
1282   g_object_set (G_OBJECT (sink), "async", FALSE, NULL);
1283   g_object_set (G_OBJECT (sink), "num-buffers", 10, NULL);
1284   g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
1285
1286   g_signal_connect (sink, "handoff", G_CALLBACK (test_async_false_seek_handoff),
1287       NULL);
1288   g_signal_connect (sink, "preroll-handoff",
1289       G_CALLBACK (test_async_false_seek_preroll), NULL);
1290
1291   /* we add all elements into the pipeline */
1292   gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
1293
1294   /* we link the elements together */
1295   gst_element_link (source, sink);
1296
1297   GST_DEBUG ("Now pausing");
1298   g_mutex_lock (preroll_lock);
1299   gst_element_set_state (pipeline, GST_STATE_PAUSED);
1300
1301   /* wait for preroll */
1302   GST_DEBUG ("wait for preroll");
1303   g_cond_wait (preroll_cond, preroll_lock);
1304   g_mutex_unlock (preroll_lock);
1305
1306   g_mutex_lock (preroll_lock);
1307   GST_DEBUG ("Seeking");
1308   fail_unless (gst_element_seek (pipeline, 1.0, GST_FORMAT_BYTES,
1309           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1));
1310
1311   GST_DEBUG ("wait for new preroll");
1312   /* this either prerolls or fails */
1313   g_cond_wait (preroll_cond, preroll_lock);
1314   g_mutex_unlock (preroll_lock);
1315
1316   GST_DEBUG ("bring pipe to state NULL");
1317   gst_element_set_state (pipeline, GST_STATE_NULL);
1318
1319   GST_DEBUG ("Deleting pipeline");
1320   gst_object_unref (GST_OBJECT (pipeline));
1321
1322   g_mutex_free (preroll_lock);
1323   g_cond_free (preroll_cond);
1324 }
1325
1326 GST_END_TEST;
1327
1328 static GMutex *handoff_lock;
1329 static GCond *handoff_cond;
1330
1331 static void
1332 test_async_false_seek_in_playing_handoff (GstElement * elem, GstBuffer * buf,
1333     GstPad * pad, gpointer data)
1334 {
1335   g_mutex_lock (handoff_lock);
1336   GST_DEBUG ("Got handoff buffer %p", buf);
1337   g_cond_signal (handoff_cond);
1338   g_mutex_unlock (handoff_lock);
1339 }
1340
1341 GST_START_TEST (test_async_false_seek_in_playing)
1342 {
1343   GstElement *pipeline, *source, *sink;
1344
1345   handoff_lock = g_mutex_new ();
1346   handoff_cond = g_cond_new ();
1347
1348   /* Create gstreamer elements */
1349   pipeline = gst_pipeline_new ("test-pipeline");
1350   source = gst_element_factory_make ("fakesrc", "fake-source");
1351   sink = gst_element_factory_make ("fakesink", "fake-output");
1352
1353   g_object_set (G_OBJECT (sink), "async", FALSE, NULL);
1354   g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL);
1355
1356   g_signal_connect (sink, "handoff",
1357       G_CALLBACK (test_async_false_seek_in_playing_handoff), NULL);
1358
1359   /* we add all elements into the pipeline */
1360   gst_bin_add_many (GST_BIN (pipeline), source, sink, NULL);
1361
1362   /* we link the elements together */
1363   gst_element_link (source, sink);
1364
1365   GST_DEBUG ("Now playing");
1366   gst_element_set_state (pipeline, GST_STATE_PLAYING);
1367
1368   g_mutex_lock (handoff_lock);
1369   GST_DEBUG ("wait for handoff buffer");
1370   g_cond_wait (handoff_cond, handoff_lock);
1371   g_mutex_unlock (handoff_lock);
1372
1373   GST_DEBUG ("Seeking");
1374   fail_unless (gst_element_seek (source, 1.0, GST_FORMAT_BYTES,
1375           GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, -1));
1376
1377   g_mutex_lock (handoff_lock);
1378   GST_DEBUG ("wait for handoff buffer");
1379   g_cond_wait (handoff_cond, handoff_lock);
1380   g_mutex_unlock (handoff_lock);
1381
1382   GST_DEBUG ("bring pipe to state NULL");
1383   gst_element_set_state (pipeline, GST_STATE_NULL);
1384
1385   GST_DEBUG ("Deleting pipeline");
1386   gst_object_unref (GST_OBJECT (pipeline));
1387
1388   g_mutex_free (handoff_lock);
1389   g_cond_free (handoff_cond);
1390 }
1391
1392 GST_END_TEST;
1393
1394 /* test: try changing state of sinks */
1395 static Suite *
1396 gst_sinks_suite (void)
1397 {
1398   Suite *s = suite_create ("Sinks");
1399   TCase *tc_chain = tcase_create ("general");
1400   guint timeout = 10;
1401
1402   /* time out after 10s, not the default 3, we need this for the last test.
1403    * We need a longer timeout when running under valgrind though. */
1404   if (g_getenv ("CK_DEFAULT_TIMEOUT") != NULL)
1405     timeout = MAX (10, atoi (g_getenv ("CK_DEFAULT_TIMEOUT")));
1406   tcase_set_timeout (tc_chain, timeout);
1407
1408   suite_add_tcase (s, tc_chain);
1409   tcase_add_test (tc_chain, test_sink);
1410   tcase_add_test (tc_chain, test_sink_completion);
1411   tcase_add_test (tc_chain, test_src_sink);
1412   tcase_add_test (tc_chain, test_livesrc_remove);
1413   tcase_add_test (tc_chain, test_livesrc_sink);
1414   tcase_add_test (tc_chain, test_livesrc2_sink);
1415   tcase_add_test (tc_chain, test_livesrc3_sink);
1416   tcase_add_test (tc_chain, test_locked_sink);
1417   tcase_add_test (tc_chain, test_unlinked_live);
1418   tcase_add_test (tc_chain, test_delayed_async);
1419   tcase_add_test (tc_chain, test_added_async);
1420   tcase_add_test (tc_chain, test_added_async2);
1421   tcase_add_test (tc_chain, test_add_live);
1422   tcase_add_test (tc_chain, test_add_live2);
1423   tcase_add_test (tc_chain, test_bin_live);
1424   tcase_add_test (tc_chain, test_fake_eos);
1425   tcase_add_test (tc_chain, test_async_done);
1426   tcase_add_test (tc_chain, test_async_done_eos);
1427   tcase_add_test (tc_chain, test_async_false_seek);
1428   tcase_add_test (tc_chain, test_async_false_seek_in_playing);
1429
1430   return s;
1431 }
1432
1433 GST_CHECK_MAIN (gst_sinks);