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
This commit is contained in:
Steve Baker 2001-09-14 19:17:45 +00:00
parent a466301057
commit 4e4f06b50e
2 changed files with 117 additions and 7 deletions

View file

@ -22,6 +22,7 @@
#include "gst_private.h" #include "gst_private.h"
#include "gstdparam.h" #include "gstdparam.h"
#include "gstdparammanager.h"
static void gst_dparam_class_init (GstDParamClass *klass); static void gst_dparam_class_init (GstDParamClass *klass);
static void gst_dparam_base_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); g_return_if_fail (dparam != NULL);
GST_DPARAM_VALUE(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 (); dparam->lock = g_mutex_new ();
} }
/** /**
* gst_dparam_new: * gst_dparam_new:
* @type: the type that this dparam will store
* *
* Returns: a new instance of GstDParam * 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->get_point_func = gst_dparam_get_point_realtime;
dparam->point = gst_dparam_new_value_array(type, 0); dparam->point = gst_dparam_new_value_array(type, 0);
GST_DPARAM_TYPE(dparam) = type;
return dparam; return dparam;
} }
/** /**
* gst_dparam_set_parent * gst_dparam_attach
* @dparam: GstDParam instance * @dparam: GstDParam instance
* @parent: the GstDParamManager that this dparam belongs to * @parent: the GstDParamManager that this dparam belongs to
* *
*/ */
void 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 (dparam != NULL);
g_return_if_fail (GST_IS_DPARAM (dparam)); g_return_if_fail (GST_IS_DPARAM (dparam));
g_return_if_fail (GST_DPARAM_PARENT (dparam) == NULL); g_return_if_fail (GST_DPARAM_PARENT (dparam) == NULL);
g_return_if_fail (parent != NULL); g_return_if_fail (parent != NULL);
g_return_if_fail (G_IS_OBJECT (parent)); 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 ((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); 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)) { switch (G_VALUE_TYPE(value)) {
case G_TYPE_STRING: case G_TYPE_STRING:
g_value_set_string(value, value_str); g_value_set_string(value, g_strdup(value_str));
break; break;
case G_TYPE_ENUM: case G_TYPE_ENUM:
case G_TYPE_INT: { case G_TYPE_INT: {
@ -259,4 +273,89 @@ gst_dparam_get_point_realtime (GstDParam *dparam, gint64 timestamp)
return dparam->point; 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;
}

View file

@ -30,7 +30,7 @@ extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#define GST_TYPE_DPARAM (gst_dparam_get_type ()) #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_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(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_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_NAME(dparam) (GST_OBJECT_NAME(dparam))
#define GST_DPARAM_PARENT(dparam) (GST_OBJECT_PARENT(dparam)) #define GST_DPARAM_PARENT(dparam) (GST_OBJECT_PARENT(dparam))
#define GST_DPARAM_VALUE(dparam) ((dparam)->value) #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_LOCK(dparam) (g_mutex_lock((dparam)->lock))
#define GST_DPARAM_UNLOCK(dparam) (g_mutex_unlock((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_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_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) \ #define GST_DPARAM_GET_POINT(dparam, timestamp) \
((dparam->get_point_func)(dparam, timestamp)) ((dparam->get_point_func)(dparam, timestamp))
@ -98,9 +101,11 @@ struct _GstDParam {
GMutex *lock; GMutex *lock;
GValue *value; GValue *value;
GValue **point; GValue **point;
GType type;
gint64 last_update_timestamp;
gint64 next_update_timestamp; gint64 next_update_timestamp;
gint64 default_update_period;
gboolean ready_for_update; gboolean ready_for_update;
}; };
struct _GstDParamClass { struct _GstDParamClass {
@ -111,10 +116,16 @@ struct _GstDParamClass {
GType gst_dparam_get_type (void); GType gst_dparam_get_type (void);
GstDParam* gst_dparam_new (GType type); 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, ...); GValue** gst_dparam_new_value_array(GType type, ...);
void gst_dparam_set_value_from_string(GValue *value, const gchar *value_str); void gst_dparam_set_value_from_string(GValue *value, const gchar *value_str);
/**********************
* GstDParamSmooth
**********************/
GstDParam* gst_dparam_smooth_new (GType type);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */