155c86302981e1bdd063701470166e6d88e75f23
[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 dot net>
6  * Copyright (C) <2006-2007> Sebastian Dröge <slomo@circular-chaos.org>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27 #include <gst/gst.h>
28 #include <gst/check/gstcheck.h>
29 #include <gst/controller/gstinterpolationcontrolsource.h>
30 #include <gst/controller/gstlfocontrolsource.h>
31 #include <gst/controller/gsttriggercontrolsource.h>
32
33 /* enum for text element */
34
35 #define GST_TYPE_TEST_ENUM (gst_test_enum_get_type ())
36
37 typedef enum
38 {
39   ENUM_V0 = 0,
40   ENUM_V10 = 10,
41   ENUM_V11,
42   ENUM_V12,
43   ENUM_V255 = 255
44 } GstTestEnum;
45
46 static GType
47 gst_test_enum_get_type (void)
48 {
49   static gsize gtype = 0;
50   static const GEnumValue values[] = {
51     {ENUM_V0, "ENUM_V0", "0"},
52     {ENUM_V10, "ENUM_V10", "10"},
53     {ENUM_V11, "ENUM_V11", "11"},
54     {ENUM_V12, "ENUM_V12", "12"},
55     {ENUM_V255, "ENUM_V255", "255"},
56     {0, NULL, NULL}
57   };
58
59   if (g_once_init_enter (&gtype)) {
60     GType tmp = g_enum_register_static ("GstTestEnum", values);
61     g_once_init_leave (&gtype, tmp);
62   }
63
64   return (GType) gtype;
65 }
66
67 /* local test element */
68
69 enum
70 {
71   PROP_INT = 1,
72   PROP_FLOAT,
73   PROP_DOUBLE,
74   PROP_BOOLEAN,
75   PROP_ENUM,
76   PROP_READONLY,
77   PROP_STATIC,
78   PROP_CONSTRUCTONLY,
79   PROP_COUNT
80 };
81
82 #define GST_TYPE_TEST_OBJ            (gst_test_obj_get_type ())
83 #define GST_TEST_OBJ(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TEST_OBJ, GstTestObj))
84 #define GST_TEST_OBJ_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_TEST_OBJ, GstTestObjClass))
85 #define GST_IS_TEST_OBJ(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TEST_OBJ))
86 #define GST_IS_TEST_OBJ_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_TEST_OBJ))
87 #define GST_TEST_OBJ_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_TEST_OBJ, GstTestObjClass))
88
89 typedef struct _GstTestObj GstTestObj;
90 typedef struct _GstTestObjClass GstTestObjClass;
91
92 struct _GstTestObj
93 {
94   GstElement parent;
95   gint val_int;
96   gfloat val_float;
97   gdouble val_double;
98   gboolean val_boolean;
99   GstTestEnum val_enum;
100 };
101 struct _GstTestObjClass
102 {
103   GstElementClass parent_class;
104 };
105
106 static GType gst_test_obj_get_type (void);
107
108 static void
109 gst_test_obj_get_property (GObject * object,
110     guint property_id, GValue * value, GParamSpec * pspec)
111 {
112   GstTestObj *self = GST_TEST_OBJ (object);
113
114   switch (property_id) {
115     case PROP_INT:
116       g_value_set_int (value, self->val_int);
117       break;
118     case PROP_FLOAT:
119       g_value_set_float (value, self->val_float);
120       break;
121     case PROP_DOUBLE:
122       g_value_set_double (value, self->val_double);
123       break;
124     case PROP_BOOLEAN:
125       g_value_set_boolean (value, self->val_boolean);
126       break;
127     case PROP_ENUM:
128       g_value_set_enum (value, self->val_enum);
129       break;
130     default:
131       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
132       break;
133   }
134 }
135
136 static void
137 gst_test_obj_set_property (GObject * object,
138     guint property_id, const GValue * value, GParamSpec * pspec)
139 {
140   GstTestObj *self = GST_TEST_OBJ (object);
141
142   switch (property_id) {
143     case PROP_INT:
144       self->val_int = g_value_get_int (value);
145       GST_DEBUG ("test value int=%d", self->val_int);
146       break;
147     case PROP_FLOAT:
148       self->val_float = g_value_get_float (value);
149       GST_DEBUG ("test value float=%f", self->val_float);
150       break;
151     case PROP_DOUBLE:
152       self->val_double = g_value_get_double (value);
153       GST_DEBUG ("test value double=%lf", self->val_double);
154       break;
155     case PROP_BOOLEAN:
156       self->val_boolean = g_value_get_boolean (value);
157       GST_DEBUG ("test value boolean=%d", self->val_boolean);
158       break;
159     case PROP_ENUM:
160       self->val_enum = g_value_get_enum (value);
161       GST_DEBUG ("test value enum=%d", self->val_enum);
162       break;
163     case PROP_CONSTRUCTONLY:
164       break;
165     default:
166       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
167       break;
168   }
169 }
170
171 static void
172 gst_test_obj_class_init (GstTestObjClass * klass)
173 {
174   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
175
176   gobject_class->set_property = gst_test_obj_set_property;
177   gobject_class->get_property = gst_test_obj_get_property;
178
179   g_object_class_install_property (gobject_class, PROP_INT,
180       g_param_spec_int ("int",
181           "int prop",
182           "int number parameter",
183           0, 100, 0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
184
185   g_object_class_install_property (gobject_class, PROP_FLOAT,
186       g_param_spec_float ("float",
187           "float prop",
188           "float number parameter",
189           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
190
191   g_object_class_install_property (gobject_class, PROP_DOUBLE,
192       g_param_spec_double ("double",
193           "double prop",
194           "double number parameter",
195           0.0, 100.0, 0.0, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
196
197   g_object_class_install_property (gobject_class, PROP_BOOLEAN,
198       g_param_spec_boolean ("boolean",
199           "boolean prop",
200           "boolean parameter",
201           FALSE, G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
202
203   g_object_class_install_property (gobject_class, PROP_ENUM,
204       g_param_spec_enum ("enum",
205           "enum prop",
206           "enum parameter",
207           GST_TYPE_TEST_ENUM, ENUM_V0,
208           G_PARAM_READWRITE | GST_PARAM_CONTROLLABLE));
209
210   g_object_class_install_property (gobject_class, PROP_READONLY,
211       g_param_spec_int ("readonly",
212           "readonly prop",
213           "readonly parameter",
214           0, G_MAXINT, 0, G_PARAM_READABLE | GST_PARAM_CONTROLLABLE));
215
216   g_object_class_install_property (gobject_class, PROP_STATIC,
217       g_param_spec_int ("static",
218           "static prop",
219           "static parameter", 0, G_MAXINT, 0, G_PARAM_READWRITE));
220
221   g_object_class_install_property (gobject_class, PROP_CONSTRUCTONLY,
222       g_param_spec_int ("construct-only",
223           "construct-only prop",
224           "construct-only parameter",
225           0, G_MAXINT, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
226 }
227
228 static void
229 gst_test_obj_base_init (GstTestObjClass * klass)
230 {
231   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
232
233   gst_element_class_set_details_simple (element_class,
234       "test object for unit tests",
235       "Test", "Use in unit tests", "Stefan Sauer <ensonic@users.sf.net>");
236 }
237
238 static GType
239 gst_test_obj_get_type (void)
240 {
241   static volatile gsize test_obj_type = 0;
242
243   if (g_once_init_enter (&test_obj_type)) {
244     GType type;
245     static const GTypeInfo info = {
246       (guint16) sizeof (GstTestObjClass),
247       (GBaseInitFunc) gst_test_obj_base_init,   // base_init
248       NULL,                     // base_finalize
249       (GClassInitFunc) gst_test_obj_class_init, // class_init
250       NULL,                     // class_finalize
251       NULL,                     // class_data
252       (guint16) sizeof (GstTestObj),
253       0,                        // n_preallocs
254       NULL,                     // instance_init
255       NULL                      // value_table
256     };
257     type = g_type_register_static (GST_TYPE_ELEMENT, "GstTestObj", &info, 0);
258     g_once_init_leave (&test_obj_type, type);
259   }
260   return test_obj_type;
261 }
262
263 static void
264 setup (void)
265 {
266   gst_element_register (NULL, "testobj", GST_RANK_NONE, GST_TYPE_TEST_OBJ);
267 }
268
269 static void
270 teardown (void)
271 {
272 }
273
274
275 /* TESTS */
276
277 /* tests if we don't fail on empty interpolation controlsources */
278 GST_START_TEST (controller_controlsource_empty1)
279 {
280   GstElement *elem;
281   GstControlSource *csource;
282
283   elem = gst_element_factory_make ("testobj", NULL);
284
285   csource = (GstControlSource *) gst_interpolation_control_source_new ();
286   fail_unless (csource != NULL, NULL);
287
288   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int",
289           csource));
290
291   /* don't fail on empty control point lists */
292   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
293
294   /* unref objects */
295   gst_object_unref (csource);
296   gst_object_unref (elem);
297 }
298
299 GST_END_TEST;
300
301 /* tests if we don't fail on interpolation controlsources that are empty again */
302 GST_START_TEST (controller_controlsource_empty2)
303 {
304   GstElement *elem;
305   GstInterpolationControlSource *csource;
306   GstTimedValueControlSource *cs;
307
308   elem = gst_element_factory_make ("testobj", NULL);
309
310   csource = gst_interpolation_control_source_new ();
311   fail_unless (csource != NULL, NULL);
312
313   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int",
314           (GstControlSource *) csource));
315
316   /* set control values */
317   cs = (GstTimedValueControlSource *) csource;
318   gst_timed_value_control_source_set (cs, 0 * GST_SECOND, 0);
319
320   /* ... and unset the value */
321   gst_timed_value_control_source_unset (cs, 0 * GST_SECOND);
322
323   /* don't fail on empty control point lists */
324   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
325
326   /* unref objects */
327   gst_object_unref (csource);
328   gst_object_unref (elem);
329 }
330
331 GST_END_TEST;
332
333 /* test timed value handling without interpolation */
334 GST_START_TEST (controller_interpolate_none)
335 {
336   GstInterpolationControlSource *csource;
337   GstTimedValueControlSource *tvcs;
338   GstControlSource *cs;
339   GstElement *elem;
340   gdouble v;
341
342   elem = gst_element_factory_make ("testobj", NULL);
343
344   /* new interpolation control source */
345   csource = gst_interpolation_control_source_new ();
346   tvcs = (GstTimedValueControlSource *) csource;
347   cs = (GstControlSource *) csource;
348
349   fail_unless (csource != NULL);
350   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
351
352   /* set interpolation mode */
353   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
354
355   /* set control values */
356   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
357   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
358
359   /* check values on control source directly */
360   fail_unless (gst_control_source_get_value (cs, 0 * GST_SECOND, &v));
361   fail_unless_equals_float (v, 0.0);
362   fail_unless (gst_control_source_get_value (cs, 1 * GST_SECOND, &v));
363   fail_unless_equals_float (v, 0.0);
364   fail_unless (gst_control_source_get_value (cs, 2 * GST_SECOND, &v));
365   fail_unless_equals_float (v, 1.0);
366   fail_unless (gst_control_source_get_value (cs, 3 * GST_SECOND, &v));
367   fail_unless_equals_float (v, 1.0);
368
369   /* now pull in values for some timestamps */
370   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
371   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
372   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
373   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
374   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
375   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
376   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
377   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
378
379   gst_object_unref (csource);
380   gst_object_unref (elem);
381 }
382
383 GST_END_TEST;
384
385 /* test timed value handling with linear interpolation */
386 GST_START_TEST (controller_interpolate_linear)
387 {
388   GstInterpolationControlSource *csource;
389   GstTimedValueControlSource *tvcs;
390   GstControlSource *cs;
391   GstElement *elem;
392
393   elem = gst_element_factory_make ("testobj", NULL);
394
395   /* new interpolation control source */
396   csource = gst_interpolation_control_source_new ();
397   tvcs = (GstTimedValueControlSource *) csource;
398   cs = (GstControlSource *) csource;
399
400   fail_unless (csource != NULL);
401   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
402
403   /* set interpolation mode */
404   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
405
406   /* set control values */
407   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
408   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
409
410   /* now pull in values for some timestamps */
411   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
412   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
413   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
414   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
415   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
416   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
417
418   gst_object_unref (csource);
419   gst_object_unref (elem);
420 }
421
422 GST_END_TEST;
423
424 /* test timed value handling with cubic interpolation */
425 GST_START_TEST (controller_interpolate_cubic)
426 {
427   GstInterpolationControlSource *csource;
428   GstTimedValueControlSource *tvcs;
429   GstControlSource *cs;
430   GstElement *elem;
431
432   elem = gst_element_factory_make ("testobj", NULL);
433
434   /* new interpolation control source */
435   csource = gst_interpolation_control_source_new ();
436   tvcs = (GstTimedValueControlSource *) csource;
437   cs = (GstControlSource *) csource;
438
439   fail_unless (csource != NULL);
440   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "double", cs));
441
442   /* set interpolation mode */
443   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
444
445   /* set control values */
446   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
447   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 0.5));
448   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.2));
449   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 0.8));
450
451   /* now pull in values for some timestamps */
452   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
453   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
454   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
455   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 50.0);
456   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
457   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
458   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
459   fail_unless (GST_TEST_OBJ (elem)->val_double > 20.0 &&
460       GST_TEST_OBJ (elem)->val_double < 80.0, NULL);
461   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
462   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 80.0);
463   gst_object_sync_values (GST_OBJECT (elem), 5 * GST_SECOND);
464   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 80.0);
465
466   gst_object_unref (csource);
467   gst_object_unref (elem);
468 }
469
470 GST_END_TEST;
471
472 /* test timed value handling with cubic interpolation */
473 GST_START_TEST (controller_interpolate_cubic_too_few_cp)
474 {
475   GstInterpolationControlSource *csource;
476   GstTimedValueControlSource *tvcs;
477   GstControlSource *cs;
478   GstElement *elem;
479
480   elem = gst_element_factory_make ("testobj", NULL);
481
482   /* new interpolation control source */
483   csource = gst_interpolation_control_source_new ();
484   tvcs = (GstTimedValueControlSource *) csource;
485   cs = (GstControlSource *) csource;
486
487   fail_unless (csource != NULL);
488   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "double", cs));
489
490   /* set interpolation mode */
491   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
492
493   /* set 2 control values */
494   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
495   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.4));
496
497   /* now pull in values for some timestamps and verify that it used linear
498    * interpolation as we don't gave enough control points
499    */
500   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
501   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
502   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
503   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
504   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
505   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
506
507   gst_object_unref (csource);
508   gst_object_unref (elem);
509 }
510
511 GST_END_TEST;
512
513 /* test _unset() */
514 GST_START_TEST (controller_interpolation_unset)
515 {
516   GstInterpolationControlSource *csource;
517   GstTimedValueControlSource *tvcs;
518   GstControlSource *cs;
519   GstElement *elem;
520
521   elem = gst_element_factory_make ("testobj", NULL);
522
523   /* new interpolation control source */
524   csource = gst_interpolation_control_source_new ();
525   tvcs = (GstTimedValueControlSource *) csource;
526   cs = (GstControlSource *) csource;
527
528   fail_unless (csource != NULL);
529   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
530
531   /* set interpolation mode */
532   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
533
534   /* set control values */
535   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
536   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
537   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 0.5));
538
539   /* verify values */
540   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
541   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
542   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
543   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
544   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
545   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
546
547   /* unset second */
548   fail_unless (gst_timed_value_control_source_unset (tvcs, 1 * GST_SECOND));
549
550   /* verify value again */
551   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
552   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
553   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
554   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
555
556   /* unset all values, reset and try to unset again */
557   fail_unless (gst_timed_value_control_source_unset (tvcs, 0 * GST_SECOND));
558   fail_unless (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
559   gst_timed_value_control_source_unset_all (tvcs);
560   fail_if (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
561
562   gst_object_unref (csource);
563   gst_object_unref (elem);
564 }
565
566 GST_END_TEST;
567
568 /* test _unset_all() */
569 GST_START_TEST (controller_interpolation_unset_all)
570 {
571   GstInterpolationControlSource *csource;
572   GstTimedValueControlSource *tvcs;
573   GstControlSource *cs;
574   GstElement *elem;
575
576   elem = gst_element_factory_make ("testobj", NULL);
577
578   /* new interpolation control source */
579   csource = gst_interpolation_control_source_new ();
580   tvcs = (GstTimedValueControlSource *) csource;
581   cs = (GstControlSource *) csource;
582
583   fail_unless (csource != NULL);
584   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
585
586   /* set interpolation mode */
587   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
588
589   /* set control values */
590   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
591   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
592
593   /* verify values */
594   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
595   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
596   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
597   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
598
599   /* unset all */
600   gst_timed_value_control_source_unset_all (tvcs);
601   GST_TEST_OBJ (elem)->val_int = 0;
602
603   /* verify value again */
604   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
605   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
606
607   gst_object_unref (csource);
608   gst_object_unref (elem);
609 }
610
611 GST_END_TEST;
612
613 /* test retrieval of an array of values with get_value_array() */
614 GST_START_TEST (controller_interpolation_linear_value_array)
615 {
616   GstInterpolationControlSource *csource;
617   GstTimedValueControlSource *tvcs;
618   GstControlSource *cs;
619   GstElement *elem;
620   gdouble *raw_values;
621   GValue *g_values;
622
623   elem = gst_element_factory_make ("testobj", NULL);
624
625   /* new interpolation control source */
626   csource = gst_interpolation_control_source_new ();
627   tvcs = (GstTimedValueControlSource *) csource;
628   cs = (GstControlSource *) csource;
629
630   fail_unless (csource != NULL);
631   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
632
633   /* set interpolation mode */
634   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
635
636   /* set control values */
637   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
638   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 1.0));
639
640   /* now pull in raw-values for some timestamps */
641   raw_values = g_new (gdouble, 3);
642
643   fail_unless (gst_control_source_get_value_array (cs,
644           0, GST_SECOND / 2, 3, raw_values));
645   fail_unless_equals_float ((raw_values)[0], 0.0);
646   fail_unless_equals_float ((raw_values)[1], 0.5);
647   fail_unless_equals_float ((raw_values)[2], 1.0);
648
649   g_free (raw_values);
650
651   /* now pull in mapped values for some timestamps */
652   g_values = g_new0 (GValue, 3);
653
654   fail_unless (gst_object_get_value_array (GST_OBJECT (elem), "int",
655           0, GST_SECOND / 2, 3, g_values));
656   fail_unless_equals_int (g_value_get_int (&g_values[0]), 0);
657   fail_unless_equals_int (g_value_get_int (&g_values[1]), 50);
658   fail_unless_equals_int (g_value_get_int (&g_values[2]), 100);
659
660   g_free (g_values);
661
662   gst_object_unref (csource);
663   gst_object_unref (elem);
664 }
665
666 GST_END_TEST;
667
668 /* test if values below minimum and above maximum are clipped */
669 GST_START_TEST (controller_interpolation_linear_invalid_values)
670 {
671   GstInterpolationControlSource *csource;
672   GstTimedValueControlSource *tvcs;
673   GstControlSource *cs;
674   GstElement *elem;
675
676   elem = gst_element_factory_make ("testobj", NULL);
677
678   /* new interpolation control source */
679   csource = gst_interpolation_control_source_new ();
680   tvcs = (GstTimedValueControlSource *) csource;
681   cs = (GstControlSource *) csource;
682
683   fail_unless (csource != NULL);
684   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "float", cs));
685
686   /* set interpolation mode */
687   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
688
689   /* set control values */
690   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 2.0));
691   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, -2.0));
692
693   /* now pull in values for some timestamps and see if clipping works */
694   /* 200.0 */
695   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
696   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 100.0);
697   /* 100.0 */
698   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
699   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 100.0);
700   /* 50.0 */
701   gst_object_sync_values (GST_OBJECT (elem),
702       1 * GST_SECOND + 500 * GST_MSECOND);
703   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 50.0);
704   /* 0.0 */
705   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
706   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
707   /* -100.0 */
708   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
709   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
710   /* -200.0 */
711   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
712   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_float, 0.0);
713
714   gst_object_unref (csource);
715   gst_object_unref (elem);
716 }
717
718 GST_END_TEST;
719
720 GST_START_TEST (controller_interpolation_linear_default_values)
721 {
722   GstInterpolationControlSource *csource;
723   GstTimedValueControlSource *tvcs;
724   GstControlSource *cs;
725   GstElement *elem;
726
727   elem = gst_element_factory_make ("testobj", NULL);
728
729   /* new interpolation control source */
730   csource = gst_interpolation_control_source_new ();
731   tvcs = (GstTimedValueControlSource *) csource;
732   cs = (GstControlSource *) csource;
733
734   fail_unless (csource != NULL);
735   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
736
737   /* set interpolation mode */
738   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
739
740   /* Should fail if no value was set yet
741    * FIXME: will not fail, as interpolation assumes val[0]=default_value if
742    * nothing else is set.
743    fail_if (gst_control_source_get_value (GST_CONTROL_SOURCE (csource),
744    1 * GST_SECOND, &val_int));
745    */
746
747   /* set control values */
748   fail_unless (gst_timed_value_control_source_set (tvcs, 1 * GST_SECOND, 0.0));
749   fail_unless (gst_timed_value_control_source_set (tvcs, 3 * GST_SECOND, 1.0));
750
751   /* now pull in values for some timestamps */
752   /* should give the value of the first control point for timestamps before it */
753   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
754   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
755   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
756   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
757   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
758   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
759   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
760   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
761
762   /* set control values */
763   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
764   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
765
766   /* unset the old ones */
767   fail_unless (gst_timed_value_control_source_unset (tvcs, 1 * GST_SECOND));
768   fail_unless (gst_timed_value_control_source_unset (tvcs, 3 * GST_SECOND));
769
770   /* now pull in values for some timestamps */
771   /* should now give our value for timestamp 0 */
772   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
773   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
774   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
775   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
776   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
777   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
778
779   gst_object_unref (csource);
780   gst_object_unref (elem);
781 }
782
783 GST_END_TEST;
784
785 /* test gst_controller_set_disabled() with linear interpolation */
786 GST_START_TEST (controller_interpolate_linear_disabled)
787 {
788   GstInterpolationControlSource *csource1, *csource2;
789   GstTimedValueControlSource *tvcs1, *tvcs2;
790   GstControlSource *cs1, *cs2;
791   GstElement *elem;
792
793   elem = gst_element_factory_make ("testobj", NULL);
794
795   /* new interpolation control source */
796   csource1 = gst_interpolation_control_source_new ();
797   tvcs1 = (GstTimedValueControlSource *) csource1;
798   cs1 = (GstControlSource *) csource1;
799
800   csource2 = gst_interpolation_control_source_new ();
801   tvcs2 = (GstTimedValueControlSource *) csource2;
802   cs2 = (GstControlSource *) csource2;
803
804   fail_unless (csource1 != NULL);
805   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs1));
806   fail_unless (csource2 != NULL);
807   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "double",
808           cs2));
809
810   /* set interpolation mode */
811   g_object_set (csource1, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
812   g_object_set (csource2, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
813
814   /* set control values */
815   fail_unless (gst_timed_value_control_source_set (tvcs1, 0 * GST_SECOND, 0.0));
816   fail_unless (gst_timed_value_control_source_set (tvcs1, 2 * GST_SECOND, 1.0));
817
818   /* set control values */
819   fail_unless (gst_timed_value_control_source_set (tvcs2, 0 * GST_SECOND, 0.2));
820   fail_unless (gst_timed_value_control_source_set (tvcs2, 2 * GST_SECOND, 0.4));
821
822   /* now pull in values for some timestamps */
823   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
824   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
825   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
826   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
827   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
828   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
829   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
830   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
831   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
832
833   /* now pull in values for some timestamps, prop double disabled */
834   GST_TEST_OBJ (elem)->val_int = 0;
835   GST_TEST_OBJ (elem)->val_double = 0.0;
836   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", TRUE);
837   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
838   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
839   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
840   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
841   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
842   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
843   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
844   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
845   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
846
847   /* now pull in values for some timestamps, after enabling double again */
848   GST_TEST_OBJ (elem)->val_int = 0;
849   GST_TEST_OBJ (elem)->val_double = 0.0;
850   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE);
851   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
852   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
853   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
854   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
855   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
856   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
857   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
858   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
859   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
860
861   /* now pull in values for some timestamps, after disabling all props */
862   GST_TEST_OBJ (elem)->val_int = 0;
863   GST_TEST_OBJ (elem)->val_double = 0.0;
864   gst_object_set_control_bindings_disabled (GST_OBJECT (elem), TRUE);
865   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
866   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
867   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
868   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
869   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
870   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
871   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
872   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
873   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 0.0);
874
875   /* now pull in values for some timestamps, enabling double again */
876   GST_TEST_OBJ (elem)->val_int = 0;
877   GST_TEST_OBJ (elem)->val_double = 0.0;
878   gst_object_set_control_binding_disabled (GST_OBJECT (elem), "double", FALSE);
879   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
880   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
881   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
882   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
883   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
884   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
885   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
886   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
887   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
888
889   /* now pull in values for some timestamps, enabling all */
890   GST_TEST_OBJ (elem)->val_int = 0;
891   GST_TEST_OBJ (elem)->val_double = 0.0;
892   gst_object_set_control_bindings_disabled (GST_OBJECT (elem), FALSE);
893   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
894   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
895   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 20.0);
896   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
897   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
898   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 30.0);
899   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
900   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
901   fail_unless_equals_float (GST_TEST_OBJ (elem)->val_double, 40.0);
902
903   gst_object_unref (csource1);
904   gst_object_unref (csource2);
905   gst_object_unref (elem);
906 }
907
908 GST_END_TEST;
909
910
911 GST_START_TEST (controller_interpolation_set_from_list)
912 {
913   GstInterpolationControlSource *csource;
914   GstTimedValueControlSource *tvcs;
915   GstControlSource *cs;
916   GstTimedValue *tval;
917   GstElement *elem;
918   GSList *list = NULL;
919
920   /* test that an invalid timestamp throws a warning of some sort */
921   elem = gst_element_factory_make ("testobj", NULL);
922
923   /* new interpolation control source */
924   csource = gst_interpolation_control_source_new ();
925   tvcs = (GstTimedValueControlSource *) csource;
926   cs = (GstControlSource *) csource;
927
928   fail_unless (csource != NULL);
929   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
930
931   /* set interpolation mode */
932   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
933
934   /* set control value */
935   tval = g_new0 (GstTimedValue, 1);
936   tval->timestamp = GST_CLOCK_TIME_NONE;
937   tval->value = 0.0;
938
939   list = g_slist_append (list, tval);
940
941   fail_if (gst_timed_value_control_source_set_from_list (tvcs, list));
942
943   /* try again with a valid stamp, should work now */
944   tval->timestamp = 0;
945   fail_unless (gst_timed_value_control_source_set_from_list (tvcs, list));
946
947   /* allocated GstTimedValue now belongs to the controller, but list not */
948   g_free (tval);
949   g_slist_free (list);
950   gst_object_unref (csource);
951   gst_object_unref (elem);
952 }
953
954 GST_END_TEST;
955
956
957 /* test linear interpolation for ts < first control point */
958 GST_START_TEST (controller_interpolate_linear_before_ts0)
959 {
960   GstInterpolationControlSource *csource;
961   GstTimedValueControlSource *tvcs;
962   GstControlSource *cs;
963   GstElement *elem;
964
965   elem = gst_element_factory_make ("testobj", NULL);
966
967   /* new interpolation control source */
968   csource = gst_interpolation_control_source_new ();
969   tvcs = (GstTimedValueControlSource *) csource;
970   cs = (GstControlSource *) csource;
971
972   fail_unless (csource != NULL);
973   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
974
975   /* set interpolation mode */
976   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
977
978   /* set control values */
979   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
980   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 0.0));
981
982   /* now pull in values for some timestamps after first control point */
983   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
984   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
985   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
986   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
987   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
988   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
989
990   /* now pull in values for some timestamps before first control point */
991   GST_TEST_OBJ (elem)->val_int = 25;
992   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
993   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
994   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
995   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
996
997   gst_object_unref (csource);
998   gst_object_unref (elem);
999 }
1000
1001 GST_END_TEST;
1002
1003 /* test linear interpolation of enums */
1004 GST_START_TEST (controller_interpolate_linear_enums)
1005 {
1006   GstInterpolationControlSource *csource;
1007   GstTimedValueControlSource *tvcs;
1008   GstControlSource *cs;
1009   GstElement *elem;
1010
1011   elem = gst_element_factory_make ("testobj", NULL);
1012
1013   /* new interpolation control source */
1014   csource = gst_interpolation_control_source_new ();
1015   tvcs = (GstTimedValueControlSource *) csource;
1016   cs = (GstControlSource *) csource;
1017
1018   fail_unless (csource != NULL);
1019   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "enum", cs));
1020
1021   /* set interpolation mode */
1022   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
1023
1024   /* set control values */
1025   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
1026   fail_unless (gst_timed_value_control_source_set (tvcs, 4 * GST_SECOND, 1.0));
1027
1028   /* now pull in values going over the enum values */
1029   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1030   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V0);
1031   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1032   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V10);
1033   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1034   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V11);
1035   gst_object_sync_values (GST_OBJECT (elem), 3 * GST_SECOND);
1036   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V12);
1037   gst_object_sync_values (GST_OBJECT (elem), 4 * GST_SECOND);
1038   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_enum, ENUM_V255);
1039
1040   gst_object_unref (csource);
1041   gst_object_unref (elem);
1042 }
1043
1044 GST_END_TEST;
1045
1046 /* test timed value counts */
1047 GST_START_TEST (controller_timed_value_count)
1048 {
1049   GstInterpolationControlSource *csource;
1050   GstTimedValueControlSource *tvcs;
1051   GstControlSource *cs;
1052   GstElement *elem;
1053
1054   elem = gst_element_factory_make ("testobj", NULL);
1055
1056   /* new interpolation control source */
1057   csource = gst_interpolation_control_source_new ();
1058   tvcs = (GstTimedValueControlSource *) csource;
1059   cs = (GstControlSource *) csource;
1060
1061   fail_unless (csource != NULL);
1062   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1063
1064   /* set interpolation mode */
1065   g_object_set (csource, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
1066
1067   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 0);
1068
1069   /* set control values */
1070   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.0));
1071   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 1);
1072   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1073   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 2);
1074
1075   /* unset control values */
1076   fail_unless (gst_timed_value_control_source_unset (tvcs, 2 * GST_SECOND));
1077   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 1);
1078   fail_unless (gst_timed_value_control_source_unset (tvcs, 0 * GST_SECOND));
1079   fail_unless (gst_timed_value_control_source_get_count (tvcs) == 0);
1080
1081   gst_object_unref (csource);
1082   gst_object_unref (elem);
1083 }
1084
1085 GST_END_TEST;
1086
1087
1088 /* test lfo control source with sine waveform */
1089 GST_START_TEST (controller_lfo_sine)
1090 {
1091   GstLFOControlSource *csource;
1092   GstControlSource *cs;
1093   GstElement *elem;
1094
1095   elem = gst_element_factory_make ("testobj", NULL);
1096
1097   /* new lfo control source */
1098   csource = gst_lfo_control_source_new ();
1099   cs = (GstControlSource *) csource;
1100
1101   fail_unless (csource != NULL);
1102   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1103
1104   /* configure lfo */
1105   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SINE,
1106       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1107       "amplitude", 0.5, "offset", 0.5, NULL);
1108
1109   /* now pull in values for some timestamps */
1110   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1111   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1112   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1113   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1114   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1115   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1116   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1117   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1118   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1119   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1120   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1121   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1122   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1123   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1124   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1125   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1126   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1127   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1128   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1129   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1130   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1131   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1132   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1133   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1134
1135   gst_object_unref (csource);
1136   gst_object_unref (elem);
1137 }
1138
1139 GST_END_TEST;
1140
1141 /* test lfo control source with sine waveform and timeshift */
1142 GST_START_TEST (controller_lfo_sine_timeshift)
1143 {
1144   GstLFOControlSource *csource;
1145   GstControlSource *cs;
1146   GstElement *elem;
1147
1148   elem = gst_element_factory_make ("testobj", NULL);
1149
1150   /* new lfo control source */
1151   csource = gst_lfo_control_source_new ();
1152   cs = (GstControlSource *) csource;
1153
1154   fail_unless (csource != NULL);
1155   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1156
1157   /* configure lfo */
1158   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SINE,
1159       "frequency", 1.0, "timeshift", 250 * GST_MSECOND,
1160       "amplitude", 0.5, "offset", 0.5, NULL);
1161
1162   /* now pull in values for some timestamps */
1163   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1164   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1165   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1166   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1167   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1168   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1169   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1170   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1171   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1172   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1173   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1174   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1175   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1176   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1177   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1178   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1179   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1180   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1181   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1182   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1183   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1184   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1185   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1186   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1187
1188   gst_object_unref (csource);
1189   gst_object_unref (elem);
1190 }
1191
1192 GST_END_TEST;
1193
1194 /* test lfo control source with square waveform */
1195 GST_START_TEST (controller_lfo_square)
1196 {
1197   GstLFOControlSource *csource;
1198   GstControlSource *cs;
1199   GstElement *elem;
1200
1201   elem = gst_element_factory_make ("testobj", NULL);
1202
1203   /* new lfo control source */
1204   csource = gst_lfo_control_source_new ();
1205   cs = (GstControlSource *) csource;
1206
1207   fail_unless (csource != NULL);
1208   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1209
1210   /* configure lfo */
1211   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SQUARE,
1212       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1213       "amplitude", 0.5, "offset", 0.5, NULL);
1214
1215   /* now pull in values for some timestamps */
1216   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1217   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1218   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1219   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1220   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1221   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1222   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1223   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1224   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1225   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1226   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1227   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1228   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1229   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1230   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1231   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1232   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1233   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1234   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1235   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1236   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1237   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1238   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1239   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1240
1241   gst_object_unref (csource);
1242   gst_object_unref (elem);
1243 }
1244
1245 GST_END_TEST;
1246
1247 /* test lfo control source with saw waveform */
1248 GST_START_TEST (controller_lfo_saw)
1249 {
1250   GstLFOControlSource *csource;
1251   GstControlSource *cs;
1252   GstElement *elem;
1253
1254   elem = gst_element_factory_make ("testobj", NULL);
1255
1256   /* new lfo control source */
1257   csource = gst_lfo_control_source_new ();
1258   cs = (GstControlSource *) csource;
1259
1260   fail_unless (csource != NULL);
1261   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1262
1263   /* configure lfo */
1264   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_SAW,
1265       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1266       "amplitude", 0.5, "offset", 0.5, NULL);
1267
1268   /* now pull in values for some timestamps */
1269   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1270   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1271   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1272   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1273   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1274   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1275   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1276   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1277   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1278   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1279   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1280   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1281   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1282   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1283   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1284   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1285   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1286   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1287   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1288   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1289   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1290   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1291   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1292   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1293
1294   gst_object_unref (csource);
1295   gst_object_unref (elem);
1296 }
1297
1298 GST_END_TEST;
1299
1300 /* test lfo control source with reverse saw waveform */
1301 GST_START_TEST (controller_lfo_rsaw)
1302 {
1303   GstLFOControlSource *csource;
1304   GstControlSource *cs;
1305   GstElement *elem;
1306
1307   elem = gst_element_factory_make ("testobj", NULL);
1308
1309   /* new lfo control source */
1310   csource = gst_lfo_control_source_new ();
1311   cs = (GstControlSource *) csource;
1312
1313   fail_unless (csource != NULL);
1314   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1315
1316   /* configure lfo */
1317   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW,
1318       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1319       "amplitude", 0.5, "offset", 0.5, NULL);
1320
1321   /* now pull in values for some timestamps */
1322   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1323   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1324   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1325   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1326   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1327   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1328   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1329   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1330   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1331   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1332   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1333   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1334   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1335   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1336   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1337   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1338   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1339   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1340   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1341   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 25);
1342   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1343   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1344   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1345   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 75);
1346
1347   gst_object_unref (csource);
1348   gst_object_unref (elem);
1349 }
1350
1351 GST_END_TEST;
1352
1353 /* test lfo control source with saw waveform */
1354 GST_START_TEST (controller_lfo_triangle)
1355 {
1356   GstLFOControlSource *csource;
1357   GstControlSource *cs;
1358   GstElement *elem;
1359
1360   elem = gst_element_factory_make ("testobj", NULL);
1361
1362   /* new lfo control source */
1363   csource = gst_lfo_control_source_new ();
1364   cs = (GstControlSource *) csource;
1365
1366   fail_unless (csource != NULL);
1367   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1368
1369   /* configure lfo */
1370   g_object_set (csource, "waveform", GST_LFO_WAVEFORM_TRIANGLE,
1371       "frequency", 1.0, "timeshift", (GstClockTime) 0,
1372       "amplitude", 0.5, "offset", 0.5, NULL);
1373
1374   /* now pull in values for some timestamps */
1375   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1376   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1377   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1378   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1379   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1380   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1381   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1382   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1383   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1384   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1385   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1386   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1387   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1388   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1389   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1390   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1391   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1392   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1393   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1394   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1395   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1396   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1397   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1398   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1399
1400   gst_object_unref (csource);
1401   gst_object_unref (elem);
1402 }
1403
1404 GST_END_TEST;
1405
1406 /* test lfo control source with nothing set */
1407 GST_START_TEST (controller_lfo_none)
1408 {
1409   GstLFOControlSource *csource;
1410   GstControlSource *cs;
1411   GstElement *elem;
1412
1413   elem = gst_element_factory_make ("testobj", NULL);
1414
1415   /* new lfo control source */
1416   csource = gst_lfo_control_source_new ();
1417   cs = (GstControlSource *) csource;
1418
1419   fail_unless (csource != NULL);
1420   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1421
1422   /* now pull in values for some timestamps */
1423   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_MSECOND);
1424   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1425   gst_object_sync_values (GST_OBJECT (elem), 250 * GST_MSECOND);
1426   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1427   gst_object_sync_values (GST_OBJECT (elem), 500 * GST_MSECOND);
1428   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1429   gst_object_sync_values (GST_OBJECT (elem), 750 * GST_MSECOND);
1430   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1431   gst_object_sync_values (GST_OBJECT (elem), 1000 * GST_MSECOND);
1432   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1433   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1434   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1435   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1436   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1437   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1438   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1439   gst_object_sync_values (GST_OBJECT (elem), 2000 * GST_MSECOND);
1440   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1441   gst_object_sync_values (GST_OBJECT (elem), 1250 * GST_MSECOND);
1442   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1443   gst_object_sync_values (GST_OBJECT (elem), 1500 * GST_MSECOND);
1444   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1445   gst_object_sync_values (GST_OBJECT (elem), 1750 * GST_MSECOND);
1446   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1447
1448   gst_object_unref (csource);
1449   gst_object_unref (elem);
1450 }
1451
1452 GST_END_TEST;
1453
1454 /* test timed value handling in trigger mode */
1455 GST_START_TEST (controller_trigger_exact)
1456 {
1457   GstTriggerControlSource *csource;
1458   GstControlSource *cs;
1459   GstTimedValueControlSource *tvcs;
1460   GstElement *elem;
1461   gdouble raw_val;
1462
1463   elem = gst_element_factory_make ("testobj", NULL);
1464
1465   /* new interpolation control source */
1466   csource = gst_trigger_control_source_new ();
1467   tvcs = (GstTimedValueControlSource *) csource;
1468   cs = (GstControlSource *) csource;
1469
1470   fail_unless (csource != NULL);
1471   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int", cs));
1472
1473   fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1474
1475   /* set control values */
1476   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5));
1477   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1478
1479   /* now pull in values for some timestamps */
1480   fail_unless (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1481
1482   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1483   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1484
1485   GST_TEST_OBJ (elem)->val_int = 0;
1486   fail_if (gst_control_source_get_value (cs, 1 * GST_SECOND, &raw_val));
1487   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1488   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1489
1490   fail_unless (gst_control_source_get_value (cs, 2 * GST_SECOND, &raw_val));
1491   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1492   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1493
1494   gst_object_unref (csource);
1495   gst_object_unref (elem);
1496 }
1497
1498 GST_END_TEST;
1499
1500 GST_START_TEST (controller_trigger_tolerance)
1501 {
1502   GstTriggerControlSource *csource;
1503   GstControlSource *cs;
1504   GstTimedValueControlSource *tvcs;
1505   GstElement *elem;
1506   gdouble raw_val;
1507
1508   elem = gst_element_factory_make ("testobj", NULL);
1509
1510   /* new interpolation control source */
1511   csource = gst_trigger_control_source_new ();
1512   tvcs = (GstTimedValueControlSource *) csource;
1513   cs = (GstControlSource *) csource;
1514
1515   fail_unless (csource != NULL);
1516   fail_unless (gst_object_set_control_source (GST_OBJECT (elem), "int",
1517           GST_CONTROL_SOURCE (csource)));
1518
1519   g_object_set (csource, "tolerance", G_GINT64_CONSTANT (10), NULL);
1520
1521   fail_if (gst_control_source_get_value (cs, 0 * GST_SECOND, &raw_val));
1522
1523   /* set control values */
1524   fail_unless (gst_timed_value_control_source_set (tvcs, 0 * GST_SECOND, 0.5));
1525   fail_unless (gst_timed_value_control_source_set (tvcs, 2 * GST_SECOND, 1.0));
1526
1527   /* now pull in values for some timestamps */
1528   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND);
1529   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1530   gst_object_sync_values (GST_OBJECT (elem), 0 * GST_SECOND + 5);
1531   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 50);
1532
1533   GST_TEST_OBJ (elem)->val_int = 0;
1534   gst_object_sync_values (GST_OBJECT (elem), 1 * GST_SECOND);
1535   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 0);
1536
1537   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND - 5);
1538   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1539   gst_object_sync_values (GST_OBJECT (elem), 2 * GST_SECOND);
1540   fail_unless_equals_int (GST_TEST_OBJ (elem)->val_int, 100);
1541
1542   gst_object_unref (csource);
1543   gst_object_unref (elem);
1544 }
1545
1546 GST_END_TEST;
1547
1548
1549 static Suite *
1550 gst_controller_suite (void)
1551 {
1552   Suite *s = suite_create ("Controller");
1553   TCase *tc = tcase_create ("general");
1554
1555   suite_add_tcase (s, tc);
1556   tcase_add_checked_fixture (tc, setup, teardown);
1557   tcase_add_test (tc, controller_controlsource_empty1);
1558   tcase_add_test (tc, controller_controlsource_empty2);
1559   tcase_add_test (tc, controller_interpolate_none);
1560   tcase_add_test (tc, controller_interpolate_linear);
1561   tcase_add_test (tc, controller_interpolate_cubic);
1562   tcase_add_test (tc, controller_interpolate_cubic_too_few_cp);
1563   tcase_add_test (tc, controller_interpolation_unset);
1564   tcase_add_test (tc, controller_interpolation_unset_all);
1565   tcase_add_test (tc, controller_interpolation_linear_value_array);
1566   tcase_add_test (tc, controller_interpolation_linear_invalid_values);
1567   tcase_add_test (tc, controller_interpolation_linear_default_values);
1568   tcase_add_test (tc, controller_interpolate_linear_disabled);
1569   tcase_add_test (tc, controller_interpolation_set_from_list);
1570   tcase_add_test (tc, controller_interpolate_linear_before_ts0);
1571   tcase_add_test (tc, controller_interpolate_linear_enums);
1572   tcase_add_test (tc, controller_timed_value_count);
1573   tcase_add_test (tc, controller_lfo_sine);
1574   tcase_add_test (tc, controller_lfo_sine_timeshift);
1575   tcase_add_test (tc, controller_lfo_square);
1576   tcase_add_test (tc, controller_lfo_saw);
1577   tcase_add_test (tc, controller_lfo_rsaw);
1578   tcase_add_test (tc, controller_lfo_triangle);
1579   tcase_add_test (tc, controller_lfo_none);
1580   tcase_add_test (tc, controller_trigger_exact);
1581   tcase_add_test (tc, controller_trigger_tolerance);
1582
1583   return s;
1584 }
1585
1586 GST_CHECK_MAIN (gst_controller);