summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e1fe257)
raw | patch | inline | side by side (parent: e1fe257)
author | Steve Baker <steve@stevebaker.org> | |
Wed, 29 May 2002 18:47:06 +0000 (18:47 +0000) | ||
committer | Steve Baker <steve@stevebaker.org> | |
Wed, 29 May 2002 18:47:06 +0000 (18:47 +0000) |
Original commit message from CVS:
completely rewrite interpolation so that it is more stable, faster, easier to maintain and it now sounds damned smoooth
completely rewrite interpolation so that it is more stable, faster, easier to maintain and it now sounds damned smoooth
libs/gst/control/dparam_smooth.c | patch | blob | history | |
libs/gst/control/dparam_smooth.h | patch | blob | history |
index 9bcfe33f9082b50bf83d1e545d4d01f9e849e24a..2e0607819b49e404003b373c3cc0573fa6a24a89 100644 (file)
static void gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
static void gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info);
+static void gst_dpsmooth_value_changed_float (GstDParam *dparam);
enum {
ARG_0,
switch (type){
case G_TYPE_FLOAT: {
dparam->do_update_func = gst_dpsmooth_do_update_float;
+ g_signal_connect (G_OBJECT (dpsmooth), "value_changed", G_CALLBACK (gst_dpsmooth_value_changed_float), NULL);
break;
}
default:
@@ -197,23 +199,55 @@ gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParam
}
}
+static void
+gst_dpsmooth_value_changed_float (GstDParam *dparam)
+{
+ GstDParamSmooth *dpsmooth;
+ gfloat time_ratio;
+
+ g_return_if_fail(GST_IS_DPSMOOTH(dparam));
+ dpsmooth = GST_DPSMOOTH(dparam);
+
+ if (GST_DPARAM_IS_LOG(dparam)){
+ dparam->value_float = log(dparam->value_float);
+ }
+ dpsmooth->start_float = dpsmooth->current_float;
+ dpsmooth->diff_float = dparam->value_float - dpsmooth->start_float;
+
+ time_ratio = ABS(dpsmooth->diff_float) / dpsmooth->slope_delta_float;
+ dpsmooth->duration_interp = (gint64)(time_ratio * (gfloat)dpsmooth->slope_time);
+
+ dpsmooth->need_interp_times = TRUE;
+
+ GST_DEBUG(GST_CAT_PARAMS, "%f to %f ratio:%f duration:%lld\n",
+ dpsmooth->start_float, dparam->value_float, time_ratio, dpsmooth->duration_interp);
+}
+
static void
gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value, GstDParamUpdateInfo update_info)
{
- gint64 time_diff;
gfloat time_ratio;
- gfloat current, target, max_change, final_val;
- gfloat current_diff = 0;
-
GstDParamSmooth *dpsmooth = GST_DPSMOOTH(dparam);
GST_DPARAM_LOCK(dparam);
- if (update_info == GST_DPARAM_UPDATE_FIRST){
- /*this is the first update since the pipeline started.
- * the value won't be smoothed, it will be updated immediately
- */
- g_value_set_float(value, dparam->value_float);
+ if (dpsmooth->need_interp_times){
+ dpsmooth->start_interp = timestamp;
+ dpsmooth->end_interp = timestamp + dpsmooth->duration_interp;
+ dpsmooth->need_interp_times = FALSE;
+ }
+
+ if ((update_info == GST_DPARAM_UPDATE_FIRST) || (timestamp >= dpsmooth->end_interp)){
+ if (GST_DPARAM_IS_LOG(dparam)){
+ g_value_set_float(value, exp(dparam->value_float));
+ }
+ else {
+ g_value_set_float(value, dparam->value_float);
+ }
+ dpsmooth->current_float = dparam->value_float;
+
+ GST_DEBUG(GST_CAT_PARAMS, "interp finished at %lld", timestamp);
+
GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp;
@@ -221,59 +255,46 @@ gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value
GST_DPARAM_UNLOCK(dparam);
return;
}
-
- time_diff = timestamp - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam);
-
- target = dparam->value_float;
- current = g_value_get_float(value);
-
- time_ratio = (gfloat)time_diff / (gfloat)dpsmooth->slope_time;
- max_change = time_ratio * dpsmooth->slope_delta_float;
-
- GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f max_change:%f ",
- target, current, max_change);
-
- if (GST_DPARAM_IS_LOG(dparam)){
- if (current == 0.0F){
- /* this shouldn't happen, so forget about smoothing and just set the value */
- final_val = target;
- }
- else {
- gfloat current_log;
- current_log = log(current);
- current_diff = ABS(current_log - log(target));
-
- GST_DEBUG(GST_CAT_PARAMS, "current_log:%f",current_log);
- GST_DEBUG(GST_CAT_PARAMS, "current_diff:%f",current_diff);
-
- if (current_diff > max_change){
- final_val = (target < current) ? exp(current_log-max_change) : exp(current_log+max_change);
- }
- else {
- final_val = target;
- }
- }
- }
- else {
- current_diff = ABS (current - target);
- if (current_diff > max_change){
- final_val = (target < current) ? current-max_change : current+max_change;
+ if (timestamp <= dpsmooth->start_interp){
+ if (GST_DPARAM_IS_LOG(dparam)){
+ g_value_set_float(value, exp(dpsmooth->start_float));
}
else {
- final_val = target;
+ g_value_set_float(value, dpsmooth->start_float);
}
+ GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
+ GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->start_interp + dpsmooth->update_period;
+
+ GST_DEBUG(GST_CAT_PARAMS, "interp started at %lld", timestamp);
+
+ GST_DPARAM_UNLOCK(dparam);
+ return;
+
}
- GST_DPARAM_READY_FOR_UPDATE(dparam) = (final_val != target);
- if (GST_DPARAM_READY_FOR_UPDATE(dparam)){
- GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp + dpsmooth->update_period;
+ time_ratio = (gfloat)(timestamp - dpsmooth->start_interp) / (gfloat)dpsmooth->duration_interp;
+
+ GST_DEBUG(GST_CAT_PARAMS, "start:%lld current:%lld end:%lld ratio%f", dpsmooth->start_interp, timestamp, dpsmooth->end_interp, time_ratio);
+ GST_DEBUG(GST_CAT_PARAMS, "pre start:%f current:%f target:%f", dpsmooth->start_float, dpsmooth->current_float, dparam->value_float);
+
+ dpsmooth->current_float = dpsmooth->start_float + (dpsmooth->diff_float * time_ratio);
+
+ GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = timestamp + dpsmooth->update_period;
+ if (GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) > dpsmooth->end_interp){
+ GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->end_interp;
}
+
GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = timestamp;
- g_value_set_float(value, final_val);
-
- GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f final:%f actual:%f", target, current, final_val, g_value_get_float(value));
+ if (GST_DPARAM_IS_LOG(dparam)){
+ g_value_set_float(value, exp(dpsmooth->current_float));
+ }
+ else {
+ g_value_set_float(value, dpsmooth->current_float);
+ }
+
+ GST_DEBUG(GST_CAT_PARAMS, "post start:%f current:%f target:%f", dpsmooth->start_float, dpsmooth->current_float, dparam->value_float);
GST_DPARAM_UNLOCK(dparam);
}
index 0210e34faf2f9a6511518cdff9086ce3ed45ce87..bcfdbb75717cf381a2744c968266ecfd6a04a2de 100644 (file)
struct _GstDParamSmooth {
GstDParam dparam;
+ gint64 start_interp;
+ gint64 end_interp;
+ gint64 duration_interp;
+
+ gfloat start_float;
+ gfloat diff_float;
+ gfloat current_float;
+
gint64 update_period;
gint64 slope_time;
gfloat slope_delta_float;
+
+ gboolean need_interp_times;
};
struct _GstDParamSmoothClass {