libs/gst/controller/gstcontroller.*: Clarify the docs of gst_controller_get_value_arr...
[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_FLOAT,
36   ARG_DOUBLE,
37   ARG_BOOLEAN,
38   ARG_READONLY,
39   ARG_STATIC,
40   ARG_CONSTRUCTONLY,
41   ARG_COUNT
42 };
43
44 #define GST_TYPE_TEST_MONO_SOURCE            (gst_test_mono_source_get_type ())
45 #define GST_TEST_MONO_SOURCE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSource))
46 #define GST_TEST_MONO_SOURCE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
47 #define GST_IS_TEST_MONO_SOURCE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_MONO_SOURCE))
48 #define GST_IS_TEST_MONO_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_MONO_SOURCE))
49 #define GST_TEST_MONO_SOURCE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_MONO_SOURCE, GstTestMonoSourceClass))
50
51 typedef struct _GstTestMonoSource GstTestMonoSource;
52 typedef struct _GstTestMonoSourceClass GstTestMonoSourceClass;
53
54 struct _GstTestMonoSource
55 {
56   GstElement parent;
57   gulong val_ulong;
58   gfloat val_float;
59   gdouble val_double;
60   gboolean val_boolean;
61 };
62 struct _GstTestMonoSourceClass
63 {
64   GstElementClass parent_class;
65 };
66
67 GType gst_test_mono_source_get_type (void);
68
69 static void
70 gst_test_mono_source_get_property (GObject * object,
71     guint property_id, GValue * value, GParamSpec * pspec)
72 {
73   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
74
75   switch (property_id) {
76     case ARG_ULONG:
77       g_value_set_ulong (value, self->val_ulong);
78       break;
79     case ARG_FLOAT:
80       g_value_set_float (value, self->val_float);
81       break;
82     case ARG_DOUBLE:
83       g_value_set_double (value, self->val_double);
84       break;
85     case ARG_BOOLEAN:
86       g_value_set_boolean (value, self->val_boolean);
87       break;
88     default:
89       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
90       break;
91   }
92 }
93
94 static void
95 gst_test_mono_source_set_property (GObject * object,
96     guint property_id, const GValue * value, GParamSpec * pspec)
97 {
98   GstTestMonoSource *self = GST_TEST_MONO_SOURCE (object);
99
100   switch (property_id) {
101     case ARG_ULONG:
102       self->val_ulong = g_value_get_ulong (value);
103       break;
104     case ARG_FLOAT:
105       self->val_float = g_value_get_float (value);
106       break;
107     case ARG_DOUBLE:
108       self->val_double = g_value_get_double (value);
109       break;
110     case ARG_BOOLEAN:
111       self->val_boolean = g_value_get_boolean (value);
112       break;
113     case ARG_CONSTRUCTONLY:
114       break;
115     default:
116       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
117       break;
118   }
119 }
120
121 static void
122 gst_test_mono_source_class_init (GstTestMonoSourceClass * klass)
123 {
124   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
125
126   gobject_class->set_property = gst_test_mono_source_set_property;
127   gobject_class->get_property = gst_test_mono_source_get_property;
128
129   g_object_class_install_property (gobject_class, ARG_ULONG,
130       g_param_spec_ulong ("ulong",
131           "ulong prop",
132           "ulong number parameter for the test_mono_source",
133           0, G_MAXULONG, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
134
135   g_object_class_install_property (gobject_class, ARG_FLOAT,
136       g_param_spec_float ("float",
137           "float prop",
138           "float number parameter for the test_mono_source",
139           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
140
141   g_object_class_install_property (gobject_class, ARG_DOUBLE,
142       g_param_spec_double ("double",
143           "double prop",
144           "double number parameter for the test_mono_source",
145           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
146
147   g_object_class_install_property (gobject_class, ARG_BOOLEAN,
148       g_param_spec_boolean ("boolean",
149           "boolean prop",
150           "boolean parameter for the test_mono_source",
151           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
152
153   g_object_class_install_property (gobject_class, ARG_READONLY,
154       g_param_spec_ulong ("readonly",
155           "readonly prop",
156           "readonly parameter for the test_mono_source",
157           0, G_MAXULONG, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
158
159   g_object_class_install_property (gobject_class, ARG_STATIC,
160       g_param_spec_ulong ("static",
161           "static prop",
162           "static parameter for the test_mono_source",
163           0, G_MAXULONG, 0, G_PARAM_READWRITE));
164
165   g_object_class_install_property (gobject_class, ARG_CONSTRUCTONLY,
166       g_param_spec_ulong ("construct-only",
167           "construct-only prop",
168           "construct-only parameter for the test_mono_source",
169           0, G_MAXULONG, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
170 }
171
172 static void
173 gst_test_mono_source_base_init (GstTestMonoSourceClass * klass)
174 {
175   static const GstElementDetails details = {
176     "Monophonic source for unit tests",
177     "Source/Audio/MonoSource",
178     "Use in unit tests",
179     "Stefan Kost <ensonic@users.sf.net>"
180   };
181   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
182
183   gst_element_class_set_details (element_class, &details);
184 }
185
186 GType
187 gst_test_mono_source_get_type (void)
188 {
189   static GType type = 0;
190
191   if (type == 0) {
192     static const GTypeInfo info = {
193       (guint16) sizeof (GstTestMonoSourceClass),
194       (GBaseInitFunc) gst_test_mono_source_base_init,   // base_init
195       NULL,                     // base_finalize
196       (GClassInitFunc) gst_test_mono_source_class_init, // class_init
197       NULL,                     // class_finalize
198       NULL,                     // class_data
199       (guint16) sizeof (GstTestMonoSource),
200       0,                        // n_preallocs
201       NULL,                     // instance_init
202       NULL                      // value_table
203     };
204     type =
205         g_type_register_static (GST_TYPE_ELEMENT, "GstTestMonoSource", &info,
206         0);
207   }
208   return type;
209 }
210
211 static gboolean
212 plugin_init (GstPlugin * plugin)
213 {
214   gboolean res = TRUE;
215
216   res &= gst_element_register (plugin, "testmonosource", GST_RANK_NONE,
217       GST_TYPE_TEST_MONO_SOURCE);
218   return res;
219 }
220
221 GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR,
222     GST_VERSION_MINOR,
223     "gst-test",
224     "controller test plugin - several unit test support elements",
225     plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);
226
227 /*
228 static void __attribute__ ((constructor))
229 _gst_plugin_static_init__plugin_init (void)
230 {
231   static GstPluginDesc plugin_desc_ = {
232     GST_VERSION_MAJOR,
233     GST_VERSION_MINOR,
234     "gst-test",
235     "controller test plugin - several unit test support elements",
236     plugin_init,
237     VERSION,
238     GST_LICENSE,
239     PACKAGE,
240     GST_PACKAGE,
241     GST_ORIGIN,
242     GST_PADDING_INIT
243   };
244   _gst_plugin_register_static (&plugin_desc_);
245 }
246 */
247 /* TESTS */
248 /* double init should not harm */
249 GST_START_TEST (controller_init)
250 {
251   gst_controller_init (NULL, NULL);
252   gst_controller_init (NULL, NULL);
253   gst_controller_init (NULL, NULL);
254   gst_controller_init (NULL, NULL);
255 }
256
257 GST_END_TEST;
258
259 /* tests for an element with no controlled params */
260 GST_START_TEST (controller_new_fail1)
261 {
262   GstController *ctrl;
263   GstElement *elem;
264
265   gst_controller_init (NULL, NULL);
266
267   elem = gst_element_factory_make ("fakesrc", "test_source");
268
269   /* that property should not exist */
270   ctrl = gst_controller_new (G_OBJECT (elem), "_schrompf_", NULL);
271   fail_unless (ctrl == NULL, NULL);
272
273   gst_object_unref (elem);
274 }
275
276 GST_END_TEST;
277
278 /* tests for an element with controlled params, but none given */
279 GST_START_TEST (controller_new_fail2)
280 {
281   GstController *ctrl;
282   GstElement *elem;
283
284   gst_controller_init (NULL, NULL);
285
286   elem = gst_element_factory_make ("testmonosource", "test_source");
287
288   /* no property given */
289   ctrl = gst_controller_new (G_OBJECT (elem), NULL);
290   fail_unless (ctrl == NULL, NULL);
291
292   gst_object_unref (elem);
293 }
294
295 GST_END_TEST;
296
297 /* tests for readonly params */
298 GST_START_TEST (controller_new_fail3)
299 {
300   GstController *ctrl;
301   GstElement *elem;
302
303   gst_controller_init (NULL, NULL);
304
305   elem = gst_element_factory_make ("testmonosource", "test_source");
306
307   /* that property should exist and but is readonly */
308   ASSERT_CRITICAL (ctrl =
309       gst_controller_new (G_OBJECT (elem), "readonly", NULL));
310   fail_unless (ctrl == NULL, NULL);
311
312   gst_object_unref (elem);
313 }
314
315 GST_END_TEST;
316
317 /* tests for static params */
318 GST_START_TEST (controller_new_fail4)
319 {
320   GstController *ctrl;
321   GstElement *elem;
322
323   gst_controller_init (NULL, NULL);
324
325   elem = gst_element_factory_make ("testmonosource", "test_source");
326
327   /* that property should exist and but is not controlable */
328   ASSERT_CRITICAL (ctrl = gst_controller_new (G_OBJECT (elem), "static", NULL));
329   fail_unless (ctrl == NULL, NULL);
330
331   gst_object_unref (elem);
332 }
333
334 GST_END_TEST;
335
336 /* tests for static params */
337 GST_START_TEST (controller_new_fail5)
338 {
339   GstController *ctrl;
340   GstElement *elem;
341
342   gst_controller_init (NULL, NULL);
343
344   elem = gst_element_factory_make ("testmonosource", "test_source");
345
346   /* that property should exist and but is construct-only */
347   ASSERT_CRITICAL (ctrl =
348       gst_controller_new (G_OBJECT (elem), "construct-only", NULL));
349   fail_unless (ctrl == NULL, NULL);
350
351   gst_object_unref (elem);
352 }
353
354 GST_END_TEST;
355
356
357 /* tests for an element with controlled params */
358 GST_START_TEST (controller_new_okay1)
359 {
360   GstController *ctrl;
361   GstElement *elem;
362
363   gst_controller_init (NULL, NULL);
364
365   elem = gst_element_factory_make ("testmonosource", "test_source");
366
367   /* that property should exist and should be controllable */
368   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
369   fail_unless (ctrl != NULL, NULL);
370
371   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
372   g_object_unref (ctrl);
373   gst_object_unref (elem);
374 }
375
376 GST_END_TEST;
377
378 /* tests for an element with several controlled params */
379 GST_START_TEST (controller_new_okay2)
380 {
381   GstController *ctrl, *ctrl2, *ctrl3;
382   GstElement *elem;
383
384   gst_controller_init (NULL, NULL);
385
386   elem = gst_element_factory_make ("testmonosource", "test_source");
387
388   /* that property should exist and should be controllable */
389   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "double", "float", NULL);
390   fail_unless (ctrl != NULL, NULL);
391
392   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
393   fail_unless (G_OBJECT (ctrl)->ref_count == 1);
394
395   ctrl2 = gst_controller_new (G_OBJECT (elem), "boolean", NULL);
396   fail_unless (ctrl2 != NULL, NULL);
397   fail_unless (ctrl2 == ctrl, NULL);
398
399   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
400   fail_unless (G_OBJECT (ctrl)->ref_count == 2);
401
402   /* trying to control the same properties again should correctly
403    * increase the refcount of the object returned as well */
404   ctrl3 =
405       gst_controller_new (G_OBJECT (elem), "ulong", "double", "float", NULL);
406   fail_unless (ctrl3 != NULL, NULL);
407   fail_unless (ctrl3 == ctrl, NULL);
408
409   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
410   fail_unless (G_OBJECT (ctrl)->ref_count == 3);
411
412   g_object_unref (ctrl);
413   g_object_unref (ctrl2);
414   g_object_unref (ctrl3);
415   gst_object_unref (elem);
416 }
417
418 GST_END_TEST;
419
420 /* controlling several params should return the same controller */
421 GST_START_TEST (controller_new_okay3)
422 {
423   GstController *ctrl1, *ctrl2, *ctrl3;
424   GstElement *elem;
425
426   gst_controller_init (NULL, NULL);
427
428   elem = gst_element_factory_make ("testmonosource", "test_source");
429
430   /* that property should exist and should be controllable */
431   ctrl1 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
432   fail_unless (ctrl1 != NULL, NULL);
433
434   /* that property should exist and should be controllable */
435   ctrl2 = gst_controller_new (G_OBJECT (elem), "double", NULL);
436   fail_unless (ctrl2 != NULL, NULL);
437   fail_unless (ctrl1 == ctrl2, NULL);
438
439   /* that property should exist and should be controllable */
440   ctrl3 = gst_controller_new (G_OBJECT (elem), "float", NULL);
441   fail_unless (ctrl3 != NULL, NULL);
442   fail_unless (ctrl1 == ctrl3, NULL);
443
444   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl1)->ref_count);
445   fail_unless (G_OBJECT (ctrl1)->ref_count == 3);
446   g_object_unref (ctrl1);
447   g_object_unref (ctrl2);
448   g_object_unref (ctrl3);
449   gst_object_unref (elem);
450 }
451
452 GST_END_TEST;
453
454 /* controlling a params twice should be handled */
455 GST_START_TEST (controller_param_twice)
456 {
457   GstController *ctrl;
458   GstElement *elem;
459   gboolean res;
460
461   gst_controller_init (NULL, NULL);
462
463   elem = gst_element_factory_make ("testmonosource", "test_source");
464
465   /* that property should exist and should be controllable */
466   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", "ulong", NULL);
467   fail_unless (ctrl != NULL, NULL);
468
469   /* it should have been added at least once, let remove it */
470   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
471   fail_unless (res, NULL);
472
473   /* removing it agian should not work */
474   res = gst_controller_remove_properties (ctrl, "ulong", NULL);
475   fail_unless (!res, NULL);
476
477   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
478   g_object_unref (ctrl);
479   gst_object_unref (elem);
480 }
481
482 GST_END_TEST;
483
484 /* tests if we cleanup properly */
485 GST_START_TEST (controller_finalize)
486 {
487   GstController *ctrl;
488   GstElement *elem;
489
490   gst_controller_init (NULL, NULL);
491
492   elem = gst_element_factory_make ("testmonosource", "test_source");
493
494   /* that property should exist and should be controllable */
495   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
496   fail_unless (ctrl != NULL, NULL);
497
498   /* free the controller */
499   g_object_unref (ctrl);
500
501   /* object shouldn't have a controller anymore */
502   ctrl = gst_object_get_controller (G_OBJECT (elem));
503   fail_unless (ctrl == NULL, NULL);
504
505   gst_object_unref (elem);
506 }
507
508 GST_END_TEST;
509
510 /* test timed value handling without interpolation */
511 GST_START_TEST (controller_interpolate_none)
512 {
513   GstController *ctrl;
514   GstElement *elem;
515   gboolean res;
516   GValue val_ulong = { 0, };
517
518   gst_controller_init (NULL, NULL);
519
520   elem = gst_element_factory_make ("testmonosource", "test_source");
521
522   /* that property should exist and should be controllable */
523   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
524   fail_unless (ctrl != NULL, NULL);
525
526   /* set interpolation mode */
527   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
528
529   /* set control values */
530   g_value_init (&val_ulong, G_TYPE_ULONG);
531   g_value_set_ulong (&val_ulong, 0);
532   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
533   fail_unless (res, NULL);
534   g_value_set_ulong (&val_ulong, 100);
535   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
536   fail_unless (res, NULL);
537
538   /* now pull in values for some timestamps */
539   gst_controller_sync_values (ctrl, 0 * GST_SECOND);
540   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
541   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
542   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
543   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
544   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
545
546   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
547   g_object_unref (ctrl);
548   gst_object_unref (elem);
549 }
550
551 GST_END_TEST;
552
553 /* test timed value handling in trigger mode */
554 GST_START_TEST (controller_interpolate_trigger)
555 {
556   GstController *ctrl;
557   GstElement *elem;
558   gboolean res;
559   GValue val_ulong = { 0, };
560
561   gst_controller_init (NULL, NULL);
562
563   elem = gst_element_factory_make ("testmonosource", "test_source");
564
565   /* that property should exist and should be controllable */
566   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
567   fail_unless (ctrl != NULL, NULL);
568
569   /* set interpolation mode */
570   gst_controller_set_interpolation_mode (ctrl, "ulong",
571       GST_INTERPOLATE_TRIGGER);
572
573   /* set control values */
574   g_value_init (&val_ulong, G_TYPE_ULONG);
575   g_value_set_ulong (&val_ulong, 50);
576   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
577   fail_unless (res, NULL);
578   g_value_set_ulong (&val_ulong, 100);
579   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
580   fail_unless (res, NULL);
581
582   /* now pull in values for some timestamps */
583   gst_controller_sync_values (ctrl, 0 * GST_SECOND);
584   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 50, NULL);
585   GST_TEST_MONO_SOURCE (elem)->val_ulong = 0;
586   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
587   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
588   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
589   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
590
591   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
592   g_object_unref (ctrl);
593   gst_object_unref (elem);
594 }
595
596 GST_END_TEST;
597
598 /* test timed value handling with linear interpolation */
599 GST_START_TEST (controller_interpolate_linear)
600 {
601   GstController *ctrl;
602   GstElement *elem;
603   gboolean res;
604   GValue val_ulong = { 0, };
605
606   gst_controller_init (NULL, NULL);
607
608   elem = gst_element_factory_make ("testmonosource", "test_source");
609
610   /* that property should exist and should be controllable */
611   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
612   fail_unless (ctrl != NULL, NULL);
613
614   /* set interpolation mode */
615   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_LINEAR);
616
617   /* set control values */
618   g_value_init (&val_ulong, G_TYPE_ULONG);
619   g_value_set_ulong (&val_ulong, 0);
620   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
621   fail_unless (res, NULL);
622   g_value_set_ulong (&val_ulong, 100);
623   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
624   fail_unless (res, NULL);
625
626   /* now pull in values for some timestamps */
627   gst_controller_sync_values (ctrl, 0 * GST_SECOND);
628   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
629   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
630   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 50, NULL);
631   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
632   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
633
634   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
635   g_object_unref (ctrl);
636   gst_object_unref (elem);
637 }
638
639 GST_END_TEST;
640
641 /* make sure we don't crash when someone sets an unsupported interpolation
642  * mode */
643 GST_START_TEST (controller_interpolate_unimplemented)
644 {
645   GstController *ctrl;
646   GstElement *elem;
647
648   gst_controller_init (NULL, NULL);
649
650   elem = gst_element_factory_make ("testmonosource", "test_source");
651
652   /* that property should exist and should be controllable */
653   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
654   fail_unless (ctrl != NULL, NULL);
655
656   /* set unsupported interpolation mode */
657   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_CUBIC);
658
659   /* set another unsupported interpolation mode */
660   gst_controller_set_interpolation_mode (ctrl, "ulong",
661       GST_INTERPOLATE_QUADRATIC);
662
663   /* set completely bogus interpolation mode */
664   gst_controller_set_interpolation_mode (ctrl, "ulong",
665       (GstInterpolateMode) 93871);
666
667   g_object_unref (ctrl);
668   gst_object_unref (elem);
669 }
670
671 GST_END_TEST;
672
673 /* test _unset() */
674 GST_START_TEST (controller_unset)
675 {
676   GstController *ctrl;
677   GstElement *elem;
678   gboolean res;
679   GValue val_ulong = { 0, };
680
681   gst_controller_init (NULL, NULL);
682
683   elem = gst_element_factory_make ("testmonosource", "test_source");
684
685   /* that property should exist and should be controllable */
686   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
687   fail_unless (ctrl != NULL, NULL);
688
689   /* set interpolation mode */
690   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
691
692   /* set control values */
693   g_value_init (&val_ulong, G_TYPE_ULONG);
694   g_value_set_ulong (&val_ulong, 0);
695   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
696   fail_unless (res, NULL);
697   g_value_set_ulong (&val_ulong, 100);
698   res = gst_controller_set (ctrl, "ulong", 1 * GST_SECOND, &val_ulong);
699   fail_unless (res, NULL);
700   g_value_set_ulong (&val_ulong, 50);
701   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
702   fail_unless (res, NULL);
703
704   /* verify values */
705   gst_controller_sync_values (ctrl, 0 * GST_SECOND);
706   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
707   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
708   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
709   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
710   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 50, NULL);
711
712   /* unset second */
713   res = gst_controller_unset (ctrl, "ulong", 1 * GST_SECOND);
714   fail_unless (res, NULL);
715
716   /* verify value again */
717   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
718   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
719   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
720   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 50, NULL);
721
722   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
723   g_object_unref (ctrl);
724   gst_object_unref (elem);
725 }
726
727 GST_END_TEST;
728
729 /* test _unset_all() */
730 GST_START_TEST (controller_unset_all)
731 {
732   GstController *ctrl;
733   GstElement *elem;
734   gboolean res;
735   GValue val_ulong = { 0, };
736
737   gst_controller_init (NULL, NULL);
738
739   elem = gst_element_factory_make ("testmonosource", "test_source");
740
741   /* that property should exist and should be controllable */
742   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
743   fail_unless (ctrl != NULL, NULL);
744
745   /* set interpolation mode */
746   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_NONE);
747
748   /* set control values */
749   g_value_init (&val_ulong, G_TYPE_ULONG);
750   g_value_set_ulong (&val_ulong, 0);
751   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
752   fail_unless (res, NULL);
753   g_value_set_ulong (&val_ulong, 100);
754   res = gst_controller_set (ctrl, "ulong", 1 * GST_SECOND, &val_ulong);
755   fail_unless (res, NULL);
756
757   /* verify values */
758   gst_controller_sync_values (ctrl, 0 * GST_SECOND);
759   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
760   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
761   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
762
763   /* unset second */
764   res = gst_controller_unset_all (ctrl, "ulong");
765   fail_unless (res, NULL);
766
767   /* verify value again */
768   gst_controller_sync_values (ctrl, 1 * GST_SECOND);
769   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 0, NULL);
770
771   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
772   g_object_unref (ctrl);
773   gst_object_unref (elem);
774 }
775
776 GST_END_TEST;
777
778 /* test live value handling */
779 GST_START_TEST (controller_live)
780 {
781   GstController *ctrl;
782   GstElement *elem;
783   gboolean res;
784   GValue val_ulong = { 0, };
785
786   gst_controller_init (NULL, NULL);
787
788   elem = gst_element_factory_make ("testmonosource", "test_source");
789
790   /* that property should exist and should be controllable */
791   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
792   fail_unless (ctrl != NULL, NULL);
793
794   /* set interpolation mode */
795   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_LINEAR);
796
797   /* set control values */
798   g_value_init (&val_ulong, G_TYPE_ULONG);
799   g_value_set_ulong (&val_ulong, 0);
800   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
801   fail_unless (res, NULL);
802   g_value_set_ulong (&val_ulong, 100);
803   res = gst_controller_set (ctrl, "ulong", 4 * GST_SECOND, &val_ulong);
804   fail_unless (res, NULL);
805   g_value_set_ulong (&val_ulong, 200);
806   res = gst_controller_set (ctrl, "ulong", 8 * GST_SECOND, &val_ulong);
807   fail_unless (res, NULL);
808
809   /* verify value */
810   gst_controller_sync_values (ctrl, 2 * GST_SECOND);
811   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 50, NULL);
812
813   /* set live value */
814   g_object_set (elem, "ulong", 500, NULL);
815
816   /* we should still get the live value */
817   gst_controller_sync_values (ctrl, 3 * GST_SECOND);
818   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 500, NULL);
819
820   /* we should not get the live value anymore */
821   gst_controller_sync_values (ctrl, 4 * GST_SECOND);
822   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 100, NULL);
823   gst_controller_sync_values (ctrl, 6 * GST_SECOND);
824   fail_unless (GST_TEST_MONO_SOURCE (elem)->val_ulong == 150, NULL);
825
826   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
827   g_object_unref (ctrl);
828   gst_object_unref (elem);
829 }
830
831 GST_END_TEST;
832
833 /* tests if we can run helper methods against any GObject */
834 GST_START_TEST (controller_helper_any_gobject)
835 {
836   GstElement *elem;
837   gboolean res;
838
839   gst_controller_init (NULL, NULL);
840
841   elem = gst_element_factory_make ("bin", "test_elem");
842
843   /* that element is not controllable */
844   res = gst_object_sync_values (G_OBJECT (elem), 0LL);
845   fail_unless (res == FALSE, NULL);
846
847   gst_object_unref (elem);
848 }
849
850 GST_END_TEST;
851
852 GST_START_TEST (controller_misc)
853 {
854   GstController *ctrl;
855   GstTimedValue *tval;
856   GstElement *elem;
857   GSList *list = NULL;
858
859   gst_controller_init (NULL, NULL);
860
861   /* test that an invalid timestamp throws a warning of some sort */
862   elem = gst_element_factory_make ("testmonosource", "test_source");
863
864   /* that property should exist and should be controllable */
865   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
866   fail_unless (ctrl != NULL, NULL);
867
868   /* set interpolation mode */
869   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_LINEAR);
870
871   /* set control value */
872   tval = g_new0 (GstTimedValue, 1);
873   tval->timestamp = GST_CLOCK_TIME_NONE;
874   g_value_init (&tval->value, G_TYPE_ULONG);
875   g_value_set_ulong (&tval->value, 0);
876
877   list = g_slist_append (list, tval);
878
879   ASSERT_WARNING (fail_if (gst_controller_set_from_list (ctrl, "ulong", list)));
880
881   /* try again with a valid stamp, should work now */
882   tval->timestamp = 0;
883   fail_unless (gst_controller_set_from_list (ctrl, "ulong", list));
884
885   /* allocated GstTimedValue now belongs to the controller, but list not */
886   g_value_unset (&tval->value);
887   g_free (tval);
888   g_slist_free (list);
889   g_object_unref (ctrl);
890   gst_object_unref (elem);
891 }
892
893 GST_END_TEST;
894
895 GST_START_TEST (controller_refcount_new_list)
896 {
897   GstController *ctrl, *ctrl2;
898   GstElement *elem;
899   GList *list = NULL;
900
901   gst_controller_init (NULL, NULL);
902
903   /* that property should exist and should be controllable */
904   elem = gst_element_factory_make ("testmonosource", "test_source");
905   list = g_list_append (NULL, "ulong");
906   ctrl = gst_controller_new_list (G_OBJECT (elem), list);
907   fail_unless (ctrl != NULL, NULL);
908   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
909   fail_unless (G_OBJECT (ctrl)->ref_count == 1);
910   g_list_free (list);
911   g_object_unref (ctrl);
912   gst_object_unref (elem);
913
914   /* try the same property twice, make sure the refcount is still 1 */
915   elem = gst_element_factory_make ("testmonosource", "test_source");
916   list = g_list_append (NULL, "ulong");
917   list = g_list_append (list, "ulong");
918   ctrl = gst_controller_new_list (G_OBJECT (elem), list);
919   fail_unless (ctrl != NULL, NULL);
920   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
921   fail_unless (G_OBJECT (ctrl)->ref_count == 1);
922   g_list_free (list);
923   g_object_unref (ctrl);
924   gst_object_unref (elem);
925
926   /* try two properties, make sure the refcount is still 1 */
927   elem = gst_element_factory_make ("testmonosource", "test_source");
928   list = g_list_append (NULL, "ulong");
929   list = g_list_append (list, "boolean");
930   ctrl = gst_controller_new_list (G_OBJECT (elem), list);
931   fail_unless (ctrl != NULL, NULL);
932   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
933   fail_unless (G_OBJECT (ctrl)->ref_count == 1);
934   g_list_free (list);
935   g_object_unref (ctrl);
936   gst_object_unref (elem);
937
938   /* try _new_list with existing controller */
939   elem = gst_element_factory_make ("testmonosource", "test_source");
940   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
941   fail_unless (ctrl != NULL, NULL);
942   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
943   list = g_list_append (NULL, "ulong");
944   ctrl2 = gst_controller_new_list (G_OBJECT (elem), list);
945   fail_unless (ctrl2 != NULL, NULL);
946   fail_unless (ctrl == ctrl2, NULL);
947   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
948   fail_unless (G_OBJECT (ctrl)->ref_count == 2);
949   g_list_free (list);
950   g_object_unref (ctrl);
951   g_object_unref (ctrl2);
952   gst_object_unref (elem);
953
954   /* try _new_list first and then _new */
955   elem = gst_element_factory_make ("testmonosource", "test_source");
956   list = g_list_append (NULL, "ulong");
957   ctrl = gst_controller_new_list (G_OBJECT (elem), list);
958   fail_unless (ctrl != NULL, NULL);
959   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
960   ctrl2 = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
961   fail_unless (ctrl2 != NULL, NULL);
962   fail_unless (ctrl == ctrl2, NULL);
963   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
964   fail_unless (G_OBJECT (ctrl)->ref_count == 2);
965   g_list_free (list);
966   g_object_unref (ctrl);
967   g_object_unref (ctrl2);
968   gst_object_unref (elem);
969 }
970
971 GST_END_TEST;
972
973
974 /* test retrieval of an array of values with get_value_array() */
975 GST_START_TEST (controller_interpolate_linear_value_array)
976 {
977   GstController *ctrl;
978   GstElement *elem;
979   gboolean res;
980   GValue val_ulong = { 0, };
981   GstValueArray values = { 0, };
982
983   gst_controller_init (NULL, NULL);
984
985   elem = gst_element_factory_make ("testmonosource", "test_source");
986
987   /* that property should exist and should be controllable */
988   ctrl = gst_controller_new (G_OBJECT (elem), "ulong", NULL);
989   fail_unless (ctrl != NULL, NULL);
990
991   /* set interpolation mode */
992   gst_controller_set_interpolation_mode (ctrl, "ulong", GST_INTERPOLATE_LINEAR);
993
994   /* set control values */
995   g_value_init (&val_ulong, G_TYPE_ULONG);
996   g_value_set_ulong (&val_ulong, 0);
997   res = gst_controller_set (ctrl, "ulong", 0 * GST_SECOND, &val_ulong);
998   fail_unless (res, NULL);
999   g_value_set_ulong (&val_ulong, 100);
1000   res = gst_controller_set (ctrl, "ulong", 2 * GST_SECOND, &val_ulong);
1001   fail_unless (res, NULL);
1002
1003   /* now pull in values for some timestamps */
1004   values.property_name = "ulong";
1005   values.nbsamples = 3;
1006   values.sample_interval = GST_SECOND;
1007   values.values = (gpointer) g_new (gulong, 3);
1008
1009   fail_unless (gst_controller_get_value_array (ctrl, 0, &values));
1010   fail_unless_equals_int (((gulong *) values.values)[0], 0);
1011   fail_unless_equals_int (((gulong *) values.values)[1], 50);
1012   fail_unless_equals_int (((gulong *) values.values)[2], 100);
1013
1014   GST_INFO ("controller->ref_count=%d", G_OBJECT (ctrl)->ref_count);
1015   g_free (values.values);
1016   g_object_unref (ctrl);
1017   gst_object_unref (elem);
1018 }
1019
1020 GST_END_TEST;
1021
1022 static Suite *
1023 gst_controller_suite (void)
1024 {
1025   Suite *s = suite_create ("Controller");
1026   TCase *tc = tcase_create ("general");
1027
1028   suite_add_tcase (s, tc);
1029   tcase_add_test (tc, controller_init);
1030   tcase_add_test (tc, controller_refcount_new_list);
1031   tcase_add_test (tc, controller_new_fail1);
1032   tcase_add_test (tc, controller_new_fail2);
1033   tcase_add_test (tc, controller_new_fail3);
1034   tcase_add_test (tc, controller_new_fail4);
1035   tcase_add_test (tc, controller_new_fail5);
1036   tcase_add_test (tc, controller_new_okay1);
1037   tcase_add_test (tc, controller_new_okay2);
1038   tcase_add_test (tc, controller_new_okay3);
1039   tcase_add_test (tc, controller_param_twice);
1040   tcase_add_test (tc, controller_finalize);
1041   tcase_add_test (tc, controller_interpolate_none);
1042   tcase_add_test (tc, controller_interpolate_trigger);
1043   tcase_add_test (tc, controller_interpolate_linear);
1044   tcase_add_test (tc, controller_interpolate_unimplemented);
1045   tcase_add_test (tc, controller_unset);
1046   tcase_add_test (tc, controller_unset_all);
1047   tcase_add_test (tc, controller_live);
1048   tcase_add_test (tc, controller_helper_any_gobject);
1049   tcase_add_test (tc, controller_misc);
1050   tcase_add_test (tc, controller_interpolate_linear_value_array);
1051
1052   return s;
1053 }
1054
1055 GST_CHECK_MAIN (gst_controller);