From 4e4f06b50ef6c896ec62dd76bb0ed4ecf37e03f4 Mon Sep 17 00:00:00 2001 From: Steve Baker Date: Fri, 14 Sep 2001 19:17:45 +0000 Subject: [PATCH] add gst_dparam_attach, add a new dparam which smooths linear realtime values to minimise discontinuity artifacts Original commit message from CVS: add gst_dparam_attach, add a new dparam which smooths linear realtime values to minimise discontinuity artifacts --- gst/gstdparam.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++-- gst/gstdparam.h | 17 ++++++-- 2 files changed, 117 insertions(+), 7 deletions(-) diff --git a/gst/gstdparam.c b/gst/gstdparam.c index 5c42c17214..17bec9d949 100644 --- a/gst/gstdparam.c +++ b/gst/gstdparam.c @@ -22,6 +22,7 @@ #include "gst_private.h" #include "gstdparam.h" +#include "gstdparammanager.h" static void gst_dparam_class_init (GstDParamClass *klass); static void gst_dparam_base_class_init (GstDParamClass *klass); @@ -80,11 +81,16 @@ 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 (); } /** * gst_dparam_new: + * @type: the type that this dparam will store * * Returns: a new instance of GstDParam */ @@ -98,26 +104,34 @@ gst_dparam_new (GType type) dparam->get_point_func = gst_dparam_get_point_realtime; dparam->point = gst_dparam_new_value_array(type, 0); + GST_DPARAM_TYPE(dparam) = type; return dparam; } /** - * gst_dparam_set_parent + * gst_dparam_attach * @dparam: GstDParam instance * @parent: the GstDParamManager that this dparam belongs to * */ void -gst_dparam_set_parent (GstDParam *dparam, GstObject *parent) +gst_dparam_attach (GstDParam *dparam, GstObject *parent, gchar *dparam_name, GValue *value) { + g_return_if_fail (dparam != NULL); g_return_if_fail (GST_IS_DPARAM (dparam)); g_return_if_fail (GST_DPARAM_PARENT (dparam) == NULL); g_return_if_fail (parent != NULL); g_return_if_fail (G_IS_OBJECT (parent)); + g_return_if_fail (GST_IS_DPMAN (parent)); g_return_if_fail ((gpointer)dparam != (gpointer)parent); - + g_return_if_fail (dparam_name != NULL); + g_return_if_fail (value != NULL); + g_return_if_fail (GST_DPARAM_TYPE(dparam) == G_VALUE_TYPE(value)); + + GST_DPARAM_NAME(dparam) = dparam_name; + GST_DPARAM_VALUE(dparam) = value; gst_object_set_parent (GST_OBJECT (dparam), parent); } @@ -180,7 +194,7 @@ gst_dparam_set_value_from_string(GValue *value, const gchar *value_str) switch (G_VALUE_TYPE(value)) { case G_TYPE_STRING: - g_value_set_string(value, value_str); + g_value_set_string(value, g_strdup(value_str)); break; case G_TYPE_ENUM: case G_TYPE_INT: { @@ -259,4 +273,89 @@ gst_dparam_get_point_realtime (GstDParam *dparam, gint64 timestamp) 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 target = g_value_get_float(dparam->point[0]); + gfloat current = g_value_get_float(GST_DPARAM_VALUE(dparam)); + gfloat 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 (ABS (current - target) < max_change){ + GST_DPARAM_READY_FOR_UPDATE(dparam) = FALSE; + current = target; + } + else { + current += (target < current) ? -max_change : max_change; + } + g_value_set_float(GST_DPARAM_VALUE(dparam), current); + + } + 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/gst/gstdparam.h b/gst/gstdparam.h index 1d19c372bb..ede16f937a 100644 --- a/gst/gstdparam.h +++ b/gst/gstdparam.h @@ -30,7 +30,7 @@ extern "C" { #endif /* __cplusplus */ #define GST_TYPE_DPARAM (gst_dparam_get_type ()) -#define GST_DPARAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DPARAM,GstDparam)) +#define GST_DPARAM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_DPARAM,GstDParam)) #define GST_DPARAM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_DPARAM,GstDParam)) #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)) @@ -38,12 +38,15 @@ extern "C" { #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_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_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)) @@ -98,9 +101,11 @@ struct _GstDParam { GMutex *lock; GValue *value; GValue **point; + GType type; + gint64 last_update_timestamp; gint64 next_update_timestamp; + gint64 default_update_period; gboolean ready_for_update; - }; struct _GstDParamClass { @@ -111,10 +116,16 @@ struct _GstDParamClass { GType gst_dparam_get_type (void); GstDParam* gst_dparam_new (GType type); -void gst_dparam_set_parent (GstDParam *dparam, GstObject *parent); +void gst_dparam_attach (GstDParam *dparam, GstObject *parent, gchar *dparam_name, GValue *value); 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); + #ifdef __cplusplus } #endif /* __cplusplus */