mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 19:21:06 +00:00
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.
This commit is contained in:
parent
fc70188d3e
commit
286cd75855
17 changed files with 2968 additions and 1248 deletions
78
ChangeLog
78
ChangeLog
|
@ -1,3 +1,81 @@
|
|||
2007-07-06 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
|
||||
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-05 Wim Taymans <wim.taymans@gmail.com>
|
||||
|
||||
Patch by: Mark Nauwelaerts <manauw at skynet be>
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
<!ENTITY GstCheckBufferStraw SYSTEM "xml/gstcheckbufferstraw.xml">
|
||||
|
||||
<!ENTITY GstController SYSTEM "xml/gstcontroller.xml">
|
||||
<!ENTITY GstControlSource SYSTEM "xml/gstcontrolsource.xml">
|
||||
<!ENTITY GstInterpolationControlSource SYSTEM "xml/gstinterpolationcontrolsource.xml">
|
||||
<!ENTITY GstControllerGObject SYSTEM "xml/gstcontrollergobject.xml">
|
||||
<!ENTITY GstDataProtocol SYSTEM "xml/gstdataprotocol.xml">
|
||||
|
||||
|
@ -66,6 +68,8 @@
|
|||
<chapter id="gstreamer-control">
|
||||
<title>GStreamer Dynamic Parameter Control</title>
|
||||
&GstController;
|
||||
&GstControlSource;
|
||||
&GstInterpolationControlSource;
|
||||
&GstControllerGObject;
|
||||
</chapter>
|
||||
|
||||
|
|
|
@ -59,7 +59,6 @@ gst_dp_version_get_type
|
|||
<TITLE>GstController</TITLE>
|
||||
<INCLUDE>gst/controller/gstcontroller.h</INCLUDE>
|
||||
GstController
|
||||
GstInterpolateMode
|
||||
gst_controller_init
|
||||
gst_controller_new
|
||||
gst_controller_new_list
|
||||
|
@ -67,16 +66,20 @@ gst_controller_new_valist
|
|||
gst_controller_remove_properties
|
||||
gst_controller_remove_properties_list
|
||||
gst_controller_remove_properties_valist
|
||||
gst_controller_set_disabled
|
||||
gst_controller_set_property_disabled
|
||||
gst_controller_suggest_next_sync
|
||||
gst_controller_sync_values
|
||||
gst_controller_get_control_source
|
||||
gst_controller_set_control_source
|
||||
gst_controller_get
|
||||
gst_controller_get_value_arrays
|
||||
gst_controller_get_value_array
|
||||
gst_controller_set
|
||||
gst_controller_set_from_list
|
||||
gst_controller_unset
|
||||
gst_controller_unset_all
|
||||
gst_controller_get
|
||||
gst_controller_get_all
|
||||
gst_controller_suggest_next_sync
|
||||
gst_controller_sync_values
|
||||
gst_controller_get_value_arrays
|
||||
gst_controller_get_value_array
|
||||
gst_controller_set_interpolation_mode
|
||||
GST_PARAM_CONTROLLABLE
|
||||
<SUBSECTION Standard>
|
||||
|
@ -89,12 +92,62 @@ GST_IS_CONTROLLER_CLASS
|
|||
GST_CONTROLLER_GET_CLASS
|
||||
GST_TYPE_CONTROLLER
|
||||
<SUBSECTION Private>
|
||||
InterpolateGet
|
||||
InterpolateGetValueArray
|
||||
GST_CONTROLLED_PROPERTY
|
||||
gst_controller_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstcontrolsource</FILE>
|
||||
<TITLE>GstControlSource</TITLE>
|
||||
<INCLUDE>libs/controller/gstcontrolsource.h</INCLUDE>
|
||||
GstControlSource
|
||||
GstControlSourceClass
|
||||
GstControlSourceBind
|
||||
GstControlSourceGetValue
|
||||
GstControlSourceGetValueArray
|
||||
GstTimedValue
|
||||
GstValueArray
|
||||
gst_control_source_bind
|
||||
gst_control_source_get_value
|
||||
gst_control_source_get_value_array
|
||||
<SUBSECTION Standard>
|
||||
GST_CONTROL_SOURCE
|
||||
GST_IS_CONTROL_SOURCE
|
||||
GST_CONTROL_SOURCE_CLASS
|
||||
GST_IS_CONTROL_SOURCE_CLASS
|
||||
GST_CONTROL_SOURCE_GET_CLASS
|
||||
GST_TYPE_CONTROL_SOURCE
|
||||
<SUBSECTION Private>
|
||||
gst_control_source_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstinterpolationcontrolsource</FILE>
|
||||
<TITLE>GstInterpolationControlSource</TITLE>
|
||||
<INCLUDE>libs/controller/gstinterpolationcontrolsource.h</INCLUDE>
|
||||
GstInterpolationControlSource
|
||||
GstInterpolateMode
|
||||
gst_interpolation_control_source_new
|
||||
gst_interpolation_control_source_set
|
||||
gst_interpolation_control_source_set_from_list
|
||||
gst_interpolation_control_source_set_interpolation_mode
|
||||
gst_interpolation_control_source_get_all
|
||||
gst_interpolation_control_source_unset
|
||||
gst_interpolation_control_source_unset_all
|
||||
gst_interpolation_control_source_get_count
|
||||
<SUBSECTION Standard>
|
||||
GstInterpolationControlSourceClass
|
||||
GstInterpolationControlSourcePrivate
|
||||
GST_INTERPOLATION_CONTROL_SOURCE
|
||||
GST_IS_INTERPOLATION_CONTROL_SOURCE
|
||||
GST_INTERPOLATION_CONTROL_SOURCE_CLASS
|
||||
GST_IS_INTERPOLATION_CONTROL_SOURCE_CLASS
|
||||
GST_INTERPOLATION_CONTROL_SOURCE_GET_CLASS
|
||||
GST_TYPE_INTERPOLATION_CONTROL_SOURCE
|
||||
<SUBSECTION Private>
|
||||
gst_interpolation_control_source_get_type
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gstcontrollergobject</FILE>
|
||||
<TITLE>GstControllerGObject</TITLE>
|
||||
|
@ -105,6 +158,8 @@ gst_object_get_controller
|
|||
gst_object_set_controller
|
||||
gst_object_suggest_next_sync
|
||||
gst_object_sync_values
|
||||
gst_object_get_control_source
|
||||
gst_object_set_control_source
|
||||
gst_object_get_value_arrays
|
||||
gst_object_get_value_array
|
||||
gst_object_get_control_rate
|
||||
|
@ -113,7 +168,6 @@ gst_object_set_control_rate
|
|||
<SUBSECTION Private>
|
||||
</SECTION>
|
||||
|
||||
|
||||
# base classes
|
||||
|
||||
<SECTION>
|
||||
|
|
|
@ -2,6 +2,10 @@
|
|||
|
||||
#include <gst/controller/gstcontroller.h>
|
||||
gst_controller_get_type
|
||||
#include <gst/controller/gstcontrolsource.h>
|
||||
gst_control_source_get_type
|
||||
#include <gst/controller/gstinterpolationcontrolsource.h>
|
||||
gst_interpolation_control_source_get_type
|
||||
|
||||
#include <gst/base/gstadapter.h>
|
||||
gst_adapter_get_type
|
||||
|
|
|
@ -2,14 +2,21 @@ lib_LTLIBRARIES = libgstcontroller-@GST_MAJORMINOR@.la
|
|||
|
||||
libgstcontroller_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/controller
|
||||
libgstcontroller_@GST_MAJORMINOR@_include_HEADERS = \
|
||||
gstcontroller.h
|
||||
noinst_HEADERS = gstcontrollerprivate.h
|
||||
gstcontroller.h \
|
||||
gstcontrolsource.h \
|
||||
gstinterpolationcontrolsource.h
|
||||
|
||||
noinst_HEADERS = \
|
||||
gstcontrollerprivate.h \
|
||||
gstinterpolationcontrolsourceprivate.h
|
||||
|
||||
libgstcontroller_@GST_MAJORMINOR@_la_SOURCES = \
|
||||
lib.c \
|
||||
gstcontroller.c \
|
||||
gstinterpolation.c \
|
||||
gsthelper.c
|
||||
gsthelper.c \
|
||||
gstcontrolsource.c \
|
||||
gstinterpolationcontrolsource.c
|
||||
|
||||
libgstcontroller_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
|
||||
libgstcontroller_@GST_MAJORMINOR@_la_LIBADD = $(GST_OBJ_LIBS)
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,9 @@
|
|||
#include <glib/gprintf.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "gstcontrolsource.h"
|
||||
#include "gstinterpolationcontrolsource.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**
|
||||
|
@ -41,59 +44,6 @@ G_BEGIN_DECLS
|
|||
*/
|
||||
#define GST_PARAM_CONTROLLABLE (1 << (G_PARAM_USER_SHIFT + 1))
|
||||
|
||||
|
||||
/**
|
||||
* GstTimedValue:
|
||||
*
|
||||
* a structure for value+time
|
||||
*/
|
||||
typedef struct _GstTimedValue
|
||||
{
|
||||
GstClockTime timestamp; /* timestamp of the value change */
|
||||
GValue value; /* the new value */
|
||||
} GstTimedValue;
|
||||
|
||||
|
||||
/**
|
||||
* GstValueArray:
|
||||
* @property_name: the name of the property this array belongs to
|
||||
* @nbsamples: number of samples requested
|
||||
* @sample_interval: interval between each sample
|
||||
* @values: pointer to the array
|
||||
*
|
||||
* Structure to receive multiple values at once.
|
||||
*/
|
||||
typedef struct _GstValueArray
|
||||
{
|
||||
gchar *property_name;
|
||||
gint nbsamples;
|
||||
GstClockTime sample_interval;
|
||||
gpointer *values;
|
||||
} GstValueArray;
|
||||
|
||||
|
||||
/**
|
||||
* GstInterpolateMode:
|
||||
* @GST_INTERPOLATE_NONE: steps-like interpolation, default
|
||||
* @GST_INTERPOLATE_TRIGGER: returns the default value of the property,
|
||||
* except for times with specific values
|
||||
* @GST_INTERPOLATE_LINEAR: linear interpolation
|
||||
* @GST_INTERPOLATE_QUADRATIC: square interpolation (not yet available)
|
||||
* @GST_INTERPOLATE_CUBIC: cubic interpolation (not yet available)
|
||||
* @GST_INTERPOLATE_USER: user-provided interpolation (not yet available)
|
||||
*
|
||||
* The various interpolation modes available.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_INTERPOLATE_NONE,
|
||||
GST_INTERPOLATE_TRIGGER,
|
||||
GST_INTERPOLATE_LINEAR,
|
||||
GST_INTERPOLATE_QUADRATIC,
|
||||
GST_INTERPOLATE_CUBIC,
|
||||
GST_INTERPOLATE_USER
|
||||
} GstInterpolateMode;
|
||||
|
||||
/* type macros */
|
||||
|
||||
#define GST_TYPE_CONTROLLER (gst_controller_get_type ())
|
||||
|
@ -107,7 +57,6 @@ typedef struct _GstController GstController;
|
|||
typedef struct _GstControllerClass GstControllerClass;
|
||||
typedef struct _GstControllerPrivate GstControllerPrivate;
|
||||
|
||||
|
||||
/**
|
||||
* GstController:
|
||||
*
|
||||
|
@ -135,7 +84,7 @@ struct _GstControllerClass
|
|||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_controller_get_type (void);
|
||||
GType gst_controller_get_type ();
|
||||
|
||||
/* GstController functions */
|
||||
|
||||
|
@ -149,33 +98,22 @@ gboolean gst_controller_remove_properties_list (GstController * self,
|
|||
GList *list);
|
||||
gboolean gst_controller_remove_properties (GstController * self, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
gboolean gst_controller_set (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp, GValue * value);
|
||||
gboolean gst_controller_set_from_list (GstController * self,
|
||||
gchar * property_name, GSList * timedvalues);
|
||||
|
||||
gboolean gst_controller_unset (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp);
|
||||
gboolean gst_controller_unset_all (GstController * self, gchar * property_name);
|
||||
|
||||
GValue *gst_controller_get (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp);
|
||||
const GList *gst_controller_get_all (GstController * self,
|
||||
gchar * property_name);
|
||||
void gst_controller_set_disabled (GstController *self, gboolean disabled);
|
||||
void gst_controller_set_property_disabled (GstController *self, gchar * property_name, gboolean disabled);
|
||||
gboolean gst_controller_set_control_source (GstController *self, gchar * property_name, GstControlSource *csource);
|
||||
GstControlSource * gst_controller_get_control_source (GstController *self, gchar * property_name);
|
||||
|
||||
GstClockTime gst_controller_suggest_next_sync (GstController *self);
|
||||
gboolean gst_controller_sync_values (GstController * self,
|
||||
GstClockTime timestamp);
|
||||
|
||||
GValue *gst_controller_get (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp);
|
||||
gboolean gst_controller_get_value_arrays (GstController * self,
|
||||
GstClockTime timestamp, GSList * value_arrays);
|
||||
gboolean gst_controller_get_value_array (GstController * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array);
|
||||
|
||||
gboolean gst_controller_set_interpolation_mode (GstController * self,
|
||||
gchar * property_name, GstInterpolateMode mode);
|
||||
|
||||
|
||||
/* GObject convenience functions */
|
||||
|
||||
GstController *gst_object_control_properties (GObject * object, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
@ -187,6 +125,9 @@ gboolean gst_object_set_controller (GObject * object, GstController * controller
|
|||
GstClockTime gst_object_suggest_next_sync (GObject * object);
|
||||
gboolean gst_object_sync_values (GObject * object, GstClockTime timestamp);
|
||||
|
||||
gboolean gst_object_set_control_source (GObject *object, gchar * property_name, GstControlSource *csource);
|
||||
GstControlSource * gst_object_get_control_source (GObject *object, gchar * property_name);
|
||||
|
||||
gboolean gst_object_get_value_arrays (GObject * object,
|
||||
GstClockTime timestamp, GSList * value_arrays);
|
||||
gboolean gst_object_get_value_array (GObject * object,
|
||||
|
@ -199,5 +140,25 @@ void gst_object_set_control_rate (GObject * object, GstClockTime control_rate);
|
|||
|
||||
gboolean gst_controller_init (int * argc, char ***argv);
|
||||
|
||||
|
||||
/* FIXME: deprecated functions */
|
||||
#ifndef GST_DISABLE_DEPRECATED
|
||||
gboolean gst_controller_set (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp, GValue * value);
|
||||
gboolean gst_controller_set_from_list (GstController * self,
|
||||
gchar * property_name, GSList * timedvalues);
|
||||
|
||||
gboolean gst_controller_unset (GstController * self, gchar * property_name,
|
||||
GstClockTime timestamp);
|
||||
gboolean gst_controller_unset_all (GstController * self, gchar * property_name);
|
||||
|
||||
const GList *gst_controller_get_all (GstController * self,
|
||||
gchar * property_name);
|
||||
|
||||
gboolean gst_controller_set_interpolation_mode (GstController * self,
|
||||
gchar * property_name, GstInterpolateMode mode);
|
||||
#endif /* GST_DISABLE_DEPRECATED */
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CONTROLLER_H__ */
|
||||
|
|
|
@ -28,97 +28,19 @@
|
|||
#include <gst/gst.h>
|
||||
|
||||
#include "gstcontroller.h"
|
||||
#include "gstcontrolsource.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct _GstControlledProperty;
|
||||
|
||||
typedef GValue *(*InterpolateGet) (struct _GstControlledProperty * prop,
|
||||
GstClockTime timestamp);
|
||||
typedef gboolean (*InterpolateGetValueArray) (struct _GstControlledProperty * prop,
|
||||
GstClockTime timestamp, GstValueArray * value_array);
|
||||
|
||||
/**
|
||||
* GstInterpolateMethod:
|
||||
*
|
||||
* Function pointer structure to do user-defined interpolation methods
|
||||
*/
|
||||
typedef struct _GstInterpolateMethod
|
||||
{
|
||||
InterpolateGet get_int;
|
||||
InterpolateGetValueArray get_int_value_array;
|
||||
InterpolateGet get_uint;
|
||||
InterpolateGetValueArray get_uint_value_array;
|
||||
InterpolateGet get_long;
|
||||
InterpolateGetValueArray get_long_value_array;
|
||||
InterpolateGet get_ulong;
|
||||
InterpolateGetValueArray get_ulong_value_array;
|
||||
InterpolateGet get_float;
|
||||
InterpolateGetValueArray get_float_value_array;
|
||||
InterpolateGet get_double;
|
||||
InterpolateGetValueArray get_double_value_array;
|
||||
InterpolateGet get_boolean;
|
||||
InterpolateGetValueArray get_boolean_value_array;
|
||||
InterpolateGet get_enum;
|
||||
InterpolateGetValueArray get_enum_value_array;
|
||||
InterpolateGet get_string;
|
||||
InterpolateGetValueArray get_string_value_array;
|
||||
} GstInterpolateMethod;
|
||||
|
||||
/**
|
||||
* GstControlPoint:
|
||||
*
|
||||
* a internal structure for value+time and various temporary
|
||||
* values used for interpolation. This "inherits" from
|
||||
* GstTimedValue.
|
||||
*/
|
||||
/* FIXME 0.11: This should be merged with GstTimedValue for 0.11 */
|
||||
typedef struct _GstControlPoint
|
||||
{
|
||||
/* fields from GstTimedValue. DO NOT CHANGE! */
|
||||
GstClockTime timestamp; /* timestamp of the value change */
|
||||
GValue value; /* the new value */
|
||||
|
||||
/* internal fields */
|
||||
|
||||
/* Caches for the interpolators */
|
||||
union {
|
||||
struct {
|
||||
gdouble h;
|
||||
gdouble z;
|
||||
} cubic;
|
||||
} cache;
|
||||
|
||||
} GstControlPoint;
|
||||
|
||||
/**
|
||||
* GstControlledProperty:
|
||||
*/
|
||||
typedef struct _GstControlledProperty
|
||||
{
|
||||
GParamSpec *pspec; /* GParamSpec for this property */
|
||||
gchar *name; /* name of the property */
|
||||
GType type; /* type of the handled property */
|
||||
GType base; /* base-type of the handled property */
|
||||
GValue default_value; /* default value for the handled property */
|
||||
GValue min_value; /* min value for the handled property */
|
||||
GValue max_value; /* max value for the handled property */
|
||||
GValue result_value; /* result value location for the interpolation method */
|
||||
GstControlPoint last_value; /* the last value a _sink call wrote */
|
||||
GstControlPoint live_value; /* temporary value override for live input */
|
||||
gulong notify_handler_id; /* id of the notify::<name> signal handler */
|
||||
GstInterpolateMode interpolation; /* Interpolation mode */
|
||||
/* TODO instead of *method, have pointers to get() and get_value_array() here
|
||||
gst_controller_set_interpolation_mode() will pick the right ones for the
|
||||
properties value type
|
||||
GstInterpolateMethod *method; // User-implemented handler (if interpolation == GST_INTERPOLATE_USER)
|
||||
*/
|
||||
InterpolateGet get;
|
||||
InterpolateGetValueArray get_value_array;
|
||||
|
||||
GList *values; /* List of GstControlPoint */
|
||||
gint nvalues; /* Number of control points */
|
||||
GList *last_requested_value; /* last search result, can be used for incremental searches */
|
||||
gboolean valid_cache;
|
||||
GstControlSource *csource; /* GstControlSource for this property */
|
||||
gboolean disabled;
|
||||
} GstControlledProperty;
|
||||
|
||||
#define GST_CONTROLLED_PROPERTY(obj) ((GstControlledProperty *)(obj))
|
||||
|
|
158
libs/gst/controller/gstcontrolsource.c
Normal file
158
libs/gst/controller/gstcontrolsource.c
Normal file
|
@ -0,0 +1,158 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
*
|
||||
* gstcontrolsource.c: Interface declaration for control sources
|
||||
*
|
||||
* 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:gstcontrolsource
|
||||
* @short_description: base class for control source sources
|
||||
*
|
||||
* The #GstControlSource is a base class for control value sources that could
|
||||
* be used by #GstController to get timestamp-value pairs.
|
||||
*
|
||||
* A #GstControlSource is used by first getting an instance, binding it to a
|
||||
* #GParamSpec (for example by using gst_controller_set_control_source()) and
|
||||
* then by having it used by the #GstController or calling
|
||||
* gst_control_source_get_value() or gst_control_source_get_value_array().
|
||||
*
|
||||
* For implementing a new #GstControlSource one has to implement a
|
||||
* #GstControlSourceBind method, which will depending on the #GParamSpec set up
|
||||
* the control source for use and sets the #GstControlSourceGetValue and
|
||||
* #GstControlSourceGetValueArray functions. These are then used by
|
||||
* gst_control_source_get_value() or gst_control_source_get_value_array()
|
||||
* to get values for specific timestamps.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "gstcontrolsource.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_controller_debug
|
||||
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
|
||||
|
||||
static void gst_control_source_class_init (GstControlSourceClass * klass);
|
||||
static void gst_control_source_init (GstControlSource * self);
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GstControlSource, gst_control_source, G_TYPE_OBJECT);
|
||||
|
||||
static GObjectClass *parent_class = NULL;
|
||||
|
||||
static void
|
||||
gst_control_source_class_init (GstControlSourceClass * klass)
|
||||
{
|
||||
//GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
parent_class = g_type_class_peek_parent (klass);
|
||||
|
||||
/* Has to be implemented by children */
|
||||
klass->bind = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_control_source_init (GstControlSource * self)
|
||||
{
|
||||
/* Set default handlers that print a warning */
|
||||
self->get_value = NULL;
|
||||
self->get_value_array = NULL;
|
||||
self->bound = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_control_source_get_value:
|
||||
* @self: the #GstControlSource object
|
||||
* @timestamp: the time for which the value should be returned
|
||||
* @value: the value
|
||||
*
|
||||
* Gets the value for this #GstControlSource at a given timestamp.
|
||||
*
|
||||
* Returns: FALSE if the value couldn't be returned, TRUE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
gst_control_source_get_value (GstControlSource * self, GstClockTime timestamp,
|
||||
GValue * value)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE);
|
||||
|
||||
if (self->get_value) {
|
||||
return self->get_value (self, timestamp, value);
|
||||
} else {
|
||||
GST_ERROR ("Not bound to a specific property yet!");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_control_source_get_value_array:
|
||||
* @self: the #GstControlSource object
|
||||
* @timestamp: the time that should be processed
|
||||
* @value_array: array to put control-values in
|
||||
*
|
||||
* Gets an array of values for one element property.
|
||||
*
|
||||
* All fields of @value_array must be filled correctly. Especially the
|
||||
* @value_array->values array must be big enough to keep the requested amount
|
||||
* of values.
|
||||
*
|
||||
* The type of the values in the array is the same as the property's type.
|
||||
*
|
||||
* Returns: %TRUE if the given array could be filled, %FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
gst_control_source_get_value_array (GstControlSource * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE);
|
||||
|
||||
if (self->get_value_array) {
|
||||
return self->get_value_array (self, timestamp, value_array);
|
||||
} else {
|
||||
GST_ERROR ("Not bound to a specific property yet!");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_control_source_bind:
|
||||
* @self: the #GstControlSource object
|
||||
* @pspec: #GParamSpec for the property for which this #GstControlSource should generate values.
|
||||
*
|
||||
* Binds a #GstControlSource to a specific property. This must be called only once for a
|
||||
* #GstControlSource.
|
||||
*
|
||||
* Returns: %TRUE if the #GstControlSource was bound correctly, %FALSE otherwise.
|
||||
*/
|
||||
gboolean
|
||||
gst_control_source_bind (GstControlSource * self, GParamSpec * pspec)
|
||||
{
|
||||
gboolean ret = FALSE;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CONTROL_SOURCE (self), FALSE);
|
||||
g_return_val_if_fail (GST_CONTROL_SOURCE_GET_CLASS (self)->bind, FALSE);
|
||||
g_return_val_if_fail (!self->bound, FALSE);
|
||||
|
||||
ret = GST_CONTROL_SOURCE_GET_CLASS (self)->bind (self, pspec);
|
||||
|
||||
if (ret)
|
||||
self->bound = TRUE;
|
||||
|
||||
return ret;
|
||||
}
|
161
libs/gst/controller/gstcontrolsource.h
Normal file
161
libs/gst/controller/gstcontrolsource.h
Normal file
|
@ -0,0 +1,161 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
*
|
||||
* gstcontrolsource.h: Interface declaration for control sources
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GST_CONTROL_SOURCE_H__
|
||||
#define __GST_CONTROL_SOURCE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_CONTROL_SOURCE \
|
||||
(gst_control_source_get_type())
|
||||
#define GST_CONTROL_SOURCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_CONTROL_SOURCE,GstControlSource))
|
||||
#define GST_CONTROL_SOURCE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_CONTROL_SOURCE,GstControlSourceClass))
|
||||
#define GST_IS_CONTROL_SOURCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_CONTROL_SOURCE))
|
||||
#define GST_IS_CONTROL_SOURCE_CLASS(klass) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_CONTROL_SOURCE))
|
||||
#define GST_CONTROL_SOURCE_GET_CLASS(obj) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_CONTOL_SOURCE, GstControlSourceClass))
|
||||
|
||||
typedef struct _GstControlSource GstControlSource;
|
||||
typedef struct _GstControlSourceClass GstControlSourceClass;
|
||||
typedef struct _GstTimedValue GstTimedValue;
|
||||
typedef struct _GstValueArray GstValueArray;
|
||||
|
||||
/**
|
||||
* GstTimedValue:
|
||||
*
|
||||
* Structure for saving a timestamp and a value.
|
||||
*/
|
||||
struct _GstTimedValue
|
||||
{
|
||||
GstClockTime timestamp; /* timestamp of the value change */
|
||||
GValue value; /* the corresponding value */
|
||||
};
|
||||
|
||||
/**
|
||||
* GstValueArray:
|
||||
* @property_name: the name of the property this array belongs to
|
||||
* @nbsamples: number of samples requested
|
||||
* @sample_interval: interval between each sample
|
||||
* @values: pointer to the array
|
||||
*
|
||||
* Structure to receive multiple values at once.
|
||||
*/
|
||||
struct _GstValueArray
|
||||
{
|
||||
gchar *property_name;
|
||||
gint nbsamples;
|
||||
GstClockTime sample_interval;
|
||||
gpointer *values;
|
||||
};
|
||||
|
||||
/**
|
||||
* GstControlSourceGetValue
|
||||
* @self: the #GstControlSource instance
|
||||
* @timestamp: timestamp for which a value should be calculated
|
||||
* @value: a #GValue which will be set to the result. It must be initialized to the correct type.
|
||||
*
|
||||
* Function for returning a value for a given timestamp.
|
||||
*
|
||||
* Returns: %TRUE if the value was successfully calculated.
|
||||
*
|
||||
*/
|
||||
typedef gboolean (* GstControlSourceGetValue) (GstControlSource *self, GstClockTime timestamp, GValue *value);
|
||||
|
||||
/**
|
||||
* GstControlSourceGetValueArray
|
||||
* @self: the #GstControlSource instance
|
||||
* @timestamp: timestamp for which a value should be calculated
|
||||
* @value_array: array to put control-values in
|
||||
*
|
||||
* Function for returning a #GstValueArray for a given timestamp.
|
||||
*
|
||||
* Returns: %TRUE if the values were successfully calculated.
|
||||
*
|
||||
*/
|
||||
typedef gboolean (* GstControlSourceGetValueArray) (GstControlSource *self, GstClockTime timestamp, GstValueArray *value_array);
|
||||
|
||||
/**
|
||||
* GstControlSourceBind
|
||||
* @self: the #GstControlSource instance
|
||||
* @pspec: #GParamSpec that should be bound to
|
||||
*
|
||||
* Function for binding a #GstControlSource to a #GParamSpec.
|
||||
*
|
||||
* Returns: %TRUE if the property could be bound to the #GstControlSource, %FALSE otherwise.
|
||||
*/
|
||||
typedef gboolean (* GstControlSourceBind) (GstControlSource *self, GParamSpec *pspec);
|
||||
|
||||
/**
|
||||
* GstControlSource:
|
||||
* @get_value: Function for returning a value for a given timestamp
|
||||
* @get_value_array: Function for returning a #GstValueArray for a given timestamp
|
||||
*
|
||||
* The instance structure of #GstControlSource.
|
||||
*/
|
||||
struct _GstControlSource {
|
||||
GObject parent;
|
||||
|
||||
/*< public >*/
|
||||
GstControlSourceGetValue get_value; /* Returns the value for a property at a given timestamp */
|
||||
GstControlSourceGetValueArray get_value_array; /* Returns values for a property in a given timespan */
|
||||
|
||||
/*< private >*/
|
||||
gboolean bound;
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/**
|
||||
* GstControlSourceClass:
|
||||
* @parent_class: Parent class
|
||||
* @bind: Class method for binding the #GstControlSource to a specific GParamSpec
|
||||
*
|
||||
* The class structure of #GstControlSource.
|
||||
*/
|
||||
|
||||
struct _GstControlSourceClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
GstControlSourceBind bind; /* Binds the GstControlSource to a specific GParamSpec */
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_control_source_get_type ();
|
||||
|
||||
/* Functions */
|
||||
|
||||
gboolean gst_control_source_get_value (GstControlSource *self, GstClockTime timestamp, GValue *value);
|
||||
gboolean gst_control_source_get_value_array (GstControlSource *self, GstClockTime timestamp, GstValueArray *value_array);
|
||||
gboolean gst_control_source_bind (GstControlSource *self, GParamSpec *pspec);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_CONTROL_SOURCE_H__ */
|
|
@ -148,7 +148,6 @@ gst_object_set_controller (GObject * object, GstController * controller)
|
|||
/**
|
||||
* gst_object_suggest_next_sync:
|
||||
* @object: the object that has controlled properties
|
||||
* @timestamp: the time that should be processed
|
||||
*
|
||||
* Convenience function for GObject
|
||||
*
|
||||
|
@ -192,6 +191,61 @@ gst_object_sync_values (GObject * object, GstClockTime timestamp)
|
|||
return (FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_object_set_control_source:
|
||||
* @object: the controller object
|
||||
* @property_name: name of the property for which the #GstControlSource should be set
|
||||
* @csource: the #GstControlSource that should be used for the property
|
||||
*
|
||||
* Sets the #GstControlSource for @property_name. If there already was a #GstControlSource
|
||||
* for this property it will be unreferenced.
|
||||
*
|
||||
* Returns: %FALSE if the given property isn't handled by the controller or the new #GstControlSource
|
||||
* couldn't be bound to the property, %TRUE if everything worked as expected.
|
||||
*
|
||||
* Since: 0.10.14
|
||||
*/
|
||||
gboolean
|
||||
gst_object_set_control_source (GObject * object, gchar * property_name,
|
||||
GstControlSource * csource)
|
||||
{
|
||||
GstController *ctrl = NULL;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
|
||||
g_return_val_if_fail (GST_IS_CONTROL_SOURCE (csource), FALSE);
|
||||
|
||||
if ((ctrl = g_object_get_qdata (object, __gst_controller_key))) {
|
||||
return gst_controller_set_control_source (ctrl, property_name, csource);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_object_get_control_source:
|
||||
* @object: the object
|
||||
* @property_name: name of the property for which the #GstControlSource should be get
|
||||
*
|
||||
* Gets the corresponding #GstControlSource for the property. This should be unreferenced
|
||||
* again after use.
|
||||
*
|
||||
* Returns: the #GstControlSource for @property_name or NULL if the property is not
|
||||
* controlled by this controller or no #GstControlSource was assigned yet.
|
||||
*
|
||||
* Since: 0.10.14
|
||||
*/
|
||||
GstControlSource *
|
||||
gst_object_get_control_source (GObject * object, gchar * property_name)
|
||||
{
|
||||
GstController *ctrl = NULL;
|
||||
|
||||
g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
|
||||
|
||||
if ((ctrl = g_object_get_qdata (object, __gst_controller_key))) {
|
||||
return gst_controller_get_control_source (ctrl, property_name);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_object_get_value_arrays:
|
||||
* @object: the object that has controlled properties
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include "gstcontrollerprivate.h"
|
||||
#include "gstcontroller.h"
|
||||
|
||||
#include "gstinterpolationcontrolsource.h"
|
||||
#include "gstinterpolationcontrolsourceprivate.h"
|
||||
|
||||
#define GST_CAT_DEFAULT gst_controller_debug
|
||||
GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
|
||||
|
@ -33,28 +34,29 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
|
|||
/* common helper */
|
||||
|
||||
/*
|
||||
* gst_controlled_property_find_control_point_node:
|
||||
* @prop: the controlled property to search in
|
||||
* gst_interpolation_control_source_find_control_point_node:
|
||||
* @self: the interpolation control source to search in
|
||||
* @timestamp: the search key
|
||||
*
|
||||
* Find last value before given timestamp in control point list.
|
||||
*
|
||||
* Returns: the found #GList node or %NULL
|
||||
*/
|
||||
GList *
|
||||
gst_controlled_property_find_control_point_node (GstControlledProperty * prop,
|
||||
GstClockTime timestamp)
|
||||
static GList *gst_interpolation_control_source_find_control_point_node
|
||||
(GstInterpolationControlSource * self, GstClockTime timestamp)
|
||||
{
|
||||
GList *prev_node = g_list_last (prop->values);
|
||||
GList *prev_node = g_list_last (self->priv->values);
|
||||
GList *node;
|
||||
GstControlPoint *cp;
|
||||
|
||||
node = prop->values;
|
||||
if (prop->last_requested_value) {
|
||||
GstControlPoint *last_cp = prop->last_requested_value->data;
|
||||
/* Check if we can start from the last requested value
|
||||
* to save some time */
|
||||
node = self->priv->values;
|
||||
if (self->priv->last_requested_value) {
|
||||
GstControlPoint *last_cp = self->priv->last_requested_value->data;
|
||||
|
||||
if (timestamp > last_cp->timestamp)
|
||||
node = prop->last_requested_value;
|
||||
node = self->priv->last_requested_value;
|
||||
}
|
||||
|
||||
/* iterate over timed value list */
|
||||
|
@ -68,286 +70,476 @@ gst_controlled_property_find_control_point_node (GstControlledProperty * prop,
|
|||
}
|
||||
}
|
||||
|
||||
/* If we have something to return save it as a
|
||||
* potential start position for the next search */
|
||||
if (prev_node)
|
||||
prop->last_requested_value = prev_node;
|
||||
self->priv->last_requested_value = prev_node;
|
||||
|
||||
return prev_node;
|
||||
}
|
||||
|
||||
/*
|
||||
* gst_interpolation_control_source_get_first_value:
|
||||
* @self: the interpolation control source to search in
|
||||
*
|
||||
* Find the first value and return it.
|
||||
*
|
||||
* Returns: the found #GValue or %NULL if there are none.
|
||||
*/
|
||||
static inline GValue *
|
||||
gst_interpolation_control_source_get_first_value (GstInterpolationControlSource
|
||||
* self)
|
||||
{
|
||||
if (self->priv->values && self->priv->nvalues > 0) {
|
||||
GstControlPoint *cp = self->priv->values->data;
|
||||
|
||||
return &cp->value;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* steps-like (no-)interpolation, default */
|
||||
/* just returns the value for the most recent key-frame */
|
||||
|
||||
static GValue *
|
||||
interpolate_none_get (GstControlledProperty * prop, GstClockTime timestamp)
|
||||
{
|
||||
GList *node;
|
||||
|
||||
if ((node =
|
||||
gst_controlled_property_find_control_point_node (prop, timestamp))) {
|
||||
GstControlPoint *cp = node->data;
|
||||
|
||||
return &cp->value;
|
||||
}
|
||||
return &prop->default_value;
|
||||
}
|
||||
|
||||
#define interpolate_none_get_boolean interpolate_none_get
|
||||
|
||||
#define DEFINE_NONE_GET(type) \
|
||||
static GValue * \
|
||||
interpolate_none_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
static inline GValue * \
|
||||
_interpolate_none_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp) \
|
||||
{ \
|
||||
GValue *ret; \
|
||||
GList *node; \
|
||||
\
|
||||
if ((node = \
|
||||
gst_controlled_property_find_control_point_node (prop, timestamp))) { \
|
||||
gst_interpolation_control_source_find_control_point_node (self, timestamp))) { \
|
||||
GstControlPoint *cp = node->data; \
|
||||
g##type ret = g_value_get_##type (&cp->value); \
|
||||
if (g_value_get_##type (&prop->min_value) > ret) \
|
||||
return &prop->min_value; \
|
||||
else if (g_value_get_##type (&prop->max_value) < ret) \
|
||||
return &prop->max_value; \
|
||||
return &cp->value; \
|
||||
g##type ret_val = g_value_get_##type (&cp->value); \
|
||||
\
|
||||
if (g_value_get_##type (&self->priv->minimum_value) > ret_val) \
|
||||
ret = &self->priv->minimum_value; \
|
||||
else if (g_value_get_##type (&self->priv->maximum_value) < ret_val) \
|
||||
ret = &self->priv->maximum_value; \
|
||||
else \
|
||||
ret = &cp->value; \
|
||||
} else { \
|
||||
ret = gst_interpolation_control_source_get_first_value (self); \
|
||||
} \
|
||||
return &prop->default_value; \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_none_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, GValue *value) \
|
||||
{ \
|
||||
GValue *ret; \
|
||||
g_mutex_lock (self->lock); \
|
||||
\
|
||||
ret = _interpolate_none_get_##type (self, timestamp); \
|
||||
if (!ret) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
g_value_copy (ret, value); \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_none_get_##type##_value_array (GstInterpolationControlSource *self, \
|
||||
GstClockTime timestamp, GstValueArray * value_array) \
|
||||
{ \
|
||||
gint i; \
|
||||
GstClockTime ts = timestamp; \
|
||||
g##type *values = (g##type *) value_array->values; \
|
||||
GValue *ret; \
|
||||
\
|
||||
g_mutex_lock (self->lock); \
|
||||
for(i = 0; i < value_array->nbsamples; i++) { \
|
||||
ret = _interpolate_none_get_##type (self, timestamp); \
|
||||
if (!ret) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
*values = g_value_get_##type (ret); \
|
||||
ts += value_array->sample_interval; \
|
||||
values++; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
|
||||
DEFINE_NONE_GET (int);
|
||||
DEFINE_NONE_GET (uint);
|
||||
DEFINE_NONE_GET (long);
|
||||
|
||||
DEFINE_NONE_GET (ulong);
|
||||
DEFINE_NONE_GET (int64);
|
||||
DEFINE_NONE_GET (uint64);
|
||||
DEFINE_NONE_GET (float);
|
||||
DEFINE_NONE_GET (double);
|
||||
|
||||
#define DEFINE_NONE_GET_VALUE_ARRAY(type) \
|
||||
static gboolean \
|
||||
interpolate_none_get_##type##_value_array (GstControlledProperty * prop, \
|
||||
GstClockTime timestamp, GstValueArray * value_array) \
|
||||
{ \
|
||||
gint i; \
|
||||
GstClockTime ts = timestamp; \
|
||||
g##type *values = (g##type *) value_array->values; \
|
||||
\
|
||||
for(i = 0; i < value_array->nbsamples; i++) { \
|
||||
*values = g_value_get_##type (interpolate_none_get_##type (prop,ts)); \
|
||||
ts += value_array->sample_interval; \
|
||||
values++; \
|
||||
} \
|
||||
return TRUE; \
|
||||
static inline GValue *
|
||||
_interpolate_none_get (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp)
|
||||
{
|
||||
GList *node;
|
||||
GValue *ret;
|
||||
|
||||
if ((node =
|
||||
gst_interpolation_control_source_find_control_point_node (self,
|
||||
timestamp))) {
|
||||
GstControlPoint *cp = node->data;
|
||||
|
||||
ret = &cp->value;
|
||||
} else {
|
||||
ret = gst_interpolation_control_source_get_first_value (self);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (int);
|
||||
static gboolean
|
||||
interpolate_none_get (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GValue * value)
|
||||
{
|
||||
GValue *ret;
|
||||
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (uint);
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (long);
|
||||
g_mutex_lock (self->lock);
|
||||
ret = _interpolate_none_get (self, timestamp);
|
||||
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (ulong);
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (float);
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (double);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DEFINE_NONE_GET_VALUE_ARRAY (boolean);
|
||||
g_value_copy (ret, value);
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_none_get_enum_value_array (GstControlledProperty * prop,
|
||||
interpolate_none_get_boolean_value_array (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gboolean *values = (gboolean *) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
ret = _interpolate_none_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = g_value_get_boolean (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_none_get_enum_value_array (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gint *values = (gint *) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
*values = g_value_get_enum (interpolate_none_get (prop, ts));
|
||||
ret = _interpolate_none_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = g_value_get_enum (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_none_get_string_value_array (GstControlledProperty * prop,
|
||||
interpolate_none_get_string_value_array (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gchar **values = (gchar **) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
*values = (gchar *) g_value_get_string (interpolate_none_get (prop, ts));
|
||||
ret = _interpolate_none_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = (gchar *) g_value_get_string (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstInterpolateMethod interpolate_none = {
|
||||
interpolate_none_get_int,
|
||||
interpolate_none_get_int_value_array,
|
||||
interpolate_none_get_uint,
|
||||
interpolate_none_get_uint_value_array,
|
||||
interpolate_none_get_long,
|
||||
interpolate_none_get_long_value_array,
|
||||
interpolate_none_get_ulong,
|
||||
interpolate_none_get_ulong_value_array,
|
||||
interpolate_none_get_float,
|
||||
interpolate_none_get_float_value_array,
|
||||
interpolate_none_get_double,
|
||||
interpolate_none_get_double_value_array,
|
||||
interpolate_none_get,
|
||||
interpolate_none_get_boolean_value_array,
|
||||
interpolate_none_get,
|
||||
interpolate_none_get_enum_value_array,
|
||||
interpolate_none_get,
|
||||
interpolate_none_get_string_value_array
|
||||
(GstControlSourceGetValue) interpolate_none_get_int,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_int_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_uint,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_uint_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_long,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_long_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_ulong,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_ulong_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_int64,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_int64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_uint64,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_uint64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_float,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_float_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get_double,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_double_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_boolean_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_enum_value_array,
|
||||
(GstControlSourceGetValue) interpolate_none_get,
|
||||
(GstControlSourceGetValueArray) interpolate_none_get_string_value_array
|
||||
};
|
||||
|
||||
/* returns the default value of the property, except for times with specific values */
|
||||
/* needed for one-shot events, such as notes and triggers */
|
||||
|
||||
static GValue *
|
||||
interpolate_trigger_get (GstControlledProperty * prop, GstClockTime timestamp)
|
||||
{
|
||||
GList *node;
|
||||
GstControlPoint *cp;
|
||||
|
||||
/* check if there is a value at the registered timestamp */
|
||||
if ((node =
|
||||
gst_controlled_property_find_control_point_node (prop, timestamp))) {
|
||||
cp = node->data;
|
||||
if (timestamp == cp->timestamp) {
|
||||
return &cp->value;
|
||||
}
|
||||
}
|
||||
|
||||
return &prop->default_value;
|
||||
}
|
||||
|
||||
#define interpolate_trigger_get_boolean interpolate_trigger_get
|
||||
|
||||
#define DEFINE_TRIGGER_GET(type) \
|
||||
static GValue * \
|
||||
interpolate_trigger_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
static inline GValue * \
|
||||
_interpolate_trigger_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp) \
|
||||
{ \
|
||||
GList *node; \
|
||||
GstControlPoint *cp; \
|
||||
\
|
||||
/* check if there is a value at the registered timestamp */ \
|
||||
if ((node = \
|
||||
gst_controlled_property_find_control_point_node (prop, timestamp))) { \
|
||||
gst_interpolation_control_source_find_control_point_node (self, timestamp))) { \
|
||||
cp = node->data; \
|
||||
if (timestamp == cp->timestamp) { \
|
||||
g##type ret = g_value_get_##type (&cp->value); \
|
||||
if (g_value_get_##type (&prop->min_value) > ret) \
|
||||
return &prop->min_value; \
|
||||
else if (g_value_get_##type (&prop->max_value) < ret) \
|
||||
return &prop->max_value; \
|
||||
return &cp->value; \
|
||||
if (g_value_get_##type (&self->priv->minimum_value) > ret) \
|
||||
return &self->priv->minimum_value; \
|
||||
else if (g_value_get_##type (&self->priv->maximum_value) < ret) \
|
||||
return &self->priv->maximum_value; \
|
||||
else \
|
||||
return &cp->value; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return &prop->default_value; \
|
||||
}
|
||||
|
||||
DEFINE_TRIGGER_GET (int);
|
||||
DEFINE_TRIGGER_GET (uint);
|
||||
DEFINE_TRIGGER_GET (long);
|
||||
|
||||
DEFINE_TRIGGER_GET (ulong);
|
||||
DEFINE_TRIGGER_GET (float);
|
||||
DEFINE_TRIGGER_GET (double);
|
||||
|
||||
#define DEFINE_TRIGGER_GET_VALUE_ARRAY(type) \
|
||||
if (self->priv->nvalues > 0) \
|
||||
return &self->priv->default_value; \
|
||||
else \
|
||||
return NULL; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_trigger_get_##type##_value_array (GstControlledProperty * prop, \
|
||||
interpolate_trigger_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, GValue *value) \
|
||||
{ \
|
||||
GValue *ret; \
|
||||
g_mutex_lock (self->lock); \
|
||||
ret = _interpolate_trigger_get_##type (self, timestamp); \
|
||||
if (!ret) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
g_value_copy (ret, value); \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_trigger_get_##type##_value_array (GstInterpolationControlSource *self, \
|
||||
GstClockTime timestamp, GstValueArray * value_array) \
|
||||
{ \
|
||||
gint i; \
|
||||
GstClockTime ts = timestamp; \
|
||||
g##type *values = (g##type *) value_array->values; \
|
||||
GValue *ret; \
|
||||
\
|
||||
g_mutex_lock (self->lock); \
|
||||
for(i = 0; i < value_array->nbsamples; i++) { \
|
||||
*values = g_value_get_##type (interpolate_trigger_get_##type (prop,ts)); \
|
||||
ret = _interpolate_trigger_get_##type (self, timestamp); \
|
||||
if (!ret) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
*values = g_value_get_##type (ret); \
|
||||
ts += value_array->sample_interval; \
|
||||
values++; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (int);
|
||||
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (uint);
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (long);
|
||||
DEFINE_TRIGGER_GET (int);
|
||||
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (ulong);
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (float);
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (double);
|
||||
DEFINE_TRIGGER_GET (uint);
|
||||
DEFINE_TRIGGER_GET (long);
|
||||
|
||||
DEFINE_TRIGGER_GET_VALUE_ARRAY (boolean);
|
||||
DEFINE_TRIGGER_GET (ulong);
|
||||
DEFINE_TRIGGER_GET (int64);
|
||||
DEFINE_TRIGGER_GET (uint64);
|
||||
DEFINE_TRIGGER_GET (float);
|
||||
DEFINE_TRIGGER_GET (double);
|
||||
|
||||
static inline GValue *
|
||||
_interpolate_trigger_get (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp)
|
||||
{
|
||||
GList *node;
|
||||
GstControlPoint *cp;
|
||||
|
||||
/* check if there is a value at the registered timestamp */
|
||||
if ((node =
|
||||
gst_interpolation_control_source_find_control_point_node (self,
|
||||
timestamp))) {
|
||||
cp = node->data;
|
||||
if (timestamp == cp->timestamp) {
|
||||
return &cp->value;
|
||||
}
|
||||
}
|
||||
if (self->priv->nvalues > 0)
|
||||
return &self->priv->default_value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_trigger_get_enum_value_array (GstControlledProperty * prop,
|
||||
interpolate_trigger_get (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GValue * value)
|
||||
{
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
ret = _interpolate_trigger_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
g_value_copy (ret, value);
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_trigger_get_boolean_value_array (GstInterpolationControlSource *
|
||||
self, GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gint *values = (gint *) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
ret = _interpolate_trigger_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = g_value_get_boolean (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_trigger_get_enum_value_array (GstInterpolationControlSource * self,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gint *values = (gint *) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
*values = g_value_get_enum (interpolate_trigger_get (prop, ts));
|
||||
ret = _interpolate_trigger_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = g_value_get_enum (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
interpolate_trigger_get_string_value_array (GstControlledProperty * prop,
|
||||
GstClockTime timestamp, GstValueArray * value_array)
|
||||
interpolate_trigger_get_string_value_array (GstInterpolationControlSource *
|
||||
self, GstClockTime timestamp, GstValueArray * value_array)
|
||||
{
|
||||
gint i;
|
||||
GstClockTime ts = timestamp;
|
||||
gchar **values = (gchar **) value_array->values;
|
||||
GValue *ret;
|
||||
|
||||
g_mutex_lock (self->lock);
|
||||
for (i = 0; i < value_array->nbsamples; i++) {
|
||||
*values = (gchar *) g_value_get_string (interpolate_trigger_get (prop, ts));
|
||||
ret = _interpolate_trigger_get (self, timestamp);
|
||||
if (!ret) {
|
||||
g_mutex_unlock (self->lock);
|
||||
return FALSE;
|
||||
}
|
||||
*values = (gchar *) g_value_get_string (ret);
|
||||
ts += value_array->sample_interval;
|
||||
values++;
|
||||
}
|
||||
g_mutex_unlock (self->lock);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GstInterpolateMethod interpolate_trigger = {
|
||||
interpolate_trigger_get_int,
|
||||
interpolate_trigger_get_int_value_array,
|
||||
interpolate_trigger_get_uint,
|
||||
interpolate_trigger_get_uint_value_array,
|
||||
interpolate_trigger_get_long,
|
||||
interpolate_trigger_get_long_value_array,
|
||||
interpolate_trigger_get_ulong,
|
||||
interpolate_trigger_get_ulong_value_array,
|
||||
interpolate_trigger_get_float,
|
||||
interpolate_trigger_get_float_value_array,
|
||||
interpolate_trigger_get_double,
|
||||
interpolate_trigger_get_double_value_array,
|
||||
interpolate_trigger_get,
|
||||
interpolate_trigger_get_boolean_value_array,
|
||||
interpolate_trigger_get,
|
||||
interpolate_trigger_get_enum_value_array,
|
||||
interpolate_trigger_get,
|
||||
interpolate_trigger_get_string_value_array
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_int,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_int_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_uint,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_uint_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_long,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_long_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_ulong,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_ulong_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_int64,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_int64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_uint64,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_uint64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_float,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_float_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get_double,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_double_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_boolean_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_enum_value_array,
|
||||
(GstControlSourceGetValue) interpolate_trigger_get,
|
||||
(GstControlSourceGetValueArray) interpolate_trigger_get_string_value_array
|
||||
};
|
||||
|
||||
/* linear interpolation */
|
||||
/* smoothes inbetween values */
|
||||
|
||||
#define DEFINE_LINEAR_GET(type) \
|
||||
static g##type \
|
||||
_interpolate_linear_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
static inline gboolean \
|
||||
_interpolate_linear_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, g##type *ret) \
|
||||
{ \
|
||||
GList *node; \
|
||||
g##type ret; \
|
||||
\
|
||||
if ((node = gst_controlled_property_find_control_point_node (prop, timestamp))) { \
|
||||
if ((node = gst_interpolation_control_source_find_control_point_node (self, timestamp))) { \
|
||||
GstControlPoint *cp1, *cp2; \
|
||||
\
|
||||
cp1 = node->data; \
|
||||
|
@ -361,38 +553,53 @@ _interpolate_linear_get_##type (GstControlledProperty * prop, GstClockTime times
|
|||
value2 = g_value_get_##type (&cp2->value); \
|
||||
slope = (gdouble) (value2 - value1) / gst_guint64_to_gdouble (cp2->timestamp - cp1->timestamp); \
|
||||
\
|
||||
ret = (g##type) (value1 + gst_guint64_to_gdouble (timestamp - cp1->timestamp) * slope); \
|
||||
*ret = (g##type) (value1 + gst_guint64_to_gdouble (timestamp - cp1->timestamp) * slope); \
|
||||
} \
|
||||
else { \
|
||||
ret = g_value_get_##type (&cp1->value); \
|
||||
*ret = g_value_get_##type (&cp1->value); \
|
||||
} \
|
||||
} else { \
|
||||
ret = g_value_get_##type (&prop->default_value); \
|
||||
GValue *first = gst_interpolation_control_source_get_first_value (self); \
|
||||
if (!first) \
|
||||
return FALSE; \
|
||||
*ret = g_value_get_##type (first); \
|
||||
} \
|
||||
ret = CLAMP (ret, g_value_get_##type (&prop->min_value), g_value_get_##type (&prop->max_value)); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static GValue * \
|
||||
interpolate_linear_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
{ \
|
||||
g_value_set_##type (&prop->result_value,_interpolate_linear_get_##type (prop,timestamp)); \
|
||||
return &prop->result_value; \
|
||||
*ret = CLAMP (*ret, g_value_get_##type (&self->priv->minimum_value), g_value_get_##type (&self->priv->maximum_value)); \
|
||||
return TRUE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_linear_get_##type##_value_array (GstControlledProperty * prop, \
|
||||
interpolate_linear_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, GValue *value) \
|
||||
{ \
|
||||
g##type ret; \
|
||||
g_mutex_lock (self->lock); \
|
||||
if (_interpolate_linear_get_##type (self, timestamp, &ret)) { \
|
||||
g_value_set_##type (value, ret); \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_linear_get_##type##_value_array (GstInterpolationControlSource *self, \
|
||||
GstClockTime timestamp, GstValueArray * value_array) \
|
||||
{ \
|
||||
gint i; \
|
||||
GstClockTime ts = timestamp; \
|
||||
g##type *values = (g##type *) value_array->values; \
|
||||
\
|
||||
g_mutex_lock (self->lock); \
|
||||
for(i = 0; i < value_array->nbsamples; i++) { \
|
||||
*values = _interpolate_linear_get_##type (prop, ts); \
|
||||
if (! _interpolate_linear_get_##type (self, ts, values)) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
ts += value_array->sample_interval; \
|
||||
values++; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
|
@ -402,28 +609,34 @@ DEFINE_LINEAR_GET (uint);
|
|||
DEFINE_LINEAR_GET (long);
|
||||
|
||||
DEFINE_LINEAR_GET (ulong);
|
||||
DEFINE_LINEAR_GET (int64);
|
||||
DEFINE_LINEAR_GET (uint64);
|
||||
DEFINE_LINEAR_GET (float);
|
||||
DEFINE_LINEAR_GET (double);
|
||||
|
||||
static GstInterpolateMethod interpolate_linear = {
|
||||
interpolate_linear_get_int,
|
||||
interpolate_linear_get_int_value_array,
|
||||
interpolate_linear_get_uint,
|
||||
interpolate_linear_get_uint_value_array,
|
||||
interpolate_linear_get_long,
|
||||
interpolate_linear_get_long_value_array,
|
||||
interpolate_linear_get_ulong,
|
||||
interpolate_linear_get_ulong_value_array,
|
||||
interpolate_linear_get_float,
|
||||
interpolate_linear_get_float_value_array,
|
||||
interpolate_linear_get_double,
|
||||
interpolate_linear_get_double_value_array,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
(GstControlSourceGetValue) interpolate_linear_get_int,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_int_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_uint,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_uint_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_long,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_long_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_ulong,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_ulong_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_int64,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_int64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_uint64,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_uint64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_float,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_float_value_array,
|
||||
(GstControlSourceGetValue) interpolate_linear_get_double,
|
||||
(GstControlSourceGetValueArray) interpolate_linear_get_double_value_array,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL
|
||||
};
|
||||
|
||||
/* square interpolation */
|
||||
|
@ -445,9 +658,9 @@ static GstInterpolateMethod interpolate_linear = {
|
|||
|
||||
#define DEFINE_CUBIC_GET(type) \
|
||||
static void \
|
||||
_interpolate_cubic_update_cache_##type (GstControlledProperty *prop) \
|
||||
_interpolate_cubic_update_cache_##type (GstInterpolationControlSource *self) \
|
||||
{ \
|
||||
gint i, n = prop->nvalues; \
|
||||
gint i, n = self->priv->nvalues; \
|
||||
gdouble *o = g_new0 (gdouble, n); \
|
||||
gdouble *p = g_new0 (gdouble, n); \
|
||||
gdouble *q = g_new0 (gdouble, n); \
|
||||
|
@ -462,7 +675,7 @@ _interpolate_cubic_update_cache_##type (GstControlledProperty *prop) \
|
|||
g##type y_prev, y, y_next; \
|
||||
\
|
||||
/* Fill linear system of equations */ \
|
||||
node = prop->values; \
|
||||
node = self->priv->values; \
|
||||
cp = node->data; \
|
||||
x = cp->timestamp; \
|
||||
y = g_value_get_##type (&cp->value); \
|
||||
|
@ -508,7 +721,7 @@ _interpolate_cubic_update_cache_##type (GstControlledProperty *prop) \
|
|||
\
|
||||
/* Save cache next in the GstControlPoint */ \
|
||||
\
|
||||
node = prop->values; \
|
||||
node = self->priv->values; \
|
||||
for (i = 0; i < n; i++) { \
|
||||
cp = node->data; \
|
||||
cp->cache.cubic.h = h[i]; \
|
||||
|
@ -525,21 +738,20 @@ _interpolate_cubic_update_cache_##type (GstControlledProperty *prop) \
|
|||
g_free (z); \
|
||||
} \
|
||||
\
|
||||
static g##type \
|
||||
_interpolate_cubic_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
static inline gboolean \
|
||||
_interpolate_cubic_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, g##type *ret) \
|
||||
{ \
|
||||
GList *node; \
|
||||
g##type ret; \
|
||||
\
|
||||
if (prop->nvalues <= 2) \
|
||||
return _interpolate_linear_get_##type (prop, timestamp); \
|
||||
if (self->priv->nvalues <= 2) \
|
||||
return _interpolate_linear_get_##type (self, timestamp, ret); \
|
||||
\
|
||||
if (!prop->valid_cache) { \
|
||||
_interpolate_cubic_update_cache_##type (prop); \
|
||||
prop->valid_cache = TRUE; \
|
||||
if (!self->priv->valid_cache) { \
|
||||
_interpolate_cubic_update_cache_##type (self); \
|
||||
self->priv->valid_cache = TRUE; \
|
||||
} \
|
||||
\
|
||||
if ((node = gst_controlled_property_find_control_point_node (prop, timestamp))) { \
|
||||
if ((node = gst_interpolation_control_source_find_control_point_node (self, timestamp))) { \
|
||||
GstControlPoint *cp1, *cp2; \
|
||||
\
|
||||
cp1 = node->data; \
|
||||
|
@ -560,38 +772,53 @@ _interpolate_cubic_get_##type (GstControlledProperty * prop, GstClockTime timest
|
|||
out += (value2 / cp1->cache.cubic.h - cp1->cache.cubic.h * cp2->cache.cubic.z) * diff1; \
|
||||
out += (value1 / cp1->cache.cubic.h - cp1->cache.cubic.h * cp1->cache.cubic.z) * diff2; \
|
||||
\
|
||||
ret = (g##type) out; \
|
||||
*ret = (g##type) out; \
|
||||
} \
|
||||
else { \
|
||||
ret = g_value_get_##type (&cp1->value); \
|
||||
*ret = g_value_get_##type (&cp1->value); \
|
||||
} \
|
||||
} else {\
|
||||
ret = g_value_get_##type (&prop->default_value); \
|
||||
} else { \
|
||||
GValue *first = gst_interpolation_control_source_get_first_value (self); \
|
||||
if (!first) \
|
||||
return FALSE; \
|
||||
*ret = g_value_get_##type (first); \
|
||||
} \
|
||||
ret = CLAMP (ret, g_value_get_##type (&prop->min_value), g_value_get_##type (&prop->max_value)); \
|
||||
return ret; \
|
||||
} \
|
||||
\
|
||||
static GValue * \
|
||||
interpolate_cubic_get_##type (GstControlledProperty * prop, GstClockTime timestamp) \
|
||||
{ \
|
||||
g_value_set_##type (&prop->result_value,_interpolate_cubic_get_##type (prop,timestamp)); \
|
||||
return &prop->result_value; \
|
||||
*ret = CLAMP (*ret, g_value_get_##type (&self->priv->minimum_value), g_value_get_##type (&self->priv->maximum_value)); \
|
||||
return TRUE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_cubic_get_##type##_value_array (GstControlledProperty * prop, \
|
||||
interpolate_cubic_get_##type (GstInterpolationControlSource *self, GstClockTime timestamp, GValue *value) \
|
||||
{ \
|
||||
g##type ret; \
|
||||
g_mutex_lock (self->lock); \
|
||||
if (_interpolate_cubic_get_##type (self, timestamp, &ret)) { \
|
||||
g_value_set_##type (value, ret); \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
\
|
||||
static gboolean \
|
||||
interpolate_cubic_get_##type##_value_array (GstInterpolationControlSource *self, \
|
||||
GstClockTime timestamp, GstValueArray * value_array) \
|
||||
{ \
|
||||
gint i; \
|
||||
GstClockTime ts = timestamp; \
|
||||
g##type *values = (g##type *) value_array->values; \
|
||||
\
|
||||
g_mutex_lock (self->lock); \
|
||||
for(i = 0; i < value_array->nbsamples; i++) { \
|
||||
*values = _interpolate_cubic_get_##type (prop, ts); \
|
||||
if (! _interpolate_cubic_get_##type (self, ts, values)) { \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return FALSE; \
|
||||
} \
|
||||
ts += value_array->sample_interval; \
|
||||
values++; \
|
||||
} \
|
||||
g_mutex_unlock (self->lock); \
|
||||
return TRUE; \
|
||||
}
|
||||
|
||||
|
@ -601,28 +828,34 @@ DEFINE_CUBIC_GET (uint);
|
|||
DEFINE_CUBIC_GET (long);
|
||||
|
||||
DEFINE_CUBIC_GET (ulong);
|
||||
DEFINE_CUBIC_GET (int64);
|
||||
DEFINE_CUBIC_GET (uint64);
|
||||
DEFINE_CUBIC_GET (float);
|
||||
DEFINE_CUBIC_GET (double);
|
||||
|
||||
static GstInterpolateMethod interpolate_cubic = {
|
||||
interpolate_cubic_get_int,
|
||||
interpolate_cubic_get_int_value_array,
|
||||
interpolate_cubic_get_uint,
|
||||
interpolate_cubic_get_uint_value_array,
|
||||
interpolate_cubic_get_long,
|
||||
interpolate_cubic_get_long_value_array,
|
||||
interpolate_cubic_get_ulong,
|
||||
interpolate_cubic_get_ulong_value_array,
|
||||
interpolate_cubic_get_float,
|
||||
interpolate_cubic_get_float_value_array,
|
||||
interpolate_cubic_get_double,
|
||||
interpolate_cubic_get_double_value_array,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_int,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_int_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_uint,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_uint_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_long,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_long_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_ulong,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_ulong_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_int64,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_int64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_uint64,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_uint64_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_float,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_float_value_array,
|
||||
(GstControlSourceGetValue) interpolate_cubic_get_double,
|
||||
(GstControlSourceGetValueArray) interpolate_cubic_get_double_value_array,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL,
|
||||
(GstControlSourceGetValue) NULL,
|
||||
(GstControlSourceGetValueArray) NULL
|
||||
};
|
||||
|
||||
|
||||
|
|
667
libs/gst/controller/gstinterpolationcontrolsource.c
Normal file
667
libs/gst/controller/gstinterpolationcontrolsource.c
Normal file
|
@ -0,0 +1,667 @@
|
|||
/* 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 *
|
||||
gst_interpolation_control_source_new ()
|
||||
{
|
||||
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;
|
||||
}
|
109
libs/gst/controller/gstinterpolationcontrolsource.h
Normal file
109
libs/gst/controller/gstinterpolationcontrolsource.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
*
|
||||
* gstinterpolationcontrolsource.h: 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.
|
||||
*/
|
||||
|
||||
#ifndef __GST_INTERPOLATION_CONTROL_SOURCE_H__
|
||||
#define __GST_INTERPOLATION_CONTROL_SOURCE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "gstcontrolsource.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GST_TYPE_INTERPOLATION_CONTROL_SOURCE \
|
||||
(gst_interpolation_control_source_get_type ())
|
||||
#define GST_INTERPOLATION_CONTROL_SOURCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_INTERPOLATION_CONTROL_SOURCE, GstInterpolationControlSource))
|
||||
#define GST_INTERPOLATION_CONTROL_SOURCE_CLASS(vtable) \
|
||||
(G_TYPE_CHECK_CLASS_CAST ((vtable), GST_TYPE_INTERPOLATION_CONTROL_SOURCE, GstInterpolationControlSourceClass))
|
||||
#define GST_IS_INTERPOLATION_CONTROL_SOURCE(obj) \
|
||||
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INTERPOLATION_CONTROL_SOURCE))
|
||||
#define GST_IS_INTERPOLATION_CONTROL_SOURCE_CLASS(vtable) \
|
||||
(G_TYPE_CHECK_CLASS_TYPE ((vtable), GST_TYPE_INTERPOLATION_CONTROL_SOURCE))
|
||||
#define GST_INTERPOLATION_CONTROL_SOURCE_GET_CLASS(inst) \
|
||||
(G_TYPE_INSTANCE_GET_CLASS ((inst), GST_TYPE_INTERPOLATION_CONTROL_SOURCE, GstInterpolationControlSourceClass))
|
||||
|
||||
typedef struct _GstInterpolationControlSource GstInterpolationControlSource;
|
||||
typedef struct _GstInterpolationControlSourceClass GstInterpolationControlSourceClass;
|
||||
typedef struct _GstInterpolationControlSourcePrivate GstInterpolationControlSourcePrivate;
|
||||
|
||||
/**
|
||||
* GstInterpolateMode:
|
||||
* @GST_INTERPOLATE_NONE: steps-like interpolation, default
|
||||
* @GST_INTERPOLATE_TRIGGER: returns the default value of the property,
|
||||
* except for times with specific values
|
||||
* @GST_INTERPOLATE_LINEAR: linear interpolation
|
||||
* @GST_INTERPOLATE_QUADRATIC: square interpolation (deprecated, maps to cubic)
|
||||
* @GST_INTERPOLATE_CUBIC: cubic interpolation
|
||||
* @GST_INTERPOLATE_USER: user-provided interpolation (not yet available)
|
||||
*
|
||||
* The various interpolation modes available.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GST_INTERPOLATE_NONE,
|
||||
GST_INTERPOLATE_TRIGGER,
|
||||
GST_INTERPOLATE_LINEAR,
|
||||
GST_INTERPOLATE_QUADRATIC,
|
||||
GST_INTERPOLATE_CUBIC,
|
||||
GST_INTERPOLATE_USER
|
||||
} GstInterpolateMode;
|
||||
|
||||
/**
|
||||
* GstInterpolationControlSource:
|
||||
*
|
||||
* The instance structure of #GstControlSource.
|
||||
*/
|
||||
struct _GstInterpolationControlSource {
|
||||
GstControlSource parent;
|
||||
|
||||
/* <private> */
|
||||
GMutex *lock;
|
||||
GstInterpolationControlSourcePrivate *priv;
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
struct _GstInterpolationControlSourceClass {
|
||||
GstControlSourceClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
GType gst_interpolation_control_source_get_type ();
|
||||
|
||||
/* Functions */
|
||||
|
||||
GstInterpolationControlSource *gst_interpolation_control_source_new ();
|
||||
gboolean gst_interpolation_control_source_set_interpolation_mode (GstInterpolationControlSource *self, GstInterpolateMode mode);
|
||||
gboolean gst_interpolation_control_source_set (GstInterpolationControlSource * self, GstClockTime timestamp, GValue * value);
|
||||
gboolean gst_interpolation_control_source_set_from_list (GstInterpolationControlSource * self, GSList * timedvalues);
|
||||
gboolean gst_interpolation_control_source_unset (GstInterpolationControlSource * self, GstClockTime timestamp);
|
||||
void gst_interpolation_control_source_unset_all (GstInterpolationControlSource *self);
|
||||
GList *gst_interpolation_control_source_get_all (GstInterpolationControlSource * self);
|
||||
gint gst_interpolation_control_source_get_count (GstInterpolationControlSource * self);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_INTERPOLATION_CONTROL_SOURCE_H__ */
|
100
libs/gst/controller/gstinterpolationcontrolsourceprivate.h
Normal file
100
libs/gst/controller/gstinterpolationcontrolsourceprivate.h
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
*
|
||||
* gstinterpolationcontrolsourceprivate.h: Private declarations for the
|
||||
* GstInterpolationControlSource
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__
|
||||
#define __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__
|
||||
|
||||
/**
|
||||
* GstInterpolateMethod:
|
||||
*
|
||||
* Function pointer structure to do user-defined interpolation methods
|
||||
*/
|
||||
typedef struct _GstInterpolateMethod
|
||||
{
|
||||
GstControlSourceGetValue get_int;
|
||||
GstControlSourceGetValueArray get_int_value_array;
|
||||
GstControlSourceGetValue get_uint;
|
||||
GstControlSourceGetValueArray get_uint_value_array;
|
||||
GstControlSourceGetValue get_long;
|
||||
GstControlSourceGetValueArray get_long_value_array;
|
||||
GstControlSourceGetValue get_ulong;
|
||||
GstControlSourceGetValueArray get_ulong_value_array;
|
||||
GstControlSourceGetValue get_int64;
|
||||
GstControlSourceGetValueArray get_int64_value_array;
|
||||
GstControlSourceGetValue get_uint64;
|
||||
GstControlSourceGetValueArray get_uint64_value_array;
|
||||
GstControlSourceGetValue get_float;
|
||||
GstControlSourceGetValueArray get_float_value_array;
|
||||
GstControlSourceGetValue get_double;
|
||||
GstControlSourceGetValueArray get_double_value_array;
|
||||
GstControlSourceGetValue get_boolean;
|
||||
GstControlSourceGetValueArray get_boolean_value_array;
|
||||
GstControlSourceGetValue get_enum;
|
||||
GstControlSourceGetValueArray get_enum_value_array;
|
||||
GstControlSourceGetValue get_string;
|
||||
GstControlSourceGetValueArray get_string_value_array;
|
||||
} GstInterpolateMethod;
|
||||
|
||||
/**
|
||||
* GstControlPoint:
|
||||
*
|
||||
* a internal structure for value+time and various temporary
|
||||
* values used for interpolation. This "inherits" from
|
||||
* GstTimedValue.
|
||||
*/
|
||||
typedef struct _GstControlPoint
|
||||
{
|
||||
/* fields from GstTimedValue. DO NOT CHANGE! */
|
||||
GstClockTime timestamp; /* timestamp of the value change */
|
||||
GValue value; /* the new value */
|
||||
|
||||
/* internal fields */
|
||||
|
||||
/* Caches for the interpolators */
|
||||
union {
|
||||
struct {
|
||||
gdouble h;
|
||||
gdouble z;
|
||||
} cubic;
|
||||
} cache;
|
||||
|
||||
} GstControlPoint;
|
||||
|
||||
struct _GstInterpolationControlSourcePrivate
|
||||
{
|
||||
GType type; /* type of the handled property */
|
||||
GType base; /* base-type of the handled property */
|
||||
|
||||
GValue default_value; /* default value for the handled property */
|
||||
GValue minimum_value; /* min value for the handled property */
|
||||
GValue maximum_value; /* max value for the handled property */
|
||||
GstInterpolateMode interpolation_mode;
|
||||
|
||||
GList *values; /* List of GstControlPoint */
|
||||
gint nvalues; /* Number of control points */
|
||||
GList *last_requested_value; /* last search result, can be used for incremental searches */
|
||||
gboolean valid_cache;
|
||||
};
|
||||
|
||||
#endif /* __GST_INTERPOLATION_CONTROL_SOURCE_PRIVATE_H__ */
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
#include <gst/controller/gstcontroller.h>
|
||||
#include <gst/controller/gstinterpolationcontrolsource.h>
|
||||
|
||||
gint
|
||||
main (gint argc, gchar ** argv)
|
||||
|
@ -17,6 +18,7 @@ main (gint argc, gchar ** argv)
|
|||
GstElement *src, *sink;
|
||||
GstElement *bin;
|
||||
GstController *ctrl;
|
||||
GstInterpolationControlSource *csource1, *csource2;
|
||||
GstClock *clock;
|
||||
GstClockID clock_id;
|
||||
GstClockReturn wait_ret;
|
||||
|
@ -46,23 +48,38 @@ main (gint argc, gchar ** argv)
|
|||
goto Error;
|
||||
}
|
||||
|
||||
/* set interpolation */
|
||||
gst_controller_set_interpolation_mode (ctrl, "volume",
|
||||
csource1 = gst_interpolation_control_source_new ();
|
||||
csource2 = gst_interpolation_control_source_new ();
|
||||
|
||||
gst_controller_set_control_source (ctrl, "volume",
|
||||
GST_CONTROL_SOURCE (csource1));
|
||||
gst_controller_set_control_source (ctrl, "freq",
|
||||
GST_CONTROL_SOURCE (csource2));
|
||||
|
||||
/* Set interpolation mode */
|
||||
|
||||
gst_interpolation_control_source_set_interpolation_mode (csource1,
|
||||
GST_INTERPOLATE_LINEAR);
|
||||
gst_interpolation_control_source_set_interpolation_mode (csource2,
|
||||
GST_INTERPOLATE_LINEAR);
|
||||
gst_controller_set_interpolation_mode (ctrl, "freq", GST_INTERPOLATE_LINEAR);
|
||||
|
||||
/* set control values */
|
||||
g_value_init (&vol, G_TYPE_DOUBLE);
|
||||
g_value_set_double (&vol, 0.0);
|
||||
gst_controller_set (ctrl, "volume", 0 * GST_SECOND, &vol);
|
||||
gst_interpolation_control_source_set (csource1, 0 * GST_SECOND, &vol);
|
||||
g_value_set_double (&vol, 1.0);
|
||||
gst_controller_set (ctrl, "volume", 5 * GST_SECOND, &vol);
|
||||
gst_interpolation_control_source_set (csource1, 5 * GST_SECOND, &vol);
|
||||
|
||||
g_object_unref (csource1);
|
||||
|
||||
g_value_set_double (&vol, 220.0);
|
||||
gst_controller_set (ctrl, "freq", 0 * GST_SECOND, &vol);
|
||||
gst_interpolation_control_source_set (csource2, 0 * GST_SECOND, &vol);
|
||||
g_value_set_double (&vol, 3520.0);
|
||||
gst_controller_set (ctrl, "freq", 3 * GST_SECOND, &vol);
|
||||
gst_interpolation_control_source_set (csource2, 3 * GST_SECOND, &vol);
|
||||
g_value_set_double (&vol, 440.0);
|
||||
gst_controller_set (ctrl, "freq", 6 * GST_SECOND, &vol);
|
||||
gst_interpolation_control_source_set (csource2, 6 * GST_SECOND, &vol);
|
||||
|
||||
g_object_unref (csource2);
|
||||
|
||||
clock_id =
|
||||
gst_clock_new_single_shot_id (clock,
|
||||
|
|
Loading…
Reference in a new issue