libs/gst/controller/: API: Refactor GstController into the core controller which can take a GstControlSource for prov...
Original commit message from CVS:
Reviewed by: Stefan Kost <ensonic@users.sf.net>
* libs/gst/controller/Makefile.am:
* libs/gst/controller/gstcontroller.c:
(gst_controlled_property_add_interpolation_control_source),
(gst_controlled_property_new), (gst_controlled_property_free),
(gst_controller_find_controlled_property),
(gst_controller_new_valist), (gst_controller_new_list),
(gst_controller_new), (gst_controller_remove_properties_valist),
(gst_controller_remove_properties_list),
(gst_controller_remove_properties),
(gst_controller_set_property_disabled),
(gst_controller_set_disabled), (gst_controller_set_control_source),
(gst_controller_get_control_source), (gst_controller_get),
(gst_controller_sync_values), (gst_controller_get_value_array),
(_gst_controller_dispose), (gst_controller_get_type),
(gst_controlled_property_set_interpolation_mode),
(gst_controller_set), (gst_controller_set_from_list),
(gst_controller_unset), (gst_controller_unset_all),
(gst_controller_get_all), (gst_controller_set_interpolation_mode):
* libs/gst/controller/gstcontroller.h:
* libs/gst/controller/gstcontrollerprivate.h:
* libs/gst/controller/gstcontrolsource.c:
(gst_control_source_class_init), (gst_control_source_init),
(gst_control_source_get_value),
(gst_control_source_get_value_array), (gst_control_source_bind):
* libs/gst/controller/gstcontrolsource.h:
* libs/gst/controller/gsthelper.c: (gst_object_set_control_source),
(gst_object_get_control_source):
* libs/gst/controller/gstinterpolation.c:
(gst_interpolation_control_source_find_control_point_node),
(gst_interpolation_control_source_get_first_value),
(_interpolate_none_get), (interpolate_none_get),
(interpolate_none_get_boolean_value_array),
(interpolate_none_get_enum_value_array),
(interpolate_none_get_string_value_array),
(_interpolate_trigger_get), (interpolate_trigger_get),
(interpolate_trigger_get_boolean_value_array),
(interpolate_trigger_get_enum_value_array),
(interpolate_trigger_get_string_value_array):
* libs/gst/controller/gstinterpolationcontrolsource.c:
(gst_control_point_free), (gst_interpolation_control_source_reset),
(gst_interpolation_control_source_new),
(gst_interpolation_control_source_set_interpolation_mode),
(gst_interpolation_control_source_bind),
(gst_control_point_compare), (gst_control_point_find),
(gst_interpolation_control_source_set_internal),
(gst_interpolation_control_source_set),
(gst_interpolation_control_source_set_from_list),
(gst_interpolation_control_source_unset),
(gst_interpolation_control_source_unset_all),
(gst_interpolation_control_source_get_all),
(gst_interpolation_control_source_get_count),
(gst_interpolation_control_source_init),
(gst_interpolation_control_source_finalize),
(gst_interpolation_control_source_dispose),
(gst_interpolation_control_source_class_init):
* libs/gst/controller/gstinterpolationcontrolsource.h:
* libs/gst/controller/gstinterpolationcontrolsourceprivate.h:
API: Refactor GstController into the core controller which can take
a GstControlSource for providing actual values for timestamps.
Implement a interpolation control source and use this for backward
compatibility, deprecate a bunch of functions that are now handled
by GstControlSource or GstInterpolationControlSource.
Make it possible to disable the controller completely or only for
specific properties. Fixes #450711.
* docs/libs/gstreamer-libs-docs.sgml:
* docs/libs/gstreamer-libs-sections.txt:
* docs/libs/gstreamer-libs.types:
Add new functions and classes to the docs.
* tests/check/libs/controller.c: (GST_START_TEST),
(gst_controller_suite):
* tests/examples/controller/audio-example.c: (main):
Port unit test and example to the new API and add some new
unit tests.
2007-07-06 21:50:02 +00:00
|
|
|
/* GStreamer
|
|
|
|
*
|
|
|
|
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
|
|
|
*
|
|
|
|
* gstinterpolationcontrolsource.c: Control source that provides several
|
|
|
|
* interpolation methods
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the
|
|
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
* Boston, MA 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SECTION:gstinterpolationcontrolsource
|
|
|
|
* @short_description: interpolation control source
|
|
|
|
*
|
|
|
|
* #GstInterpolationControlSource is a #GstControlSource, that interpolates values between user-given
|
|
|
|
* control points. It supports several interpolation modes and property types.
|
|
|
|
*
|
|
|
|
* To use #GstInterpolationControlSource get a new instance by calling
|
|
|
|
* gst_interpolation_control_source_new(), bind it to a #GParamSpec, select a interpolation mode with
|
|
|
|
* gst_interpolation_control_source_set_interpolation_mode() and set some control points by calling
|
|
|
|
* gst_interpolation_control_source_set().
|
|
|
|
*
|
|
|
|
* All functions are MT-safe.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <glib-object.h>
|
|
|
|
#include <gst/gst.h>
|
|
|
|
|
|
|
|
#include "gstcontrolsource.h"
|
|
|
|
#include "gstinterpolationcontrolsource.h"
|
|
|
|
#include "gstinterpolationcontrolsourceprivate.h"
|
|
|
|
|
|
|
|
extern GstInterpolateMethod *interpolation_methods[];
|
|
|
|
extern guint num_interpolation_methods;
|
|
|
|
|
|
|
|
static void gst_interpolation_control_source_init (GstInterpolationControlSource
|
|
|
|
* self);
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_class_init (GstInterpolationControlSourceClass
|
|
|
|
* klass);
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (GstInterpolationControlSource, gst_interpolation_control_source,
|
|
|
|
GST_TYPE_CONTROL_SOURCE);
|
|
|
|
|
|
|
|
static GObjectClass *parent_class = NULL;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gst_control_point_free:
|
|
|
|
* @prop: the object to free
|
|
|
|
*
|
|
|
|
* Private method which frees all data allocated by a #GstControlPoint
|
|
|
|
* instance.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
gst_control_point_free (GstControlPoint * cp)
|
|
|
|
{
|
|
|
|
g_return_if_fail (cp);
|
|
|
|
|
|
|
|
g_value_unset (&cp->value);
|
|
|
|
g_free (cp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_reset (GstInterpolationControlSource * self)
|
|
|
|
{
|
|
|
|
GstControlSource *csource = GST_CONTROL_SOURCE (self);
|
|
|
|
|
|
|
|
csource->get_value = NULL;
|
|
|
|
csource->get_value_array = NULL;
|
|
|
|
|
|
|
|
self->priv->type = self->priv->base = G_TYPE_INVALID;
|
|
|
|
|
|
|
|
if (G_IS_VALUE (&self->priv->default_value))
|
|
|
|
g_value_unset (&self->priv->default_value);
|
|
|
|
if (G_IS_VALUE (&self->priv->minimum_value))
|
|
|
|
g_value_unset (&self->priv->minimum_value);
|
|
|
|
if (G_IS_VALUE (&self->priv->maximum_value))
|
|
|
|
g_value_unset (&self->priv->maximum_value);
|
|
|
|
|
|
|
|
if (self->priv->values) {
|
|
|
|
g_list_foreach (self->priv->values, (GFunc) gst_control_point_free, NULL);
|
|
|
|
g_list_free (self->priv->values);
|
|
|
|
self->priv->values = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
self->priv->nvalues = 0;
|
|
|
|
self->priv->last_requested_value = NULL;
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_new:
|
|
|
|
*
|
|
|
|
* This returns a new, unbound #GstInterpolationControlSource.
|
|
|
|
*
|
|
|
|
* Returns: a new, unbound #GstInterpolationControlSource.
|
|
|
|
*/
|
|
|
|
GstInterpolationControlSource *
|
Correct all relevant warnings found by the sparse semantic code analyzer. This include marking several symbols static...
Original commit message from CVS:
* gst/gstconfig.h.in:
* libs/gst/base/gstcollectpads.c: (gst_collect_pads_read_buffer):
* libs/gst/check/gstcheck.c: (gst_check_log_message_func),
(gst_check_log_critical_func), (gst_check_drop_buffers),
(gst_check_element_push_buffer_list):
* libs/gst/controller/gstcontroller.c: (gst_controller_get),
(gst_controller_get_type):
* libs/gst/controller/gsthelper.c: (gst_object_control_properties),
(gst_object_get_controller), (gst_object_get_control_source):
* libs/gst/controller/gstinterpolationcontrolsource.c:
(gst_interpolation_control_source_new):
* libs/gst/controller/gstlfocontrolsource.c:
(gst_lfo_control_source_new):
* libs/gst/dataprotocol/dataprotocol.c:
(gst_dp_event_from_packet_0_2):
* plugins/elements/gstfdsrc.c:
* plugins/elements/gstmultiqueue.c:
* plugins/elements/gsttee.c:
* plugins/elements/gsttypefindelement.c:
* plugins/indexers/gstfileindex.c: (_file_index_id_save_xml),
(gst_file_index_add_association):
* plugins/indexers/gstmemindex.c:
* tests/benchmarks/gstpollstress.c: (mess_some_more):
* tests/check/elements/queue.c: (setup_queue):
* tests/check/gst/gstpipeline.c:
* tests/check/libs/collectpads.c: (setup), (teardown),
(gst_collect_pads_suite):
* tests/examples/adapter/adapter_test.c:
* tests/examples/metadata/read-metadata.c: (make_pipeline):
* tests/examples/xml/createxml.c:
* tests/examples/xml/runxml.c:
* tools/gst-inspect.c:
* tools/gst-run.c:
Correct all relevant warnings found by the sparse semantic code
analyzer. This include marking several symbols static, using
NULL instead of 0 for pointers, not using variable sized arrays
on the stack, moving variable declarations to the beginning of
a block and using "foo (void)" instead of "foo ()" for declarations.
2008-02-29 12:41:33 +00:00
|
|
|
gst_interpolation_control_source_new (void)
|
libs/gst/controller/: API: Refactor GstController into the core controller which can take a GstControlSource for prov...
Original commit message from CVS:
Reviewed by: Stefan Kost <ensonic@users.sf.net>
* libs/gst/controller/Makefile.am:
* libs/gst/controller/gstcontroller.c:
(gst_controlled_property_add_interpolation_control_source),
(gst_controlled_property_new), (gst_controlled_property_free),
(gst_controller_find_controlled_property),
(gst_controller_new_valist), (gst_controller_new_list),
(gst_controller_new), (gst_controller_remove_properties_valist),
(gst_controller_remove_properties_list),
(gst_controller_remove_properties),
(gst_controller_set_property_disabled),
(gst_controller_set_disabled), (gst_controller_set_control_source),
(gst_controller_get_control_source), (gst_controller_get),
(gst_controller_sync_values), (gst_controller_get_value_array),
(_gst_controller_dispose), (gst_controller_get_type),
(gst_controlled_property_set_interpolation_mode),
(gst_controller_set), (gst_controller_set_from_list),
(gst_controller_unset), (gst_controller_unset_all),
(gst_controller_get_all), (gst_controller_set_interpolation_mode):
* libs/gst/controller/gstcontroller.h:
* libs/gst/controller/gstcontrollerprivate.h:
* libs/gst/controller/gstcontrolsource.c:
(gst_control_source_class_init), (gst_control_source_init),
(gst_control_source_get_value),
(gst_control_source_get_value_array), (gst_control_source_bind):
* libs/gst/controller/gstcontrolsource.h:
* libs/gst/controller/gsthelper.c: (gst_object_set_control_source),
(gst_object_get_control_source):
* libs/gst/controller/gstinterpolation.c:
(gst_interpolation_control_source_find_control_point_node),
(gst_interpolation_control_source_get_first_value),
(_interpolate_none_get), (interpolate_none_get),
(interpolate_none_get_boolean_value_array),
(interpolate_none_get_enum_value_array),
(interpolate_none_get_string_value_array),
(_interpolate_trigger_get), (interpolate_trigger_get),
(interpolate_trigger_get_boolean_value_array),
(interpolate_trigger_get_enum_value_array),
(interpolate_trigger_get_string_value_array):
* libs/gst/controller/gstinterpolationcontrolsource.c:
(gst_control_point_free), (gst_interpolation_control_source_reset),
(gst_interpolation_control_source_new),
(gst_interpolation_control_source_set_interpolation_mode),
(gst_interpolation_control_source_bind),
(gst_control_point_compare), (gst_control_point_find),
(gst_interpolation_control_source_set_internal),
(gst_interpolation_control_source_set),
(gst_interpolation_control_source_set_from_list),
(gst_interpolation_control_source_unset),
(gst_interpolation_control_source_unset_all),
(gst_interpolation_control_source_get_all),
(gst_interpolation_control_source_get_count),
(gst_interpolation_control_source_init),
(gst_interpolation_control_source_finalize),
(gst_interpolation_control_source_dispose),
(gst_interpolation_control_source_class_init):
* libs/gst/controller/gstinterpolationcontrolsource.h:
* libs/gst/controller/gstinterpolationcontrolsourceprivate.h:
API: Refactor GstController into the core controller which can take
a GstControlSource for providing actual values for timestamps.
Implement a interpolation control source and use this for backward
compatibility, deprecate a bunch of functions that are now handled
by GstControlSource or GstInterpolationControlSource.
Make it possible to disable the controller completely or only for
specific properties. Fixes #450711.
* docs/libs/gstreamer-libs-docs.sgml:
* docs/libs/gstreamer-libs-sections.txt:
* docs/libs/gstreamer-libs.types:
Add new functions and classes to the docs.
* tests/check/libs/controller.c: (GST_START_TEST),
(gst_controller_suite):
* tests/examples/controller/audio-example.c: (main):
Port unit test and example to the new API and add some new
unit tests.
2007-07-06 21:50:02 +00:00
|
|
|
{
|
|
|
|
return g_object_new (GST_TYPE_INTERPOLATION_CONTROL_SOURCE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_set_interpolation_mode:
|
|
|
|
* @self: the #GstInterpolationControlSource object
|
|
|
|
* @mode: interpolation mode
|
|
|
|
*
|
|
|
|
* Sets the given interpolation mode.
|
|
|
|
*
|
|
|
|
* <note><para>User interpolation is not yet available and quadratic interpolation
|
|
|
|
* is deprecated and maps to cubic interpolation.</para></note>
|
|
|
|
*
|
|
|
|
* Returns: %TRUE if the interpolation mode could be set, %FALSE otherwise
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_interpolation_control_source_set_interpolation_mode
|
|
|
|
(GstInterpolationControlSource * self, GstInterpolateMode mode) {
|
|
|
|
gboolean ret = TRUE;
|
|
|
|
GstControlSource *csource = GST_CONTROL_SOURCE (self);
|
|
|
|
|
|
|
|
if (mode >= num_interpolation_methods || interpolation_methods[mode] == NULL) {
|
|
|
|
GST_WARNING ("interpolation mode %d invalid or not implemented yet", mode);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == GST_INTERPOLATE_QUADRATIC) {
|
|
|
|
GST_WARNING ("Quadratic interpolation mode is deprecated, using cubic"
|
|
|
|
"interpolation mode");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mode == GST_INTERPOLATE_USER) {
|
|
|
|
GST_WARNING ("User interpolation mode is not implemented yet");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
switch (self->priv->base) {
|
|
|
|
case G_TYPE_INT:
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_int;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_int_value_array;
|
|
|
|
break;
|
|
|
|
case G_TYPE_UINT:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_uint;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_uint_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_LONG:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_long;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_long_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_ULONG:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_ulong;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_ulong_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_INT64:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_int64;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_int64_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_UINT64:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_uint64;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_uint64_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_FLOAT:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_float;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_float_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_DOUBLE:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_double;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_double_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_BOOLEAN:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_boolean;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_boolean_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_ENUM:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_enum;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_enum_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_STRING:{
|
|
|
|
csource->get_value = interpolation_methods[mode]->get_string;
|
|
|
|
csource->get_value_array =
|
|
|
|
interpolation_methods[mode]->get_string_value_array;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
ret = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Incomplete implementation */
|
|
|
|
if (!ret || !csource->get_value || !csource->get_value_array) {
|
|
|
|
gst_interpolation_control_source_reset (self);
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
self->priv->interpolation_mode = mode;
|
|
|
|
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gst_interpolation_control_source_bind (GstControlSource * source,
|
|
|
|
GParamSpec * pspec)
|
|
|
|
{
|
|
|
|
GType type, base;
|
|
|
|
GstInterpolationControlSource *self =
|
|
|
|
GST_INTERPOLATION_CONTROL_SOURCE (source);
|
|
|
|
gboolean ret = TRUE;
|
|
|
|
|
|
|
|
/* get the fundamental base type */
|
|
|
|
self->priv->type = base = type = G_PARAM_SPEC_VALUE_TYPE (pspec);
|
|
|
|
while ((type = g_type_parent (type)))
|
|
|
|
base = type;
|
|
|
|
|
|
|
|
self->priv->base = base;
|
|
|
|
/* restore type */
|
|
|
|
type = self->priv->type;
|
|
|
|
|
|
|
|
if (!gst_interpolation_control_source_set_interpolation_mode (self,
|
|
|
|
self->priv->interpolation_mode))
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
switch (base) {
|
|
|
|
case G_TYPE_INT:{
|
|
|
|
GParamSpecInt *tpspec = G_PARAM_SPEC_INT (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_int (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_int (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_int (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_UINT:{
|
|
|
|
GParamSpecUInt *tpspec = G_PARAM_SPEC_UINT (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_uint (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_uint (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_uint (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_LONG:{
|
|
|
|
GParamSpecLong *tpspec = G_PARAM_SPEC_LONG (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_long (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_long (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_long (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_ULONG:{
|
|
|
|
GParamSpecULong *tpspec = G_PARAM_SPEC_ULONG (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_ulong (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_ulong (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_ulong (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_INT64:{
|
|
|
|
GParamSpecInt64 *tpspec = G_PARAM_SPEC_INT64 (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_int64 (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_int64 (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_int64 (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_UINT64:{
|
|
|
|
GParamSpecUInt64 *tpspec = G_PARAM_SPEC_UINT64 (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_uint64 (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_uint64 (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_uint64 (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_FLOAT:{
|
|
|
|
GParamSpecFloat *tpspec = G_PARAM_SPEC_FLOAT (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_float (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_float (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_float (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_DOUBLE:{
|
|
|
|
GParamSpecDouble *tpspec = G_PARAM_SPEC_DOUBLE (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_double (&self->priv->default_value, tpspec->default_value);
|
|
|
|
g_value_init (&self->priv->minimum_value, type);
|
|
|
|
g_value_set_double (&self->priv->minimum_value, tpspec->minimum);
|
|
|
|
g_value_init (&self->priv->maximum_value, type);
|
|
|
|
g_value_set_double (&self->priv->maximum_value, tpspec->maximum);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_BOOLEAN:{
|
|
|
|
GParamSpecBoolean *tpspec = G_PARAM_SPEC_BOOLEAN (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_boolean (&self->priv->default_value, tpspec->default_value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_ENUM:{
|
|
|
|
GParamSpecEnum *tpspec = G_PARAM_SPEC_ENUM (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_enum (&self->priv->default_value, tpspec->default_value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case G_TYPE_STRING:{
|
|
|
|
GParamSpecString *tpspec = G_PARAM_SPEC_STRING (pspec);
|
|
|
|
|
|
|
|
g_value_init (&self->priv->default_value, type);
|
|
|
|
g_value_set_string (&self->priv->default_value, tpspec->default_value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
GST_WARNING ("incomplete implementation for paramspec type '%s'",
|
|
|
|
G_PARAM_SPEC_TYPE_NAME (pspec));
|
|
|
|
ret = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret) {
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
self->priv->nvalues = 0;
|
|
|
|
} else {
|
|
|
|
gst_interpolation_control_source_reset (self);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gst_control_point_compare:
|
|
|
|
* @p1: a pointer to a #GstControlPoint
|
|
|
|
* @p2: a pointer to a #GstControlPoint
|
|
|
|
*
|
|
|
|
* Compare function for g_list operations that operates on two #GstControlPoint
|
|
|
|
* parameters.
|
|
|
|
*/
|
|
|
|
static gint
|
|
|
|
gst_control_point_compare (gconstpointer p1, gconstpointer p2)
|
|
|
|
{
|
|
|
|
GstClockTime ct1 = ((GstControlPoint *) p1)->timestamp;
|
|
|
|
GstClockTime ct2 = ((GstControlPoint *) p2)->timestamp;
|
|
|
|
|
|
|
|
return ((ct1 < ct2) ? -1 : ((ct1 == ct2) ? 0 : 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* gst_control_point_find:
|
|
|
|
* @p1: a pointer to a #GstControlPoint
|
|
|
|
* @p2: a pointer to a #GstClockTime
|
|
|
|
*
|
|
|
|
* Compare function for g_list operations that operates on a #GstControlPoint and
|
|
|
|
* a #GstClockTime.
|
|
|
|
*/
|
|
|
|
static gint
|
|
|
|
gst_control_point_find (gconstpointer p1, gconstpointer p2)
|
|
|
|
{
|
|
|
|
GstClockTime ct1 = ((GstControlPoint *) p1)->timestamp;
|
|
|
|
GstClockTime ct2 = *(GstClockTime *) p2;
|
|
|
|
|
|
|
|
return ((ct1 < ct2) ? -1 : ((ct1 == ct2) ? 0 : 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_set_internal (GstInterpolationControlSource *
|
|
|
|
self, GstClockTime timestamp, GValue * value)
|
|
|
|
{
|
|
|
|
GstControlPoint *cp;
|
|
|
|
GList *node;
|
|
|
|
|
|
|
|
/* check if a control point for the timestamp already exists */
|
|
|
|
if ((node = g_list_find_custom (self->priv->values, ×tamp,
|
|
|
|
gst_control_point_find))) {
|
|
|
|
cp = node->data;
|
|
|
|
g_value_reset (&cp->value);
|
|
|
|
g_value_copy (value, &cp->value);
|
|
|
|
} else {
|
|
|
|
/* create a new GstControlPoint */
|
|
|
|
cp = g_new0 (GstControlPoint, 1);
|
|
|
|
cp->timestamp = timestamp;
|
|
|
|
g_value_init (&cp->value, self->priv->type);
|
|
|
|
g_value_copy (value, &cp->value);
|
|
|
|
/* and sort it into the prop->values list */
|
|
|
|
self->priv->values =
|
|
|
|
g_list_insert_sorted (self->priv->values, cp,
|
|
|
|
gst_control_point_compare);
|
|
|
|
self->priv->nvalues++;
|
|
|
|
}
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_set:
|
|
|
|
* @self: the #GstInterpolationControlSource object
|
|
|
|
* @timestamp: the time the control-change is scheduled for
|
|
|
|
* @value: the control-value
|
|
|
|
*
|
|
|
|
* Set the value of given controller-handled property at a certain time.
|
|
|
|
*
|
|
|
|
* Returns: FALSE if the values couldn't be set, TRUE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_interpolation_control_source_set (GstInterpolationControlSource * self,
|
|
|
|
GstClockTime timestamp, GValue * value)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self), FALSE);
|
|
|
|
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
|
|
|
g_return_val_if_fail (G_IS_VALUE (value), FALSE);
|
|
|
|
g_return_val_if_fail (G_VALUE_TYPE (value) == self->priv->type, FALSE);
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
gst_interpolation_control_source_set_internal (self, timestamp, value);
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_set_from_list:
|
|
|
|
* @self: the #GstInterpolationControlSource object
|
|
|
|
* @timedvalues: a list with #GstTimedValue items
|
|
|
|
*
|
|
|
|
* Sets multiple timed values at once.
|
|
|
|
*
|
|
|
|
* Returns: FALSE if the values couldn't be set, TRUE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_interpolation_control_source_set_from_list (GstInterpolationControlSource *
|
|
|
|
self, GSList * timedvalues)
|
|
|
|
{
|
|
|
|
GSList *node;
|
|
|
|
GstTimedValue *tv;
|
|
|
|
gboolean res = FALSE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self), FALSE);
|
|
|
|
|
|
|
|
for (node = timedvalues; node; node = g_slist_next (node)) {
|
|
|
|
tv = node->data;
|
|
|
|
if (!GST_CLOCK_TIME_IS_VALID (tv->timestamp)) {
|
|
|
|
GST_WARNING ("GstTimedValued with invalid timestamp passed to %s",
|
|
|
|
GST_FUNCTION);
|
|
|
|
} else if (!G_IS_VALUE (&tv->value)) {
|
|
|
|
GST_WARNING ("GstTimedValued with invalid value passed to %s",
|
|
|
|
GST_FUNCTION);
|
|
|
|
} else if (G_VALUE_TYPE (&tv->value) != self->priv->type) {
|
|
|
|
GST_WARNING ("incompatible value type for property");
|
|
|
|
} else {
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
gst_interpolation_control_source_set_internal (self, tv->timestamp,
|
|
|
|
&tv->value);
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
res = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_unset:
|
|
|
|
* @self: the #GstInterpolationControlSource object
|
|
|
|
* @timestamp: the time the control-change should be removed from
|
|
|
|
*
|
|
|
|
* Used to remove the value of given controller-handled property at a certain
|
|
|
|
* time.
|
|
|
|
*
|
|
|
|
* Returns: FALSE if the value couldn't be unset (i.e. not found, TRUE otherwise.
|
|
|
|
*/
|
|
|
|
gboolean
|
|
|
|
gst_interpolation_control_source_unset (GstInterpolationControlSource * self,
|
|
|
|
GstClockTime timestamp)
|
|
|
|
{
|
|
|
|
GList *node;
|
|
|
|
gboolean res = FALSE;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self), FALSE);
|
|
|
|
g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
/* check if a control point for the timestamp exists */
|
|
|
|
if ((node = g_list_find_custom (self->priv->values, ×tamp,
|
|
|
|
gst_control_point_find))) {
|
|
|
|
GstControlPoint *cp = node->data;
|
|
|
|
|
|
|
|
if (cp->timestamp == 0) {
|
|
|
|
/* Restore the default node */
|
|
|
|
g_value_reset (&cp->value);
|
|
|
|
g_value_copy (&self->priv->default_value, &cp->value);
|
|
|
|
} else {
|
|
|
|
if (node == self->priv->last_requested_value)
|
|
|
|
self->priv->last_requested_value = NULL;
|
|
|
|
gst_control_point_free (node->data); /* free GstControlPoint */
|
|
|
|
self->priv->values = g_list_delete_link (self->priv->values, node);
|
|
|
|
self->priv->nvalues--;
|
|
|
|
}
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
res = TRUE;
|
|
|
|
}
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_unset_all:
|
|
|
|
* @self: the #GstInterpolationControlSource object
|
|
|
|
*
|
|
|
|
* Used to remove all time-stamped values of given controller-handled property
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
gst_interpolation_control_source_unset_all (GstInterpolationControlSource *
|
|
|
|
self)
|
|
|
|
{
|
|
|
|
g_return_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self));
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
/* free GstControlPoint structures */
|
|
|
|
g_list_foreach (self->priv->values, (GFunc) gst_control_point_free, NULL);
|
|
|
|
g_list_free (self->priv->values);
|
|
|
|
self->priv->last_requested_value = NULL;
|
|
|
|
self->priv->values = NULL;
|
|
|
|
self->priv->nvalues = 0;
|
|
|
|
self->priv->valid_cache = FALSE;
|
|
|
|
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_get_all:
|
|
|
|
* @self: the #GstInterpolationControlSource to get the list from
|
|
|
|
*
|
|
|
|
* Returns a read-only copy of the list of #GstTimedValue for the given property.
|
|
|
|
* Free the list after done with it.
|
|
|
|
*
|
|
|
|
* Returns: a copy of the list, or %NULL if the property isn't handled by the controller
|
|
|
|
*/
|
|
|
|
GList *
|
|
|
|
gst_interpolation_control_source_get_all (GstInterpolationControlSource * self)
|
|
|
|
{
|
|
|
|
GList *res = NULL;
|
|
|
|
|
|
|
|
g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self), NULL);
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
if (self->priv->values)
|
|
|
|
res = g_list_copy (self->priv->values);
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gst_interpolation_control_source_get_count:
|
|
|
|
* @self: the #GstInterpolationControlSource to get the number of values from
|
|
|
|
*
|
|
|
|
* Returns the number of control points that are set.
|
|
|
|
*
|
|
|
|
* Returns: the number of control points that are set.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
gint
|
|
|
|
gst_interpolation_control_source_get_count (GstInterpolationControlSource *
|
|
|
|
self)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self), 0);
|
|
|
|
return self->priv->nvalues;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_init (GstInterpolationControlSource * self)
|
|
|
|
{
|
|
|
|
self->lock = g_mutex_new ();
|
|
|
|
self->priv =
|
|
|
|
G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_INTERPOLATION_CONTROL_SOURCE,
|
|
|
|
GstInterpolationControlSourcePrivate);
|
|
|
|
self->priv->interpolation_mode = GST_INTERPOLATE_NONE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_finalize (GObject * obj)
|
|
|
|
{
|
|
|
|
GstInterpolationControlSource *self = GST_INTERPOLATION_CONTROL_SOURCE (obj);
|
|
|
|
|
|
|
|
g_mutex_lock (self->lock);
|
|
|
|
gst_interpolation_control_source_reset (self);
|
|
|
|
g_mutex_unlock (self->lock);
|
|
|
|
g_mutex_free (self->lock);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_dispose (GObject * obj)
|
|
|
|
{
|
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gst_interpolation_control_source_class_init (GstInterpolationControlSourceClass
|
|
|
|
* klass)
|
|
|
|
{
|
|
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
|
|
GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass);
|
|
|
|
|
|
|
|
parent_class = g_type_class_peek_parent (klass);
|
|
|
|
g_type_class_add_private (klass,
|
|
|
|
sizeof (GstInterpolationControlSourcePrivate));
|
|
|
|
|
|
|
|
gobject_class->finalize = gst_interpolation_control_source_finalize;
|
|
|
|
gobject_class->dispose = gst_interpolation_control_source_dispose;
|
|
|
|
csource_class->bind = gst_interpolation_control_source_bind;
|
|
|
|
}
|