2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 * 2005 Wim Taymans <wim@fluendo.com>
6 * gstobject.c: Fundamental class used for all of GStreamer
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
26 * @short_description: Base class for the GStreamer object hierarchy
28 * #GstObject provides a root for the object hierarchy tree filed in by the
29 * GStreamer library. It is currently a thin wrapper on top of
30 * #GInitiallyUnowned. It is an abstract class that is not very usable on its own.
32 * #GstObject gives us basic refcounting, parenting functionality and locking.
33 * Most of the functions are just extended for special GStreamer needs and can be
34 * found under the same name in the base class of #GstObject which is #GObject
35 * (e.g. g_object_ref() becomes gst_object_ref()).
37 * Since #GstObject derives from #GInitiallyUnowned, it also inherits the
38 * floating reference. Be aware that functions such as gst_bin_add() and
39 * gst_element_add_pad() take ownership of the floating reference.
41 * In contrast to #GObject instances, #GstObject adds a name property. The functions
42 * gst_object_set_name() and gst_object_get_name() are used to set/get the name
46 * <title>controlled properties</title>
48 * Controlled properties offers a lightweight way to adjust gobject properties
49 * over stream-time. It works by using time-stamped value pairs that are queued
50 * for element-properties. At run-time the elements continuously pull value
51 * changes for the current stream-time.
53 * What needs to be changed in a #GstElement?
54 * Very little - it is just two steps to make a plugin controllable!
57 * mark gobject-properties paramspecs that make sense to be controlled,
58 * by GST_PARAM_CONTROLLABLE.
61 * when processing data (get, chain, loop function) at the beginning call
62 * gst_object_sync_values(element,timestamp).
63 * This will make the controller to update all gobject properties that are under
64 * control with the current values based on timestamp.
68 * What needs to be done in applications?
69 * Again it's not a lot to change.
72 * create a #GstControlSource.
73 * csource = gst_interpolation_control_source_new ();
74 * g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
77 * Attach the #GstControlSource on the controller to a property.
78 * gst_object_add_control_binding (object, gst_direct_control_binding_new (object, "prop1", csource));
81 * Set the control values
82 * gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,0 * GST_SECOND, value1);
83 * gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,1 * GST_SECOND, value2);
92 * Last reviewed on 2012-03-29 (0.11.3)
95 #include "gst_private.h"
96 #include "glib-compat-private.h"
98 #include "gstobject.h"
100 #include "gstcontrolbinding.h"
101 #include "gstcontrolsource.h"
103 #include "gstparamspecs.h"
104 #include "gstutils.h"
106 #ifndef GST_DISABLE_TRACE
107 #include "gsttrace.h"
108 static GstAllocTrace *_gst_object_trace;
111 #define DEBUG_REFCOUNT
113 /* Object signals and args */
134 /* maps type name quark => count */
135 static GData *object_name_counts = NULL;
137 G_LOCK_DEFINE_STATIC (object_name_mutex);
139 static void gst_object_set_property (GObject * object, guint prop_id,
140 const GValue * value, GParamSpec * pspec);
141 static void gst_object_get_property (GObject * object, guint prop_id,
142 GValue * value, GParamSpec * pspec);
144 static void gst_object_dispatch_properties_changed (GObject * object,
145 guint n_pspecs, GParamSpec ** pspecs);
147 static void gst_object_dispose (GObject * object);
148 static void gst_object_finalize (GObject * object);
150 static gboolean gst_object_set_name_default (GstObject * object);
152 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
154 static GParamSpec *properties[PROP_LAST];
156 G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_INITIALLY_UNOWNED);
159 gst_object_class_init (GstObjectClass * klass)
161 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
163 #ifndef GST_DISABLE_TRACE
165 _gst_alloc_trace_register (g_type_name (GST_TYPE_OBJECT), -2);
168 gobject_class->set_property = gst_object_set_property;
169 gobject_class->get_property = gst_object_get_property;
171 properties[PROP_NAME] =
172 g_param_spec_string ("name", "Name", "The name of the object", NULL,
173 G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
178 * The parent of the object. Please note, that when changing the 'parent'
179 * property, we don't emit #GObject::notify and #GstObject::deep-notify
180 * signals due to locking issues. In some cases one can use
181 * #GstBin::element-added or #GstBin::element-removed signals on the parent to
182 * achieve a similar effect.
184 properties[PROP_PARENT] =
185 g_param_spec_object ("parent", "Parent", "The parent of the object",
186 GST_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
188 g_object_class_install_properties (gobject_class, PROP_LAST, properties);
191 * GstObject::deep-notify:
192 * @gstobject: a #GstObject
193 * @prop_object: the object that originated the signal
194 * @prop: the property that changed
196 * The deep notify signal is used to be notified of property changes. It is
197 * typically attached to the toplevel bin to receive notifications from all
198 * the elements contained in that bin.
200 gst_object_signals[DEEP_NOTIFY] =
201 g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
202 G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
203 G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL,
204 NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_OBJECT,
207 klass->path_string_separator = "/";
209 /* see the comments at gst_object_dispatch_properties_changed */
210 gobject_class->dispatch_properties_changed
211 = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed);
213 gobject_class->dispose = gst_object_dispose;
214 gobject_class->finalize = gst_object_finalize;
218 gst_object_init (GstObject * object)
220 g_mutex_init (&object->lock);
221 object->parent = NULL;
223 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);
225 #ifndef GST_DISABLE_TRACE
226 _gst_alloc_trace_new (_gst_object_trace, object);
231 object->control_rate = 100 * GST_MSECOND;
232 object->last_sync = GST_CLOCK_TIME_NONE;
237 * @object: (type Gst.Object): a #GstObject to reference
239 * Increments the reference count on @object. This function
240 * does not take the lock on @object because it relies on
241 * atomic refcounting.
243 * This object returns the input parameter to ease writing
245 * result = gst_object_ref (object->parent);
247 * Returns: (transfer full) (type Gst.Object): A pointer to @object
250 gst_object_ref (gpointer object)
252 g_return_val_if_fail (object != NULL, NULL);
254 #ifdef DEBUG_REFCOUNT
255 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d", object,
256 ((GObject *) object)->ref_count, ((GObject *) object)->ref_count + 1);
258 g_object_ref (object);
265 * @object: (type Gst.Object): a #GstObject to unreference
267 * Decrements the reference count on @object. If reference count hits
268 * zero, destroy @object. This function does not take the lock
269 * on @object as it relies on atomic refcounting.
271 * The unref method should never be called with the LOCK held since
272 * this might deadlock the dispose function.
275 gst_object_unref (gpointer object)
277 g_return_if_fail (object != NULL);
278 g_return_if_fail (((GObject *) object)->ref_count > 0);
280 #ifdef DEBUG_REFCOUNT
281 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d", object,
282 ((GObject *) object)->ref_count, ((GObject *) object)->ref_count - 1);
284 g_object_unref (object);
288 * gst_object_ref_sink: (skip)
289 * @object: a #GstObject to sink
291 * Increase the reference count of @object, and possibly remove the floating
292 * reference, if @object has a floating reference.
294 * In other words, if the object is floating, then this call "assumes ownership"
295 * of the floating reference, converting it to a normal reference by clearing
296 * the floating flag while leaving the reference count unchanged. If the object
297 * is not floating, then this call adds a new normal reference increasing the
298 * reference count by one.
301 gst_object_ref_sink (gpointer object)
303 g_return_val_if_fail (object != NULL, NULL);
305 #ifdef DEBUG_REFCOUNT
306 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref_sink %d->%d",
307 object, ((GObject *) object)->ref_count,
308 ((GObject *) object)->ref_count + 1);
310 return g_object_ref_sink (object);
314 * gst_object_replace:
315 * @oldobj: (inout) (transfer full): pointer to a place of a #GstObject to
317 * @newobj: (transfer none): a new #GstObject
319 * Atomically modifies a pointer to point to a new object.
320 * The reference count of @oldobj is decreased and the reference count of
321 * @newobj is increased.
323 * Either @newobj and the value pointed to by @oldobj may be NULL.
325 * Returns: TRUE if @newobj was different from @oldobj
328 gst_object_replace (GstObject ** oldobj, GstObject * newobj)
332 g_return_val_if_fail (oldobj != NULL, FALSE);
334 #ifdef DEBUG_REFCOUNT
335 GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)",
336 *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)",
337 *oldobj ? G_OBJECT (*oldobj)->ref_count : 0,
338 newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)",
339 newobj ? G_OBJECT (newobj)->ref_count : 0);
342 oldptr = g_atomic_pointer_get ((gpointer *) oldobj);
344 if (G_UNLIKELY (oldptr == newobj))
348 gst_object_ref (newobj);
350 while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
351 oldobj, oldptr, newobj))) {
352 oldptr = g_atomic_pointer_get ((gpointer *) oldobj);
353 if (G_UNLIKELY (oldptr == newobj))
358 gst_object_unref (oldptr);
360 return oldptr != newobj;
363 /* dispose is called when the object has to release all links
364 * to other objects */
366 gst_object_dispose (GObject * object)
368 GstObject *self = (GstObject *) object;
371 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
373 GST_OBJECT_LOCK (object);
374 if ((parent = GST_OBJECT_PARENT (object)))
376 GST_OBJECT_PARENT (object) = NULL;
377 GST_OBJECT_UNLOCK (object);
379 if (self->control_bindings) {
382 for (node = self->control_bindings; node; node = g_list_next (node)) {
383 gst_object_unparent (node->data);
385 g_list_free (self->control_bindings);
386 self->control_bindings = NULL;
389 ((GObjectClass *) gst_object_parent_class)->dispose (object);
396 g_critical ("\nTrying to dispose object \"%s\", but it still has a "
397 "parent \"%s\".\nYou need to let the parent manage the "
398 "object instead of unreffing the object directly.\n",
399 GST_OBJECT_NAME (object), GST_OBJECT_NAME (parent));
400 GST_OBJECT_UNLOCK (object);
401 /* ref the object again to revive it in this error case */
402 gst_object_ref (object);
407 /* finalize is called when the object has to free its resources */
409 gst_object_finalize (GObject * object)
411 GstObject *gstobject = GST_OBJECT_CAST (object);
413 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "finalize");
415 g_signal_handlers_destroy (object);
417 g_free (gstobject->name);
418 g_mutex_clear (&gstobject->lock);
420 #ifndef GST_DISABLE_TRACE
421 _gst_alloc_trace_free (_gst_object_trace, object);
424 ((GObjectClass *) gst_object_parent_class)->finalize (object);
427 /* Changing a GObject property of a GstObject will result in "deep-notify"
428 * signals being emitted by the object itself, as well as in each parent
429 * object. This is so that an application can connect a listener to the
430 * top-level bin to catch property-change notifications for all contained
436 gst_object_dispatch_properties_changed (GObject * object,
437 guint n_pspecs, GParamSpec ** pspecs)
439 GstObject *gst_object, *parent, *old_parent;
441 #ifndef GST_DISABLE_GST_DEBUG
443 const gchar *debug_name;
446 /* do the standard dispatching */
448 gst_object_parent_class)->dispatch_properties_changed (object, n_pspecs,
451 gst_object = GST_OBJECT_CAST (object);
452 #ifndef GST_DISABLE_GST_DEBUG
453 if (G_UNLIKELY (_gst_debug_min >= GST_LEVEL_LOG)) {
454 name = gst_object_get_name (gst_object);
455 debug_name = GST_STR_NULL (name);
460 /* now let the parent dispatch those, too */
461 parent = gst_object_get_parent (gst_object);
463 for (i = 0; i < n_pspecs; i++) {
464 GST_CAT_LOG_OBJECT (GST_CAT_PROPERTIES, parent,
465 "deep notification from %s (%s)", debug_name, pspecs[i]->name);
467 g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY],
468 g_quark_from_string (pspecs[i]->name), gst_object, pspecs[i]);
472 parent = gst_object_get_parent (old_parent);
473 gst_object_unref (old_parent);
475 #ifndef GST_DISABLE_GST_DEBUG
481 * gst_object_default_deep_notify:
482 * @object: the #GObject that signalled the notify.
483 * @orig: a #GstObject that initiated the notify.
484 * @pspec: a #GParamSpec of the property.
485 * @excluded_props: (array zero-terminated=1) (element-type gchar*) (allow-none):
486 * a set of user-specified properties to exclude or NULL to show
489 * A default deep_notify signal callback for an object. The user data
490 * should contain a pointer to an array of strings that should be excluded
491 * from the notify. The default handler will print the new value of the property
494 * MT safe. This function grabs and releases @object's LOCK for getting its
498 gst_object_default_deep_notify (GObject * object, GstObject * orig,
499 GParamSpec * pspec, gchar ** excluded_props)
501 GValue value = { 0, }; /* the important thing is that value.type = 0 */
505 if (pspec->flags & G_PARAM_READABLE) {
506 /* let's not print these out for excluded properties... */
507 while (excluded_props != NULL && *excluded_props != NULL) {
508 if (strcmp (pspec->name, *excluded_props) == 0)
512 g_value_init (&value, pspec->value_type);
513 g_object_get_property (G_OBJECT (orig), pspec->name, &value);
515 if (G_VALUE_HOLDS_STRING (&value))
516 str = g_value_dup_string (&value);
518 str = gst_value_serialize (&value);
519 name = gst_object_get_path_string (orig);
520 g_print ("%s: %s = %s\n", name, pspec->name, str);
523 g_value_unset (&value);
525 name = gst_object_get_path_string (orig);
526 g_warning ("Parameter %s not readable in %s.", pspec->name, name);
532 gst_object_set_name_default (GstObject * object)
534 const gchar *type_name;
540 /* to ensure guaranteed uniqueness across threads, only one thread
541 * may ever assign a name */
542 G_LOCK (object_name_mutex);
544 if (!object_name_counts) {
545 g_datalist_init (&object_name_counts);
548 q = g_type_qname (G_OBJECT_TYPE (object));
549 count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q));
550 g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1));
552 G_UNLOCK (object_name_mutex);
554 /* GstFooSink -> foosink<N> */
555 type_name = g_quark_to_string (q);
556 if (strncmp (type_name, "Gst", 3) == 0)
558 /* give the 20th "queue" element and the first "queue2" different names */
559 l = strlen (type_name);
560 if (l > 0 && g_ascii_isdigit (type_name[l - 1])) {
561 name = g_strdup_printf ("%s-%d", type_name, count);
563 name = g_strdup_printf ("%s%d", type_name, count);
567 for (i = 0; i < l; i++)
568 name[i] = g_ascii_tolower (name[i]);
570 GST_OBJECT_LOCK (object);
571 if (G_UNLIKELY (object->parent != NULL))
574 g_free (object->name);
577 GST_OBJECT_UNLOCK (object);
584 GST_WARNING ("parented objects can't be renamed");
585 GST_OBJECT_UNLOCK (object);
591 * gst_object_set_name:
592 * @object: a #GstObject
593 * @name: new name of object
595 * Sets the name of @object, or gives @object a guaranteed unique
596 * name (if @name is NULL).
597 * This function makes a copy of the provided name, so the caller
598 * retains ownership of the name it sent.
600 * Returns: TRUE if the name could be set. Since Objects that have
601 * a parent cannot be renamed, this function returns FALSE in those
604 * MT safe. This function grabs and releases @object's LOCK.
607 gst_object_set_name (GstObject * object, const gchar * name)
611 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
613 GST_OBJECT_LOCK (object);
615 /* parented objects cannot be renamed */
616 if (G_UNLIKELY (object->parent != NULL))
620 g_free (object->name);
621 object->name = g_strdup (name);
622 GST_OBJECT_UNLOCK (object);
625 GST_OBJECT_UNLOCK (object);
626 result = gst_object_set_name_default (object);
628 /* FIXME-0.11: this misses a g_object_notify (object, "name"); unless called
629 * from gst_object_set_property.
630 * Ideally remove such custom setters (or make it static).
637 GST_WARNING ("parented objects can't be renamed");
638 GST_OBJECT_UNLOCK (object);
644 * gst_object_get_name:
645 * @object: a #GstObject
647 * Returns a copy of the name of @object.
648 * Caller should g_free() the return value after usage.
649 * For a nameless object, this returns NULL, which you can safely g_free()
652 * Free-function: g_free
654 * Returns: (transfer full): the name of @object. g_free() after usage.
656 * MT safe. This function grabs and releases @object's LOCK.
659 gst_object_get_name (GstObject * object)
661 gchar *result = NULL;
663 g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
665 GST_OBJECT_LOCK (object);
666 result = g_strdup (object->name);
667 GST_OBJECT_UNLOCK (object);
673 * gst_object_set_parent:
674 * @object: a #GstObject
675 * @parent: new parent of object
677 * Sets the parent of @object to @parent. The object's reference count will
678 * be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
680 * Returns: TRUE if @parent could be set or FALSE when @object
681 * already had a parent or @object and @parent are the same.
683 * MT safe. Grabs and releases @object's LOCK.
686 gst_object_set_parent (GstObject * object, GstObject * parent)
688 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
689 g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
690 g_return_val_if_fail (object != parent, FALSE);
692 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
693 "set parent (ref and sink)");
695 GST_OBJECT_LOCK (object);
696 if (G_UNLIKELY (object->parent != NULL))
699 object->parent = parent;
700 gst_object_ref_sink (object);
701 GST_OBJECT_UNLOCK (object);
703 /* FIXME-2.0: this does not work, the deep notify takes the lock from the
704 * parent object and deadlocks when the parent holds its lock when calling
705 * this function (like _element_add_pad()), we need to use a GRecMutex
706 * for locking the parent instead.
708 /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
715 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
716 "set parent failed, object already had a parent");
717 GST_OBJECT_UNLOCK (object);
723 * gst_object_get_parent:
724 * @object: a #GstObject
726 * Returns the parent of @object. This function increases the refcount
727 * of the parent object so you should gst_object_unref() it after usage.
729 * Returns: (transfer full): parent of @object, this can be NULL if @object
730 * has no parent. unref after usage.
732 * MT safe. Grabs and releases @object's LOCK.
735 gst_object_get_parent (GstObject * object)
737 GstObject *result = NULL;
739 g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
741 GST_OBJECT_LOCK (object);
742 result = object->parent;
743 if (G_LIKELY (result))
744 gst_object_ref (result);
745 GST_OBJECT_UNLOCK (object);
751 * gst_object_unparent:
752 * @object: a #GstObject to unparent
754 * Clear the parent of @object, removing the associated reference.
755 * This function decreases the refcount of @object.
757 * MT safe. Grabs and releases @object's lock.
760 gst_object_unparent (GstObject * object)
764 g_return_if_fail (GST_IS_OBJECT (object));
766 GST_OBJECT_LOCK (object);
767 parent = object->parent;
769 if (G_LIKELY (parent != NULL)) {
770 GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "unparent");
771 object->parent = NULL;
772 GST_OBJECT_UNLOCK (object);
774 /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
776 gst_object_unref (object);
778 GST_OBJECT_UNLOCK (object);
783 * gst_object_has_ancestor:
784 * @object: a #GstObject to check
785 * @ancestor: a #GstObject to check as ancestor
787 * Check if @object has an ancestor @ancestor somewhere up in
788 * the hierarchy. One can e.g. check if a #GstElement is inside a #GstPipeline.
790 * Returns: TRUE if @ancestor is an ancestor of @object.
792 * MT safe. Grabs and releases @object's locks.
795 gst_object_has_ancestor (GstObject * object, GstObject * ancestor)
797 GstObject *parent, *tmp;
799 if (!ancestor || !object)
802 parent = gst_object_ref (object);
804 if (parent == ancestor) {
805 gst_object_unref (parent);
809 tmp = gst_object_get_parent (parent);
810 gst_object_unref (parent);
818 * gst_object_check_uniqueness:
819 * @list: (transfer none) (element-type Gst.Object): a list of #GstObject to
821 * @name: the name to search for
823 * Checks to see if there is any object named @name in @list. This function
824 * does not do any locking of any kind. You might want to protect the
825 * provided list with the lock of the owner of the list. This function
826 * will lock each #GstObject in the list to compare the name, so be
827 * careful when passing a list with a locked object.
829 * Returns: TRUE if a #GstObject named @name does not appear in @list,
832 * MT safe. Grabs and releases the LOCK of each object in the list.
835 gst_object_check_uniqueness (GList * list, const gchar * name)
837 gboolean result = TRUE;
839 g_return_val_if_fail (name != NULL, FALSE);
841 for (; list; list = g_list_next (list)) {
845 child = GST_OBJECT_CAST (list->data);
847 GST_OBJECT_LOCK (child);
848 eq = strcmp (GST_OBJECT_NAME (child), name) == 0;
849 GST_OBJECT_UNLOCK (child);
851 if (G_UNLIKELY (eq)) {
861 gst_object_set_property (GObject * object, guint prop_id,
862 const GValue * value, GParamSpec * pspec)
864 GstObject *gstobject;
866 gstobject = GST_OBJECT_CAST (object);
870 gst_object_set_name (gstobject, g_value_get_string (value));
873 gst_object_set_parent (gstobject, g_value_get_object (value));
876 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
882 gst_object_get_property (GObject * object, guint prop_id,
883 GValue * value, GParamSpec * pspec)
885 GstObject *gstobject;
887 gstobject = GST_OBJECT_CAST (object);
891 g_value_take_string (value, gst_object_get_name (gstobject));
894 g_value_take_object (value, gst_object_get_parent (gstobject));
897 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
903 * gst_object_get_path_string:
904 * @object: a #GstObject
906 * Generates a string describing the path of @object in
907 * the object hierarchy. Only useful (or used) for debugging.
909 * Free-function: g_free
911 * Returns: (transfer full): a string describing the path of @object. You must
912 * g_free() the string after usage.
914 * MT safe. Grabs and releases the #GstObject's LOCK for all objects
918 gst_object_get_path_string (GstObject * object)
923 gchar *prevpath, *path;
924 const gchar *typename;
926 const gchar *separator;
928 /* ref object before adding to list */
929 gst_object_ref (object);
930 parentage = g_slist_prepend (NULL, object);
932 path = g_strdup ("");
934 /* first walk the object hierarchy to build a list of the parents,
935 * be careful here with refcounting. */
937 if (GST_IS_OBJECT (object)) {
938 parent = gst_object_get_parent (object);
939 /* add parents to list, refcount remains increased while
940 * we handle the object */
942 parentage = g_slist_prepend (parentage, parent);
947 } while (object != NULL);
949 /* then walk the parent list and print them out. we need to
950 * decrease the refcounting on each element after we handled
952 for (parents = parentage; parents; parents = g_slist_next (parents)) {
953 if (G_IS_OBJECT (parents->data)) {
954 typename = G_OBJECT_TYPE_NAME (parents->data);
958 if (GST_IS_OBJECT (parents->data)) {
959 GstObject *item = GST_OBJECT_CAST (parents->data);
960 GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item);
961 gchar *objname = gst_object_get_name (item);
963 component = g_strdup_printf ("%s:%s", typename, objname);
964 separator = oclass->path_string_separator;
966 gst_object_unref (item);
970 component = g_strdup_printf ("%s:%p", typename, parents->data);
972 component = g_strdup_printf ("%p", parents->data);
978 path = g_strjoin (separator, prevpath, component, NULL);
983 g_slist_free (parentage);
988 /* controller helper functions */
991 * gst_object_find_control_binding:
992 * @self: the gobject to search for a property in
993 * @name: the gobject property name to look for
995 * Searches the list of properties under control.
997 * Returns: a #GstControlBinding or %NULL if the property is not being
1000 static GstControlBinding *
1001 gst_object_find_control_binding (GstObject * self, const gchar * name)
1003 GstControlBinding *binding;
1006 for (node = self->control_bindings; node; node = g_list_next (node)) {
1007 binding = node->data;
1008 /* FIXME: eventually use GQuark to speed it up */
1009 if (!strcmp (binding->name, name)) {
1010 GST_DEBUG_OBJECT (self, "found control binding for property '%s'", name);
1014 GST_DEBUG_OBJECT (self, "controller does not manage property '%s'", name);
1019 /* controller functions */
1022 * gst_object_suggest_next_sync:
1023 * @object: the object that has controlled properties
1025 * Returns a suggestion for timestamps where buffers should be split
1026 * to get best controller results.
1028 * Returns: Returns the suggested timestamp or %GST_CLOCK_TIME_NONE
1029 * if no control-rate was set.
1032 gst_object_suggest_next_sync (GstObject * object)
1036 g_return_val_if_fail (GST_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
1037 g_return_val_if_fail (object->control_rate != GST_CLOCK_TIME_NONE,
1038 GST_CLOCK_TIME_NONE);
1040 GST_OBJECT_LOCK (object);
1042 /* TODO: Implement more logic, depending on interpolation mode and control
1044 * FIXME: we need playback direction
1046 ret = object->last_sync + object->control_rate;
1048 GST_OBJECT_UNLOCK (object);
1054 * gst_object_sync_values:
1055 * @object: the object that has controlled properties
1056 * @timestamp: the time that should be processed
1058 * Sets the properties of the object, according to the #GstControlSources that
1059 * (maybe) handle them and for the given timestamp.
1061 * If this function fails, it is most likely the application developers fault.
1062 * Most probably the control sources are not setup correctly.
1064 * Returns: %TRUE if the controller values could be applied to the object
1065 * properties, %FALSE otherwise
1068 gst_object_sync_values (GstObject * object, GstClockTime timestamp)
1071 gboolean ret = TRUE;
1073 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1074 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1076 GST_LOG_OBJECT (object, "sync_values");
1077 if (!object->control_bindings)
1080 /* FIXME: this deadlocks */
1081 /* GST_OBJECT_LOCK (object); */
1082 g_object_freeze_notify ((GObject *) object);
1083 for (node = object->control_bindings; node; node = g_list_next (node)) {
1084 ret &= gst_control_binding_sync_values ((GstControlBinding *) node->data,
1085 object, timestamp, object->last_sync);
1087 object->last_sync = timestamp;
1088 g_object_thaw_notify ((GObject *) object);
1089 /* GST_OBJECT_UNLOCK (object); */
1096 * gst_object_has_active_control_bindings:
1097 * @object: the object that has controlled properties
1099 * Check if the @object has an active controlled properties.
1101 * Returns: %TRUE if the object has active controlled properties
1104 gst_object_has_active_control_bindings (GstObject * object)
1106 gboolean res = FALSE;
1109 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1111 GST_OBJECT_LOCK (object);
1112 for (node = object->control_bindings; node; node = g_list_next (node)) {
1113 res |= !gst_control_binding_is_disabled ((GstControlBinding *) node->data);
1115 GST_OBJECT_UNLOCK (object);
1120 * gst_object_set_control_bindings_disabled:
1121 * @object: the object that has controlled properties
1122 * @disabled: boolean that specifies whether to disable the controller
1125 * This function is used to disable all controlled properties of the @object for
1126 * some time, i.e. gst_object_sync_values() will do nothing.
1129 gst_object_set_control_bindings_disabled (GstObject * object, gboolean disabled)
1133 g_return_if_fail (GST_IS_OBJECT (object));
1135 GST_OBJECT_LOCK (object);
1136 for (node = object->control_bindings; node; node = g_list_next (node)) {
1137 gst_control_binding_set_disabled ((GstControlBinding *) node->data,
1140 GST_OBJECT_UNLOCK (object);
1144 * gst_object_set_control_binding_disabled:
1145 * @object: the object that has controlled properties
1146 * @property_name: property to disable
1147 * @disabled: boolean that specifies whether to disable the controller
1150 * This function is used to disable the control bindings on a property for
1151 * some time, i.e. gst_object_sync_values() will do nothing for the
1155 gst_object_set_control_binding_disabled (GstObject * object,
1156 const gchar * property_name, gboolean disabled)
1158 GstControlBinding *binding;
1160 g_return_if_fail (GST_IS_OBJECT (object));
1161 g_return_if_fail (property_name);
1163 GST_OBJECT_LOCK (object);
1164 if ((binding = gst_object_find_control_binding (object, property_name))) {
1165 gst_control_binding_set_disabled (binding, disabled);
1167 GST_OBJECT_UNLOCK (object);
1172 * gst_object_add_control_binding:
1173 * @object: the controller object
1174 * @binding: (transfer full): the #GstControlBinding that should be used
1176 * Attach the #GstControlBinding to the object. If there already was a
1177 * #GstControlBinding for this property it will be replaced.
1179 * The @object will take ownership of the @binding.
1181 * Returns: %FALSE if the given @binding has not been setup for this object or
1182 * has been setup for a non suitable property, %TRUE otherwise.
1185 gst_object_add_control_binding (GstObject * object, GstControlBinding * binding)
1187 GstControlBinding *old;
1189 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1190 g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
1191 g_return_val_if_fail (binding->pspec, FALSE);
1193 GST_OBJECT_LOCK (object);
1194 if ((old = gst_object_find_control_binding (object, binding->name))) {
1195 GST_DEBUG_OBJECT (object, "controlled property %s removed", old->name);
1196 object->control_bindings = g_list_remove (object->control_bindings, old);
1197 gst_object_unparent (GST_OBJECT_CAST (old));
1199 object->control_bindings = g_list_prepend (object->control_bindings, binding);
1200 gst_object_set_parent (GST_OBJECT_CAST (binding), object);
1201 GST_DEBUG_OBJECT (object, "controlled property %s added", binding->name);
1202 GST_OBJECT_UNLOCK (object);
1208 * gst_object_get_control_binding:
1209 * @object: the object
1210 * @property_name: name of the property
1212 * Gets the corresponding #GstControlBinding for the property. This should be
1213 * unreferenced again after use.
1215 * Returns: (transfer full): the #GstControlBinding for @property_name or %NULL if
1216 * the property is not controlled.
1219 gst_object_get_control_binding (GstObject * object, const gchar * property_name)
1221 GstControlBinding *binding;
1223 g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
1224 g_return_val_if_fail (property_name, NULL);
1226 GST_OBJECT_LOCK (object);
1227 if ((binding = gst_object_find_control_binding (object, property_name))) {
1228 gst_object_ref (binding);
1230 GST_OBJECT_UNLOCK (object);
1236 * gst_object_remove_control_binding:
1237 * @object: the object
1238 * @binding: the binding
1240 * Removes the corresponding #GstControlBinding. If it was the
1241 * last ref of the binding, it will be disposed.
1243 * Returns: %TRUE if the binding could be removed.
1246 gst_object_remove_control_binding (GstObject * object,
1247 GstControlBinding * binding)
1250 gboolean ret = FALSE;
1252 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1253 g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
1255 GST_OBJECT_LOCK (object);
1256 if ((node = g_list_find (object->control_bindings, binding))) {
1257 GST_DEBUG_OBJECT (object, "controlled property %s removed", binding->name);
1258 object->control_bindings =
1259 g_list_delete_link (object->control_bindings, node);
1260 gst_object_unparent (GST_OBJECT_CAST (binding));
1263 GST_OBJECT_UNLOCK (object);
1269 * gst_object_get_value:
1270 * @object: the object that has controlled properties
1271 * @property_name: the name of the property to get
1272 * @timestamp: the time the control-change should be read from
1274 * Gets the value for the given controlled property at the requested time.
1276 * Returns: the GValue of the property at the given time, or %NULL if the
1277 * property isn't controlled.
1280 gst_object_get_value (GstObject * object, const gchar * property_name,
1281 GstClockTime timestamp)
1283 GstControlBinding *binding;
1286 g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
1287 g_return_val_if_fail (property_name, NULL);
1288 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);
1290 GST_OBJECT_LOCK (object);
1291 if ((binding = gst_object_find_control_binding (object, property_name))) {
1292 val = gst_control_binding_get_value (binding, timestamp);
1294 GST_OBJECT_UNLOCK (object);
1300 * gst_object_get_value_array:
1301 * @object: the object that has controlled properties
1302 * @property_name: the name of the property to get
1303 * @timestamp: the time that should be processed
1304 * @interval: the time spacing between subsequent values
1305 * @n_values: the number of values
1306 * @values: array to put control-values in
1308 * Gets a number of values for the given controlled property starting at the
1309 * requested time. The array @values need to hold enough space for @n_values of
1310 * the same type as the objects property's type.
1312 * This function is useful if one wants to e.g. draw a graph of the control
1313 * curve or apply a control curve sample by sample.
1315 * The values are unboxed and ready to be used. The similar function
1316 * gst_object_get_g_value_array() returns the array as #GValues and is
1317 * better suites for bindings.
1319 * Returns: %TRUE if the given array could be filled, %FALSE otherwise
1322 gst_object_get_value_array (GstObject * object, const gchar * property_name,
1323 GstClockTime timestamp, GstClockTime interval, guint n_values,
1326 gboolean res = FALSE;
1327 GstControlBinding *binding;
1329 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1330 g_return_val_if_fail (property_name, FALSE);
1331 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1332 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
1333 g_return_val_if_fail (values, FALSE);
1335 GST_OBJECT_LOCK (object);
1336 if ((binding = gst_object_find_control_binding (object, property_name))) {
1337 res = gst_control_binding_get_value_array (binding, timestamp, interval,
1340 GST_OBJECT_UNLOCK (object);
1345 * gst_object_get_g_value_array:
1346 * @object: the object that has controlled properties
1347 * @property_name: the name of the property to get
1348 * @timestamp: the time that should be processed
1349 * @interval: the time spacing between subsequent values
1350 * @n_values: the number of values
1351 * @values: array to put control-values in
1353 * Gets a number of #GValues for the given controlled property starting at the
1354 * requested time. The array @values need to hold enough space for @n_values of
1357 * This function is useful if one wants to e.g. draw a graph of the control
1358 * curve or apply a control curve sample by sample.
1360 * Returns: %TRUE if the given array could be filled, %FALSE otherwise
1363 gst_object_get_g_value_array (GstObject * object, const gchar * property_name,
1364 GstClockTime timestamp, GstClockTime interval, guint n_values,
1367 gboolean res = FALSE;
1368 GstControlBinding *binding;
1370 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1371 g_return_val_if_fail (property_name, FALSE);
1372 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1373 g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
1374 g_return_val_if_fail (values, FALSE);
1376 GST_OBJECT_LOCK (object);
1377 if ((binding = gst_object_find_control_binding (object, property_name))) {
1378 res = gst_control_binding_get_g_value_array (binding, timestamp, interval,
1381 GST_OBJECT_UNLOCK (object);
1387 * gst_object_get_control_rate:
1388 * @object: the object that has controlled properties
1390 * Obtain the control-rate for this @object. Audio processing #GstElement
1391 * objects will use this rate to sub-divide their processing loop and call
1392 * gst_object_sync_values() inbetween. The length of the processing segment
1393 * should be up to @control-rate nanoseconds.
1395 * If the @object is not under property control, this will return
1396 * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
1398 * The control-rate is not expected to change if the element is in
1399 * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
1401 * Returns: the control rate in nanoseconds
1404 gst_object_get_control_rate (GstObject * object)
1406 g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1408 return object->control_rate;
1412 * gst_object_set_control_rate:
1413 * @object: the object that has controlled properties
1414 * @control_rate: the new control-rate in nanoseconds.
1416 * Change the control-rate for this @object. Audio processing #GstElement
1417 * objects will use this rate to sub-divide their processing loop and call
1418 * gst_object_sync_values() inbetween. The length of the processing segment
1419 * should be up to @control-rate nanoseconds.
1421 * The control-rate should not change if the element is in %GST_STATE_PAUSED or
1422 * %GST_STATE_PLAYING.
1425 gst_object_set_control_rate (GstObject * object, GstClockTime control_rate)
1427 g_return_if_fail (GST_IS_OBJECT (object));
1429 object->control_rate = control_rate;