From: <en...@fr...> - 2005-04-15 17:16:25
|
CVS Root: /cvs/gstreamer Module: gst-sandbox Changes by: ensonic Date: Fri Apr 15 2005 10:16:23 PDT Log message: linear interpolation should start to work for INTs more API implemented more locking Modified files: gst-controller : ChangeLog gst-controller/src: gst-controller.c gst-controller.h gst-interpolation.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-controller/ChangeLog.diff?r1=1.17&r2=1.18 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-controller/src/gst-controller.c.diff?r1=1.18&r2=1.19 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-controller/src/gst-controller.h.diff?r1=1.16&r2=1.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-sandbox/gst-controller/src/gst-interpolation.c.diff?r1=1.7&r2=1.8 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-sandbox/gst-controller/ChangeLog,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- ChangeLog 11 Apr 2005 18:56:10 -0000 1.17 +++ ChangeLog 15 Apr 2005 17:15:52 -0000 1.18 @@ -1,6 +1,21 @@ -2005-04-11 Stefan Kost <en...@us...> +2005-04-15 Stefan Kost <en...@us...> - reviewed by: <delete if not using a buddy> + * src/gst-controller.c: + (gst_controlled_property_set_interpolation_mode), + (gst_controlled_property_new), (gst_controller_get), + (gst_controller_get_all), (gst_controller_sink_values), + (gst_controller_get_value_arrays), + (gst_controller_get_value_array), + (gst_controller_set_interpolation_mode): + * src/gst-controller.h: + * src/gst-interpolation.c: (interpolate_none_get_int_value_array), + (_interpolate_linear_get_int), (interpolate_linear_get_int), + (interpolate_linear_get_int_value_array): + linear interpolation should start to work for INTs + more API implemented + more locking + +2005-04-11 Stefan Kost <en...@us...> * README: * examples/.cvsignore: Index: gst-controller.c RCS file: /cvs/gstreamer/gst-sandbox/gst-controller/src/gst-controller.c,v retrieving revision 1.19 diff -u -d -r1.18 -r1.19 --- gst-controller.c 13 Apr 2005 11:06:30 -0000 1.18 +++ gst-controller.c 15 Apr 2005 17:15:59 -0000 1.19 @@ -59,6 +59,46 @@ return (((GstTimedValue *) a)->timestamp - *(GstClockTime *) b); } +static gboolean +gst_controlled_property_set_interpolation_mode (GstControlledProperty * self, + GstInterpolateMode mode) +{ + self->interpolation = mode; + if (mode != GST_INTERPOLATE_USER) { + switch (self->type) { + case G_TYPE_INT: + case G_TYPE_UINT: + self->get = interpolation_methods[mode]->get_int; + self->get_value_array = interpolation_methods[mode]->get_int_value_array; + break; + case G_TYPE_LONG: + case G_TYPE_ULONG: + self->get = interpolation_methods[mode]->get_long; + self->get_value_array = interpolation_methods[mode]->get_long_value_array; + case G_TYPE_FLOAT: + self->get = interpolation_methods[mode]->get_float; + self->get_value_array = interpolation_methods[mode]->get_float_value_array; + case G_TYPE_DOUBLE: + self->get = interpolation_methods[mode]->get_double; + self->get_value_array = interpolation_methods[mode]->get_double_value_array; + default: + self->get = NULL; + self->get_value_array = NULL; + GST_WARNING ("incomplete implementation for type '%d'", self->type); + } + } else { + /* TODO shouldn't this also get a GstInterpolateMethod *user_method + for the case mode==GST_INTERPOLATE_USER + */ + } + return (TRUE); +} /* * gst_controlled_property_new: * @object: for which object the controlled property should be set up @@ -101,43 +141,48 @@ prop->name = pspec->name; // so we don't use the same mem twice prop->parent_type = G_OBJECT_TYPE (object); prop->type = G_PARAM_SPEC_VALUE_TYPE (pspec); - prop->interpolation = GST_INTERPOLATE_NONE; - prop->method = interpolation_methods[prop->interpolation]; + gst_controlled_property_set_interpolation_mode (prop, GST_INTERPOLATE_NONE); g_value_init (&prop->default_value, prop->type); - if (prop->type == G_TYPE_INT) { - GParamSpecInt *tpspec = G_PARAM_SPEC_INT (pspec); + switch (prop->type) { + case G_TYPE_INT: { + GParamSpecInt *tpspec = G_PARAM_SPEC_INT (pspec); - g_value_set_int (&prop->default_value, tpspec->default_value); - } else if (prop->type == G_TYPE_UINT) { - GParamSpecUInt *tpspec = G_PARAM_SPEC_UINT (pspec); + g_value_set_int (&prop->default_value, tpspec->default_value); + } break; + case G_TYPE_UINT: { + GParamSpecUInt *tpspec = G_PARAM_SPEC_UINT (pspec); - g_value_set_uint (&prop->default_value, tpspec->default_value); - } - if (prop->type == G_TYPE_LONG) { - GParamSpecLong *tpspec = G_PARAM_SPEC_LONG (pspec); + g_value_set_uint (&prop->default_value, tpspec->default_value); + case G_TYPE_LONG: { + GParamSpecLong *tpspec = G_PARAM_SPEC_LONG (pspec); - g_value_set_long (&prop->default_value, tpspec->default_value); - } else if (prop->type == G_TYPE_ULONG) { - GParamSpecULong *tpspec = G_PARAM_SPEC_ULONG (pspec); + g_value_set_long (&prop->default_value, tpspec->default_value); + case G_TYPE_ULONG: { + GParamSpecULong *tpspec = G_PARAM_SPEC_ULONG (pspec); - g_value_set_ulong (&prop->default_value, tpspec->default_value); - } else if (prop->type == G_TYPE_FLOAT) { - GParamSpecFloat *tpspec = G_PARAM_SPEC_FLOAT (pspec); + g_value_set_ulong (&prop->default_value, tpspec->default_value); + case G_TYPE_FLOAT: { + GParamSpecFloat *tpspec = G_PARAM_SPEC_FLOAT (pspec); - g_value_set_float (&prop->default_value, tpspec->default_value); - } else if (prop->type == G_TYPE_DOUBLE) { - GParamSpecDouble *tpspec = G_PARAM_SPEC_DOUBLE (pspec); + g_value_set_float (&prop->default_value, tpspec->default_value); + } + case G_TYPE_DOUBLE: { + GParamSpecDouble *tpspec = G_PARAM_SPEC_DOUBLE (pspec); - g_value_set_double (&prop->default_value, tpspec->default_value); - } else { - GST_WARNING ("incomplete implementation for paramspec type '%s'", + g_value_set_double (&prop->default_value, tpspec->default_value); + default: + GST_WARNING ("incomplete implementation for paramspec type '%s'", G_PARAM_SPEC_TYPE_NAME (pspec)); } /* TODO what about adding a timedval with timestamp=0 and value=default + a bit easier for interpolators, example: * first timestamp is at 5 * requested value if for timestamp=3 - * LINEAR and Co. would need to interpolate fromdefault value + * LINEAR and Co. would need to interpolate from default value to value at timestamp 5 */ } @@ -422,10 +467,12 @@ g_return_val_if_fail (property_name, NULL); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL); + g_mutex_lock (self->lock); if ((prop = gst_controller_find_controlled_property (self, property_name))) { //get current value via interpolator - val = prop->method->get (prop, timestamp); + val = prop->get (prop, timestamp); } + g_mutex_unlock (self->lock); return (val); @@ -445,9 +492,11 @@ { GstControlledProperty *prop; return (g_list_copy (prop->values)); return (NULL); @@ -477,7 +526,7 @@ for (node = self->properties; node; node = g_list_next (node)) { prop = node->data; g_object_set_property (object, prop->name, val); g_mutex_unlock (self->lock); @@ -504,39 +553,48 @@ gst_controller_get_value_arrays (GstController * self, GstClockTime timestamp, GSList * value_arrays) + gboolean res = TRUE; + GSList *node; + g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE); g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); g_return_val_if_fail (value_arrays, FALSE); - /* - foreach() { - gst_controller_get_value_array() - } - */ + for (node = value_arrays; (res && node); node = g_slist_next (node)) { + res = gst_controller_get_value_array (self, timestamp, node->data); - return (FALSE); + return (res); gboolean gst_controller_get_value_array (GstController * self, GstClockTime timestamp, GstValueArray * value_array) + gboolean res=FALSE; + GstControlledProperty *prop; g_return_val_if_fail (value_array, FALSE); + g_return_val_if_fail (value_array->property_name, FALSE); /* TODO and if GstValueArray->values is not NULL, the caller is resposible that is is big enough for nbsamples values, right? - */ - - /* - for(i=0;i<value_array->nbsample;i++) { - val=gst_controller_get(self,value_array->property_name,timestamp); - timestamp+=value_array->sample_interval; + */ + if ((prop = gst_controller_find_controlled_property (self, value_array->property_name))) { + if (!value_array->values) { + /* TODO get the base size + value_array->values=g_new(sizeof(???),nbsamples); + */ + //get current value_array via interpolator + res = prop->get_value_array (prop, timestamp, value_array); /** @@ -553,22 +611,20 @@ gst_controller_set_interpolation_mode (GstController * self, gchar * property_name, GstInterpolateMode mode) g_mutex_lock (self->lock); - prop->interpolation = mode; - if (mode != GST_INTERPOLATE_USER) { - } else { - /* TODO shouldn't this also get a GstInterpolateMethod *user_method - for the case mode==GST_INTERPOLATE_USER - */ - } + gst_controlled_property_set_interpolation_mode (prop, mode); + res = TRUE; /* gobject handling */ Index: gst-controller.h RCS file: /cvs/gstreamer/gst-sandbox/gst-controller/src/gst-controller.h,v retrieving revision 1.16 diff -u -d -r1.16 -r1.17 --- gst-controller.h 13 Apr 2005 11:06:30 -0000 1.16 +++ gst-controller.h 15 Apr 2005 17:15:59 -0000 1.17 @@ -83,11 +83,21 @@ */ struct _GstControlledProperty; +typedef GValue *(*InterpolateGet) (struct _GstControlledProperty * prop, GstClockTime timestamp); +typedef gboolean (*InterpolateGetValueArray) (struct _GstControlledProperty * prop, + GstClockTime timestamp, GstValueArray * value_array); typedef struct _GstInterpolateMethod - GValue *(*get) (struct _GstControlledProperty * prop, GstClockTime timestamp); - gboolean (*get_value_array) (struct _GstControlledProperty * prop, - GstClockTime timestamp, GstValueArray * value_array); + InterpolateGet get_int; + InterpolateGetValueArray get_int_value_array; + InterpolateGet get_long; + InterpolateGetValueArray get_long_value_array; + InterpolateGet get_float; + InterpolateGetValueArray get_float_value_array; + InterpolateGet get_double; + InterpolateGetValueArray get_double_value_array; } GstInterpolateMethod; @@ -101,16 +111,14 @@ GType type; // type of the handled property GValue default_value; // default value for the handled property GstInterpolateMode interpolation; // Interpolation mode - GstInterpolateMethod *method; // User-implemented handler (if interpolation == GST_INTERPOLATE_USER) /* TODO instead of *method, have pointers to get() and get_value_array() here gst_controller_set_interpolation_mode() will pick the right ones for the properties value type + GstInterpolateMethod *method; // User-implemented handler (if interpolation == GST_INTERPOLATE_USER) + InterpolateGet get; + InterpolateGetValueArray get_value_array; - GValue * (* get) (struct _GstControlledProperty *prop, GstClockTime timestamp); - gboolean (* get_value_array) (struct _GstControlledProperty *prop, - GstClockTime timestamp, GstValueArray *value_array); GList *values; // List of GstTimedValue /* TODO keep the last search result to be able to continue GList *last_value; // last search result, can be used for incremental searches Index: gst-interpolation.c RCS file: /cvs/gstreamer/gst-sandbox/gst-controller/src/gst-interpolation.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- gst-interpolation.c 13 Apr 2005 11:06:30 -0000 1.7 +++ gst-interpolation.c 15 Apr 2005 17:15:59 -0000 1.8 @@ -64,16 +64,32 @@ return (&prop->default_value); static gboolean -interpolate_none_get_value_array (GstControlledProperty * prop, +interpolate_none_get_int_value_array (GstControlledProperty * prop, + gint i; + GstClockTime ts=timestamp; + gint *values=(gint *)value_array->values; + for(i=0;i<value_array->nbsamples;i++) { + *values=g_value_get_int(interpolate_none_get(prop,ts)); + ts+=value_array->sample_interval; + values++; static GstInterpolateMethod interpolate_none = { interpolate_none_get, - interpolate_none_get_value_array + interpolate_none_get_int_value_array, + interpolate_none_get, + NULL, + NULL }; // returns the default value of the property, except for times with specific values @@ -83,6 +99,7 @@ interpolate_trigger_get_value_array (GstControlledProperty * prop, @@ -92,13 +109,19 @@ static GstInterpolateMethod interpolate_trigger = { interpolate_trigger_get, - interpolate_trigger_get_value_array + interpolate_trigger_get_value_array, // linear interpolation -static GValue * -interpolate_linear_get (GstControlledProperty * prop, GstClockTime timestamp) +static gint +_interpolate_linear_get_int (GstControlledProperty * prop, GstClockTime timestamp) GList *node; @@ -107,40 +130,56 @@ tv1 = node->data; if ((node = g_list_next (node))) { - GstClockTime timediff; + gdouble timediff,valuediff; + gint value1,value2; tv2 = node->data; - timediff = tv2->timestamp - tv1->timestamp; - /* TODO yieks, now we need to do that for each GValue type :( - IDEA - We can have function pointers to g_value_{set,get}_xxx in - the GstControlledProperty. - Next we have implementations for: - LONG: G_TYPE_CHAR, G_TYPE_UCHAR, ... G_TYPE_INT - INT64: G_TYPE_LONG, G_TYPE_ULONG - DOUBLE: G_TYPE_FLOAT, G_TYPE_DOUBLE - What do we do about INT64? - valuediff=value2-value1 - result=value1+valuediff*((timestamp-tv1->timestamp)/timediff); + timediff = (gdouble)(tv2->timestamp - tv1->timestamp); + value1 = g_value_get_int(&tv1->value); + value2 = g_value_get_int(&tv2->value); + valuediff = (gdouble)(value2-value1); + + return((gint)(value1+valuediff*((timestamp-tv1->timestamp)/timediff))); - return (&prop->default_value); + return (g_value_get_int(&prop->default_value)); +static GValue * +interpolate_linear_get_int (GstControlledProperty * prop, GstClockTime timestamp) + /* TODO we need an readily initializes prop->result_value + g_value_set_int(&prop->result_value,_interpolate_linear_get_int(prop,timestamp)); + return (&prop->result_value); + */ -interpolate_linear_get_value_array (GstControlledProperty * prop, +interpolate_linear_get_int_value_array (GstControlledProperty * prop, + *values=_interpolate_linear_get_int(prop,ts); static GstInterpolateMethod interpolate_linear = { - interpolate_linear_get, - interpolate_linear_get_value_array + interpolate_linear_get_int, + interpolate_linear_get_int_value_array, // square interpolation |