Convert %lld and %llu in printf formats to G_G[U]INT64_FORMAT. Fix pointer<->int...
[platform/upstream/gstreamer.git] / libs / gst / control / dparam_smooth.c
1 /* GStreamer
2  * Copyright (C) 2001 Steve Baker <stevebaker_org@yahoo.co.uk>
3  *
4  * gstdparam_smooth.c: Realtime smoothed dynamic parameter
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #include <math.h>
23 #include <string.h>
24 #include <gst/gstinfo.h>
25
26 #include "dparam_smooth.h"
27 #include "dparammanager.h"
28
29 static void gst_dpsmooth_class_init (GstDParamSmoothClass *klass);
30 static void gst_dpsmooth_init (GstDParamSmooth *dparam);
31 static void gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
32 static void gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
33 static void gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info);
34 static void gst_dpsmooth_value_changed_float (GstDParam *dparam);
35
36 enum {
37         ARG_0,
38         ARG_UPDATE_PERIOD,
39         ARG_SLOPE_TIME,
40         ARG_SLOPE_DELTA_FLOAT,
41         ARG_SLOPE_DELTA_INT,
42         ARG_SLOPE_DELTA_INT64,
43 };
44
45 GType 
46 gst_dpsmooth_get_type(void) {
47         static GType dpsmooth_type = 0;
48
49         if (!dpsmooth_type) {
50                 static const GTypeInfo dpsmooth_info = {
51                         sizeof(GstDParamSmoothClass),
52                         NULL,
53                         NULL,
54                         (GClassInitFunc)gst_dpsmooth_class_init,
55                         NULL,
56                         NULL,
57                         sizeof(GstDParamSmooth),
58                         0,
59                         (GInstanceInitFunc)gst_dpsmooth_init,
60                 };
61                 dpsmooth_type = g_type_register_static(GST_TYPE_DPARAM, "GstDParamSmooth", &dpsmooth_info, 0);
62         }
63         return dpsmooth_type;
64 }
65
66 static void
67 gst_dpsmooth_class_init (GstDParamSmoothClass *klass)
68 {
69         GObjectClass *gobject_class;
70         GstDParamSmoothClass *dpsmooth_class;
71         GstObjectClass *gstobject_class;
72
73         gobject_class = (GObjectClass*)klass;
74         dpsmooth_class = (GstDParamSmoothClass*)klass;
75         gstobject_class = (GstObjectClass*) klass;
76         
77         gobject_class->get_property = gst_dpsmooth_get_property;
78         gobject_class->set_property = gst_dpsmooth_set_property;
79         
80         g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_UPDATE_PERIOD,
81                 g_param_spec_int64("update_period", 
82                                    "Update Period (nanoseconds)", 
83                                    "Number of nanoseconds between updates",
84                                    0LL, G_MAXINT64, 2000000LL, G_PARAM_READWRITE));
85                                    
86         g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SLOPE_TIME,
87                 g_param_spec_int64("slope_time", 
88                                    "Slope Time (nanoseconds)", 
89                                    "The time period to define slope_delta by",
90                                    0LL, G_MAXINT64, 10000000LL, G_PARAM_READWRITE));
91                                    
92         g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SLOPE_DELTA_FLOAT,
93                 g_param_spec_float("slope_delta_float", 
94                                    "Slope Delta float", 
95                                    "The amount a float value can change for a given slope_time",
96                                    0.0F, G_MAXFLOAT, 0.2F, G_PARAM_READWRITE));
97         
98         /*gstobject_class->save_thyself = gst_dparam_save_thyself; */
99
100 }
101
102 static void
103 gst_dpsmooth_init (GstDParamSmooth *dpsmooth)
104 {
105         g_return_if_fail (dpsmooth != NULL);
106 }
107
108 /**
109  * gst_dpsmooth_new:
110  * @type: the type that this dparam will store
111  *
112  * Returns: a new instance of GstDParam
113  */
114 GstDParam* 
115 gst_dpsmooth_new (GType type)
116 {
117         GstDParam *dparam;
118         GstDParamSmooth *dpsmooth;
119         
120         dpsmooth =g_object_new (gst_dpsmooth_get_type (), NULL);
121         dparam = GST_DPARAM(dpsmooth);
122         
123         GST_DPARAM_TYPE(dparam) = type;
124
125         switch (type){
126                 case G_TYPE_FLOAT: {
127                         dparam->do_update_func = gst_dpsmooth_do_update_float;
128                         g_signal_connect (G_OBJECT (dpsmooth), "value_changed", G_CALLBACK (gst_dpsmooth_value_changed_float), NULL);
129                         break;
130                 }
131                 default:
132                         /* we don't support this type here */
133                         dparam->do_update_func = gst_dparam_do_update_default;
134                         break;
135         }
136         return dparam;
137 }
138
139 static void 
140 gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 
141 {
142         GstDParam *dparam;
143         GstDParamSmooth *dpsmooth;
144
145         g_return_if_fail(GST_IS_DPSMOOTH(object));
146         
147         dpsmooth = GST_DPSMOOTH(object);
148         dparam = GST_DPARAM(object);
149         
150         GST_DPARAM_LOCK(dparam);
151
152         switch (prop_id) {
153                 case ARG_UPDATE_PERIOD:
154                         dpsmooth->update_period = g_value_get_int64 (value);
155                         GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
156                         break;
157
158                 case ARG_SLOPE_TIME:
159                         dpsmooth->slope_time = g_value_get_int64 (value);
160                         GST_DEBUG(GST_CAT_PARAMS, "dpsmooth->slope_time:%"
161                                                   G_GINT64_FORMAT,
162                                   dpsmooth->slope_time);
163                         GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
164                         break;
165
166                 case ARG_SLOPE_DELTA_FLOAT:
167                         dpsmooth->slope_delta_float = g_value_get_float (value);
168                         GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE;
169                         break;
170                         
171                 default:
172                         break;
173         }
174         GST_DPARAM_UNLOCK(dparam);
175 }
176
177 static void 
178 gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 
179 {
180         GstDParam *dparam;
181         GstDParamSmooth *dpsmooth;
182
183         g_return_if_fail(GST_IS_DPSMOOTH(object));
184         
185         dpsmooth = GST_DPSMOOTH(object);
186         dparam = GST_DPARAM(object);
187         
188         switch (prop_id) {
189                 case ARG_UPDATE_PERIOD:
190                         g_value_set_int64(value, dpsmooth->update_period);
191                         break;
192                 case ARG_SLOPE_TIME:
193                         g_value_set_int64(value, dpsmooth->slope_time);
194                         break;
195                 case ARG_SLOPE_DELTA_FLOAT:
196                         g_value_set_float (value, dpsmooth->slope_delta_float);
197                         break;
198                 default:
199                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
200                         break;
201         }
202 }
203
204 static void 
205 gst_dpsmooth_value_changed_float (GstDParam *dparam)
206 {
207         GstDParamSmooth *dpsmooth;
208         gfloat time_ratio;
209
210         g_return_if_fail(GST_IS_DPSMOOTH(dparam));
211         dpsmooth = GST_DPSMOOTH(dparam);
212
213         if (GST_DPARAM_IS_LOG(dparam)){
214                 dparam->value_float = log(dparam->value_float);
215         }
216         dpsmooth->start_float = dpsmooth->current_float;
217         dpsmooth->diff_float = dparam->value_float - dpsmooth->start_float;
218
219         time_ratio = ABS(dpsmooth->diff_float) / dpsmooth->slope_delta_float;
220         dpsmooth->duration_interp = (gint64)(time_ratio * (gfloat)dpsmooth->slope_time);
221
222         dpsmooth->need_interp_times = TRUE;
223
224         GST_DEBUG(GST_CAT_PARAMS, "%f to %f ratio:%f duration:%"
225                                   G_GINT64_FORMAT "\n", 
226                   dpsmooth->start_float, dparam->value_float, time_ratio, dpsmooth->duration_interp);
227 }
228
229 static void
230 gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info)
231 {
232         gfloat time_ratio;
233         GstDParamSmooth *dpsmooth = GST_DPSMOOTH(dparam);
234
235         GST_DPARAM_LOCK(dparam);
236
237         if (dpsmooth->need_interp_times){
238                 dpsmooth->start_interp = timestamp;
239                 dpsmooth->end_interp = timestamp + dpsmooth->duration_interp;
240                 dpsmooth->need_interp_times = FALSE;
241         }
242
243         if ((update_info == GST_DPARAM_UPDATE_FIRST) || (timestamp >= dpsmooth->end_interp)){
244                 if (GST_DPARAM_IS_LOG(dparam)){
245                         g_value_set_float(value, exp(dparam->value_float)); 
246                 }
247                 else {
248                         g_value_set_float(value, dparam->value_float); 
249                 }
250                 dpsmooth->current_float = dparam->value_float;
251                 
252                 GST_DEBUG(GST_CAT_PARAMS, "interp finished at %"
253                                           G_GINT64_FORMAT, timestamp); 
254
255                 GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;  
256                 GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp;
257                 
258                 GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE;
259                 GST_DPARAM_UNLOCK(dparam);
260                 return;
261         }
262
263         if (timestamp <= dpsmooth->start_interp){
264                 if (GST_DPARAM_IS_LOG(dparam)){
265                         g_value_set_float(value, exp(dpsmooth->start_float)); 
266                 }
267                 else {
268                         g_value_set_float(value, dpsmooth->start_float); 
269                 }
270                 GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;  
271                 GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->start_interp + dpsmooth->update_period; 
272                 
273                 GST_DEBUG(GST_CAT_PARAMS, "interp started at %" G_GINT64_FORMAT, timestamp); 
274
275                 GST_DPARAM_UNLOCK(dparam);
276                 return;
277                 
278         }
279
280         time_ratio = (gfloat)(timestamp - dpsmooth->start_interp) / (gfloat)dpsmooth->duration_interp;
281
282         GST_DEBUG(GST_CAT_PARAMS, "start:%" G_GINT64_FORMAT " current:%" G_GINT64_FORMAT " end:%" G_GINT64_FORMAT " ratio%f", dpsmooth->start_interp, timestamp, dpsmooth->end_interp, time_ratio); 
283         GST_DEBUG(GST_CAT_PARAMS, "pre  start:%f current:%f target:%f", dpsmooth->start_float, dpsmooth->current_float, dparam->value_float);
284                                    
285         dpsmooth->current_float = dpsmooth->start_float + (dpsmooth->diff_float * time_ratio);
286
287         GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp + dpsmooth->update_period; 
288         if (GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) > dpsmooth->end_interp){
289                 GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->end_interp;        
290         }
291
292         GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
293
294         if (GST_DPARAM_IS_LOG(dparam)){
295                 g_value_set_float(value, exp(dpsmooth->current_float)); 
296         }
297         else {
298                 g_value_set_float(value, dpsmooth->current_float); 
299         }
300
301         GST_DEBUG(GST_CAT_PARAMS, "post start:%f current:%f target:%f", dpsmooth->start_float, dpsmooth->current_float, dparam->value_float);
302
303         GST_DPARAM_UNLOCK(dparam);
304 }
305