gstcaps.c \
gstchildproxy.c \
gstclock.c \
+ gstcontroller.c \
+ gstcontrolsource.c \
gstdatetime.c \
gstdebugutils.c \
gstelement.c \
gstchildproxy.h \
gstclock.h \
gstcompat.h \
+ gstcontroller.h \
+ gstcontrolsource.h \
gstdatetime.h \
gstdebugutils.h \
gstelement.h \
#include <gst/gstcaps.h>
#include <gst/gstchildproxy.h>
#include <gst/gstclock.h>
+#include <gst/gstcontroller.h>
+#include <gst/gstcontrolsource.h>
#include <gst/gstdatetime.h>
#include <gst/gstdebugutils.h>
#include <gst/gstelement.h>
#ifndef __GST_CLOCK_H__
#define __GST_CLOCK_H__
-#include <gst/gstobject.h>
-
G_BEGIN_DECLS
/* --- standard type macros --- */
gboolean woken_up;
};
+#include <gst/gstobject.h>
+
/**
* GstClockFlags:
* @GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC: clock can do a single sync timeout request
/* GStreamer
*
- * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
- * Copyright (C) 2007 Sebastian Dröge <slomo@circular-chaos.org>
+ * Copyright (C) 2005 Stefan Kost <ensonic at users dot sf dot net>
+ * 2007 Sebastian Dröge <slomo@circular-chaos.org>
+ * 2011 Stefan Sauer <ensonic at users dot sf dot net>
*
* gstcontroller.c: dynamic parameter control subsystem
*
* </orderedlist>
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "gst_private.h"
+#include "gstobject.h"
+#include "gstclock.h"
+#include "gstinfo.h"
#include "gstcontroller.h"
-#include "gstcontrollerprivate.h"
#include "gstcontrolsource.h"
-#include "gstinterpolationcontrolsource.h"
+#include "gstparamspecs.h"
#define GST_CAT_DEFAULT controller_debug
-GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
+GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
static GObjectClass *parent_class = NULL;
-GQuark priv_gst_controller_key;
/* property ids */
enum
/* helper */
/*
+ * GstControlledProperty:
+ */
+typedef struct _GstControlledProperty
+{
+ GParamSpec *pspec; /* GParamSpec for this property */
+ const gchar *name; /* name of the property */
+ GstControlSource *csource; /* GstControlSource for this property */
+ gboolean disabled;
+ GValue last_value;
+} GstControlledProperty;
+
+#define GST_CONTROLLED_PROPERTY(obj) ((GstControlledProperty *)(obj))
+
+/*
* gst_controlled_property_new:
* @object: for which object the controlled property should be set up
* @name: the name of the property to be controlled
* Returns: a freshly allocated structure or %NULL
*/
static GstControlledProperty *
-gst_controlled_property_new (GObject * object, const gchar * name)
+gst_controlled_property_new (GstObject * object, const gchar * name)
{
GstControlledProperty *prop = NULL;
GParamSpec *pspec;
/*
* gst_controller_add_property:
- * @self: the controller object or %NULL if none yet exists
- * @object: object to bind the property
+ * @self: the controller object
* @name: name of projecty in @object
- * @ref_existing: pointer to flag that tracks if we need to ref an existing
- * controller still
*
* Creates a new #GstControlledProperty if there is none for property @name yet.
- * In case this is the first controlled propery, it creates the controller as
- * well.
*
- * Returns: a newly created controller object or reffed existing one with the
- * given property bound.
+ * Returns: %TRUE if the property has been added to the controller
*/
-static GstController *
-gst_controller_add_property (GstController * self, GObject * object,
- const gchar * name, gboolean * ref_existing)
+static gboolean
+gst_controller_add_property (GstController * self, const gchar * name)
{
+ gboolean res = TRUE;
+
/* test if this property isn't yet controlled */
- if (!self || !gst_controller_find_controlled_property (self, name)) {
+ if (!gst_controller_find_controlled_property (self, name)) {
GstControlledProperty *prop;
- /* create GstControlledProperty and add to self->propeties List */
- if ((prop = gst_controlled_property_new (object, name))) {
- /* if we don't have a controller object yet, now is the time to create one */
- if (!self) {
- self = g_object_newv (GST_TYPE_CONTROLLER, 0, NULL);
- self->object = g_object_ref (object);
- /* store the controller */
- g_object_set_qdata (object, priv_gst_controller_key, self);
- *ref_existing = FALSE;
- } else {
- /* only want one single _ref(), even for multiple properties */
- if (*ref_existing) {
- g_object_ref (self);
- *ref_existing = FALSE;
- GST_INFO ("returning existing controller");
- }
- }
+ /* create GstControlledProperty and add to self->properties list */
+ if ((prop = gst_controlled_property_new (self->object, name)))
self->properties = g_list_prepend (self->properties, prop);
- }
+ else
+ res = FALSE;
} else {
GST_WARNING ("trying to control property %s again", name);
- if (*ref_existing) {
- g_object_ref (self);
- *ref_existing = FALSE;
- }
}
- return self;
+ return res;
+}
+
+/*
+ * gst_controller_remove_property:
+ * @self: the controller object
+ * @name: name of projecty in @object
+ *
+ * Removes a #GstControlledProperty for property @name.
+ *
+ * Returns: %TRUE if the property has been removed from the controller
+ */
+static gboolean
+gst_controller_remove_property (GstController * self, const gchar * name)
+{
+ gboolean res = TRUE;
+ GstControlledProperty *prop;
+
+ if ((prop = gst_controller_find_controlled_property (self, name))) {
+ self->properties = g_list_remove (self->properties, prop);
+ //g_signal_handler_disconnect (self->object, prop->notify_handler_id);
+ gst_controlled_property_free (prop);
+ } else {
+ res = FALSE;
+ }
+ return res;
}
/* methods */
* Returns: the new controller.
*/
GstController *
-gst_controller_new_valist (GObject * object, va_list var_args)
+gst_controller_new_valist (GstObject * object, va_list var_args)
{
GstController *self;
- gboolean ref_existing = TRUE;
gchar *name;
g_return_val_if_fail (G_IS_OBJECT (object), NULL);
GST_INFO ("setting up a new controller");
- self = g_object_get_qdata (object, priv_gst_controller_key);
+ self = g_object_newv (GST_TYPE_CONTROLLER, 0, NULL);
+ self->object = g_object_ref (object);
+
/* create GstControlledProperty for each property */
while ((name = va_arg (var_args, gchar *))) {
- self = gst_controller_add_property (self, object, name, &ref_existing);
+ gst_controller_add_property (self, name);
}
va_end (var_args);
- if (self)
- GST_INFO ("controller->ref_count=%d", G_OBJECT (self)->ref_count);
return self;
}
* Returns: the new controller.
*/
GstController *
-gst_controller_new_list (GObject * object, GList * list)
+gst_controller_new_list (GstObject * object, GList * list)
{
GstController *self;
- gboolean ref_existing = TRUE;
gchar *name;
GList *node;
GST_INFO ("setting up a new controller");
- self = g_object_get_qdata (object, priv_gst_controller_key);
+ self = g_object_newv (GST_TYPE_CONTROLLER, 0, NULL);
+ self->object = g_object_ref (object);
+
/* create GstControlledProperty for each property */
for (node = list; node; node = g_list_next (node)) {
name = (gchar *) node->data;
- self = gst_controller_add_property (self, object, name, &ref_existing);
+ gst_controller_add_property (self, name);
}
- if (self)
- GST_INFO ("controller->ref_count=%d", G_OBJECT (self)->ref_count);
return self;
}
* Returns: the new controller.
*/
GstController *
-gst_controller_new (GObject * object, ...)
+gst_controller_new (GstObject * object, ...)
{
GstController *self;
va_list var_args;
return self;
}
+// FIXME: docs
+gboolean
+gst_controller_add_properties_valist (GstController * self, va_list var_args)
+{
+ gboolean res = TRUE;
+ gchar *name;
+
+ g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
+
+ while ((name = va_arg (var_args, gchar *))) {
+ /* find the property in the properties list of the controller, remove and free it */
+ g_mutex_lock (self->lock);
+ res &= gst_controller_add_property (self, name);
+ g_mutex_unlock (self->lock);
+ }
+
+ return res;
+}
+
+// FIXME: docs
+gboolean
+gst_controller_add_properties_list (GstController * self, GList * list)
+{
+ gboolean res = TRUE;
+ gchar *name;
+ GList *tmp;
+
+ g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
+
+ for (tmp = list; tmp; tmp = g_list_next (tmp)) {
+ name = (gchar *) tmp->data;
+
+ /* find the property in the properties list of the controller, remove and free it */
+ g_mutex_lock (self->lock);
+ res &= gst_controller_add_property (self, name);
+ g_mutex_unlock (self->lock);
+ }
+
+ return res;
+}
+
+// FIXME: docs
+gboolean
+gst_controller_add_properties (GstController * self, ...)
+{
+ gboolean res;
+ va_list var_args;
+
+ g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
+
+ va_start (var_args, self);
+ res = gst_controller_add_properties_valist (self, var_args);
+ va_end (var_args);
+
+ return res;
+}
+
/**
* gst_controller_remove_properties_valist:
* @self: the controller object from which some properties should be removed
gst_controller_remove_properties_valist (GstController * self, va_list var_args)
{
gboolean res = TRUE;
- GstControlledProperty *prop;
gchar *name;
g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
while ((name = va_arg (var_args, gchar *))) {
/* find the property in the properties list of the controller, remove and free it */
g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, name))) {
- self->properties = g_list_remove (self->properties, prop);
- //g_signal_handler_disconnect (self->object, prop->notify_handler_id);
- gst_controlled_property_free (prop);
- } else {
- res = FALSE;
- }
+ res &= gst_controller_remove_property (self, name);
g_mutex_unlock (self->lock);
}
gst_controller_remove_properties_list (GstController * self, GList * list)
{
gboolean res = TRUE;
- GstControlledProperty *prop;
gchar *name;
GList *tmp;
/* find the property in the properties list of the controller, remove and free it */
g_mutex_lock (self->lock);
- if ((prop = gst_controller_find_controlled_property (self, name))) {
- self->properties = g_list_remove (self->properties, prop);
- //g_signal_handler_disconnect (self->object, prop->notify_handler_id);
- gst_controlled_property_free (prop);
- } else {
- res = FALSE;
- }
+ res &= gst_controller_remove_property (self, name);
g_mutex_unlock (self->lock);
}
val = NULL;
}
} else {
- g_object_get_property (self->object, prop->name, val);
+ g_object_get_property ((GObject *) self->object, prop->name, val);
}
}
g_mutex_unlock (self->lock);
GST_LOG ("sync_values");
g_mutex_lock (self->lock);
- g_object_freeze_notify (self->object);
+ g_object_freeze_notify ((GObject *) self->object);
/* go over the controlled properties of the controller */
for (node = self->properties; node; node = g_list_next (node)) {
prop = node->data;
*/
if ((timestamp < self->priv->last_sync) ||
gst_value_compare (&value, &prop->last_value) != GST_VALUE_EQUAL) {
- g_object_set_property (self->object, prop->name, &value);
+ g_object_set_property ((GObject *) self->object, prop->name, &value);
g_value_copy (&value, &prop->last_value);
}
} else {
ret &= val_ret;
}
self->priv->last_sync = timestamp;
- g_object_thaw_notify (self->object);
+ g_object_thaw_notify ((GObject *) self->object);
g_mutex_unlock (self->lock);
self->properties = NULL;
}
- /* remove controller from object's qdata list */
- g_object_set_qdata (self->object, priv_gst_controller_key, NULL);
g_object_unref (self->object);
self->object = NULL;
g_mutex_unlock (self->lock);
gobject_class->dispose = _gst_controller_dispose;
gobject_class->finalize = _gst_controller_finalize;
- priv_gst_controller_key = g_quark_from_static_string ("gst::controller");
-
/* register properties */
g_object_class_install_property (gobject_class, PROP_CONTROL_RATE,
g_param_spec_uint64 ("control-rate",
1, G_MAXUINT, 100 * GST_MSECOND,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- /* register signals */
- /* set defaults for overridable methods */
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "gstcontroller", 0,
+ "dynamic parameter control for gstreamer elements");
}
GType
/* GStreamer
*
- * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
+ * Copyright (C) 2005 Stefan Kost <ensonic at users dot sf dot net>
+ * 2011 Stefan Sauer <ensonic at users dot sf dot net>
*
- * gst-controller.h: dynamic parameter control subsystem
+ * gstcontroller.h: dynamic parameter control subsystem
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#ifndef __GST_CONTROLLER_H__
#define __GST_CONTROLLER_H__
+#include <gst/gstconfig.h>
+
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include <glib/gprintf.h>
-#include <gst/gst.h>
-#include <gst/controller/gstcontrolsource.h>
-#include <gst/controller/gstinterpolationcontrolsource.h>
+#include <gst/gstobject.h>
+#include <gst/gstcontrolsource.h>
G_BEGIN_DECLS
GList *properties; /* List of GstControlledProperty */
GMutex *lock; /* Secure property access, elements will access from threads */
- GObject *object; /* the object we control */
+ GstObject *object; /* the object we control */
/*< private >*/
GstControllerPrivate *priv;
/* GstController functions */
-GstController *gst_controller_new_valist (GObject * object, va_list var_args);
-GstController *gst_controller_new_list (GObject * object, GList *list);
-GstController *gst_controller_new (GObject * object, ...) G_GNUC_NULL_TERMINATED;
+GstController *gst_controller_new_valist (GstObject * object, va_list var_args);
+GstController *gst_controller_new_list (GstObject * object, GList *list);
+GstController *gst_controller_new (GstObject * object, ...) G_GNUC_NULL_TERMINATED;
+
+gboolean gst_controller_add_properties_valist (GstController * self, va_list var_args);
+gboolean gst_controller_add_properties_list (GstController * self, GList *list);
+gboolean gst_controller_add_properties (GstController * self, ...) G_GNUC_NULL_TERMINATED;
-gboolean gst_controller_remove_properties_valist (GstController * self,
- va_list var_args);
-gboolean gst_controller_remove_properties_list (GstController * self,
- GList *list);
+gboolean gst_controller_remove_properties_valist (GstController * self, va_list var_args);
+gboolean gst_controller_remove_properties_list (GstController * self, GList *list);
gboolean gst_controller_remove_properties (GstController * self, ...) G_GNUC_NULL_TERMINATED;
void gst_controller_set_disabled (GstController *self, gboolean disabled);
gboolean gst_controller_get_value_array (GstController * self,
GstClockTime timestamp, GstValueArray * value_array);
-/* GObject convenience functions */
-
-GstController *gst_object_control_properties (GObject * object, ...) G_GNUC_NULL_TERMINATED;
-gboolean gst_object_uncontrol_properties (GObject * object, ...) G_GNUC_NULL_TERMINATED;
-
-GstController *gst_object_get_controller (GObject * object);
-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, const gchar * property_name, GstControlSource *csource);
-GstControlSource * gst_object_get_control_source (GObject *object, const gchar * property_name);
-
-gboolean gst_object_get_value_arrays (GObject * object,
- GstClockTime timestamp, GSList * value_arrays);
-gboolean gst_object_get_value_array (GObject * object,
- GstClockTime timestamp, GstValueArray * value_array);
-
-GstClockTime gst_object_get_control_rate (GObject * object);
-void gst_object_set_control_rate (GObject * object, GstClockTime control_rate);
-
-/* lib init/done */
-
-gboolean gst_controller_init (int * argc, char ***argv);
-
G_END_DECLS
*
*/
+#include "gst_private.h"
+
#include <glib-object.h>
#include <gst/gst.h>
#ifndef __GST_CONTROL_SOURCE_H__
#define __GST_CONTROL_SOURCE_H__
+#include <gst/gstconfig.h>
+
#include <glib-object.h>
-#include <gst/gst.h>
+
+#include <gst/gstclock.h>
G_BEGIN_DECLS
#include "gstobject.h"
#include "gstmarshal.h"
+#include "gstcontroller.h"
#include "gstinfo.h"
#include "gstutils.h"
static void
gst_object_dispose (GObject * object)
{
+ GstObject *self = (GstObject *) object;
GstObject *parent;
GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
GST_OBJECT_PARENT (object) = NULL;
GST_OBJECT_UNLOCK (object);
+ if (self->ctrl) {
+ g_object_unref (self->ctrl);
+ self->ctrl = NULL;
+ }
+
((GObjectClass *) gst_object_parent_class)->dispose (object);
return;
return path;
}
+
+/* controller functions */
+
+/**
+ * gst_object_control_properties:
+ * @object: the object of which some properties should be controlled
+ * @...: %NULL terminated list of property names that should be controlled
+ *
+ * Creates a GstController that allows you to dynamically control one, or more,
+ * GObject properties. If the given GstObject already has a GstController,
+ * it adds the given properties to the existing
+ * controller and returns that controller.
+ *
+ * Returns: %TRUE if the properties have been made controllable.
+ */
+gboolean
+gst_object_control_properties (GstObject * object, ...)
+{
+ gboolean res = FALSE;
+ va_list var_args;
+
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+
+ va_start (var_args, object);
+ if (object->ctrl) {
+ object->ctrl = gst_controller_new_valist (object, var_args);
+ res = (object->ctrl != NULL);
+ } else {
+ res = gst_controller_add_properties_valist ((GstController *) object->ctrl,
+ var_args);
+ }
+ va_end (var_args);
+ return res;
+}
+
+/**
+ * gst_object_uncontrol_properties:
+ * @object: the object of which some properties should not be controlled anymore
+ * @...: %NULL terminated list of property names that should be controlled
+ *
+ * Removes the given element's properties from it's controller
+ *
+ * Returns: %FALSE if one of the given property names isn't handled by the
+ * controller, %TRUE otherwise
+ */
+gboolean
+gst_object_uncontrol_properties (GstObject * object, ...)
+{
+ gboolean res = FALSE;
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+
+ if (object->ctrl) {
+ va_list var_args;
+
+ va_start (var_args, object);
+ res = gst_controller_remove_properties_valist (
+ (GstController *) object->ctrl, var_args);
+ va_end (var_args);
+ }
+ return (res);
+}
+
+/**
+ * gst_object_suggest_next_sync:
+ * @object: the object that has controlled properties
+ *
+ * Convenience function for GObject
+ *
+ * Returns: same thing as gst_controller_suggest_next_sync()
+ */
+GstClockTime
+gst_object_suggest_next_sync (GstObject * object)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
+
+ if (object->ctrl)
+ return gst_controller_suggest_next_sync ((GstController *) object->ctrl);
+ return (GST_CLOCK_TIME_NONE);
+}
+
+/**
+ * gst_object_sync_values:
+ * @object: the object that has controlled properties
+ * @timestamp: the time that should be processed
+ *
+ * Convenience function for GObject
+ *
+ * Returns: same thing as gst_controller_sync_values()
+ */
+gboolean
+gst_object_sync_values (GstObject * object, GstClockTime timestamp)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+
+ if (object->ctrl)
+ return gst_controller_sync_values ((GstController *) object->ctrl,
+ timestamp);
+ /* this is no failure, its called by elements regardless if there is a
+ * controller assigned or not */
+ return (TRUE);
+}
+
+// FIXME: docs
+void
+gst_object_set_automation_disabled (GstObject * object, gboolean disabled)
+{
+ g_return_if_fail (GST_IS_OBJECT (object));
+
+ if (object->ctrl)
+ gst_controller_set_disabled (object->ctrl, disabled);
+}
+
+// FIXME: docs
+void
+gst_object_set_property_automation_disabled (GstObject * object,
+ const gchar * property_name, gboolean disabled)
+{
+ g_return_if_fail (GST_IS_OBJECT (object));
+ g_return_if_fail (property_name);
+
+ if (object->ctrl)
+ gst_controller_set_property_disabled ((GstController *) object->ctrl,
+ property_name, disabled);
+}
+
+/**
+ * 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.
+ */
+gboolean
+gst_object_set_control_source (GstObject * object, const gchar * property_name,
+ GstControlSource * csource)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (property_name, FALSE);
+ g_return_val_if_fail (GST_IS_CONTROL_SOURCE (csource), FALSE);
+
+ if (object->ctrl)
+ return gst_controller_set_control_source ((GstController *) object->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: (transfer full): the #GstControlSource for @property_name or NULL if
+ * the property is not controlled by this controller or no #GstControlSource was
+ * assigned yet.
+ */
+GstControlSource *
+gst_object_get_control_source (GstObject * object, const gchar * property_name)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (property_name, NULL);
+
+ if (object->ctrl)
+ return gst_controller_get_control_source ((GstController *) object->ctrl,
+ property_name);
+ return NULL;
+}
+
+// FIXME: docs
+GValue *
+gst_object_get_value (GstObject * object, const gchar * property_name,
+ GstClockTime timestamp)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
+ g_return_val_if_fail (property_name, NULL);
+
+ if (object->ctrl)
+ return gst_controller_get (object->ctrl, property_name, timestamp);
+ return NULL;
+}
+
+/**
+ * gst_object_get_value_arrays:
+ * @object: the object that has controlled properties
+ * @timestamp: the time that should be processed
+ * @value_arrays: list to return the control-values in
+ *
+ * Function to be able to get an array of values for one or more given element
+ * properties.
+ *
+ * If the GstValueArray->values array in list nodes is NULL, it will be created
+ * by the function.
+ * The type of the values in the array are the same as the property's type.
+ *
+ * The g_object_* functions are just convenience functions for GObject
+ *
+ * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
+ */
+gboolean
+gst_object_get_value_arrays (GstObject * object, GstClockTime timestamp,
+ GSList * value_arrays)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
+
+ if (object->ctrl)
+ return gst_controller_get_value_arrays ((GstController *) object->ctrl,
+ timestamp, value_arrays);
+ return (FALSE);
+}
+
+/**
+ * gst_object_get_value_array:
+ * @object: the object that has controlled properties
+ * @timestamp: the time that should be processed
+ * @value_array: array to put control-values in
+ *
+ * Function to be able to get an array of values for one element properties
+ *
+ * If the GstValueArray->values array is NULL, it will be created by the function.
+ * The type of the values in the array are the same as the property's type.
+ *
+ * The g_object_* functions are just convenience functions for GObject
+ *
+ * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
+ */
+gboolean
+gst_object_get_value_array (GstObject * object, GstClockTime timestamp,
+ GstValueArray * value_array)
+{
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+ g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
+
+ if (object->ctrl)
+ return gst_controller_get_value_array ((GstController *) object->ctrl,
+ timestamp, value_array);
+ return (FALSE);
+}
+
+/**
+ * gst_object_get_control_rate:
+ * @object: the object that has controlled properties
+ *
+ * Obtain the control-rate for this @object. Audio processing #GstElement
+ * objects will use this rate to sub-divide their processing loop and call
+ * gst_object_sync_values() inbetween. The length of the processing segment
+ * should be up to @control-rate nanoseconds.
+ *
+ * If the @object is not under property control, this will return
+ * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
+ *
+ * The control-rate is not expected to change if the element is in
+ * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
+ *
+ * Returns: the control rate in nanoseconds
+ */
+GstClockTime
+gst_object_get_control_rate (GstObject * object)
+{
+ GstClockTime control_rate = GST_CLOCK_TIME_NONE;
+
+ g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
+
+ if (object->ctrl)
+ g_object_get (object->ctrl, "control-rate", &control_rate, NULL);
+ return (control_rate);
+}
+
+/**
+ * gst_object_set_control_rate:
+ * @object: the object that has controlled properties
+ * @control_rate: the new control-rate in nanoseconds.
+ *
+ * Change the control-rate for this @object. Audio processing #GstElement
+ * objects will use this rate to sub-divide their processing loop and call
+ * gst_object_sync_values() inbetween. The length of the processing segment
+ * should be up to @control-rate nanoseconds.
+ *
+ * The control-rate should not change if the element is in %GST_STATE_PAUSED or
+ * %GST_STATE_PLAYING.
+ */
+void
+gst_object_set_control_rate (GstObject * object, GstClockTime control_rate)
+{
+ g_return_if_fail (GST_IS_OBJECT (object));
+
+ if (object->ctrl)
+ g_object_set (object->ctrl, "control-rate", control_rate, NULL);
+}
*/
#define GST_OBJECT_FLAG_UNSET(obj,flag) (GST_OBJECT_FLAGS (obj) &= ~(flag))
-
typedef struct _GstObject GstObject;
typedef struct _GstObjectClass GstObjectClass;
guint32 flags;
/*< private >*/
+ gpointer ctrl; /* time controlled properties */
gpointer _gst_reserved;
};
/* misc utils */
gboolean gst_object_check_uniqueness (GList *list, const gchar *name);
+/* controller functions */
+#include <gst/gstclock.h>
+#include <gst/gstcontrolsource.h>
+
+gboolean gst_object_control_properties (GstObject * object, ...) G_GNUC_NULL_TERMINATED;
+gboolean gst_object_uncontrol_properties (GstObject * object, ...) G_GNUC_NULL_TERMINATED;
+
+GstClockTime gst_object_suggest_next_sync (GstObject * object);
+gboolean gst_object_sync_values (GstObject * object, GstClockTime timestamp);
+
+void gst_object_set_automation_disabled (GstObject *object, gboolean disabled); // NEW was gst_controller_set_disabled
+void gst_object_set_property_automation_disabled (GstObject *object, const gchar * property_name, gboolean disabled); // NEW was gst_controller_set_property_disabled
+
+gboolean gst_object_set_control_source (GstObject *object, const gchar * property_name, GstControlSource *csource);
+GstControlSource * gst_object_get_control_source (GstObject *object, const gchar * property_name);
+
+GValue *gst_object_get_value (GstObject * object, const gchar * property_name, GstClockTime timestamp); // NEW was gst_controller_get
+gboolean gst_object_get_value_arrays (GstObject * object, GstClockTime timestamp, GSList * value_arrays);
+gboolean gst_object_get_value_array (GstObject * object, GstClockTime timestamp, GstValueArray * value_array);
+
+GstClockTime gst_object_get_control_rate (GstObject * object);
+void gst_object_set_control_rate (GstObject * object, GstClockTime control_rate);
+
G_END_DECLS
#endif /* __GST_OBJECT_H__ */
libgstcontroller_@GST_MAJORMINOR@_includedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/controller
libgstcontroller_@GST_MAJORMINOR@_include_HEADERS = \
- gstcontroller.h \
- gstcontrolsource.h \
gstinterpolationcontrolsource.h \
gstlfocontrolsource.h
noinst_HEADERS = \
- gstcontrollerprivate.h \
gstinterpolationcontrolsourceprivate.h \
gstlfocontrolsourceprivate.h
libgstcontroller_@GST_MAJORMINOR@_la_SOURCES = \
- lib.c \
- gstcontroller.c \
gstinterpolation.c \
- gsthelper.c \
- gstcontrolsource.c \
gstinterpolationcontrolsource.c \
gstlfocontrolsource.c
+++ /dev/null
-/* GStreamer
- *
- * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
- *
- * gstcontrollerprivate.h: dynamic parameter control subsystem
- *
- * 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_CONTROLLER_PRIVATE_H__
-#define __GST_CONTROLLER_PRIVATE_H__
-
-#include <glib.h>
-#include <glib-object.h>
-#include <gst/gst.h>
-
-#include <gst/controller/gstcontroller.h>
-#include <gst/controller/gstcontrolsource.h>
-
-G_BEGIN_DECLS
-
-/**
- * GstControlledProperty:
- */
-typedef struct _GstControlledProperty
-{
- GParamSpec *pspec; /* GParamSpec for this property */
- const gchar *name; /* name of the property */
- GstControlSource *csource; /* GstControlSource for this property */
- gboolean disabled;
- GValue last_value;
-} GstControlledProperty;
-
-#define GST_CONTROLLED_PROPERTY(obj) ((GstControlledProperty *)(obj))
-
-extern GQuark priv_gst_controller_key;
-
-G_END_DECLS
-
-#endif /* __GST_CONTROLLER_PRIVATE_H__ */
+++ /dev/null
-/* GStreamer
- *
- * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
- *
- * gsthelper.c: GObject convenience methods for using dynamic properties
- *
- * 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:gstcontrollergobject
- * @short_description: #GObject convenience methods for using dynamic properties
- * @see_also: #GstController
- *
- * These methods allow to use some #GstController functionality directly from
- * the #GObject class.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <stdarg.h>
-
-#include "gstcontrollerprivate.h"
-#include "gstcontroller.h"
-
-#define GST_CAT_DEFAULT controller_debug
-GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
-
-/**
- * gst_object_control_properties:
- * @object: the object of which some properties should be controlled
- * @...: %NULL terminated list of property names that should be controlled
- *
- * Convenience function for GObject
- *
- * Creates a GstController that allows you to dynamically control one, or more, GObject properties.
- * If the given GObject already has a GstController, it adds the given properties to the existing
- * controller and returns that controller.
- *
- * Returns: (transfer full): The GstController with which the user can control the given properties dynamically or NULL if
- * one or more of the given properties aren't available, or cannot be controlled, for the given element.
- */
-GstController *
-gst_object_control_properties (GObject * object, ...)
-{
- GstController *ctrl;
- va_list var_args;
-
- g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-
- va_start (var_args, object);
- ctrl = gst_controller_new_valist (object, var_args);
- va_end (var_args);
- return (ctrl);
-}
-
-/**
- * gst_object_uncontrol_properties:
- * @object: the object of which some properties should not be controlled anymore
- * @...: %NULL terminated list of property names that should be controlled
- *
- * Convenience function for GObject
- *
- * Removes the given element's properties from it's controller
- *
- * Returns: %FALSE if one of the given property names isn't handled by the
- * controller, %TRUE otherwise
- */
-gboolean
-gst_object_uncontrol_properties (GObject * object, ...)
-{
- gboolean res = FALSE;
- GstController *ctrl;
-
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- va_list var_args;
-
- va_start (var_args, object);
- res = gst_controller_remove_properties_valist (ctrl, var_args);
- va_end (var_args);
- }
- return (res);
-}
-
-/**
- * gst_object_get_controller:
- * @object: the object that has controlled properties
- *
- * Gets the controller for the given GObject
- *
- * Returns: (transfer full): the controller handling some of the given element's
- * properties, %NULL if no controller
- */
-/* FIXME 0.11: This should return a new reference */
-GstController *
-gst_object_get_controller (GObject * object)
-{
- g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-
- return (g_object_get_qdata (object, priv_gst_controller_key));
-}
-
-/**
- * gst_object_set_controller:
- * @object: the object that should get the controller
- * @controller: (transfer none): the controller object to plug in
- *
- * Sets the controller on the given GObject
- *
- * Returns: %FALSE if the GObject already has an controller, %TRUE otherwise
- */
-/* FIXME 0.11: This should increase the refcount before storing */
-gboolean
-gst_object_set_controller (GObject * object, GstController * controller)
-{
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (controller, FALSE);
-
- if (!g_object_get_qdata (object, priv_gst_controller_key)) {
- g_object_set_qdata (object, priv_gst_controller_key, controller);
- return (TRUE);
- }
- return (FALSE);
-}
-
- /**
- * gst_object_suggest_next_sync:
- * @object: the object that has controlled properties
- *
- * Convenience function for GObject
- *
- * Returns: same thing as gst_controller_suggest_next_sync()
- */
-GstClockTime
-gst_object_suggest_next_sync (GObject * object)
-{
- GstController *ctrl = NULL;
-
- g_return_val_if_fail (G_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- return gst_controller_suggest_next_sync (ctrl);
- }
- return (GST_CLOCK_TIME_NONE);
-}
-
-/**
- * gst_object_sync_values:
- * @object: the object that has controlled properties
- * @timestamp: the time that should be processed
- *
- * Convenience function for GObject
- *
- * Returns: same thing as gst_controller_sync_values()
- */
-gboolean
-gst_object_sync_values (GObject * object, GstClockTime timestamp)
-{
- GstController *ctrl = NULL;
-
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- return gst_controller_sync_values (ctrl, timestamp);
- }
- /* this is no failure, its called by elements regardless if there is a
- * controller assigned or not
- */
- return (TRUE);
-}
-
-/**
- * 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.
- */
-gboolean
-gst_object_set_control_source (GObject * object, const 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, priv_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: (transfer full): the #GstControlSource for @property_name or NULL if
- * the property is not controlled by this controller or no #GstControlSource was
- * assigned yet.
- */
-GstControlSource *
-gst_object_get_control_source (GObject * object, const gchar * property_name)
-{
- GstController *ctrl = NULL;
-
- g_return_val_if_fail (G_IS_OBJECT (object), NULL);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- return gst_controller_get_control_source (ctrl, property_name);
- }
- return NULL;
-}
-
-/**
- * gst_object_get_value_arrays:
- * @object: the object that has controlled properties
- * @timestamp: the time that should be processed
- * @value_arrays: list to return the control-values in
- *
- * Function to be able to get an array of values for one or more given element
- * properties.
- *
- * If the GstValueArray->values array in list nodes is NULL, it will be created
- * by the function.
- * The type of the values in the array are the same as the property's type.
- *
- * The g_object_* functions are just convenience functions for GObject
- *
- * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- */
-gboolean
-gst_object_get_value_arrays (GObject * object, GstClockTime timestamp,
- GSList * value_arrays)
-{
- GstController *ctrl;
-
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- return gst_controller_get_value_arrays (ctrl, timestamp, value_arrays);
- }
- return (FALSE);
-}
-
-/**
- * gst_object_get_value_array:
- * @object: the object that has controlled properties
- * @timestamp: the time that should be processed
- * @value_array: array to put control-values in
- *
- * Function to be able to get an array of values for one element properties
- *
- * If the GstValueArray->values array is NULL, it will be created by the function.
- * The type of the values in the array are the same as the property's type.
- *
- * The g_object_* functions are just convenience functions for GObject
- *
- * Returns: %TRUE if the given array(s) could be filled, %FALSE otherwise
- */
-gboolean
-gst_object_get_value_array (GObject * object, GstClockTime timestamp,
- GstValueArray * value_array)
-{
- GstController *ctrl;
-
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
- g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- return gst_controller_get_value_array (ctrl, timestamp, value_array);
- }
- return (FALSE);
-}
-
-/**
- * gst_object_get_control_rate:
- * @object: the object that has controlled properties
- *
- * Obtain the control-rate for this @object. Audio processing #GstElement
- * objects will use this rate to sub-divide their processing loop and call
- * gst_object_sync_values() inbetween. The length of the processing segment
- * should be up to @control-rate nanoseconds.
- *
- * If the @object is not under property control, this will return
- * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
- *
- * The control-rate is not expected to change if the element is in
- * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
- *
- * Returns: the control rate in nanoseconds
- */
-GstClockTime
-gst_object_get_control_rate (GObject * object)
-{
- GstController *ctrl;
- GstClockTime control_rate = GST_CLOCK_TIME_NONE;
-
- g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- g_object_get (ctrl, "control-rate", &control_rate, NULL);
- }
- return (control_rate);
-}
-
-/**
- * gst_object_set_control_rate:
- * @object: the object that has controlled properties
- * @control_rate: the new control-rate in nanoseconds.
- *
- * Change the control-rate for this @object. Audio processing #GstElement
- * objects will use this rate to sub-divide their processing loop and call
- * gst_object_sync_values() inbetween. The length of the processing segment
- * should be up to @control-rate nanoseconds.
- *
- * The control-rate should not change if the element is in %GST_STATE_PAUSED or
- * %GST_STATE_PLAYING.
- */
-void
-gst_object_set_control_rate (GObject * object, GstClockTime control_rate)
-{
- GstController *ctrl;
-
- g_return_if_fail (G_IS_OBJECT (object));
-
- if ((ctrl = g_object_get_qdata (object, priv_gst_controller_key))) {
- g_object_set (ctrl, "control-rate", control_rate, NULL);
- }
-}
#include <glib-object.h>
#include <gst/gst.h>
-#include "gstcontrolsource.h"
#include "gstinterpolationcontrolsource.h"
#include "gstinterpolationcontrolsourceprivate.h"
#define GST_CAT_DEFAULT controller_debug
-GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT);
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
-G_DEFINE_TYPE (GstInterpolationControlSource, gst_interpolation_control_source,
- GST_TYPE_CONTROL_SOURCE);
+#define _do_init \
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "interpolation control source", 0, "timeline value interpolating control source")
+
+G_DEFINE_TYPE_WITH_CODE (GstInterpolationControlSource,
+ gst_interpolation_control_source, GST_TYPE_CONTROL_SOURCE, _do_init);
static GObjectClass *parent_class = NULL;
#include <glib-object.h>
#include <gst/gst.h>
-#include <gst/controller/gstcontrolsource.h>
+#include <gst/gstcontrolsource.h>
G_BEGIN_DECLS
#include <glib-object.h>
#include <gst/gst.h>
+#include <gst/gstcontrolsource.h>
-#include "gstcontrolsource.h"
#include "gstlfocontrolsource.h"
#include "gstlfocontrolsourceprivate.h"
#include <gst/math-compat.h>
+#define GST_CAT_DEFAULT controller_debug
+GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
+
+
#define EMPTY(x) (x)
/* FIXME: as % in C is not the modulo operator we need here for
return (GType) gtype;
}
-G_DEFINE_TYPE (GstLFOControlSource, gst_lfo_control_source,
- GST_TYPE_CONTROL_SOURCE);
+#define _do_init \
+ GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "lfo control source", 0, "low frequency oscillator control source")
+
+G_DEFINE_TYPE_WITH_CODE (GstLFOControlSource, gst_lfo_control_source,
+ GST_TYPE_CONTROL_SOURCE, _do_init);
static GObjectClass *parent_class = NULL;
#include <glib-object.h>
#include <gst/gst.h>
-#include <gst/controller/gstcontrolsource.h>
-
G_BEGIN_DECLS
#define GST_TYPE_LFO_CONTROL_SOURCE \
+++ /dev/null
-/* GStreamer
- *
- * Copyright (C) <2005> Stefan Kost <ensonic at users dot sf dot net>
- *
- * lib.c: controller subsystem init
- *
- * 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.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include <gst/gst.h>
-#include <gst/controller/gstcontroller.h>
-
-/* library initialisation */
-
-#define GST_CAT_DEFAULT controller_debug
-GST_DEBUG_CATEGORY (GST_CAT_DEFAULT);
-
-/**
- * gst_controller_init:
- * @argc: pointer to the commandline argument count
- * @argv: pointer to the commandline argument values
- *
- * Initializes the use of the controller library. Suggested to be called right
- * after gst_init().
- *
- * Returns: the %TRUE for success.
- */
-gboolean
-gst_controller_init (int *argc, char ***argv)
-{
- static gboolean _gst_controller_initialized = FALSE;
-
- if (_gst_controller_initialized)
- return TRUE;
-
- _gst_controller_initialized = TRUE;
-
- GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "gstcontroller", 0,
- "dynamic parameter control for gstreamer elements");
-
- return TRUE;
-}