mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
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:
parent
a466301057
commit
4e4f06b50e
2 changed files with 117 additions and 7 deletions
107
gst/gstdparam.c
107
gst/gstdparam.c
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue