74591c839ffe4d1cab6f005fadce7e86157feb33
[platform/upstream/gstreamer.git] / tests / check / libs / controller.c
1 /* GStreamer
2  *
3  * unit test for the controller library
4  *
5  * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dor net>
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 #include <gst/gst.h>
27 #include <gst/check/gstcheck.h>
28 #include <gst/controller/gstcontroller.h>
29
30 /* LOCAL TEST ELEMENT */
31
32 enum
33 {
34   ARG_ULONG = 1,
35   ARG_DOUBLE,
36   ARG_BOOLEAN,
37   ARG_READONLY,
38   ARG_STATIC,
39   ARG_CONSTRUCTONLY,
40   ARG_COUNT
41 };
42
43 #define GST_TYPE_TEST_MONO_SOURCE            (gst_test_mono_source_get_type ())
44 #define GST_TEST_MONO_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSource))
45 #define GST_TEST_MONO_SOURCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
46 #define GST_IS_TEST_MONO_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_MONO_SOURCE))
47 #define GST_IS_TEST_MONO_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_MONO_SOURCE))
48 #define GST_TEST_MONO_SOURCE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
49
50 typedef struct _GstTestMonoSource GstTestMonoSource;
51 typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass;
52
53 struct _GstTestMonoSource
54 {
55   GstElement parent;
56   gulong val_ulong;
57   gdouble val_double;
58   gboolean val_boolean;
59 };
60 struct _GstTestMonoSourceClass
61 {
62   GstElementClass parent_class;
63 };
64
65 GType gst_test_mono_source_get_type (void);
66
67 static void
68 gst_test_mono_source_get_property (GObject * object,
69     guint property_id, GValue * value, GParamSpec * pspec)
70 {
71   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
72
73   switch (property_id) {
74     case ARG_ULONG:
75       g_value_set_ulong (value, self->val_ulong);
76       break;
77     case ARG_DOUBLE:
78       g_value_set_double (value, self->val_double);
79       break;
80     case ARG_BOOLEAN:
81       g_value_set_boolean (value, self->val_boolean);
82       break;
83     default:
84       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
85       break;
86   }
87 }
88
89 static void
90 gst_test_mono_source_set_property (GObject * object,
91     guint property_id, const GValue * value, GParamSpec * pspec)
92 {
93   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
94
95   switch (property_id) {
96     case ARG_ULONG:
97       self->val_ulong = g_value_get_ulong (value);
98       break;
99     case ARG_DOUBLE:
100       self->val_double = g_value_get_double (value);
101       break;
102     case ARG_BOOLEAN:
103       self->val_boolean = g_value_get_boolean (value);
104       break;
105     case ARG_CONSTRUCTONLY:
106       break;
107     default:
108       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
109       break;
110   }
111 }
112
113 static void
114 gst_test_mono_source_class_init (GstTestMonoSourceClass * klass)
115 {
116   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
117
118   gobject_class->set_property = gst_test_mono_source_set_property;
119   gobject_class->get_property = gst_test_mono_source_get_property;
120
121   g_object_class_install_property (gobject_class, ARG_ULONG,
122       g_param_spec_ulong ("ulong",
123           "ulong prop",
124           "ulong number parameter for the test_mono_source",
125           0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
126
127   g_object_class_install_property (gobject_class, ARG_DOUBLE,
128       g_param_spec_double ("double",
129           "double prop",
130           "double number parameter for the test_mono_source",
131           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
132
133   g_object_class_install_property (gobject_class, ARG_BOOLEAN,
134       g_param_spec_boolean ("boolean",
135           "boolean prop",
136           "boolean parameter for the test_mono_source",
137           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
138
139   g_object_class_install_property (gobject_class, ARG_READONLY,
140       g_param_spec_ulong ("readonly",
141           "readonly prop",
142           "readonly parameter for the test_mono_source",
143           0, G_MAXULONG, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
144
145   g_object_class_install_property (gobject_class, ARG_STATIC,
146       g_param_spec_ulong ("static",
147           "static prop",
148           "static parameter for the test_mono_source",
149           0, G_MAXULONG, 0, G_PARAM_READWRITE));
150
151   g_object_class_install_property (gobject_class, ARG_CONSTRUCTONLY,
152       g_param_spec_ulong ("construct-only",
153           "construct-only prop",
154           "construct-only parameter for the test_mono_source",
155           0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
156 }
157
158 static void
159 gst_test_mono_source_base_init (GstTestMonoSourceClass * klass)
160 {
161   static const GstElementDetails details = {
162     "Monophonic source for unit tests",
163     "Source/Audio/MonoSource",
164     "Use in unit tests",
165     "Stefan Kost <ensonic@users.sf.net>"
166   };
167   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
168
169   gst_element_class_set_details (element_class, &details);
170 }
171
172 GType
173 gst_test_mono_source_get_type (void)
174 {
175   static GType type = 0;
176
177   if (type == 0) {
178     static const GTypeInfo info = {
179       (guint16) sizeof (GstTestMonoSourceClass),
180       (GBaseInitFunc) gst_test_mono_source_base_init,   // base_init
181       NULL,                     // base_finalize
182       (GClassInitFunc) gst_test_mono_source_class_init, // class_init
183       NULL,                     // class_finalize
184       NULL,                     // class_data
185       (guint16) sizeof (GstTestMonoSource),
186       0,                        // n_preallocs
187       NULL,                     // instance_init
188       NULL                      // value_table
189     };
190     type =
191         g_type_register_static (GST_TYPE_ELEMENT, "GstTestMonoSource", &info,
192         0);
193   }
194   return type;
195 }
196
197 static gboolean
198 plugin_init (GstPlugin * plugin)
199 {
200   gboolean res = TRUE;
201
202   res &= gst_element_register (plugin, "testmonosource", GST_RANK_NONE,
203       GST_TYPE_TEST_MONO_SOURCE);
204   return res;
205 }
206
207 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
208     GST_VERSION_MINOR,
209     "gst-test",
210     "controller test plugin - several unit test support elements",
211     plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN);
212
213 /*
214 static void __attribute__ ((constructor))
215 _gst_plugin_static_init__plugin_init (void)
216 {
217   static GstPluginDesc plugin_desc_ = {
218     GST_VERSION_MAJOR,
219     GST_VERSION_MINOR,
220     "gst-test",
221     "controller test plugin - several unit test support elements",
222     plugin_init,
223     VERSION,
224     GST_LICENSE,
225     PACKAGE,
226     GST_PACKAGE,
227     GST_ORIGIN,
228     GST_PADDING_INIT
229   };
230   _gst_plugin_register_static (&plugin_desc_);
231 }
232 */
233 /* TESTS */
234 /* double init should not harm */
235 GST_START_TEST (controller_init)
236 {
237   gst_controller_init (NULL, NULL);
238 }
239
240 GST_END_TEST;
241
242 /* tests for an element with no controlled params */
243 GST_START_TEST (controller_new_fail1)
244 {
245   GstController *ctrl;
246   GstElement *elem;
247
248   elem = gst_element_factory_make ("fakesrc", "test_source");
249
250   /* that property should not exist */
251   ctrl = gst_controller_new (G_OBJECT (elem), "_schrompf_", NULL);
252   fail_unless (ctrl == NULL, NULL);
253
254   gst_object_unref (elem);
255 }
256
257 GST_END_TEST;
258
259 /* tests for an element with controlled params, but none given */
260 GST_START_TEST (controller_new_fail2)
261 {
262   GstController *ctrl;
263   GstElement *elem;
264
265   elem = gst_element_factory_make ("testmonosource", "test_source");
266
267   /* no property given */
268   ctrl = gst_controller_new (G_OBJECT (elem), NULL);
269   fail_unless (ctrl == NULL, NULL);
270
271   gst_object_unref (elem);
272 }
273
274 GST_END_TEST;
275
276 /* tests for readonly params */
277 GST_START_TEST (controller_new_fail3)
278 {
279   GstController *ctrl;
280   GstElement *elem;
281
282   elem = gst_element_factory_make ("testmonosource", "test_source");
283
284   /* that property should exist and but is readonly */
285   ASSERT_CRITICAL (ctrl =
286       gst_controller_new (G_OBJECT (elem), "readonly", NULL));
287   fail_unless (ctrl == NULL, NULL);
288
289   gst_object_unref (elem);
290 }
291
292 GST_END_TEST;
293
294 /* tests for static params */
295 GST_START_TEST (controller_new_fail4)
296 {
297   GstController *ctrl;
298   GstElement *elem;
299
300   elem = gst_element_factory_make ("testmonosource", "test_source");
301
302   /* that property should exist and but is not controlable */
303   ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "static", NULL));
304   fail_unless (ctrl == NULL, NULL);
305
306   gst_object_unref (elem);
307 }
308
309 GST_END_TEST;
310
311 /* tests for static params */
312 GST_START_TEST (controller_new_fail5)
313 {
314   GstController *ctrl;
315   GstElement *elem;
316
317   elem = gst_element_factory_make ("testmonosource", "test_source");
318
319   /* that property should exist and but is construct-only */
320   ASSERT_CRITICAL (ctrl =
321       gst_controller_new (G_OBJECT (elem), "construct-only", NULL));
322   fail_unless (ctrl == NULL, NULL);
323
324   gst_object_unref (elem);
325 }
326
327 GST_END_TEST;
328
329
330 /* tests for an element with controlled params */
331 GST_START_TEST (controller_new_okay1)
332 {
333   GstController *ctrl;
334   GstElement *elem;
335
336   elem = gst_element_factory_make ("testmonosource", "test_source");
337
338   /* that property should exist and should be controllable */
339   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
340   fail_unless (ctrl != NULL, NULL);
341
342   g_object_unref (ctrl);
343   gst_object_unref (elem);
344 }
345
346 GST_END_TEST;
347
348 /* tests for an element with several controlled params */
349 GST_START_TEST (controller_new_okay2)
350 {
351   GstController *ctrl;
352   GstElement *elem;
353
354   elem = gst_element_factory_make ("testmonosource", "test_source");
355
356   /* that property should exist and should be controllable */
357   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "double", NULL);
358   fail_unless (ctrl != NULL, NULL);
359
360   g_object_unref (ctrl);
361   gst_object_unref (elem);
362 }
363
364 GST_END_TEST;
365
366 /* controlling several params should return the same controller */
367 GST_START_TEST (controller_new_okay3)
368 {
369   GstController *ctrl1, *ctrl2;
370   GstElement *elem;
371
372   elem = gst_element_factory_make ("testmonosource", "test_source");
373
374   /* that property should exist and should be controllable */
375   ctrl1 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
376   fail_unless (ctrl1 != NULL, NULL);
377
378   /* that property should exist and should be controllable */
379   ctrl2 = gst_controller_new (G_OBJECT (elem), "double", NULL);
380   fail_unless (ctrl2 != NULL, NULL);
381   fail_unless (ctrl1 == ctrl2, NULL);
382
383   g_object_unref (ctrl2);
384   g_object_unref (ctrl1);
385   gst_object_unref (elem);
386 }
387
388 GST_END_TEST;
389
390 /* controlling a params twice should be handled */
391 GST_START_TEST (controller_param_twice)
392 {
393   GstController *ctrl;
394   GstElement *elem;
395   gboolean res;
396
397   elem = gst_element_factory_make ("testmonosource", "test_source");
398
399   /* that property should exist and should be controllable */
400   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "ulong", NULL);
401   fail_unless (ctrl != NULL, NULL);
402
403   /* it should have been added at least once, let remove it */
404   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
405   fail_unless (res, NULL);
406
407   /* removing it agian should not work */
408   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
409   fail_unless (!res, NULL);
410
411   g_object_unref (ctrl);
412   gst_object_unref (elem);
413 }
414
415 GST_END_TEST;
416
417 /* tests if we cleanup properly */
418 GST_START_TEST (controller_finalize)
419 {
420   GstController *ctrl;
421   GstElement *elem;
422
423   elem = gst_element_factory_make ("testmonosource", "test_source");
424
425   /* that property should exist and should be controllable */
426   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
427   fail_unless (ctrl != NULL, NULL);
428
429   /* free the controller */
430   g_object_unref (ctrl);
431
432   /* object shouldn't have a controller anymore */
433   ctrl = gst_object_get_controller (G_OBJECT (elem));
434   fail_unless (ctrl == NULL, NULL);
435
436   gst_object_unref (elem);
437 }
438
439 GST_END_TEST;
440
441 /* test timed value handling without interpolation */
442 GST_START_TEST (controller_interpolate_none)
443 {
444   GstController *ctrl;
445   GstElement *elem;
446   gboolean res;
447   GValue val_ulong = { 0, };
448
449   elem = gst_element_factory_make ("testmonosource", "test_source");
450
451   /* that property should exist and should be controllable */
452   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
453   fail_unless (ctrl != NULL, NULL);
454
455   /* set interpolation mode */
456   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
457
458   /* set control values */
459   g_value_init (&val_ulong, G_TYPE_ULONG);
460   g_value_set_ulong (&val_ulong, 0);
461   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
462   fail_unless (res, NULL);
463   g_value_set_ulong (&val_ulong, 100);
464   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
465   fail_unless (res, NULL);
466
467   /* now pull in values for some timestamps */
468   gst_controller_sink_values (ctrl, 0 * GST_SECOND);
469   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
470   gst_controller_sink_values (ctrl, 1 * GST_SECOND);
471   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
472   gst_controller_sink_values (ctrl, 2 * GST_SECOND);
473   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
474
475   g_object_unref (ctrl);
476   gst_object_unref (elem);
477 }
478
479 GST_END_TEST;
480
481 /* tests if we can run helper methods against any GObject */
482 GST_START_TEST (controller_helper_any_gobject)
483 {
484   GstElement *elem;
485   gboolean res;
486
487   elem = gst_element_factory_make ("bin", "test_elem");
488
489   /* that element is not controllable */
490   res = gst_object_sink_values (G_OBJECT (elem), 0LL);
491   fail_unless (res == FALSE, NULL);
492
493   gst_object_unref (elem);
494 }
495
496 GST_END_TEST;
497
498
499 Suite *
500 gst_controller_suite (void)
501 {
502   Suite *s = suite_create ("Controller");
503   TCase *tc = tcase_create ("general");
504
505   suite_add_tcase (s, tc);
506   tcase_add_test (tc, controller_init);
507   tcase_add_test (tc, controller_new_fail1);
508   tcase_add_test (tc, controller_new_fail2);
509   tcase_add_test (tc, controller_new_fail3);
510   tcase_add_test (tc, controller_new_fail4);
511   tcase_add_test (tc, controller_new_fail5);
512   tcase_add_test (tc, controller_new_okay1);
513   tcase_add_test (tc, controller_new_okay2);
514   tcase_add_test (tc, controller_new_okay3);
515   tcase_add_test (tc, controller_param_twice);
516   tcase_add_test (tc, controller_finalize);
517   tcase_add_test (tc, controller_interpolate_none);
518   tcase_add_test (tc, controller_helper_any_gobject);
519
520   return s;
521 }
522
523 int
524 main (int argc, char **argv)
525 {
526   int nf;
527
528   Suite *s = gst_controller_suite ();
529   SRunner *sr = srunner_create (s);
530
531   gst_check_init (&argc, &argv);
532   gst_controller_init (NULL, NULL);
533
534   srunner_run_all (sr, CK_NORMAL);
535   nf = srunner_ntests_failed (sr);
536   srunner_free (sr);
537
538   return nf;
539 }