tests/check/: use the new macro
[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_PLAYING, "unexpected pending");
317         } else if (n_sink == 1) {
318           fail_unless (old == GST_STATE_PAUSED, "unexpected old");
319           fail_unless (new == GST_STATE_PLAYING, "unexpected new");
320           fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
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 /* test: try changing state of sinks */
454 Suite *
455 gst_sinks_suite (void)
456 {
457   Suite *s = suite_create ("Sinks");
458   TCase *tc_chain = tcase_create ("general");
459
460   suite_add_tcase (s, tc_chain);
461   tcase_add_test (tc_chain, test_sink);
462   tcase_add_test (tc_chain, test_sink_completion);
463   tcase_add_test (tc_chain, test_src_sink);
464   tcase_add_test (tc_chain, test_livesrc_remove);
465   tcase_add_test (tc_chain, test_livesrc_sink);
466   tcase_add_test (tc_chain, test_livesrc2_sink);
467   tcase_add_test (tc_chain, test_livesrc3_sink);
468
469   return s;
470 }
471
472 GST_CHECK_MAIN (gst_sinks);