3d4cb8294ce306be3995ecbf90ba25c048d5b492
[platform/upstream/gstreamer.git] / tests / check / elements / adder.c
1 /* GStreamer
2  *
3  * unit test for adder
4  *
5  * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
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 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
26
27 #ifdef HAVE_VALGRIND
28 # include <valgrind/valgrind.h>
29 #endif
30
31 #include <unistd.h>
32
33 #include <gst/check/gstcheck.h>
34
35 static GMainLoop *main_loop;
36
37 static void
38 message_received (GstBus * bus, GstMessage * message, GstPipeline * bin)
39 {
40   GstObject *object = GST_MESSAGE_SRC (message);
41
42   GST_INFO ("bus message from \"%s\" (%s): ",
43       GST_STR_NULL (GST_ELEMENT_NAME (object)),
44       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
45
46   switch (message->type) {
47     case GST_MESSAGE_EOS:
48       g_main_loop_quit (main_loop);
49       break;
50     case GST_MESSAGE_WARNING:
51     case GST_MESSAGE_ERROR:{
52       GError *gerror;
53       gchar *debug;
54
55       gst_message_parse_error (message, &gerror, &debug);
56       gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
57       g_error_free (gerror);
58       g_free (debug);
59       g_main_loop_quit (main_loop);
60     }
61     default:
62       break;
63   }
64 }
65
66
67 static GstFormat format = GST_FORMAT_UNDEFINED;
68 static gint64 position = -1;
69
70 static void
71 test_event_message_received (GstBus * bus, GstMessage * message,
72     GstPipeline * bin)
73 {
74   GstObject *object = GST_MESSAGE_SRC (message);
75
76   GST_INFO ("bus message from \"%s\" (%s): ",
77       GST_STR_NULL (GST_ELEMENT_NAME (object)),
78       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
79
80   switch (message->type) {
81     case GST_MESSAGE_SEGMENT_DONE:
82       gst_message_parse_segment_done (message, &format, &position);
83       GST_INFO ("received segment_done : %" G_GINT64_FORMAT, position);
84       g_main_loop_quit (main_loop);
85       break;
86     default:
87       g_assert_not_reached ();
88       break;
89   }
90 }
91
92
93 GST_START_TEST (test_event)
94 {
95   GstElement *bin, *src1, *src2, *adder, *sink;
96   GstBus *bus;
97   GstEvent *seek_event;
98   gboolean res;
99
100   GST_INFO ("preparing test");
101
102   /* build pipeline */
103   bin = gst_pipeline_new ("pipeline");
104   bus = gst_element_get_bus (bin);
105   gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
106
107   /* FIXME, fakesrc with default setting will produce 0 sized
108    * buffers and incompatible caps for adder that will make
109    * adder EOS and error out */
110   src1 = gst_element_factory_make ("audiotestsrc", "src1");
111   g_object_set (src1, "wave", 4, NULL); /* silence */
112   src2 = gst_element_factory_make ("audiotestsrc", "src2");
113   g_object_set (src2, "wave", 4, NULL); /* silence */
114   adder = gst_element_factory_make ("adder", "adder");
115   sink = gst_element_factory_make ("fakesink", "sink");
116   gst_bin_add_many (GST_BIN (bin), src1, src2, adder, sink, NULL);
117
118   res = gst_element_link (src1, adder);
119   fail_unless (res == TRUE, NULL);
120   res = gst_element_link (src2, adder);
121   fail_unless (res == TRUE, NULL);
122   res = gst_element_link (adder, sink);
123   fail_unless (res == TRUE, NULL);
124
125   seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
126       GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
127       GST_SEEK_TYPE_SET, (GstClockTime) 0,
128       GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
129
130   format = GST_FORMAT_UNDEFINED;
131   position = -1;
132
133   main_loop = g_main_loop_new (NULL, FALSE);
134   g_signal_connect (bus, "message::segment-done",
135       (GCallback) test_event_message_received, bin);
136   g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
137   g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
138   g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
139
140   GST_INFO ("starting test");
141
142   /* prepare playing */
143   res = gst_element_set_state (bin, GST_STATE_PAUSED);
144   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
145
146   /* wait for completion */
147   res = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE);
148   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
149
150   res = gst_element_send_event (bin, seek_event);
151   fail_unless (res == TRUE, NULL);
152
153   /* run pipeline */
154   res = gst_element_set_state (bin, GST_STATE_PLAYING);
155   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
156
157   g_main_loop_run (main_loop);
158
159   res = gst_element_set_state (bin, GST_STATE_NULL);
160   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
161
162   fail_unless (position == 2 * GST_SECOND, NULL);
163
164   /* cleanup */
165   g_main_loop_unref (main_loop);
166   gst_object_unref (G_OBJECT (bus));
167   gst_object_unref (G_OBJECT (bin));
168 }
169
170 GST_END_TEST;
171
172 static guint play_count = 0;
173 static GstEvent *play_seek_event = NULL;
174
175 static void
176 test_play_twice_message_received (GstBus * bus, GstMessage * message,
177     GstPipeline * bin)
178 {
179   GstObject *object = GST_MESSAGE_SRC (message);
180   gboolean res;
181
182   GST_INFO ("bus message from \"%s\" (%s): ",
183       GST_STR_NULL (GST_ELEMENT_NAME (object)),
184       gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
185
186   switch (message->type) {
187     case GST_MESSAGE_SEGMENT_DONE:
188       play_count++;
189       if (play_count == 1) {
190         res = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
191         fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
192
193         /* prepare playing again */
194         res = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
195         fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
196
197         /* wait for completion */
198         res =
199             gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
200             GST_CLOCK_TIME_NONE);
201         fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
202
203         res = gst_element_send_event (GST_ELEMENT (bin), play_seek_event);
204         fail_unless (res == TRUE, NULL);
205
206         /* event is now gone */
207         play_seek_event = NULL;
208
209         res = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
210         fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
211       } else {
212         g_main_loop_quit (main_loop);
213       }
214       break;
215     default:
216       g_assert_not_reached ();
217       break;
218   }
219 }
220
221
222 GST_START_TEST (test_play_twice)
223 {
224   GstElement *bin, *src1, *src2, *adder, *sink;
225   GstBus *bus;
226   gboolean res;
227
228   GST_INFO ("preparing test");
229
230   /* build pipeline */
231   bin = gst_pipeline_new ("pipeline");
232   bus = gst_element_get_bus (bin);
233   gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
234
235   src1 = gst_element_factory_make ("audiotestsrc", "src1");
236   g_object_set (src1, "wave", 4, NULL); /* silence */
237   src2 = gst_element_factory_make ("audiotestsrc", "src2");
238   g_object_set (src2, "wave", 4, NULL); /* silence */
239   adder = gst_element_factory_make ("adder", "adder");
240   sink = gst_element_factory_make ("fakesink", "sink");
241   gst_bin_add_many (GST_BIN (bin), src1, src2, adder, sink, NULL);
242
243   res = gst_element_link (src1, adder);
244   fail_unless (res == TRUE, NULL);
245   res = gst_element_link (src2, adder);
246   fail_unless (res == TRUE, NULL);
247   res = gst_element_link (adder, sink);
248   fail_unless (res == TRUE, NULL);
249
250   play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
251       GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH,
252       GST_SEEK_TYPE_SET, (GstClockTime) 0,
253       GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND);
254
255   play_count = 0;
256
257   main_loop = g_main_loop_new (NULL, FALSE);
258   g_signal_connect (bus, "message::segment-done",
259       (GCallback) test_play_twice_message_received, bin);
260   g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
261   g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
262   g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
263
264   GST_INFO ("starting test");
265
266   /* prepare playing */
267   res = gst_element_set_state (bin, GST_STATE_PAUSED);
268   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
269
270   /* wait for completion */
271   res =
272       gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
273       GST_CLOCK_TIME_NONE);
274   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
275
276   res = gst_element_send_event (bin, gst_event_ref (play_seek_event));
277   fail_unless (res == TRUE, NULL);
278
279   /* run pipeline */
280   res = gst_element_set_state (bin, GST_STATE_PLAYING);
281   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
282
283   g_main_loop_run (main_loop);
284
285   res = gst_element_set_state (bin, GST_STATE_NULL);
286   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
287
288   fail_unless (play_count == 2, NULL);
289
290   /* cleanup */
291   g_main_loop_unref (main_loop);
292   gst_object_unref (G_OBJECT (bus));
293   gst_object_unref (G_OBJECT (bin));
294 }
295
296 GST_END_TEST;
297
298 /* check if adding pads work as expected */
299 GST_START_TEST (test_add_pad)
300 {
301   GstElement *bin, *src1, *src2, *adder, *sink;
302   GstBus *bus;
303   gboolean res;
304
305   GST_INFO ("preparing test");
306
307   /* build pipeline */
308   bin = gst_pipeline_new ("pipeline");
309   bus = gst_element_get_bus (bin);
310   gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
311
312   src1 = gst_element_factory_make ("audiotestsrc", "src1");
313   g_object_set (src1, "num-buffers", 4, NULL);
314   g_object_set (src1, "wave", 4, NULL); /* silence */
315   src2 = gst_element_factory_make ("audiotestsrc", "src2");
316   /* one buffer less, we connect with 1 buffer of delay */
317   g_object_set (src2, "num-buffers", 3, NULL);
318   g_object_set (src2, "wave", 4, NULL); /* silence */
319   adder = gst_element_factory_make ("adder", "adder");
320   sink = gst_element_factory_make ("fakesink", "sink");
321   gst_bin_add_many (GST_BIN (bin), src1, adder, sink, NULL);
322
323   res = gst_element_link (src1, adder);
324   fail_unless (res == TRUE, NULL);
325   res = gst_element_link (adder, sink);
326   fail_unless (res == TRUE, NULL);
327
328   main_loop = g_main_loop_new (NULL, FALSE);
329   g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
330       bin);
331   g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
332   g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
333   g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
334
335   GST_INFO ("starting test");
336
337   /* prepare playing */
338   res = gst_element_set_state (bin, GST_STATE_PAUSED);
339   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
340
341   /* wait for completion */
342   res =
343       gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
344       GST_CLOCK_TIME_NONE);
345   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
346
347   /* add other element */
348   gst_bin_add_many (GST_BIN (bin), src2, NULL);
349
350   /* now link the second element */
351   res = gst_element_link (src2, adder);
352   fail_unless (res == TRUE, NULL);
353
354   /* set to PAUSED as well */
355   res = gst_element_set_state (src2, GST_STATE_PAUSED);
356
357   /* now play all */
358   res = gst_element_set_state (bin, GST_STATE_PLAYING);
359   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
360
361   g_main_loop_run (main_loop);
362
363   res = gst_element_set_state (bin, GST_STATE_NULL);
364   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
365
366   /* cleanup */
367   g_main_loop_unref (main_loop);
368   gst_object_unref (G_OBJECT (bus));
369   gst_object_unref (G_OBJECT (bin));
370 }
371
372 GST_END_TEST;
373
374 /* check if removing pads work as expected */
375 GST_START_TEST (test_remove_pad)
376 {
377   GstElement *bin, *src, *adder, *sink;
378   GstBus *bus;
379   GstPad *pad;
380   gboolean res;
381
382   GST_INFO ("preparing test");
383
384   /* build pipeline */
385   bin = gst_pipeline_new ("pipeline");
386   bus = gst_element_get_bus (bin);
387   gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH);
388
389   src = gst_element_factory_make ("audiotestsrc", "src");
390   g_object_set (src, "num-buffers", 4, NULL);
391   g_object_set (src, "wave", 4, NULL);
392   adder = gst_element_factory_make ("adder", "adder");
393   sink = gst_element_factory_make ("fakesink", "sink");
394   gst_bin_add_many (GST_BIN (bin), src, adder, sink, NULL);
395
396   res = gst_element_link (src, adder);
397   fail_unless (res == TRUE, NULL);
398   res = gst_element_link (adder, sink);
399   fail_unless (res == TRUE, NULL);
400
401   /* create an unconnected sinkpad in adder */
402   pad = gst_element_get_request_pad (adder, "sink%d");
403   fail_if (pad == NULL, NULL);
404
405   main_loop = g_main_loop_new (NULL, FALSE);
406   g_signal_connect (bus, "message::segment-done", (GCallback) message_received,
407       bin);
408   g_signal_connect (bus, "message::error", (GCallback) message_received, bin);
409   g_signal_connect (bus, "message::warning", (GCallback) message_received, bin);
410   g_signal_connect (bus, "message::eos", (GCallback) message_received, bin);
411
412   GST_INFO ("starting test");
413
414   /* prepare playing, this will not preroll as adder is waiting
415    * on the unconnected sinkpad. */
416   res = gst_element_set_state (bin, GST_STATE_PAUSED);
417   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
418
419   /* wait for completion for one second, will return ASYNC */
420   res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_SECOND);
421   fail_unless (res == GST_STATE_CHANGE_ASYNC, NULL);
422
423   /* get rid of the pad now, adder should stop waiting on it and
424    * continue the preroll */
425   gst_element_release_request_pad (adder, pad);
426   gst_object_unref (pad);
427
428   /* wait for completion, should work now */
429   res =
430       gst_element_get_state (GST_ELEMENT (bin), NULL, NULL,
431       GST_CLOCK_TIME_NONE);
432   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
433
434   /* now play all */
435   res = gst_element_set_state (bin, GST_STATE_PLAYING);
436   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
437
438   g_main_loop_run (main_loop);
439
440   res = gst_element_set_state (bin, GST_STATE_NULL);
441   fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL);
442
443   /* cleanup */
444   g_main_loop_unref (main_loop);
445   gst_object_unref (G_OBJECT (bus));
446   gst_object_unref (G_OBJECT (bin));
447 }
448
449 GST_END_TEST;
450
451
452 static Suite *
453 adder_suite (void)
454 {
455   Suite *s = suite_create ("adder");
456   TCase *tc_chain = tcase_create ("general");
457
458   suite_add_tcase (s, tc_chain);
459   tcase_add_test (tc_chain, test_event);
460   tcase_add_test (tc_chain, test_play_twice);
461   tcase_add_test (tc_chain, test_add_pad);
462   tcase_add_test (tc_chain, test_remove_pad);
463
464   /* Use a longer timeout */
465 #ifdef HAVE_VALGRIND
466   if (RUNNING_ON_VALGRIND) {
467     tcase_set_timeout (tc_chain, 5 * 60);
468   } else
469 #endif
470   {
471     /* this is shorter than the default 60 seconds?! (tpm) */
472     /* tcase_set_timeout (tc_chain, 6); */
473   }
474
475   return s;
476 }
477
478 int
479 main (int argc, char **argv)
480 {
481   int nf;
482
483   Suite *s = adder_suite ();
484   SRunner *sr = srunner_create (s);
485
486   gst_check_init (&argc, &argv);
487
488   srunner_run_all (sr, CK_NORMAL);
489   nf = srunner_ntests_failed (sr);
490   srunner_free (sr);
491
492   return nf;
493 }