mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 02:01:12 +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
105
gst/gstdparam.c
105
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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue