mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
controller: expand the api to offer functions for plain and GValue arrays
Rename the _get_value_array() functions to _get_g_value_array() and reintroduce the former to operate on plain unboxed c datatypes (like in 0.10). The _g_value variants are for bindings while the _value ones are more suited to processing in elements.
This commit is contained in:
parent
12eefc0442
commit
772c58e255
12 changed files with 344 additions and 40 deletions
|
@ -615,6 +615,7 @@ GstControlBindingConvert
|
|||
gst_control_binding_sync_values
|
||||
gst_control_binding_get_value
|
||||
gst_control_binding_get_value_array
|
||||
gst_control_binding_get_g_value_array
|
||||
gst_control_binding_set_disabled
|
||||
gst_control_binding_is_disabled
|
||||
<SUBSECTION Standard>
|
||||
|
@ -1560,6 +1561,7 @@ gst_object_get_control_binding
|
|||
gst_object_remove_control_binding
|
||||
gst_object_get_value
|
||||
gst_object_get_value_array
|
||||
gst_object_get_g_value_array
|
||||
gst_object_get_control_rate
|
||||
gst_object_set_control_rate
|
||||
|
||||
|
|
|
@ -31,6 +31,13 @@
|
|||
* gst_control_binding_constructor()
|
||||
* - the weak-ref on object is not nice, as is the same as gst_object_parent()
|
||||
* once the object is added to the parent
|
||||
*
|
||||
* - another option would be do defer what I am doing in _constructor to when
|
||||
* the parent is set (need to listen to the signal then)
|
||||
* then basically I could
|
||||
* a) remove the obj arg and wait the binding to be added or
|
||||
* b) add the binding from constructor, unref object there and make obj
|
||||
* writeonly
|
||||
*/
|
||||
|
||||
#include "gst_private.h"
|
||||
|
@ -273,19 +280,23 @@ gst_control_binding_get_value (GstControlBinding * self, GstClockTime timestamp)
|
|||
* @n_values: the number of values
|
||||
* @values: array to put control-values in
|
||||
*
|
||||
* Gets a number of values for the given controllered property starting at the
|
||||
* Gets a number of values for the given controlled property starting at the
|
||||
* requested time. The array @values need to hold enough space for @n_values of
|
||||
* the same type as the objects property's type.
|
||||
*
|
||||
* This function is useful if one wants to e.g. draw a graph of the control
|
||||
* curve or apply a control curve sample by sample.
|
||||
*
|
||||
* The values are unboxed and ready to be used. The similar function
|
||||
* gst_control_binding_get_g_value_array() returns the array as #GValues and is
|
||||
* better suites for bindings.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_control_binding_get_value_array (GstControlBinding * self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
gpointer values)
|
||||
{
|
||||
GstControlBindingClass *klass;
|
||||
gboolean ret = FALSE;
|
||||
|
@ -305,6 +316,48 @@ gst_control_binding_get_value_array (GstControlBinding * self,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_control_binding_get_g_value_array:
|
||||
* @self: the control binding
|
||||
* @timestamp: the time that should be processed
|
||||
* @interval: the time spacing between subsequent values
|
||||
* @n_values: the number of values
|
||||
* @values: array to put control-values in
|
||||
*
|
||||
* Gets a number of #GValues for the given controlled property starting at the
|
||||
* requested time. The array @values need to hold enough space for @n_values of
|
||||
* #GValue.
|
||||
*
|
||||
* This function is useful if one wants to e.g. draw a graph of the control
|
||||
* curve or apply a control curve sample by sample.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_control_binding_get_g_value_array (GstControlBinding * self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
{
|
||||
GstControlBindingClass *klass;
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CONTROL_BINDING (self), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
|
||||
g_return_val_if_fail (values, FALSE);
|
||||
|
||||
klass = GST_CONTROL_BINDING_GET_CLASS (self);
|
||||
|
||||
if (G_LIKELY (klass->get_g_value_array != NULL)) {
|
||||
ret =
|
||||
klass->get_g_value_array (self, timestamp, interval, n_values, values);
|
||||
} else {
|
||||
GST_WARNING_OBJECT (self, "missing get_g_value_array implementation");
|
||||
// FIXME(ensonic): emulate
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_control_binding_set_disabled:
|
||||
* @self: the control binding
|
||||
|
|
|
@ -93,7 +93,8 @@ struct _GstControlBindingClass
|
|||
/* virtual methods */
|
||||
gboolean (* sync_values) (GstControlBinding *self, GstObject *object, GstClockTime timestamp, GstClockTime last_sync);
|
||||
GValue * (* get_value) (GstControlBinding *self, GstClockTime timestamp);
|
||||
gboolean (* get_value_array) (GstControlBinding *self, GstClockTime timestamp,GstClockTime interval, guint n_values, GValue *values);
|
||||
gboolean (* get_value_array) (GstControlBinding *self, GstClockTime timestamp,GstClockTime interval, guint n_values, gpointer values);
|
||||
gboolean (* get_g_value_array) (GstControlBinding *self, GstClockTime timestamp,GstClockTime interval, guint n_values, GValue *values);
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
|
@ -110,6 +111,8 @@ gboolean gst_control_binding_sync_values (GstControlBinding *
|
|||
GValue * gst_control_binding_get_value (GstControlBinding *binding,
|
||||
GstClockTime timestamp);
|
||||
gboolean gst_control_binding_get_value_array (GstControlBinding *binding, GstClockTime timestamp,
|
||||
GstClockTime interval, guint n_values, gpointer values);
|
||||
gboolean gst_control_binding_get_g_value_array (GstControlBinding *binding, GstClockTime timestamp,
|
||||
GstClockTime interval, guint n_values, GValue *values);
|
||||
|
||||
void gst_control_binding_set_disabled (GstControlBinding * self, gboolean disabled);
|
||||
|
|
|
@ -122,7 +122,8 @@ gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp,
|
|||
* @n_values: the number of values to fetch
|
||||
* @value_array: array to put control-values in
|
||||
*
|
||||
* Gets an array of values for for this #GstControlSource.
|
||||
* Gets an array of values for for this #GstControlSource. Values that are
|
||||
* undefined contain NANs.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
|
|
|
@ -1300,17 +1300,62 @@ gst_object_get_value (GstObject * object, const gchar * property_name,
|
|||
* @n_values: the number of values
|
||||
* @values: array to put control-values in
|
||||
*
|
||||
* Gets a number of values for the given controllered property starting at the
|
||||
* Gets a number of values for the given controlled property starting at the
|
||||
* requested time. The array @values need to hold enough space for @n_values of
|
||||
* the same type as the objects property's type.
|
||||
*
|
||||
* This function is useful if one wants to e.g. draw a graph of the control
|
||||
* curve or apply a control curve sample by sample.
|
||||
*
|
||||
* The values are unboxed and ready to be used. The similar function
|
||||
* gst_object_get_g_value_array() returns the array as #GValues and is
|
||||
* better suites for bindings.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_object_get_value_array (GstObject * object, const gchar * property_name,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
gpointer values)
|
||||
{
|
||||
gboolean res = FALSE;
|
||||
GstControlBinding *binding;
|
||||
|
||||
g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
|
||||
g_return_val_if_fail (property_name, FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
|
||||
g_return_val_if_fail (values, FALSE);
|
||||
|
||||
GST_OBJECT_LOCK (object);
|
||||
if ((binding = gst_object_find_control_binding (object, property_name))) {
|
||||
res = gst_control_binding_get_value_array (binding, timestamp, interval,
|
||||
n_values, values);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_object_get_g_value_array:
|
||||
* @object: the object that has controlled properties
|
||||
* @property_name: the name of the property to get
|
||||
* @timestamp: the time that should be processed
|
||||
* @interval: the time spacing between subsequent values
|
||||
* @n_values: the number of values
|
||||
* @values: array to put control-values in
|
||||
*
|
||||
* Gets a number of #GValues for the given controlled property starting at the
|
||||
* requested time. The array @values need to hold enough space for @n_values of
|
||||
* #GValue.
|
||||
*
|
||||
* This function is useful if one wants to e.g. draw a graph of the control
|
||||
* curve or apply a control curve sample by sample.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_object_get_value_array (GstObject * object, const gchar * property_name,
|
||||
gst_object_get_g_value_array (GstObject * object, const gchar * property_name,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
{
|
||||
|
@ -1325,7 +1370,7 @@ gst_object_get_value_array (GstObject * object, const gchar * property_name,
|
|||
|
||||
GST_OBJECT_LOCK (object);
|
||||
if ((binding = gst_object_find_control_binding (object, property_name))) {
|
||||
res = gst_control_binding_get_value_array (binding, timestamp, interval,
|
||||
res = gst_control_binding_get_g_value_array (binding, timestamp, interval,
|
||||
n_values, values);
|
||||
}
|
||||
GST_OBJECT_UNLOCK (object);
|
||||
|
|
|
@ -252,6 +252,9 @@ gboolean gst_object_remove_control_binding (GstObject * object, GstContro
|
|||
GValue * gst_object_get_value (GstObject * object, const gchar * property_name,
|
||||
GstClockTime timestamp);
|
||||
gboolean gst_object_get_value_array (GstObject * object, const gchar * property_name,
|
||||
GstClockTime timestamp, GstClockTime interval,
|
||||
guint n_values, gpointer values);
|
||||
gboolean gst_object_get_g_value_array (GstObject * object, const gchar * property_name,
|
||||
GstClockTime timestamp, GstClockTime interval,
|
||||
guint n_values, GValue *values);
|
||||
|
||||
|
|
|
@ -52,6 +52,9 @@ static gboolean gst_argb_control_binding_sync_values (GstControlBinding * _self,
|
|||
static GValue *gst_argb_control_binding_get_value (GstControlBinding * _self,
|
||||
GstClockTime timestamp);
|
||||
static gboolean gst_argb_control_binding_get_value_array (GstControlBinding *
|
||||
_self, GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
gpointer values);
|
||||
static gboolean gst_argb_control_binding_get_g_value_array (GstControlBinding *
|
||||
_self, GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values);
|
||||
|
||||
|
@ -94,6 +97,8 @@ gst_argb_control_binding_class_init (GstARGBControlBindingClass * klass)
|
|||
control_binding_class->get_value = gst_argb_control_binding_get_value;
|
||||
control_binding_class->get_value_array =
|
||||
gst_argb_control_binding_get_value_array;
|
||||
control_binding_class->get_g_value_array =
|
||||
gst_argb_control_binding_get_g_value_array;
|
||||
|
||||
properties[PROP_CS_A] =
|
||||
g_param_spec_object ("control-source-a", "ControlSource A",
|
||||
|
@ -315,6 +320,71 @@ gst_argb_control_binding_get_value (GstControlBinding * _self,
|
|||
|
||||
static gboolean
|
||||
gst_argb_control_binding_get_value_array (GstControlBinding * _self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
gpointer values_)
|
||||
{
|
||||
GstARGBControlBinding *self = GST_ARGB_CONTROL_BINDING (_self);
|
||||
gint i;
|
||||
gdouble *src_val_a = NULL, *src_val_r = NULL, *src_val_g = NULL, *src_val_b =
|
||||
NULL;
|
||||
guint *values = (guint *) values_;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_ARGB_CONTROL_BINDING (self), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
|
||||
g_return_val_if_fail (values, FALSE);
|
||||
g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);
|
||||
|
||||
if (self->cs_a) {
|
||||
src_val_a = g_new0 (gdouble, n_values);
|
||||
ret &= gst_control_source_get_value_array (self->cs_a, timestamp,
|
||||
interval, n_values, src_val_a);
|
||||
}
|
||||
if (self->cs_r) {
|
||||
src_val_r = g_new0 (gdouble, n_values);
|
||||
ret &= gst_control_source_get_value_array (self->cs_r, timestamp,
|
||||
interval, n_values, src_val_r);
|
||||
}
|
||||
if (self->cs_g) {
|
||||
src_val_g = g_new0 (gdouble, n_values);
|
||||
ret &= gst_control_source_get_value_array (self->cs_g, timestamp,
|
||||
interval, n_values, src_val_g);
|
||||
}
|
||||
if (self->cs_b) {
|
||||
src_val_b = g_new0 (gdouble, n_values);
|
||||
ret &= gst_control_source_get_value_array (self->cs_b, timestamp,
|
||||
interval, n_values, src_val_b);
|
||||
}
|
||||
if (G_LIKELY (ret)) {
|
||||
for (i = 0; i < n_values; i++) {
|
||||
gdouble a = 1.0, r = 0.0, g = 0.0, b = 0.0;
|
||||
if (src_val_a && !isnan (src_val_a[i]))
|
||||
a = src_val_a[i];
|
||||
if (src_val_r && !isnan (src_val_r[i]))
|
||||
r = src_val_r[i];
|
||||
if (src_val_g && !isnan (src_val_g[i]))
|
||||
g = src_val_g[i];
|
||||
if (src_val_b && !isnan (src_val_b[i]))
|
||||
b = src_val_b[i];
|
||||
values[i] = (((guint) (CLAMP (a, 0.0, 1.0) * 255)) << 24) |
|
||||
(((guint) (CLAMP (r, 0.0, 1.0) * 255)) << 16) |
|
||||
(((guint) (CLAMP (g, 0.0, 1.0) * 255)) << 8) |
|
||||
((guint) (CLAMP (b, 0.0, 1.0) * 255));
|
||||
}
|
||||
} else {
|
||||
GST_LOG ("failed to get control value for property %s at ts %"
|
||||
GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp));
|
||||
}
|
||||
g_free (src_val_a);
|
||||
g_free (src_val_r);
|
||||
g_free (src_val_g);
|
||||
g_free (src_val_b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_argb_control_binding_get_g_value_array (GstControlBinding * _self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
{
|
||||
|
|
|
@ -52,6 +52,9 @@ static GValue *gst_direct_control_binding_get_value (GstControlBinding * _self,
|
|||
GstClockTime timestamp);
|
||||
static gboolean gst_direct_control_binding_get_value_array (GstControlBinding *
|
||||
_self, GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
gpointer values);
|
||||
static gboolean gst_direct_control_binding_get_g_value_array (GstControlBinding
|
||||
* _self, GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values);
|
||||
|
||||
#define _do_init \
|
||||
|
@ -75,7 +78,7 @@ static GParamSpec *properties[PROP_LAST];
|
|||
|
||||
#define DEFINE_CONVERT(type,Type,TYPE) \
|
||||
static void \
|
||||
convert_to_##type (GstDirectControlBinding *self, gdouble s, GValue *d) \
|
||||
convert_g_value_to_##type (GstDirectControlBinding *self, gdouble s, GValue *d) \
|
||||
{ \
|
||||
GParamSpec##Type *pspec = G_PARAM_SPEC_##TYPE (((GstControlBinding *)self)->pspec); \
|
||||
g##type v; \
|
||||
|
@ -83,8 +86,19 @@ convert_to_##type (GstDirectControlBinding *self, gdouble s, GValue *d) \
|
|||
s = CLAMP (s, 0.0, 1.0); \
|
||||
v = pspec->minimum + (g##type) ((pspec->maximum - pspec->minimum) * s); \
|
||||
g_value_set_##type (d, v); \
|
||||
} \
|
||||
\
|
||||
static void \
|
||||
convert_value_to_##type (GstDirectControlBinding *self, gdouble s, gpointer d_) \
|
||||
{ \
|
||||
GParamSpec##Type *pspec = G_PARAM_SPEC_##TYPE (((GstControlBinding *)self)->pspec); \
|
||||
g##type *d = (g##type *)d_; \
|
||||
\
|
||||
s = CLAMP (s, 0.0, 1.0); \
|
||||
*d = pspec->minimum + (g##type) ((pspec->maximum - pspec->minimum) * s); \
|
||||
}
|
||||
|
||||
|
||||
DEFINE_CONVERT (int, Int, INT);
|
||||
DEFINE_CONVERT (uint, UInt, UINT);
|
||||
DEFINE_CONVERT (long, Long, LONG);
|
||||
|
@ -95,14 +109,25 @@ DEFINE_CONVERT (float, Float, FLOAT);
|
|||
DEFINE_CONVERT (double, Double, DOUBLE);
|
||||
|
||||
static void
|
||||
convert_to_boolean (GstDirectControlBinding * self, gdouble s, GValue * d)
|
||||
convert_g_value_to_boolean (GstDirectControlBinding * self, gdouble s,
|
||||
GValue * d)
|
||||
{
|
||||
s = CLAMP (s, 0.0, 1.0);
|
||||
g_value_set_boolean (d, (gboolean) (s + 0.5));
|
||||
}
|
||||
|
||||
static void
|
||||
convert_to_enum (GstDirectControlBinding * self, gdouble s, GValue * d)
|
||||
convert_value_to_boolean (GstDirectControlBinding * self, gdouble s,
|
||||
gpointer d_)
|
||||
{
|
||||
gboolean *d = (gboolean *) d_;
|
||||
|
||||
s = CLAMP (s, 0.0, 1.0);
|
||||
*d = (gboolean) (s + 0.5);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_g_value_to_enum (GstDirectControlBinding * self, gdouble s, GValue * d)
|
||||
{
|
||||
GParamSpecEnum *pspec =
|
||||
G_PARAM_SPEC_ENUM (((GstControlBinding *) self)->pspec);
|
||||
|
@ -114,6 +139,18 @@ convert_to_enum (GstDirectControlBinding * self, gdouble s, GValue * d)
|
|||
g_value_set_enum (d, e->values[v].value);
|
||||
}
|
||||
|
||||
static void
|
||||
convert_value_to_enum (GstDirectControlBinding * self, gdouble s, gpointer d_)
|
||||
{
|
||||
GParamSpecEnum *pspec =
|
||||
G_PARAM_SPEC_ENUM (((GstControlBinding *) self)->pspec);
|
||||
GEnumClass *e = pspec->enum_class;
|
||||
gint *d = (gint *) d_;
|
||||
|
||||
s = CLAMP (s, 0.0, 1.0);
|
||||
*d = e->values[(gint) (s * (e->n_values - 1))].value;
|
||||
}
|
||||
|
||||
/* vmethods */
|
||||
|
||||
static void
|
||||
|
@ -133,6 +170,8 @@ gst_direct_control_binding_class_init (GstDirectControlBindingClass * klass)
|
|||
control_binding_class->get_value = gst_direct_control_binding_get_value;
|
||||
control_binding_class->get_value_array =
|
||||
gst_direct_control_binding_get_value_array;
|
||||
control_binding_class->get_g_value_array =
|
||||
gst_direct_control_binding_get_g_value_array;
|
||||
|
||||
properties[PROP_CS] =
|
||||
g_param_spec_object ("control-source", "ControlSource",
|
||||
|
@ -171,34 +210,54 @@ gst_direct_control_binding_constructor (GType type, guint n_construct_params,
|
|||
// select mapping function
|
||||
switch (base) {
|
||||
case G_TYPE_INT:
|
||||
self->convert = convert_to_int;
|
||||
self->convert_g_value = convert_g_value_to_int;
|
||||
self->convert_value = convert_value_to_int;
|
||||
self->byte_size = sizeof (gint);
|
||||
break;
|
||||
case G_TYPE_UINT:
|
||||
self->convert = convert_to_uint;
|
||||
self->convert_g_value = convert_g_value_to_uint;
|
||||
self->convert_value = convert_value_to_uint;
|
||||
self->byte_size = sizeof (guint);
|
||||
break;
|
||||
case G_TYPE_LONG:
|
||||
self->convert = convert_to_long;
|
||||
self->convert_g_value = convert_g_value_to_long;
|
||||
self->convert_value = convert_value_to_long;
|
||||
self->byte_size = sizeof (glong);
|
||||
break;
|
||||
case G_TYPE_ULONG:
|
||||
self->convert = convert_to_ulong;
|
||||
self->convert_g_value = convert_g_value_to_ulong;
|
||||
self->convert_value = convert_value_to_ulong;
|
||||
self->byte_size = sizeof (gulong);
|
||||
break;
|
||||
case G_TYPE_INT64:
|
||||
self->convert = convert_to_int64;
|
||||
self->convert_g_value = convert_g_value_to_int64;
|
||||
self->convert_value = convert_value_to_int64;
|
||||
self->byte_size = sizeof (gint64);
|
||||
break;
|
||||
case G_TYPE_UINT64:
|
||||
self->convert = convert_to_uint64;
|
||||
self->convert_g_value = convert_g_value_to_uint64;
|
||||
self->convert_value = convert_value_to_uint64;
|
||||
self->byte_size = sizeof (guint64);
|
||||
break;
|
||||
case G_TYPE_FLOAT:
|
||||
self->convert = convert_to_float;
|
||||
self->convert_g_value = convert_g_value_to_float;
|
||||
self->convert_value = convert_value_to_float;
|
||||
self->byte_size = sizeof (gfloat);
|
||||
break;
|
||||
case G_TYPE_DOUBLE:
|
||||
self->convert = convert_to_double;
|
||||
self->convert_g_value = convert_g_value_to_double;
|
||||
self->convert_value = convert_value_to_double;
|
||||
self->byte_size = sizeof (gdouble);
|
||||
break;
|
||||
case G_TYPE_BOOLEAN:
|
||||
self->convert = convert_to_boolean;
|
||||
self->convert_g_value = convert_g_value_to_boolean;
|
||||
self->convert_value = convert_value_to_boolean;
|
||||
self->byte_size = sizeof (gboolean);
|
||||
break;
|
||||
case G_TYPE_ENUM:
|
||||
self->convert = convert_to_enum;
|
||||
self->convert_g_value = convert_g_value_to_enum;
|
||||
self->convert_value = convert_value_to_enum;
|
||||
self->byte_size = sizeof (gint);
|
||||
break;
|
||||
default:
|
||||
GST_WARNING ("incomplete implementation for paramspec type '%s'",
|
||||
|
@ -290,7 +349,7 @@ gst_direct_control_binding_sync_values (GstControlBinding * _self,
|
|||
GST_LOG_OBJECT (object, " mapping %s to value of type %s", _self->name,
|
||||
G_VALUE_TYPE_NAME (dst_val));
|
||||
/* run mapping function to convert gdouble to GValue */
|
||||
self->convert (self, src_val, dst_val);
|
||||
self->convert_g_value (self, src_val, dst_val);
|
||||
/* we can make this faster
|
||||
* http://bugzilla.gnome.org/show_bug.cgi?id=536939
|
||||
*/
|
||||
|
@ -319,7 +378,7 @@ gst_direct_control_binding_get_value (GstControlBinding * _self,
|
|||
if (gst_control_source_get_value (self->cs, timestamp, &src_val)) {
|
||||
dst_val = g_new0 (GValue, 1);
|
||||
g_value_init (dst_val, G_PARAM_SPEC_VALUE_TYPE (_self->pspec));
|
||||
self->convert (self, src_val, dst_val);
|
||||
self->convert_g_value (self, src_val, dst_val);
|
||||
} else {
|
||||
GST_LOG ("no control value for property %s at ts %" GST_TIME_FORMAT,
|
||||
_self->name, GST_TIME_ARGS (timestamp));
|
||||
|
@ -331,14 +390,15 @@ gst_direct_control_binding_get_value (GstControlBinding * _self,
|
|||
static gboolean
|
||||
gst_direct_control_binding_get_value_array (GstControlBinding * _self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
gpointer values_)
|
||||
{
|
||||
GstDirectControlBinding *self = GST_DIRECT_CONTROL_BINDING (_self);
|
||||
gint i;
|
||||
gdouble *src_val;
|
||||
gboolean res = FALSE;
|
||||
GType type;
|
||||
GstDirectControlBindingConvert convert;
|
||||
GstDirectControlBindingConvertValue convert;
|
||||
gint byte_size;
|
||||
guint8 *values = (guint8 *) values_;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DIRECT_CONTROL_BINDING (self), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
||||
|
@ -346,7 +406,48 @@ gst_direct_control_binding_get_value_array (GstControlBinding * _self,
|
|||
g_return_val_if_fail (values, FALSE);
|
||||
g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);
|
||||
|
||||
convert = self->convert;
|
||||
convert = self->convert_value;
|
||||
byte_size = self->byte_size;
|
||||
|
||||
src_val = g_new0 (gdouble, n_values);
|
||||
if ((res = gst_control_source_get_value_array (self->cs, timestamp,
|
||||
interval, n_values, src_val))) {
|
||||
for (i = 0; i < n_values; i++) {
|
||||
if (!isnan (src_val[i])) {
|
||||
convert (self, src_val[i], (gpointer) values);
|
||||
} else {
|
||||
GST_LOG ("no control value for property %s at index %d", _self->name,
|
||||
i);
|
||||
}
|
||||
values += byte_size;
|
||||
}
|
||||
} else {
|
||||
GST_LOG ("failed to get control value for property %s at ts %"
|
||||
GST_TIME_FORMAT, _self->name, GST_TIME_ARGS (timestamp));
|
||||
}
|
||||
g_free (src_val);
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_direct_control_binding_get_g_value_array (GstControlBinding * _self,
|
||||
GstClockTime timestamp, GstClockTime interval, guint n_values,
|
||||
GValue * values)
|
||||
{
|
||||
GstDirectControlBinding *self = GST_DIRECT_CONTROL_BINDING (_self);
|
||||
gint i;
|
||||
gdouble *src_val;
|
||||
gboolean res = FALSE;
|
||||
GType type;
|
||||
GstDirectControlBindingConvertGValue convert;
|
||||
|
||||
g_return_val_if_fail (GST_IS_DIRECT_CONTROL_BINDING (self), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
||||
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
|
||||
g_return_val_if_fail (values, FALSE);
|
||||
g_return_val_if_fail (GST_CONTROL_BINDING_PSPEC (self), FALSE);
|
||||
|
||||
convert = self->convert_g_value;
|
||||
type = G_PARAM_SPEC_VALUE_TYPE (_self->pspec);
|
||||
|
||||
src_val = g_new0 (gdouble, n_values);
|
||||
|
|
|
@ -48,14 +48,24 @@ typedef struct _GstDirectControlBinding GstDirectControlBinding;
|
|||
typedef struct _GstDirectControlBindingClass GstDirectControlBindingClass;
|
||||
|
||||
/**
|
||||
* GstDirectControlBindingConvert:
|
||||
* GstDirectControlBindingConvertValue:
|
||||
* @self: the #GstDirectControlBinding instance
|
||||
* @src_value: the value returned by the cotnrol source
|
||||
* @dest_value: the target location
|
||||
*
|
||||
* Function to map a control-value to the target plain data type.
|
||||
*/
|
||||
typedef void (* GstDirectControlBindingConvertValue) (GstDirectControlBinding *self, gdouble src_value, gpointer dest_value);
|
||||
|
||||
/**
|
||||
* GstDirectControlBindingConvertGValue:
|
||||
* @self: the #GstDirectControlBinding instance
|
||||
* @src_value: the value returned by the cotnrol source
|
||||
* @dest_value: the target GValue
|
||||
*
|
||||
* Function to map a control-value to the target GValue.
|
||||
*/
|
||||
typedef void (* GstDirectControlBindingConvert) (GstDirectControlBinding *self, gdouble src_value, GValue *dest_value);
|
||||
typedef void (* GstDirectControlBindingConvertGValue) (GstDirectControlBinding *self, gdouble src_value, GValue *dest_value);
|
||||
|
||||
/**
|
||||
* GstDirectControlBinding:
|
||||
|
@ -70,8 +80,10 @@ struct _GstDirectControlBinding {
|
|||
GstControlSource *cs; /* GstControlSource for this property */
|
||||
GValue cur_value;
|
||||
gdouble last_value;
|
||||
gint byte_size;
|
||||
|
||||
GstDirectControlBindingConvert convert;
|
||||
GstDirectControlBindingConvertValue convert_value;
|
||||
GstDirectControlBindingConvertGValue convert_g_value;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
|
|
@ -605,6 +605,7 @@ GST_START_TEST (controller_interpolation_linear_value_array)
|
|||
GstElement *elem;
|
||||
gdouble *raw_values;
|
||||
GValue *g_values;
|
||||
gint *values;
|
||||
|
||||
elem = gst_element_factory_make ("testobj", NULL);
|
||||
|
||||
|
@ -633,10 +634,10 @@ GST_START_TEST (controller_interpolation_linear_value_array)
|
|||
|
||||
g_free (raw_values);
|
||||
|
||||
/* now pull in mapped values for some timestamps */
|
||||
/* now pull in mapped GValues for some timestamps */
|
||||
g_values = g_new0 (GValue, 3);
|
||||
|
||||
fail_unless (gst_object_get_value_array (GST_OBJECT (elem), "int",
|
||||
fail_unless (gst_object_get_g_value_array (GST_OBJECT (elem), "int",
|
||||
0, GST_SECOND / 2, 3, g_values));
|
||||
fail_unless_equals_int (g_value_get_int (&g_values[0]), 0);
|
||||
fail_unless_equals_int (g_value_get_int (&g_values[1]), 50);
|
||||
|
@ -644,6 +645,17 @@ GST_START_TEST (controller_interpolation_linear_value_array)
|
|||
|
||||
g_free (g_values);
|
||||
|
||||
/* now pull in mapped values for some timestamps */
|
||||
values = g_new0 (gint, 3);
|
||||
|
||||
fail_unless (gst_object_get_value_array (GST_OBJECT (elem), "int",
|
||||
0, GST_SECOND / 2, 3, values));
|
||||
fail_unless_equals_int (values[0], 0);
|
||||
fail_unless_equals_int (values[1], 50);
|
||||
fail_unless_equals_int (values[2], 100);
|
||||
|
||||
g_free (values);
|
||||
|
||||
gst_object_unref (cs);
|
||||
gst_object_unref (elem);
|
||||
}
|
||||
|
|
|
@ -230,15 +230,15 @@ test_interpolation (void)
|
|||
|
||||
g_object_set (cs, "mode", GST_INTERPOLATION_MODE_NONE, NULL);
|
||||
v1 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
|
||||
g_object_set (cs, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
|
||||
v2 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
|
||||
|
||||
g_object_set (cs, "mode", GST_INTERPOLATION_MODE_CUBIC, NULL);
|
||||
v3 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
|
||||
|
||||
for (t = 0; t < n_values; t++) {
|
||||
i1 = g_value_get_int (&v1[t]);
|
||||
|
@ -320,23 +320,23 @@ test_lfo (void)
|
|||
|
||||
g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SINE, NULL);
|
||||
v1 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
|
||||
g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SQUARE, NULL);
|
||||
v2 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v2);
|
||||
|
||||
g_object_set (cs, "waveform", GST_LFO_WAVEFORM_SAW, NULL);
|
||||
v3 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v3);
|
||||
|
||||
g_object_set (cs, "waveform", GST_LFO_WAVEFORM_REVERSE_SAW, NULL);
|
||||
v4 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v4);
|
||||
|
||||
g_object_set (cs, "waveform", GST_LFO_WAVEFORM_TRIANGLE, NULL);
|
||||
v5 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v5);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v5);
|
||||
|
||||
for (t = 0; t < n_values; t++) {
|
||||
i1 = g_value_get_int (&v1[t]);
|
||||
|
@ -418,7 +418,7 @@ test_chained_lfo (void)
|
|||
n_values = 40 * 10;
|
||||
|
||||
v1 = g_new0 (GValue, n_values);
|
||||
gst_object_get_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
gst_object_get_g_value_array (e, "int", 0, GST_SECOND / 10, n_values, v1);
|
||||
|
||||
for (t = 0; t < n_values; t++) {
|
||||
i1 = g_value_get_int (&v1[t]);
|
||||
|
|
|
@ -254,6 +254,7 @@ EXPORTS
|
|||
gst_clock_single_shot_id_reinit
|
||||
gst_clock_type_get_type
|
||||
gst_clock_unadjust_unlocked
|
||||
gst_control_binding_get_g_value_array
|
||||
gst_control_binding_get_type
|
||||
gst_control_binding_get_value
|
||||
gst_control_binding_get_value_array
|
||||
|
@ -605,6 +606,7 @@ EXPORTS
|
|||
gst_object_flags_get_type
|
||||
gst_object_get_control_binding
|
||||
gst_object_get_control_rate
|
||||
gst_object_get_g_value_array
|
||||
gst_object_get_name
|
||||
gst_object_get_parent
|
||||
gst_object_get_path_string
|
||||
|
|
Loading…
Reference in a new issue