gst/gstutils.c: Don't leak pad references.
[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_bin_add (GST_BIN (pipeline), src);
182   gst_bin_add (GST_BIN (pipeline), sink);
183
184   srcpad = gst_element_get_pad (src, "src");
185   sinkpad = gst_element_get_pad (sink, "sink");
186   gst_pad_link (srcpad, sinkpad);
187   gst_object_unref (srcpad);
188   gst_object_unref (sinkpad);
189
190   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
191   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
192       "no no_preroll state return");
193
194   ret = gst_element_get_state (src, &current, &pending, GST_CLOCK_TIME_NONE);
195   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
196   fail_unless (current == GST_STATE_PAUSED, "not paused");
197   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
198
199   gst_bin_remove (GST_BIN (pipeline), src);
200
201   ret = gst_element_get_state (pipeline, &current, &pending, 0);
202   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
203   fail_unless (current == GST_STATE_PAUSED, "not paused");
204   fail_unless (pending == GST_STATE_PAUSED, "not paused");
205
206   gst_object_unref (pipeline);
207 }
208
209 GST_END_TEST
210 /* the sink should go ASYNC to PAUSE. The live source should go
211  * NO_PREROLL to PAUSE. the pipeline returns NO_PREROLL. An
212  * attempt to go to PLAYING will return ASYNC. polling state
213  * completion should return SUCCESS when the sink is gone to
214  * PLAYING. */
215 GST_START_TEST (test_livesrc_sink)
216 {
217   GstElement *sink, *src, *pipeline;
218   GstStateChangeReturn ret;
219   GstState current, pending;
220   GstPad *srcpad, *sinkpad;
221   GstBus *bus;
222
223   pipeline = gst_pipeline_new ("pipeline");
224   src = gst_element_factory_make ("fakesrc", "src");
225   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
226   sink = gst_element_factory_make ("fakesink", "sink");
227
228   gst_bin_add (GST_BIN (pipeline), src);
229   gst_bin_add (GST_BIN (pipeline), sink);
230
231   srcpad = gst_element_get_pad (src, "src");
232   sinkpad = gst_element_get_pad (sink, "sink");
233   gst_pad_link (srcpad, sinkpad);
234   gst_object_unref (srcpad);
235   gst_object_unref (sinkpad);
236
237   bus = gst_element_get_bus (pipeline);
238
239   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
240   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
241       "no no_preroll state return");
242
243   pop_state_change_message (bus, sink, GST_STATE_NULL, GST_STATE_READY,
244       GST_STATE_VOID_PENDING);
245   pop_state_change_message (bus, src, GST_STATE_NULL, GST_STATE_READY,
246       GST_STATE_VOID_PENDING);
247   pop_state_change_message (bus, pipeline, GST_STATE_NULL, GST_STATE_READY,
248       GST_STATE_PAUSED);
249
250   /* this order only holds true for live sources because they do not push
251      buffers in PAUSED */
252   pop_state_change_message (bus, src, GST_STATE_READY, GST_STATE_PAUSED,
253       GST_STATE_VOID_PENDING);
254   pop_state_change_message (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
255       GST_STATE_VOID_PENDING);
256
257   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
258   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
259       "no no_preroll state return the second time");
260
261   ret = gst_element_get_state (src, &current, &pending, GST_CLOCK_TIME_NONE);
262   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
263   fail_unless (current == GST_STATE_PAUSED, "not paused");
264   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
265
266   /* don't block here */
267   ret = gst_element_get_state (sink, &current, &pending, 0);
268   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
269   fail_unless (current == GST_STATE_READY, "not ready");
270   fail_unless (pending == GST_STATE_PAUSED, "not paused");
271
272   ret =
273       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
274   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not paused");
275   fail_unless (current == GST_STATE_PAUSED, "not paused");
276   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
277
278   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
279   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "not async");
280   ret =
281       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
282   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
283   fail_unless (current == GST_STATE_PLAYING, "not playing");
284   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
285
286   /* now we have four messages on the bus: src from paused to playing, sink from
287      ready to paused and paused to playing, and pipeline from paused to playing.
288      the pipeline message should be last, and the sink messages should go in
289      order, but the src message can be interleaved with the sink one. */
290   {
291     GstMessage *m;
292     GstState old, new, pending;
293     gint n_src = 1, n_sink = 2;
294
295     while (n_src + n_sink > 0) {
296       m = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND);
297       fail_unless (m != NULL, "expected state change message");
298       gst_message_parse_state_changed (m, &old, &new, &pending);
299       if (GST_MESSAGE_SRC (m) == (GstObject *) src) {
300         fail_unless (n_src == 1, "already got one message from the src");
301         n_src--;
302         fail_unless (old == GST_STATE_PAUSED, "unexpected old");
303         fail_unless (new == GST_STATE_PLAYING, "unexpected new (got %d)", new);
304         fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
305       } else if (GST_MESSAGE_SRC (m) == (GstObject *) sink) {
306         if (n_sink == 2) {
307           fail_unless (old == GST_STATE_READY, "unexpected old");
308           fail_unless (new == GST_STATE_PAUSED, "unexpected new");
309           fail_unless (pending == GST_STATE_PLAYING, "unexpected pending");
310         } else if (n_sink == 1) {
311           fail_unless (old == GST_STATE_PAUSED, "unexpected old");
312           fail_unless (new == GST_STATE_PLAYING, "unexpected new");
313           fail_unless (pending == GST_STATE_VOID_PENDING, "unexpected pending");
314         } else {
315           g_assert_not_reached ();
316         }
317         n_sink--;
318       } else {
319         g_critical
320             ("Unexpected state change message src %s (%d src %d sink pending)",
321             GST_OBJECT_NAME (GST_MESSAGE_SRC (m)), n_src, n_sink);
322       }
323       gst_message_unref (m);
324     }
325   }
326
327   pop_state_change_message (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
328       GST_STATE_VOID_PENDING);
329
330   gst_object_unref (bus);
331   gst_element_set_state (pipeline, GST_STATE_NULL);
332   gst_object_unref (pipeline);
333 }
334
335 GST_END_TEST;
336
337 /* The sink should go ASYNC to PLAYING. The source should go
338  * to PLAYING with SUCCESS. The pipeline returns ASYNC. */
339 GST_START_TEST (test_livesrc2_sink)
340 {
341   GstElement *sink, *src, *pipeline;
342   GstStateChangeReturn ret;
343   GstState current, pending;
344   GstPad *srcpad, *sinkpad;
345
346   pipeline = gst_pipeline_new ("pipeline");
347   src = gst_element_factory_make ("fakesrc", "src");
348   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
349   sink = gst_element_factory_make ("fakesink", "sink");
350
351   gst_bin_add (GST_BIN (pipeline), src);
352   gst_bin_add (GST_BIN (pipeline), sink);
353
354   srcpad = gst_element_get_pad (src, "src");
355   sinkpad = gst_element_get_pad (sink, "sink");
356   gst_pad_link (srcpad, sinkpad);
357   gst_object_unref (srcpad);
358   gst_object_unref (sinkpad);
359
360   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
361   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
362
363   ret = gst_element_get_state (src, &current, &pending, GST_CLOCK_TIME_NONE);
364   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
365   fail_unless (current == GST_STATE_PLAYING, "not playing");
366   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
367
368   ret =
369       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
370   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
371   fail_unless (current == GST_STATE_PLAYING, "not playing");
372   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
373
374   /* and back down */
375   ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
376   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL,
377       "no no_preroll state return");
378
379   ret = gst_element_get_state (src, &current, &pending, GST_CLOCK_TIME_NONE);
380   fail_unless (ret == GST_STATE_CHANGE_NO_PREROLL, "not no_preroll");
381   fail_unless (current == GST_STATE_PAUSED, "not paused");
382   fail_unless (pending == GST_STATE_VOID_PENDING, "not paused");
383
384   /* sink state is not known.. it might be prerolled or not */
385
386   /* and to READY */
387   ret = gst_element_set_state (pipeline, GST_STATE_READY);
388   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
389
390   ret = gst_element_get_state (src, &current, &pending, GST_CLOCK_TIME_NONE);
391   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
392   fail_unless (current == GST_STATE_READY, "not ready");
393   fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
394
395   ret = gst_element_get_state (sink, &current, &pending, GST_CLOCK_TIME_NONE);
396   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not success");
397   fail_unless (current == GST_STATE_READY, "not ready");
398   fail_unless (pending == GST_STATE_VOID_PENDING, "not ready");
399 }
400
401 GST_END_TEST;
402
403 GST_START_TEST (test_livesrc3_sink)
404 {
405   GstElement *sink, *src, *pipeline;
406   GstStateChangeReturn ret;
407   GstState current, pending;
408   GstPad *srcpad, *sinkpad;
409
410   pipeline = gst_pipeline_new ("pipeline");
411   src = gst_element_factory_make ("fakesrc", "src");
412   g_object_set (G_OBJECT (src), "is-live", TRUE, NULL);
413   sink = gst_element_factory_make ("fakesink", "sink");
414
415   gst_bin_add (GST_BIN (pipeline), src);
416   gst_bin_add (GST_BIN (pipeline), sink);
417
418   srcpad = gst_element_get_pad (src, "src");
419   sinkpad = gst_element_get_pad (sink, "sink");
420   gst_pad_link (srcpad, sinkpad);
421   gst_object_unref (srcpad);
422   gst_object_unref (sinkpad);
423
424   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
425   fail_unless (ret == GST_STATE_CHANGE_ASYNC, "no async state return");
426
427   ret =
428       gst_element_get_state (pipeline, &current, &pending, GST_CLOCK_TIME_NONE);
429   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "not playing");
430   fail_unless (current == GST_STATE_PLAYING, "not playing");
431   fail_unless (pending == GST_STATE_VOID_PENDING, "not playing");
432
433   /* and back down */
434   ret = gst_element_set_state (pipeline, GST_STATE_NULL);
435   fail_unless (ret == GST_STATE_CHANGE_SUCCESS, "no success state return");
436 }
437
438 GST_END_TEST;
439
440 /* test: try changing state of sinks */
441 Suite *
442 gst_object_suite (void)
443 {
444   Suite *s = suite_create ("Sinks");
445   TCase *tc_chain = tcase_create ("general");
446
447   suite_add_tcase (s, tc_chain);
448   tcase_add_test (tc_chain, test_sink);
449   tcase_add_test (tc_chain, test_sink_completion);
450   tcase_add_test (tc_chain, test_src_sink);
451   tcase_add_test (tc_chain, test_livesrc_remove);
452   tcase_add_test (tc_chain, test_livesrc_sink);
453   tcase_add_test (tc_chain, test_livesrc2_sink);
454   tcase_add_test (tc_chain, test_livesrc3_sink);
455
456   return s;
457 }
458
459 int
460 main (int argc, char **argv)
461 {
462   int nf;
463
464   Suite *s = gst_object_suite ();
465   SRunner *sr = srunner_create (s);
466
467   gst_check_init (&argc, &argv);
468
469   srunner_run_all (sr, CK_NORMAL);
470   nf = srunner_ntests_failed (sr);
471   srunner_free (sr);
472
473   return nf;
474 }