From 3e1e367954f6d62fbd56a2d24d753c163b89cec6 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Mon, 4 Mar 2002 18:54:20 +0000 Subject: [PATCH] This is a major update to the dparams api - I think it is now much cleaner and the app-side is much easier to use. hi... Original commit message from CVS: This is a major update to the dparams api - I think it is now much cleaner and the app-side is much easier to use. highlights are: - GParamSpecs are now used throughout to define dparams - currently limited to supporting types gfloat, gint and gint64. this should cover 99% of cases and new types can be added in the future - application-side api is now based almost entirely on setting object properties - the smoothing dparam is now a subclass of GstDParam - array-mode is not yet implemented but is not forgotton time to start documenting --- libs/gst/control/Makefile.am | 2 + libs/gst/control/control.h | 1 + libs/gst/control/dparam.c | 402 +++++++++++++-------------------------- libs/gst/control/dparam.h | 105 +++------- libs/gst/control/dparam_smooth.c | 290 ++++++++++++++++++++++++++++ libs/gst/control/dparam_smooth.h | 61 ++++++ libs/gst/control/dparamcommon.h | 1 - libs/gst/control/dparammanager.c | 183 +++++------------- libs/gst/control/dparammanager.h | 29 +-- 9 files changed, 587 insertions(+), 487 deletions(-) create mode 100644 libs/gst/control/dparam_smooth.c create mode 100644 libs/gst/control/dparam_smooth.h diff --git a/libs/gst/control/Makefile.am b/libs/gst/control/Makefile.am index 8984ef0..cd0f88e 100644 --- a/libs/gst/control/Makefile.am +++ b/libs/gst/control/Makefile.am @@ -7,6 +7,7 @@ libgstcontrolinclude_HEADERS = \ control.h \ dparammanager.h \ dparam.h \ + dparam_smooth.h \ dparamcommon.h \ dplinearinterp.h @@ -14,6 +15,7 @@ libgstcontrol_la_SOURCES = \ control.c \ dparammanager.c \ dparam.c \ + dparam_smooth.c \ dplinearinterp.c libgstcontrol_la_CFLAGS = $(GST_CFLAGS) -finline-functions -ffast-math diff --git a/libs/gst/control/control.h b/libs/gst/control/control.h index 8809657..a6a87b7 100644 --- a/libs/gst/control/control.h +++ b/libs/gst/control/control.h @@ -28,6 +28,7 @@ extern "C" { #include #include +#include #include void gst_control_init (int *argc, char **argv[]); diff --git a/libs/gst/control/dparam.c b/libs/gst/control/dparam.c index 088dbe1..d5cfd64 100644 --- a/libs/gst/control/dparam.c +++ b/libs/gst/control/dparam.c @@ -29,9 +29,17 @@ static void gst_dparam_class_init (GstDParamClass *klass); static void gst_dparam_init (GstDParam *dparam); static void gst_dparam_dispose (GObject *object); - -static void gst_dparam_do_update_realtime (GstDParam *dparam, gint64 timestamp); -static GValue** gst_dparam_get_point_realtime (GstDParam *dparam, gint64 timestamp); +static void gst_dparam_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void gst_dparam_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); + +enum { + ARG_0, + ARG_VALUE_FLOAT, + ARG_VALUE_INT, + ARG_VALUE_INT64, + ARG_IS_LOG, + ARG_IS_RATE, +}; GType gst_dparam_get_type(void) { @@ -64,8 +72,34 @@ gst_dparam_class_init (GstDParamClass *klass) gobject_class = (GObjectClass*)klass; dparam_class = (GstDParamClass*)klass; gstobject_class = (GstObjectClass*) klass; - + + gobject_class->get_property = gst_dparam_get_property; + gobject_class->set_property = gst_dparam_set_property; + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VALUE_FLOAT, + g_param_spec_float("value_float","Float Value", + "The value that should be changed if gfloat is the type", + (gfloat)G_MININT64, (gfloat)G_MAXINT64, 0.0F, G_PARAM_READWRITE)); + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VALUE_INT, + g_param_spec_int("value_int","Integer Value", + "The value that should be changed if gint is the type", + G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VALUE_INT64, + g_param_spec_int64("value_int64","64 bit Integer Value", + "The value that should be changed if gint64 is the type", + G_MININT64, G_MAXINT64, 0, G_PARAM_READWRITE)); + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_IS_LOG, + g_param_spec_boolean("is_log","Is a Log Value", + "This dparam should be interpreted on a log scale", + FALSE, G_PARAM_READABLE)); + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_IS_RATE, + g_param_spec_boolean("is_rate","Is a sample rate proportion", + "This dparam value represents a proportion of the sample rate (eg half of the sample rate will be 0.5)", + FALSE, G_PARAM_READABLE)); + gobject_class->dispose = gst_dparam_dispose; + //gstobject_class->save_thyself = gst_dparam_save_thyself; } @@ -74,10 +108,8 @@ static void gst_dparam_init (GstDParam *dparam) { g_return_if_fail (dparam != NULL); - GST_DPARAM_VALUE(dparam) = NULL; GST_DPARAM_TYPE(dparam) = 0; GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam)=0LL; - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam)=0LL; GST_DPARAM_READY_FOR_UPDATE(dparam)=FALSE; dparam->lock = g_mutex_new (); } @@ -94,35 +126,108 @@ gst_dparam_new (GType type) GstDParam *dparam; dparam = g_object_new (gst_dparam_get_type (), NULL); - dparam->do_update_func = gst_dparam_do_update_realtime; - dparam->get_point_func = gst_dparam_get_point_realtime; - - dparam->point = gst_dparam_new_value_array(type, 0); + dparam->do_update_func = gst_dparam_do_update_default; + GST_DPARAM_TYPE(dparam) = type; return dparam; } + +static void +gst_dparam_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstDParam *dparam; + g_return_if_fail(GST_IS_DPARAM(object)); + dparam = GST_DPARAM(object); + + switch (prop_id) { + case ARG_IS_LOG: + g_value_set_boolean (value, dparam->is_log); + break; + case ARG_IS_RATE: + g_value_set_boolean (value, dparam->is_rate); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gst_dparam_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstDParam *dparam; + g_return_if_fail(GST_IS_DPARAM(object)); + dparam = GST_DPARAM(object); + GST_DPARAM_LOCK(dparam); + + switch (prop_id) { + case ARG_VALUE_FLOAT: + GST_DEBUG(GST_CAT_PARAMS, "setting value from %f to %f\n", dparam->value_float, g_value_get_float (value)); + dparam->value_float = g_value_get_float (value); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + case ARG_VALUE_INT: + GST_DEBUG(GST_CAT_PARAMS, "setting value from %d to %d\n", dparam->value_int, g_value_get_int (value)); + dparam->value_int = g_value_get_int (value); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + case ARG_VALUE_INT64: + GST_DEBUG(GST_CAT_PARAMS, "setting value from %lld to %lld\n", dparam->value_int64, g_value_get_int64 (value)); + dparam->value_int64 = g_value_get_int (value); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + default: + break; + } + GST_DPARAM_UNLOCK(dparam); +} + +void +gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value) +{ + GST_DPARAM_LOCK(dparam); + + g_return_if_fail (G_VALUE_TYPE(value) == GST_DPARAM_TYPE(dparam)); + GST_DEBUG(GST_CAT_PARAMS, "updating value for %s(%p)\n",GST_DPARAM_NAME (dparam),dparam); + + switch (G_VALUE_TYPE(value)) { + case G_TYPE_FLOAT: + g_value_set_float(value, dparam->value_float); + break; + + case G_TYPE_INT: + g_value_set_int(value, dparam->value_int); + break; + + case G_TYPE_INT64: + g_value_set_int64(value, dparam->value_int64); + break; + + default: + break; + } + + GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; + + GST_DPARAM_UNLOCK(dparam); +} + static void gst_dparam_dispose (GObject *object) { GstDParam *dparam = GST_DPARAM(object); - GValue **point = dparam->point; - guint i = 0; gchar *dparam_name = g_strdup(GST_DPARAM_NAME(dparam)); g_print("disposing of %s\n", dparam_name); if (GST_DPARAM_MANAGER(dparam)){ gst_dpman_detach_dparam(GST_DPARAM_MANAGER(dparam), dparam_name); } - point = dparam->point; - while (point[i]){ - g_value_unset(point[i]); - g_free(point[i]); - i++; - } g_free(dparam_name); - } /** @@ -132,21 +237,23 @@ gst_dparam_dispose (GObject *object) * */ void -gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GValue *value, GstDParamSpec *spec) +gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gboolean is_log, gboolean is_rate) { g_return_if_fail (dparam != NULL); g_return_if_fail (GST_IS_DPARAM (dparam)); g_return_if_fail (manager != NULL); g_return_if_fail (GST_IS_DPMAN (manager)); - g_return_if_fail (value != NULL); - g_return_if_fail (spec != NULL); - g_return_if_fail (GST_DPARAM_TYPE(dparam) == G_VALUE_TYPE(value)); - - GST_DPARAM_NAME(dparam) = spec->dparam_name; - GST_DPARAM_VALUE(dparam) = value; - GST_DPARAM_SPEC(dparam) = spec; + g_return_if_fail (param_spec != NULL); + g_return_if_fail (G_IS_PARAM_SPEC (param_spec)); + + GST_DPARAM_NAME(dparam) = g_param_spec_get_name(param_spec); + GST_DPARAM_PARAM_SPEC(dparam) = param_spec; GST_DPARAM_MANAGER(dparam) = manager; + dparam->is_log = is_log; + dparam->is_rate = is_rate; + GST_DEBUG(GST_CAT_PARAMS, "attaching %s to dparam %p\n",GST_DPARAM_NAME (dparam),dparam); + } /** @@ -161,248 +268,13 @@ gst_dparam_detach (GstDParam *dparam) g_return_if_fail (dparam != NULL); g_return_if_fail (GST_IS_DPARAM (dparam)); + + GST_DEBUG(GST_CAT_PARAMS, "detaching %s from dparam %p\n",GST_DPARAM_NAME (dparam),dparam); GST_DPARAM_NAME(dparam) = NULL; - GST_DPARAM_VALUE(dparam) = NULL; - GST_DPARAM_SPEC(dparam) = NULL; + GST_DPARAM_PARAM_SPEC(dparam) = NULL; GST_DPARAM_MANAGER(dparam) = NULL; } -/** - * gst_dparam_new_value_array - * @type: the type of the first GValue in the array - * @...: the type of other GValues in the array - * - * The list of types should be terminated with a 0. - * If the type of a value is not yet known then use G_TYPE_NONE . - * - * Returns: an newly created array of GValues - */ -GValue** -gst_dparam_new_value_array(GType type, ...) -{ - GValue **point; - GValue *value; - guint x; - guint values_length = 0; - va_list var_args; - GType each_type; - - va_start (var_args, type); - each_type = type; - while (each_type){ - values_length++; - each_type = va_arg (var_args, GType); - } - va_end (var_args); - - point = g_new0(GValue*,values_length + 1); - - va_start (var_args, type); - each_type = type; - for (x=0 ; x < values_length ; x++){ - value = g_new0(GValue,1); - if (each_type != G_TYPE_NONE){ - g_value_init(value, each_type); - } - point[x] = value; - each_type = va_arg (var_args, GType); - } - point[values_length] = NULL; - va_end (var_args); - - GST_DEBUG(GST_CAT_PARAMS, "array with %d values created\n", values_length); - - return point; -} - -void -gst_dparam_set_value_from_string(GValue *value, const gchar *value_str) -{ - - g_return_if_fail(value != NULL); - g_return_if_fail(value_str != NULL); - - GST_DEBUG(GST_CAT_PARAMS, "parsing '%s' to type %s\n", value_str, g_type_name(G_VALUE_TYPE(value))); - - switch (G_VALUE_TYPE(value)) { - case G_TYPE_STRING: - g_value_set_string(value, g_strdup(value_str)); - break; - case G_TYPE_ENUM: - case G_TYPE_INT: { - gint i; - sscanf (value_str, "%d", &i); - g_value_set_int(value, i); - break; - } - case G_TYPE_UINT: { - guint i; - sscanf (value_str, "%u", &i); - g_value_set_uint(value, i); - break; - } - case G_TYPE_LONG: { - glong i; - sscanf (value_str, "%ld", &i); - g_value_set_long(value, i); - break; - } - case G_TYPE_ULONG: { - gulong i; - sscanf (value_str, "%lu", &i); - g_value_set_ulong(value, i); - break; - } - case G_TYPE_BOOLEAN: { - gboolean i = FALSE; - if (!strncmp ("true", value_str, 4)) i = TRUE; - g_value_set_boolean(value, i); - break; - } - case G_TYPE_CHAR: { - gchar i; - sscanf (value_str, "%c", &i); - g_value_set_char(value, i); - break; - } - case G_TYPE_UCHAR: { - guchar i; - sscanf (value_str, "%c", &i); - g_value_set_uchar(value, i); - break; - } - case G_TYPE_FLOAT: { - gfloat i; - sscanf (value_str, "%f", &i); - g_value_set_float(value, i); - break; - } - case G_TYPE_DOUBLE: { - gfloat i; - sscanf (value_str, "%g", &i); - g_value_set_double(value, (gdouble)i); - break; - } - default: - break; - } -} - -static void -gst_dparam_do_update_realtime (GstDParam *dparam, gint64 timestamp) -{ - GST_DPARAM_LOCK(dparam); - GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; - GST_DEBUG(GST_CAT_PARAMS, "updating value for %s(%p)\n",GST_DPARAM_NAME (dparam),dparam); - g_value_copy(dparam->point[0], GST_DPARAM_VALUE(dparam)); - GST_DPARAM_UNLOCK(dparam); -} - -static GValue** -gst_dparam_get_point_realtime (GstDParam *dparam, gint64 timestamp) -{ - GST_DEBUG(GST_CAT_PARAMS, "getting point for %s(%p)\n",GST_DPARAM_NAME (dparam),dparam); - return dparam->point; -} - -/********************** - * GstDParamSmooth - **********************/ - -static void gst_dparam_do_update_smooth (GstDParam *dparam, gint64 timestamp); -static GValue** gst_dparam_get_point_smooth (GstDParam *dparam, gint64 timestamp); - -/** - * gst_dparam_smooth_new: - * @type: the type that this dparam will store - * - * Returns: a new instance of GstDParamSmooth - */ -GstDParam* -gst_dparam_smooth_new (GType type) -{ - GstDParam *dparam; - - dparam = g_object_new (gst_dparam_get_type (), NULL); - - dparam->do_update_func = gst_dparam_do_update_smooth; - dparam->get_point_func = gst_dparam_get_point_smooth; - - dparam->point = gst_dparam_new_value_array(type, type, G_TYPE_FLOAT, 0); - GST_DPARAM_TYPE(dparam) = type; - - return dparam; -} - -static void -gst_dparam_do_update_smooth (GstDParam *dparam, gint64 timestamp) -{ - gint64 time_diff; - gfloat time_ratio; - - time_diff = MIN(GST_DPARAM_DEFAULT_UPDATE_PERIOD(dparam), - timestamp - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam)); - - time_ratio = (gfloat)time_diff / g_value_get_float(dparam->point[2]); - - GST_DPARAM_LOCK(dparam); - - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam); - while(GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp){ - GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) += GST_DPARAM_DEFAULT_UPDATE_PERIOD(dparam); - } - GST_DEBUG(GST_CAT_PARAMS, "last:%lld current:%lld next:%lld\n", - GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam), timestamp, GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam)); - - - switch (G_VALUE_TYPE(GST_DPARAM_VALUE(dparam))){ - case G_TYPE_FLOAT: { - gfloat current, target, max_change, current_diff, final_val; - - target = g_value_get_float(dparam->point[0]); - current = g_value_get_float(GST_DPARAM_VALUE(dparam)); - max_change = time_ratio * g_value_get_float(dparam->point[1]); - - GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f max_change:%f \n", - target, current, max_change); - - if (dparam->spec->is_log){ - gfloat current_log; - current_log = log(current); - current_diff = ABS(current_log - log(target)); - 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; - else - final_val = target; - } - - GST_DPARAM_READY_FOR_UPDATE(dparam) = (current_diff > max_change); - g_value_set_float(GST_DPARAM_VALUE(dparam), final_val); - - break; - } - default: - break; - } - - //GST_DEBUG(GST_CAT_PARAMS, "smooth update for %s(%p): %f\n", - // GST_DPARAM_NAME (dparam),dparam, g_value_get_float(GST_DPARAM_VALUE(dparam))); - GST_DPARAM_UNLOCK(dparam); -} - -static GValue** -gst_dparam_get_point_smooth (GstDParam *dparam, gint64 timestamp) -{ - GST_DEBUG(GST_CAT_PARAMS, "getting point for %s(%p)\n",GST_DPARAM_NAME (dparam),dparam); - return dparam->point; -} diff --git a/libs/gst/control/dparam.h b/libs/gst/control/dparam.h index 44c57f9..f3ada56 100644 --- a/libs/gst/control/dparam.h +++ b/libs/gst/control/dparam.h @@ -36,79 +36,48 @@ extern "C" { #define GST_IS_DPARAM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DPARAM)) #define GST_IS_DPARAM_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DPARAM)) -#define GST_DPARAM_NAME(dparam) (GST_OBJECT_NAME(dparam)) -#define GST_DPARAM_PARENT(dparam) (GST_OBJECT_PARENT(dparam)) -#define GST_DPARAM_VALUE(dparam) ((dparam)->value) -#define GST_DPARAM_SPEC(dparam) ((dparam)->spec) -#define GST_DPARAM_MANAGER(dparam) ((dparam)->manager) -#define GST_DPARAM_TYPE(dparam) ((dparam)->type) - -#define GST_DPARAM_LOCK(dparam) (g_mutex_lock((dparam)->lock)) -#define GST_DPARAM_UNLOCK(dparam) (g_mutex_unlock((dparam)->lock)) - -#define GST_DPARAM_READY_FOR_UPDATE(dparam) ((dparam)->ready_for_update) -#define GST_DPARAM_DEFAULT_UPDATE_PERIOD(dparam) ((dparam)->default_update_period) +#define GST_DPARAM_NAME(dparam) (GST_OBJECT_NAME(dparam)) +#define GST_DPARAM_PARENT(dparam) (GST_OBJECT_PARENT(dparam)) +#define GST_DPARAM_CHANGE_VALUE(dparam) ((dparam)->change_value) +#define GST_DPARAM_PARAM_SPEC(dparam) ((dparam)->param_spec) +#define GST_DPARAM_MANAGER(dparam) ((dparam)->manager) +#define GST_DPARAM_TYPE(dparam) ((dparam)->type) +#define GST_DPARAM_IS_LOG(dparam) ((dparam)->is_log) +#define GST_DPARAM_IS_RATE(dparam) ((dparam)->is_rate) +#define GST_DPARAM_META_VALUES(dparam) ((dparam)->meta_values) +#define GST_DPARAM_META_PARAM_SPECS(dparam) ((dparam)->meta_param_specs) +#define GST_DPARAM_LOCK(dparam) (g_mutex_lock((dparam)->lock)) +#define GST_DPARAM_UNLOCK(dparam) (g_mutex_unlock((dparam)->lock)) + +#define GST_DPARAM_READY_FOR_UPDATE(dparam) ((dparam)->ready_for_update) #define GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) ((dparam)->next_update_timestamp) -#define GST_DPARAM_LAST_UPDATE_TIMESTAMP(dparam) ((dparam)->last_update_timestamp) -#define GST_DPARAM_GET_POINT(dparam, timestamp) \ - ((dparam->get_point_func)(dparam, timestamp)) - -#define GST_DPARAM_FIND_POINT(dparam, timestamp, search_flag) \ - ((dparam->find_point_func)(dparam, data, search_flag)) - -#define GST_DPARAM_DO_UPDATE(dparam, timestamp) \ - ((dparam->do_update_func)(dparam, timestamp)) - -#define GST_DPARAM_INSERT_POINT(dparam, timestamp) \ - ((dparam->insert_point_func)(dparam, timestamp)) - -#define GST_DPARAM_REMOVE_POINT(dparam, data) \ - ((dparam->remove_point_func)(dparam, data)) - -typedef enum { - GST_DPARAM_CLOSEST, - GST_DPARAM_CLOSEST_AFTER, - GST_DPARAM_CLOSEST_BEFORE, - GST_DPARAM_EXACT, -} GstDParamSearchFlag; - -typedef enum { - GST_DPARAM_NOT_FOUND = 0, - GST_DPARAM_FOUND_EXACT, - GST_DPARAM_FOUND_CLOSEST, -} GstDParamSearchResult; +#define GST_DPARAM_DO_UPDATE(dparam, timestamp, value) \ + ((dparam->do_update_func)(dparam, timestamp, value)) typedef struct _GstDParamClass GstDParamClass; -typedef GValue** (*GstDParamInsertPointFunction) (GstDParam *dparam, guint64 timestamp); -typedef void (*GstDParamRemovePointFunction) (GstDParam *dparam, GValue** point); -typedef GValue** (*GstDParamGetPointFunction) (GstDParam *dparam, gint64 timestamp); -typedef GstDParamSearchResult (*GstDParamFindPointFunction) (GstDParam *dparam, gint64 *timestamp, GstDParamSearchFlag search_flag); - -typedef void (*GstDParamDoUpdateFunction) (GstDParam *dparam, gint64 timestamp); +typedef void (*GstDParamDoUpdateFunction) (GstDParam *dparam, gint64 timestamp, GValue *value); struct _GstDParam { GstObject object; - GstDParamGetPointFunction get_point_func; - GstDParamFindPointFunction find_point_func; - GstDParamDoUpdateFunction do_update_func; - GstDParamInsertPointFunction insert_point_func; - GstDParamRemovePointFunction remove_point_func; - GMutex *lock; - GValue *value; + + gfloat value_float; + gint value_int; + gint64 value_int64; + GstDParamManager *manager; - GstDParamSpec *spec; - GValue **point; + GParamSpec *param_spec; GType type; - gint64 last_update_timestamp; - gint64 next_update_timestamp; - gint64 default_update_period; gboolean ready_for_update; + + gint64 next_update_timestamp; + gboolean is_log; + gboolean is_rate; }; struct _GstDParamClass { @@ -117,28 +86,12 @@ struct _GstDParamClass { /* signal callbacks */ }; -struct _GstDParamSpec { - gchar *dparam_name; - gchar *unit_name; - GValue *min_val; - GValue *max_val; - GValue *default_val; - gboolean is_log; - gboolean is_rate; -}; GType gst_dparam_get_type (void); GstDParam* gst_dparam_new (GType type); -void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GValue *value, GstDParamSpec *spec); +void gst_dparam_attach (GstDParam *dparam, GstDParamManager *manager, GParamSpec *param_spec, gboolean is_log, gboolean is_rate); void gst_dparam_detach (GstDParam *dparam); -GValue** gst_dparam_new_value_array(GType type, ...); -void gst_dparam_set_value_from_string(GValue *value, const gchar *value_str); - -/********************** - * GstDParamSmooth - **********************/ - -GstDParam* gst_dparam_smooth_new (GType type); +void gst_dparam_do_update_default (GstDParam *dparam, gint64 timestamp, GValue *value); #ifdef __cplusplus } diff --git a/libs/gst/control/dparam_smooth.c b/libs/gst/control/dparam_smooth.c new file mode 100644 index 0000000..b42a134 --- /dev/null +++ b/libs/gst/control/dparam_smooth.c @@ -0,0 +1,290 @@ +/* GStreamer + * Copyright (C) 2001 Steve Baker + * + * gstdparam_smooth.c: Realtime smoothed dynamic parameter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +#include +#include + +static void gst_dpsmooth_class_init (GstDParamSmoothClass *klass); +static void gst_dpsmooth_init (GstDParamSmooth *dparam); +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 gint64 gst_dpsmooth_time_since_last_update(GstDParam *dparam, gint64 timestamp); +static void gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value); + +enum { + ARG_0, + ARG_UPDATE_PERIOD, + ARG_SLOPE_TIME, + ARG_SLOPE_DELTA_FLOAT, + ARG_SLOPE_DELTA_INT, + ARG_SLOPE_DELTA_INT64, +}; + +GType +gst_dpsmooth_get_type(void) { + static GType dpsmooth_type = 0; + + if (!dpsmooth_type) { + static const GTypeInfo dpsmooth_info = { + sizeof(GstDParamSmoothClass), + NULL, + NULL, + (GClassInitFunc)gst_dpsmooth_class_init, + NULL, + NULL, + sizeof(GstDParamSmooth), + 0, + (GInstanceInitFunc)gst_dpsmooth_init, + }; + dpsmooth_type = g_type_register_static(GST_TYPE_DPARAM, "GstDParamSmooth", &dpsmooth_info, 0); + } + return dpsmooth_type; +} + +static void +gst_dpsmooth_class_init (GstDParamSmoothClass *klass) +{ + GObjectClass *gobject_class; + GstDParamSmoothClass *dpsmooth_class; + GstObjectClass *gstobject_class; + + gobject_class = (GObjectClass*)klass; + dpsmooth_class = (GstDParamSmoothClass*)klass; + gstobject_class = (GstObjectClass*) klass; + + gobject_class->get_property = gst_dpsmooth_get_property; + gobject_class->set_property = gst_dpsmooth_set_property; + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_UPDATE_PERIOD, + g_param_spec_int64("update_period", + "Update Period (nanoseconds)", + "Number of nanoseconds between updates", + 0LL, G_MAXINT64, 2000000LL, G_PARAM_READWRITE)); + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SLOPE_TIME, + g_param_spec_int64("slope_time", + "Slope Time (nanoseconds)", + "The time period to define slope_delta by", + 0LL, G_MAXINT64, 10000000LL, G_PARAM_READWRITE)); + + g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SLOPE_DELTA_FLOAT, + g_param_spec_float("slope_delta_float", + "Slope Delta float", + "The amount a float value can change for a given slope_time", + 0.0F, G_MAXFLOAT, 0.2F, G_PARAM_READWRITE)); + + //gstobject_class->save_thyself = gst_dparam_save_thyself; + +} + +static void +gst_dpsmooth_init (GstDParamSmooth *dpsmooth) +{ + g_return_if_fail (dpsmooth != NULL); +} + +/** + * gst_dpsmooth_new: + * @type: the type that this dparam will store + * + * Returns: a new instance of GstDParam + */ +GstDParam* +gst_dpsmooth_new (GType type) +{ + GstDParam *dparam; + GstDParamSmooth *dpsmooth; + + dpsmooth =g_object_new (gst_dpsmooth_get_type (), NULL); + dparam = GST_DPARAM(dpsmooth); + + GST_DPARAM_TYPE(dparam) = type; + + switch (type){ + case G_TYPE_FLOAT: { + dparam->do_update_func = gst_dpsmooth_do_update_float; + break; + } + default: + /* we don't support this type here */ + dparam->do_update_func = gst_dparam_do_update_default; + break; + } + dpsmooth->last_update_timestamp = 0LL; + return dparam; +} + +static void +gst_dpsmooth_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GstDParam *dparam; + GstDParamSmooth *dpsmooth; + + g_return_if_fail(GST_IS_DPSMOOTH(object)); + + dpsmooth = GST_DPSMOOTH(object); + dparam = GST_DPARAM(object); + + GST_DPARAM_LOCK(dparam); + + switch (prop_id) { + case ARG_UPDATE_PERIOD: + dpsmooth->update_period = g_value_get_int64 (value); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + case ARG_SLOPE_TIME: + dpsmooth->slope_time = g_value_get_int64 (value); + GST_DEBUG(GST_CAT_PARAMS, "dpsmooth->slope_time:%lld\n",dpsmooth->slope_time); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + case ARG_SLOPE_DELTA_FLOAT: + dpsmooth->slope_delta_float = g_value_get_float (value); + GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; + break; + + default: + break; + } + GST_DPARAM_UNLOCK(dparam); +} + +static void +gst_dpsmooth_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GstDParam *dparam; + GstDParamSmooth *dpsmooth; + + g_return_if_fail(GST_IS_DPSMOOTH(object)); + + dpsmooth = GST_DPSMOOTH(object); + dparam = GST_DPARAM(object); + + switch (prop_id) { + case ARG_UPDATE_PERIOD: + g_value_set_int64(value, dpsmooth->update_period); + break; + case ARG_SLOPE_TIME: + g_value_set_int64(value, dpsmooth->slope_time); + break; + case ARG_SLOPE_DELTA_FLOAT: + g_value_set_float (value, dpsmooth->slope_delta_float); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gint64 +gst_dpsmooth_time_since_last_update(GstDParam *dparam, gint64 timestamp) +{ + gint64 time_diff, last_update_diff, num_update_periods; + GstDParamSmooth *dpsmooth = GST_DPSMOOTH(dparam); + + last_update_diff = timestamp - dpsmooth->last_update_timestamp; + time_diff = MIN(dpsmooth->update_period, last_update_diff); + + GST_DEBUG(GST_CAT_PARAMS, "last_update_diff:%lld\n",last_update_diff); + GST_DEBUG(GST_CAT_PARAMS, "time_diff:%lld\n",time_diff); + + dpsmooth->last_update_timestamp = GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam); + if(GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp && dpsmooth->update_period > 0LL){ + + GST_DEBUG(GST_CAT_PARAMS, "dpsmooth->update_period:%lld\n",dpsmooth->update_period); + num_update_periods = last_update_diff / dpsmooth->update_period; + + GST_DEBUG(GST_CAT_PARAMS, "num_update_periods:%lld\n",num_update_periods); + + GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) = dpsmooth->update_period * (num_update_periods + 1LL); + } + GST_DEBUG(GST_CAT_PARAMS, "last:%lld current:%lld next:%lld\n", + dpsmooth->last_update_timestamp, timestamp, GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam)); + return time_diff; +} + +static void +gst_dpsmooth_do_update_float (GstDParam *dparam, gint64 timestamp, GValue *value) +{ + gint64 time_diff; + gfloat time_ratio; + gfloat current, target, max_change, current_diff, final_val; + + GstDParamSmooth *dpsmooth = GST_DPSMOOTH(dparam); + + GST_DPARAM_LOCK(dparam); + + time_diff = gst_dpsmooth_time_since_last_update(dparam, timestamp); + + + 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 \n", + 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; + GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; + } + else { + gfloat current_log; + current_log = log(current); + current_diff = ABS(current_log - log(target)); + + GST_DEBUG(GST_CAT_PARAMS, "current_log:%f\n",current_log); + GST_DEBUG(GST_CAT_PARAMS, "current_diff:%f\n",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; + GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; + } + } + else { + current_diff = ABS (current - target); + if (current_diff > max_change) + final_val = (target < current) ? current-max_change : current+max_change; + else + final_val = target; + GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; + } + + GST_DPARAM_READY_FOR_UPDATE(dparam) = (current_diff > max_change); + g_value_set_float(value, final_val); + + + GST_DEBUG(GST_CAT_PARAMS, "target:%f current:%f final:%f actual:%f\n", target, current, final_val, g_value_get_float(value)); + + GST_DPARAM_UNLOCK(dparam); +} diff --git a/libs/gst/control/dparam_smooth.h b/libs/gst/control/dparam_smooth.h new file mode 100644 index 0000000..7deb063 --- /dev/null +++ b/libs/gst/control/dparam_smooth.h @@ -0,0 +1,61 @@ +/* GStreamer + * Copyright (C) 2001 Steve Baker + * + * gstdparam_smooth.h: Realtime smoothed dynamic parameter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GST_DPSMOOTH_H__ +#define __GST_DPSMOOTH_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define GST_TYPE_DPSMOOTH (gst_dpsmooth_get_type ()) +#define GST_DPSMOOTH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DPSMOOTH,GstDParamSmooth)) +#define GST_DPSMOOTH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DPSMOOTH,GstDParamSmooth)) +#define GST_IS_DPSMOOTH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_DPSMOOTH)) +#define GST_IS_DPSMOOTH_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_DPSMOOTH)) + +typedef struct _GstDParamSmoothClass GstDParamSmoothClass; +typedef struct _GstDParamSmooth GstDParamSmooth; + +struct _GstDParamSmooth { + GstDParam dparam; + + gint64 last_update_timestamp; + gint64 update_period; + gint64 slope_time; + gfloat slope_delta_float; +}; + +struct _GstDParamSmoothClass { + GstDParamClass parent_class; + + /* signal callbacks */ +}; + +GstDParam* gst_dpsmooth_new (GType type); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_DPSMOOTH_H__ */ diff --git a/libs/gst/control/dparamcommon.h b/libs/gst/control/dparamcommon.h index 96c388b..d51c4a7 100644 --- a/libs/gst/control/dparamcommon.h +++ b/libs/gst/control/dparamcommon.h @@ -27,7 +27,6 @@ extern "C" { #endif /* __cplusplus */ typedef struct _GstDParam GstDParam; -typedef struct _GstDParamSpec GstDParamSpec; typedef struct _GstDParamManager GstDParamManager; #ifdef __cplusplus diff --git a/libs/gst/control/dparammanager.c b/libs/gst/control/dparammanager.c index 5119ef0..71265b1 100644 --- a/libs/gst/control/dparammanager.c +++ b/libs/gst/control/dparammanager.c @@ -28,8 +28,8 @@ static GHashTable *_element_registry; static void gst_dpman_class_init (GstDParamManagerClass *klass); static void gst_dpman_init (GstDParamManager *dpman); static void gst_dpman_dispose (GObject *object); -static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, gchar *dparam_name, GType type, GstDPMUpdateMethod update_method); -static GstDParamWrapper* gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name); + static GstDParamWrapper* gst_dpman_new_wrapper(GstDParamManager *dpman, GParamSpec *param_spec, gboolean is_log, gboolean is_rate, GstDPMUpdateMethod update_method); + static GstDParamWrapper* gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name); static void gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, GstDParamManager *dpman); static void gst_dpman_caps_changed (GstPad *pad, GstCaps *caps, GstDParamManager *dpman); static guint gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 timestamp); @@ -137,8 +137,6 @@ gst_dpman_dispose (GObject *object) /** * gst_dpman_add_required_dparam_callback: * @dpman: GstDParamManager instance - * @dparam_name: a parameter name unique to this GstDParamManager - * @type: the GValue type that this parameter will store * @update_func: callback to update the element with the new value * @update_data: will be included in the call to update_func * @@ -146,8 +144,9 @@ gst_dpman_dispose (GObject *object) */ gboolean gst_dpman_add_required_dparam_callback (GstDParamManager *dpman, - gchar *dparam_name, - GType type, + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, GstDPMUpdateFunction update_func, gpointer update_data) { @@ -157,11 +156,11 @@ gst_dpman_add_required_dparam_callback (GstDParamManager *dpman, g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE); g_return_val_if_fail (update_func != NULL, FALSE); - dpwrap = gst_dpman_new_wrapper(dpman, dparam_name, type, GST_DPMAN_CALLBACK); + dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_CALLBACK); g_return_val_if_fail (dpwrap != NULL, FALSE); - GST_DEBUG(GST_CAT_PARAMS,"adding required callback dparam '%s' of type %s\n", dparam_name, g_type_name(type)); + GST_DEBUG(GST_CAT_PARAMS,"adding required callback dparam '%s'\n", g_param_spec_get_name(param_spec)); dpwrap->update_func = update_func; dpwrap->update_data = update_data; @@ -172,17 +171,16 @@ gst_dpman_add_required_dparam_callback (GstDParamManager *dpman, /** * gst_dpman_add_required_dparam_direct: * @dpman: GstDParamManager instance - * @dparam_name: a parameter name unique to this GstDParamManager - * @type: the GValue type that this parameter will store * @update_data: pointer to the member to be updated * * Returns: true if it was successfully added */ gboolean gst_dpman_add_required_dparam_direct (GstDParamManager *dpman, - gchar *dparam_name, - GType type, - gpointer update_data) + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, + gpointer update_data) { GstDParamWrapper* dpwrap; @@ -190,11 +188,11 @@ gst_dpman_add_required_dparam_direct (GstDParamManager *dpman, g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE); g_return_val_if_fail (update_data != NULL, FALSE); - dpwrap = gst_dpman_new_wrapper(dpman, dparam_name, type, GST_DPMAN_DIRECT); + dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_DIRECT); g_return_val_if_fail (dpwrap != NULL, FALSE); - GST_DEBUG(GST_CAT_PARAMS,"adding required direct dparam '%s' of type %s\n", dparam_name, g_type_name(type)); + GST_DEBUG(GST_CAT_PARAMS,"adding required direct dparam '%s'\n", g_param_spec_get_name(param_spec)); dpwrap->update_data = update_data; @@ -205,16 +203,16 @@ gst_dpman_add_required_dparam_direct (GstDParamManager *dpman, * gst_dpman_add_required_dparam_array: * @dpman: GstDParamManager instance * @dparam_name: a parameter name unique to this GstDParamManager - * @type: the GValue type that this parameter will store * @update_data: pointer to where the array will be stored * * Returns: true if it was successfully added */ gboolean gst_dpman_add_required_dparam_array (GstDParamManager *dpman, - gchar *dparam_name, - GType type, - gpointer update_data) + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, + gpointer update_data) { GstDParamWrapper* dpwrap; @@ -222,11 +220,11 @@ gst_dpman_add_required_dparam_array (GstDParamManager *dpman, g_return_val_if_fail (GST_IS_DPMAN (dpman), FALSE); g_return_val_if_fail (update_data != NULL, FALSE); - dpwrap = gst_dpman_new_wrapper(dpman, dparam_name, type, GST_DPMAN_ARRAY); + dpwrap = gst_dpman_new_wrapper(dpman, param_spec, is_log, is_rate, GST_DPMAN_ARRAY); g_return_val_if_fail (dpwrap != NULL, FALSE); - GST_DEBUG(GST_CAT_PARAMS,"adding required array dparam '%s' of type %s\n", dparam_name, g_type_name(type)); + GST_DEBUG(GST_CAT_PARAMS,"adding required array dparam '%s'\n", g_param_spec_get_name(param_spec)); dpwrap->update_data = update_data; @@ -288,7 +286,7 @@ gst_dpman_attach_dparam (GstDParamManager *dpman, gchar *dparam_name, GstDParam g_return_val_if_fail(dpwrap->value != NULL, FALSE); dpwrap->dparam = dparam; - gst_dparam_attach(dparam, dpman, dpwrap->value, dpwrap->spec); + gst_dparam_attach(dparam, dpman, dpwrap->param_spec, dpwrap->is_log, dpwrap->is_rate); return TRUE; } @@ -361,12 +359,12 @@ gst_dpman_get_dparam_type (GstDParamManager *dpman, gchar *name) return G_VALUE_TYPE(dpwrap->value); } -GstDParamSpec** +/*GstDParamSpec** gst_dpman_list_dparam_specs(GstDParamManager *dpman) { GstDParamWrapper* dpwrap; GSList *dpwraps; - GstDParamSpec** dparam_specs; + GParamSpec** param_specs; guint x = 0; g_return_val_if_fail (dpman != NULL, NULL); @@ -374,18 +372,19 @@ gst_dpman_list_dparam_specs(GstDParamManager *dpman) dpwraps = GST_DPMAN_DPARAMS_LIST(dpman); - dparam_specs = g_new0(GstDParamSpec*, g_slist_length(dpwraps) + 1); + param_specs = g_new0(GParamSpec*, g_slist_length(dpwraps) + 1); while (dpwraps){ dpwrap = (GstDParamWrapper*)dpwraps->data; - dparam_specs[x++] = dpwrap->spec; + param_specs[x++] = dpwrap->param_spec; dpwraps = g_slist_next(dpwraps); } - return dparam_specs; + return param_specs; } +*/ -GstDParamSpec* -gst_dpman_get_dparam_spec (GstDParamManager *dpman, gchar *dparam_name) +GParamSpec* +gst_dpman_get_param_spec (GstDParamManager *dpman, gchar *dparam_name) { GstDParamWrapper* dpwrap; @@ -394,13 +393,7 @@ gst_dpman_get_dparam_spec (GstDParamManager *dpman, gchar *dparam_name) g_return_val_if_fail (dparam_name != NULL, NULL); dpwrap = gst_dpman_get_wrapper(dpman, dparam_name); - return dpwrap->spec; -} - -void -gst_dpman_dparam_spec_has_changed (GstDParamManager *dpman, gchar *dparam_name) -{ - + return dpwrap->param_spec; } /** @@ -546,30 +539,30 @@ gst_dpman_get_wrapper(GstDParamManager *dpman, gchar *dparam_name) } static GstDParamWrapper* -gst_dpman_new_wrapper(GstDParamManager *dpman, gchar *dparam_name, GType type, GstDPMUpdateMethod update_method) +gst_dpman_new_wrapper(GstDParamManager *dpman, + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, + GstDPMUpdateMethod update_method) { GstDParamWrapper* dpwrap; + gchar *dparam_name; g_return_val_if_fail (dpman != NULL, NULL); g_return_val_if_fail (GST_IS_DPMAN (dpman), NULL); - g_return_val_if_fail (dparam_name != NULL, NULL); + g_return_val_if_fail (param_spec != NULL, NULL); + dparam_name = g_strdup(g_param_spec_get_name(param_spec)); g_return_val_if_fail(gst_dpman_get_wrapper(dpman, dparam_name) == NULL, NULL); dpwrap = g_new0(GstDParamWrapper,1); dpwrap->update_method = update_method; dpwrap->value = g_new0(GValue,1); - g_value_init(dpwrap->value, type); + g_value_init(dpwrap->value, G_PARAM_SPEC_VALUE_TYPE(param_spec)); + dpwrap->param_spec = param_spec; + dpwrap->is_log = is_log; + dpwrap->is_rate = is_rate; - dpwrap->spec = g_new0(GstDParamSpec,1); - dpwrap->spec->dparam_name = dparam_name; - dpwrap->spec->min_val = g_new0(GValue,1); - dpwrap->spec->max_val = g_new0(GValue,1); - dpwrap->spec->default_val = g_new0(GValue,1); - g_value_init(dpwrap->spec->min_val, type); - g_value_init(dpwrap->spec->max_val, type); - g_value_init(dpwrap->spec->default_val, type); - g_hash_table_insert(GST_DPMAN_DPARAMS(dpman), dparam_name, dpwrap); GST_DPMAN_DPARAMS_LIST(dpman) = g_slist_append(GST_DPMAN_DPARAMS_LIST(dpman), dpwrap); @@ -598,9 +591,9 @@ gst_dpman_state_change (GstElement *element, gint old_state, gint new_state, Gst if (dparam){ GST_DPARAM_READY_FOR_UPDATE(dparam) = TRUE; - if (dparam->spec){ - g_value_copy(dparam->spec->default_val, GST_DPARAM_VALUE(dparam)); - } + /*if (dparam->spec){ + g_value_copy(dparam->spec->default_val, dpwrap->value); + }*/ } dwraps = g_slist_next(dwraps); } @@ -625,7 +618,6 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t GSList *dwraps; GstDParam *dparam; GstDParamWrapper *dpwrap; - guint x; g_return_val_if_fail (dpman != NULL, frames); g_return_val_if_fail (GST_IS_DPMAN (dpman), frames); @@ -639,46 +631,22 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t if (dparam && (GST_DPARAM_READY_FOR_UPDATE(dparam) && (GST_DPARAM_NEXT_UPDATE_TIMESTAMP(dparam) <= timestamp))){ - // this will make dpwrap->value contain the latest value. - // now we just need to get it to the element - GST_DPARAM_DO_UPDATE(dparam, timestamp); - switch (dpwrap->update_method) { // direct method - set the value directly in the struct of the element case GST_DPMAN_DIRECT: + GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value); GST_DEBUG(GST_CAT_PARAMS, "doing direct update\n"); switch (G_VALUE_TYPE(dpwrap->value)){ - case G_TYPE_CHAR: - *(gchar*)dpwrap->update_data = g_value_get_char(dpwrap->value); - break; - case G_TYPE_UCHAR: - *(guchar*)dpwrap->update_data = g_value_get_uchar(dpwrap->value); - break; - case G_TYPE_BOOLEAN: - *(gboolean*)dpwrap->update_data = g_value_get_boolean(dpwrap->value); - break; case G_TYPE_INT: *(gint*)dpwrap->update_data = g_value_get_int(dpwrap->value); break; - case G_TYPE_UINT: - *(guint*)dpwrap->update_data = g_value_get_uint(dpwrap->value); - break; - case G_TYPE_LONG: - *(glong*)dpwrap->update_data = g_value_get_long(dpwrap->value); - break; - case G_TYPE_ULONG: - *(gulong*)dpwrap->update_data = g_value_get_ulong(dpwrap->value); + case G_TYPE_INT64: + *(gint64*)dpwrap->update_data = g_value_get_int64(dpwrap->value); break; case G_TYPE_FLOAT: *(gfloat*)dpwrap->update_data = g_value_get_float(dpwrap->value); break; - case G_TYPE_DOUBLE: - *(gdouble*)dpwrap->update_data = g_value_get_double(dpwrap->value); - break; - case G_TYPE_POINTER: - *(gpointer*)dpwrap->update_data = g_value_get_pointer(dpwrap->value); - break; default: break; } @@ -686,6 +654,7 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t // callback method - call the element's callback so it can do what it likes case GST_DPMAN_CALLBACK: + GST_DPARAM_DO_UPDATE(dparam, timestamp, dpwrap->value); GST_DEBUG(GST_CAT_PARAMS, "doing callback update\n"); GST_DPMAN_DO_UPDATE(dpwrap); break; @@ -695,65 +664,11 @@ gst_dpman_preprocess_synchronous(GstDParamManager *dpman, guint frames, gint64 t case GST_DPMAN_ARRAY: GST_DEBUG(GST_CAT_PARAMS, "doing array update\n"); switch (G_VALUE_TYPE(dpwrap->value)){ - case G_TYPE_CHAR: - (gchar*)dpwrap->update_data = g_new(gchar, frames); - *(gchar*)dpwrap->update_data = g_value_get_char(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gchar*)dpwrap->update_data)[x] = *(gchar*)dpwrap->update_data; - break; - case G_TYPE_UCHAR: - (guchar*)dpwrap->update_data = g_new(guchar, frames); - *(guchar*)dpwrap->update_data = g_value_get_uchar(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((guchar*)dpwrap->update_data)[x] = *(guchar*)dpwrap->update_data; - break; - case G_TYPE_BOOLEAN: - (gboolean*)dpwrap->update_data = g_new(gboolean, frames); - *(gboolean*)dpwrap->update_data = g_value_get_boolean(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gboolean*)dpwrap->update_data)[x] = *(gboolean*)dpwrap->update_data; - break; case G_TYPE_INT: - (gint*)dpwrap->update_data = g_new(gint, frames); - *(gint*)dpwrap->update_data = g_value_get_int(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gint*)dpwrap->update_data)[x] = *(gint*)dpwrap->update_data; - break; - case G_TYPE_UINT: - (guint*)dpwrap->update_data = g_new(guint, frames); - *(guint*)dpwrap->update_data = g_value_get_uint(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((guint*)dpwrap->update_data)[x] = *(guint*)dpwrap->update_data; - break; - case G_TYPE_LONG: - (glong*)dpwrap->update_data = g_new(glong, frames); - *(glong*)dpwrap->update_data = g_value_get_long(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((glong*)dpwrap->update_data)[x] = *(glong*)dpwrap->update_data; break; - case G_TYPE_ULONG: - (gulong*)dpwrap->update_data = g_new(gulong, frames); - *(gulong*)dpwrap->update_data = g_value_get_ulong(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gulong*)dpwrap->update_data)[x] = *(gulong*)dpwrap->update_data; + case G_TYPE_INT64: break; case G_TYPE_FLOAT: - (gfloat*)dpwrap->update_data = g_new(gfloat, frames); - *(gfloat*)dpwrap->update_data = g_value_get_float(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gfloat*)dpwrap->update_data)[x] = *(gfloat*)dpwrap->update_data; - break; - case G_TYPE_DOUBLE: - (gdouble*)dpwrap->update_data = g_new(gdouble, frames); - *(gdouble*)dpwrap->update_data = g_value_get_double(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gdouble*)dpwrap->update_data)[x] = *(gdouble*)dpwrap->update_data; - break; - case G_TYPE_POINTER: - (gpointer*)dpwrap->update_data = g_new(gpointer, frames); - *(gpointer*)dpwrap->update_data = g_value_get_pointer(dpwrap->value); - for (x = 1 ; x < frames ; x++) - ((gpointer*)dpwrap->update_data)[x] = *(gpointer*)dpwrap->update_data; break; default: break; diff --git a/libs/gst/control/dparammanager.h b/libs/gst/control/dparammanager.h index 965c58a..e24a8d1 100644 --- a/libs/gst/control/dparammanager.h +++ b/libs/gst/control/dparammanager.h @@ -93,12 +93,14 @@ struct _GstDPMMode { }; struct _GstDParamWrapper { - GstDParamSpec* spec; + GParamSpec* param_spec; GValue *value; GstDParam *dparam; GstDPMUpdateMethod update_method; gpointer update_data; GstDPMUpdateFunction update_func; + gboolean is_log; + gboolean is_rate; }; #define GST_DPMAN_PREPROCESSFUNC(dpman) (((dpman)->mode)->preprocessfunc) @@ -125,26 +127,31 @@ void gst_dpman_set_parent (GstDParamManager *dpman, GstElement *parent); GstDParamManager* gst_dpman_get_manager (GstElement *parent); gboolean gst_dpman_add_required_dparam_callback (GstDParamManager *dpman, - gchar *dparam_name, - GType type, - GstDPMUpdateFunction update_func, - gpointer update_data); + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, + GstDPMUpdateFunction update_func, + gpointer update_data); gboolean gst_dpman_add_required_dparam_direct (GstDParamManager *dpman, - gchar *dparam_name, - GType type, + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, gpointer update_data); + gboolean gst_dpman_add_required_dparam_array (GstDParamManager *dpman, - gchar *dparam_name, - GType type, + GParamSpec *param_spec, + gboolean is_log, + gboolean is_rate, gpointer update_data); + void gst_dpman_remove_required_dparam (GstDParamManager *dpman, gchar *dparam_name); gboolean gst_dpman_attach_dparam (GstDParamManager *dpman, gchar *dparam_name, GstDParam *dparam); void gst_dpman_detach_dparam (GstDParamManager *dpman, gchar *dparam_name); GstDParam* gst_dpman_get_dparam(GstDParamManager *dpman, gchar *name); GType gst_dpman_get_dparam_type (GstDParamManager *dpman, gchar *name); -GstDParamSpec** gst_dpman_list_dparam_specs(GstDParamManager *dpman); -GstDParamSpec* gst_dpman_get_dparam_spec (GstDParamManager *dpman, gchar *dparam_name); +GParamSpec** gst_dpman_list_param_specs(GstDParamManager *dpman); +GParamSpec* gst_dpman_get_param_spec (GstDParamManager *dpman, gchar *dparam_name); void gst_dpman_dparam_spec_has_changed (GstDParamManager *dpman, gchar *dparam_name); void gst_dpman_set_rate_change_pad(GstDParamManager *dpman, GstPad *pad); -- 2.7.4