object: Fix broken sentence structure in docs
[platform/upstream/gstreamer.git] / gst / gstobject.c
1 /* GStreamer
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>
5  *
6  * gstobject.c: Fundamental class used for all of GStreamer
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 /**
25  * SECTION:gstobject
26  * @short_description: Base class for the GStreamer object hierarchy
27  *
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.
31  *
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()).
36  *
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.
40  *
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
43  * of the object.
44  *
45  * <refsect2>
46  * <title>controlled properties</title>
47  * <para>
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.
52  *
53  * What needs to be changed in a #GstElement?
54  * Very little - it is just two steps to make a plugin controllable!
55  * <orderedlist>
56  *   <listitem><para>
57  *     mark gobject-properties paramspecs that make sense to be controlled,
58  *     by GST_PARAM_CONTROLLABLE.
59  *   </para></listitem>
60  *   <listitem><para>
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 update all GObject properties that are
64  *     under its control with the current values based on the timestamp.
65  *   </para></listitem>
66  * </orderedlist>
67  *
68  * What needs to be done in applications?
69  * Again it's not a lot to change.
70  * <orderedlist>
71  *   <listitem><para>
72  *     create a #GstControlSource.
73  *     csource = gst_interpolation_control_source_new ();
74  *     g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
75  *   </para></listitem>
76  *   <listitem><para>
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));
79  *   </para></listitem>
80  *   <listitem><para>
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);
84  *   </para></listitem>
85  *   <listitem><para>
86  *     start your pipeline
87  *   </para></listitem>
88  * </orderedlist>
89  * </para>
90  * </refsect2>
91  */
92
93 #include "gst_private.h"
94 #include "glib-compat-private.h"
95
96 #include "gstobject.h"
97 #include "gstclock.h"
98 #include "gstcontrolbinding.h"
99 #include "gstcontrolsource.h"
100 #include "gstinfo.h"
101 #include "gstparamspecs.h"
102 #include "gstutils.h"
103
104 #define DEBUG_REFCOUNT
105
106 /* Object signals and args */
107 enum
108 {
109   DEEP_NOTIFY,
110   LAST_SIGNAL
111 };
112
113 enum
114 {
115   PROP_0,
116   PROP_NAME,
117   PROP_PARENT,
118   PROP_LAST
119 };
120
121 enum
122 {
123   SO_OBJECT_LOADED,
124   SO_LAST_SIGNAL
125 };
126
127 /* maps type name quark => count */
128 static GData *object_name_counts = NULL;
129
130 G_LOCK_DEFINE_STATIC (object_name_mutex);
131
132 static void gst_object_set_property (GObject * object, guint prop_id,
133     const GValue * value, GParamSpec * pspec);
134 static void gst_object_get_property (GObject * object, guint prop_id,
135     GValue * value, GParamSpec * pspec);
136
137 static void gst_object_dispatch_properties_changed (GObject * object,
138     guint n_pspecs, GParamSpec ** pspecs);
139
140 static void gst_object_dispose (GObject * object);
141 static void gst_object_finalize (GObject * object);
142
143 static gboolean gst_object_set_name_default (GstObject * object);
144
145 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
146
147 static GParamSpec *properties[PROP_LAST];
148
149 G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_INITIALLY_UNOWNED);
150
151 static void
152 gst_object_constructed (GObject * object)
153 {
154   GST_TRACER_OBJECT_CREATED (GST_OBJECT_CAST (object));
155
156   ((GObjectClass *) gst_object_parent_class)->constructed (object);
157 }
158
159 static void
160 gst_object_class_init (GstObjectClass * klass)
161 {
162   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
163
164   gobject_class->set_property = gst_object_set_property;
165   gobject_class->get_property = gst_object_get_property;
166
167   properties[PROP_NAME] =
168       g_param_spec_string ("name", "Name", "The name of the object", NULL,
169       G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
170
171   /**
172    * GstObject:parent:
173    *
174    * The parent of the object. Please note, that when changing the 'parent'
175    * property, we don't emit #GObject::notify and #GstObject::deep-notify
176    * signals due to locking issues. In some cases one can use
177    * #GstBin::element-added or #GstBin::element-removed signals on the parent to
178    * achieve a similar effect.
179    */
180   properties[PROP_PARENT] =
181       g_param_spec_object ("parent", "Parent", "The parent of the object",
182       GST_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
183
184   g_object_class_install_properties (gobject_class, PROP_LAST, properties);
185
186   /**
187    * GstObject::deep-notify:
188    * @gstobject: a #GstObject
189    * @prop_object: the object that originated the signal
190    * @prop: the property that changed
191    *
192    * The deep notify signal is used to be notified of property changes. It is
193    * typically attached to the toplevel bin to receive notifications from all
194    * the elements contained in that bin.
195    */
196   gst_object_signals[DEEP_NOTIFY] =
197       g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
198       G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
199       G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL,
200       NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_OBJECT,
201       G_TYPE_PARAM);
202
203   klass->path_string_separator = "/";
204
205   /* see the comments at gst_object_dispatch_properties_changed */
206   gobject_class->dispatch_properties_changed
207       = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed);
208
209   gobject_class->constructed = gst_object_constructed;
210   gobject_class->dispose = gst_object_dispose;
211   gobject_class->finalize = gst_object_finalize;
212 }
213
214 static void
215 gst_object_init (GstObject * object)
216 {
217   g_mutex_init (&object->lock);
218   object->parent = NULL;
219   object->name = NULL;
220   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);
221
222   object->flags = 0;
223
224   object->control_rate = 100 * GST_MSECOND;
225   object->last_sync = GST_CLOCK_TIME_NONE;
226 }
227
228 /**
229  * gst_object_ref:
230  * @object: (type Gst.Object): a #GstObject to reference
231  *
232  * Increments the reference count on @object. This function
233  * does not take the lock on @object because it relies on
234  * atomic refcounting.
235  *
236  * This object returns the input parameter to ease writing
237  * constructs like :
238  *  result = gst_object_ref (object->parent);
239  *
240  * Returns: (transfer full) (type Gst.Object): A pointer to @object
241  */
242 gpointer
243 gst_object_ref (gpointer object)
244 {
245   g_return_val_if_fail (object != NULL, NULL);
246
247 #ifdef DEBUG_REFCOUNT
248   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d", object,
249       ((GObject *) object)->ref_count, ((GObject *) object)->ref_count + 1);
250 #endif
251   g_object_ref (object);
252
253   return object;
254 }
255
256 /**
257  * gst_object_unref:
258  * @object: (type Gst.Object): a #GstObject to unreference
259  *
260  * Decrements the reference count on @object.  If reference count hits
261  * zero, destroy @object. This function does not take the lock
262  * on @object as it relies on atomic refcounting.
263  *
264  * The unref method should never be called with the LOCK held since
265  * this might deadlock the dispose function.
266  */
267 void
268 gst_object_unref (gpointer object)
269 {
270   g_return_if_fail (object != NULL);
271   g_return_if_fail (((GObject *) object)->ref_count > 0);
272
273 #ifdef DEBUG_REFCOUNT
274   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d", object,
275       ((GObject *) object)->ref_count, ((GObject *) object)->ref_count - 1);
276 #endif
277   g_object_unref (object);
278 }
279
280 /**
281  * gst_object_ref_sink: (skip)
282  * @object: a #GstObject to sink
283  *
284  * Increase the reference count of @object, and possibly remove the floating
285  * reference, if @object has a floating reference.
286  *
287  * In other words, if the object is floating, then this call "assumes ownership"
288  * of the floating reference, converting it to a normal reference by clearing
289  * the floating flag while leaving the reference count unchanged. If the object
290  * is not floating, then this call adds a new normal reference increasing the
291  * reference count by one.
292  */
293 gpointer
294 gst_object_ref_sink (gpointer object)
295 {
296   g_return_val_if_fail (object != NULL, NULL);
297
298 #ifdef DEBUG_REFCOUNT
299   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref_sink %d->%d",
300       object, ((GObject *) object)->ref_count,
301       ((GObject *) object)->ref_count + 1);
302 #endif
303   return g_object_ref_sink (object);
304 }
305
306 /**
307  * gst_object_replace:
308  * @oldobj: (inout) (transfer full) (nullable): pointer to a place of
309  *     a #GstObject to replace
310  * @newobj: (transfer none) (allow-none): a new #GstObject
311  *
312  * Atomically modifies a pointer to point to a new object.
313  * The reference count of @oldobj is decreased and the reference count of
314  * @newobj is increased.
315  *
316  * Either @newobj and the value pointed to by @oldobj may be %NULL.
317  *
318  * Returns: %TRUE if @newobj was different from @oldobj
319  */
320 gboolean
321 gst_object_replace (GstObject ** oldobj, GstObject * newobj)
322 {
323   GstObject *oldptr;
324
325   g_return_val_if_fail (oldobj != NULL, FALSE);
326
327 #ifdef DEBUG_REFCOUNT
328   GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)",
329       *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)",
330       *oldobj ? G_OBJECT (*oldobj)->ref_count : 0,
331       newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)",
332       newobj ? G_OBJECT (newobj)->ref_count : 0);
333 #endif
334
335   oldptr = g_atomic_pointer_get ((gpointer *) oldobj);
336
337   if (G_UNLIKELY (oldptr == newobj))
338     return FALSE;
339
340   if (newobj)
341     gst_object_ref (newobj);
342
343   while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
344               oldobj, oldptr, newobj))) {
345     oldptr = g_atomic_pointer_get ((gpointer *) oldobj);
346     if (G_UNLIKELY (oldptr == newobj))
347       break;
348   }
349
350   if (oldptr)
351     gst_object_unref (oldptr);
352
353   return oldptr != newobj;
354 }
355
356 /* dispose is called when the object has to release all links
357  * to other objects */
358 static void
359 gst_object_dispose (GObject * object)
360 {
361   GstObject *self = (GstObject *) object;
362   GstObject *parent;
363
364   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p dispose", object);
365
366   GST_OBJECT_LOCK (object);
367   if ((parent = GST_OBJECT_PARENT (object)))
368     goto have_parent;
369   GST_OBJECT_PARENT (object) = NULL;
370   GST_OBJECT_UNLOCK (object);
371
372   if (self->control_bindings) {
373     GList *node;
374
375     for (node = self->control_bindings; node; node = g_list_next (node)) {
376       gst_object_unparent (node->data);
377     }
378     g_list_free (self->control_bindings);
379     self->control_bindings = NULL;
380   }
381
382   ((GObjectClass *) gst_object_parent_class)->dispose (object);
383
384   return;
385
386   /* ERRORS */
387 have_parent:
388   {
389     g_critical ("\nTrying to dispose object \"%s\", but it still has a "
390         "parent \"%s\".\nYou need to let the parent manage the "
391         "object instead of unreffing the object directly.\n",
392         GST_OBJECT_NAME (object), GST_OBJECT_NAME (parent));
393     GST_OBJECT_UNLOCK (object);
394     /* ref the object again to revive it in this error case */
395     gst_object_ref (object);
396     return;
397   }
398 }
399
400 /* finalize is called when the object has to free its resources */
401 static void
402 gst_object_finalize (GObject * object)
403 {
404   GstObject *gstobject = GST_OBJECT_CAST (object);
405
406   GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p finalize", object);
407
408   g_signal_handlers_destroy (object);
409
410   g_free (gstobject->name);
411   g_mutex_clear (&gstobject->lock);
412
413   GST_TRACER_OBJECT_DESTROYED (gstobject);
414
415   ((GObjectClass *) gst_object_parent_class)->finalize (object);
416 }
417
418 /* Changing a GObject property of a GstObject will result in "deep-notify"
419  * signals being emitted by the object itself, as well as in each parent
420  * object. This is so that an application can connect a listener to the
421  * top-level bin to catch property-change notifications for all contained
422  * elements.
423  *
424  * MT safe.
425  */
426 static void
427 gst_object_dispatch_properties_changed (GObject * object,
428     guint n_pspecs, GParamSpec ** pspecs)
429 {
430   GstObject *gst_object, *parent, *old_parent;
431   guint i;
432 #ifndef GST_DISABLE_GST_DEBUG
433   gchar *name = NULL;
434   const gchar *debug_name;
435 #endif
436
437   /* do the standard dispatching */
438   ((GObjectClass *)
439       gst_object_parent_class)->dispatch_properties_changed (object, n_pspecs,
440       pspecs);
441
442   gst_object = GST_OBJECT_CAST (object);
443 #ifndef GST_DISABLE_GST_DEBUG
444   if (G_UNLIKELY (_gst_debug_min >= GST_LEVEL_LOG)) {
445     name = gst_object_get_name (gst_object);
446     debug_name = GST_STR_NULL (name);
447   } else
448     debug_name = "";
449 #endif
450
451   /* now let the parent dispatch those, too */
452   parent = gst_object_get_parent (gst_object);
453   while (parent) {
454     for (i = 0; i < n_pspecs; i++) {
455       GST_CAT_LOG_OBJECT (GST_CAT_PROPERTIES, parent,
456           "deep notification from %s (%s)", debug_name, pspecs[i]->name);
457
458       g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY],
459           g_quark_from_string (pspecs[i]->name), gst_object, pspecs[i]);
460     }
461
462     old_parent = parent;
463     parent = gst_object_get_parent (old_parent);
464     gst_object_unref (old_parent);
465   }
466 #ifndef GST_DISABLE_GST_DEBUG
467   g_free (name);
468 #endif
469 }
470
471 /**
472  * gst_object_default_deep_notify:
473  * @object: the #GObject that signalled the notify.
474  * @orig: a #GstObject that initiated the notify.
475  * @pspec: a #GParamSpec of the property.
476  * @excluded_props: (array zero-terminated=1) (element-type gchar*) (allow-none):
477  *     a set of user-specified properties to exclude or %NULL to show
478  *     all changes.
479  *
480  * A default deep_notify signal callback for an object. The user data
481  * should contain a pointer to an array of strings that should be excluded
482  * from the notify. The default handler will print the new value of the property
483  * using g_print.
484  *
485  * MT safe. This function grabs and releases @object's LOCK for getting its
486  *          path string.
487  */
488 void
489 gst_object_default_deep_notify (GObject * object, GstObject * orig,
490     GParamSpec * pspec, gchar ** excluded_props)
491 {
492   GValue value = { 0, };        /* the important thing is that value.type = 0 */
493   gchar *str = NULL;
494   gchar *name = NULL;
495
496   if (pspec->flags & G_PARAM_READABLE) {
497     /* let's not print these out for excluded properties... */
498     while (excluded_props != NULL && *excluded_props != NULL) {
499       if (strcmp (pspec->name, *excluded_props) == 0)
500         return;
501       excluded_props++;
502     }
503     g_value_init (&value, pspec->value_type);
504     g_object_get_property (G_OBJECT (orig), pspec->name, &value);
505
506     if (G_VALUE_HOLDS_STRING (&value))
507       str = g_value_dup_string (&value);
508     else
509       str = gst_value_serialize (&value);
510     name = gst_object_get_path_string (orig);
511     g_print ("%s: %s = %s\n", name, pspec->name, str);
512     g_free (name);
513     g_free (str);
514     g_value_unset (&value);
515   } else {
516     name = gst_object_get_path_string (orig);
517     g_warning ("Parameter %s not readable in %s.", pspec->name, name);
518     g_free (name);
519   }
520 }
521
522 static gboolean
523 gst_object_set_name_default (GstObject * object)
524 {
525   const gchar *type_name;
526   gint count;
527   gchar *name;
528   GQuark q;
529   guint i, l;
530
531   /* to ensure guaranteed uniqueness across threads, only one thread
532    * may ever assign a name */
533   G_LOCK (object_name_mutex);
534
535   if (!object_name_counts) {
536     g_datalist_init (&object_name_counts);
537   }
538
539   q = g_type_qname (G_OBJECT_TYPE (object));
540   count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q));
541   g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1));
542
543   G_UNLOCK (object_name_mutex);
544
545   /* GstFooSink -> foosink<N> */
546   type_name = g_quark_to_string (q);
547   if (strncmp (type_name, "Gst", 3) == 0)
548     type_name += 3;
549   /* give the 20th "queue" element and the first "queue2" different names */
550   l = strlen (type_name);
551   if (l > 0 && g_ascii_isdigit (type_name[l - 1])) {
552     name = g_strdup_printf ("%s-%d", type_name, count);
553   } else {
554     name = g_strdup_printf ("%s%d", type_name, count);
555   }
556
557   l = strlen (name);
558   for (i = 0; i < l; i++)
559     name[i] = g_ascii_tolower (name[i]);
560
561   GST_OBJECT_LOCK (object);
562   if (G_UNLIKELY (object->parent != NULL))
563     goto had_parent;
564
565   g_free (object->name);
566   object->name = name;
567
568   GST_OBJECT_UNLOCK (object);
569
570   return TRUE;
571
572 had_parent:
573   {
574     g_free (name);
575     GST_WARNING ("parented objects can't be renamed");
576     GST_OBJECT_UNLOCK (object);
577     return FALSE;
578   }
579 }
580
581 /**
582  * gst_object_set_name:
583  * @object: a #GstObject
584  * @name: (allow-none): new name of object
585  *
586  * Sets the name of @object, or gives @object a guaranteed unique
587  * name (if @name is %NULL).
588  * This function makes a copy of the provided name, so the caller
589  * retains ownership of the name it sent.
590  *
591  * Returns: %TRUE if the name could be set. Since Objects that have
592  * a parent cannot be renamed, this function returns %FALSE in those
593  * cases.
594  *
595  * MT safe.  This function grabs and releases @object's LOCK.
596  */
597 gboolean
598 gst_object_set_name (GstObject * object, const gchar * name)
599 {
600   gboolean result;
601
602   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
603
604   GST_OBJECT_LOCK (object);
605
606   /* parented objects cannot be renamed */
607   if (G_UNLIKELY (object->parent != NULL))
608     goto had_parent;
609
610   if (name != NULL) {
611     g_free (object->name);
612     object->name = g_strdup (name);
613     GST_OBJECT_UNLOCK (object);
614     result = TRUE;
615   } else {
616     GST_OBJECT_UNLOCK (object);
617     result = gst_object_set_name_default (object);
618   }
619
620   g_object_notify (G_OBJECT (object), "name");
621   return result;
622
623   /* error */
624 had_parent:
625   {
626     GST_WARNING ("parented objects can't be renamed");
627     GST_OBJECT_UNLOCK (object);
628     return FALSE;
629   }
630 }
631
632 /**
633  * gst_object_get_name:
634  * @object: a #GstObject
635  *
636  * Returns a copy of the name of @object.
637  * Caller should g_free() the return value after usage.
638  * For a nameless object, this returns %NULL, which you can safely g_free()
639  * as well.
640  *
641  * Free-function: g_free
642  *
643  * Returns: (transfer full) (nullable): the name of @object. g_free()
644  * after usage.
645  *
646  * MT safe. This function grabs and releases @object's LOCK.
647  */
648 gchar *
649 gst_object_get_name (GstObject * object)
650 {
651   gchar *result = NULL;
652
653   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
654
655   GST_OBJECT_LOCK (object);
656   result = g_strdup (object->name);
657   GST_OBJECT_UNLOCK (object);
658
659   return result;
660 }
661
662 /**
663  * gst_object_set_parent:
664  * @object: a #GstObject
665  * @parent: new parent of object
666  *
667  * Sets the parent of @object to @parent. The object's reference count will
668  * be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
669  *
670  * Returns: %TRUE if @parent could be set or %FALSE when @object
671  * already had a parent or @object and @parent are the same.
672  *
673  * MT safe. Grabs and releases @object's LOCK.
674  */
675 gboolean
676 gst_object_set_parent (GstObject * object, GstObject * parent)
677 {
678   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
679   g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
680   g_return_val_if_fail (object != parent, FALSE);
681
682   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
683       "set parent (ref and sink)");
684
685   GST_OBJECT_LOCK (object);
686   if (G_UNLIKELY (object->parent != NULL))
687     goto had_parent;
688
689   object->parent = parent;
690   gst_object_ref_sink (object);
691   GST_OBJECT_UNLOCK (object);
692
693   /* FIXME-2.0: this does not work, the deep notify takes the lock from the
694    * parent object and deadlocks when the parent holds its lock when calling
695    * this function (like _element_add_pad()), we need to use a GRecMutex
696    * for locking the parent instead.
697    */
698   /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
699
700   return TRUE;
701
702   /* ERROR handling */
703 had_parent:
704   {
705     GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
706         "set parent failed, object already had a parent");
707     GST_OBJECT_UNLOCK (object);
708     return FALSE;
709   }
710 }
711
712 /**
713  * gst_object_get_parent:
714  * @object: a #GstObject
715  *
716  * Returns the parent of @object. This function increases the refcount
717  * of the parent object so you should gst_object_unref() it after usage.
718  *
719  * Returns: (transfer full) (nullable): parent of @object, this can be
720  *   %NULL if @object has no parent. unref after usage.
721  *
722  * MT safe. Grabs and releases @object's LOCK.
723  */
724 GstObject *
725 gst_object_get_parent (GstObject * object)
726 {
727   GstObject *result = NULL;
728
729   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
730
731   GST_OBJECT_LOCK (object);
732   result = object->parent;
733   if (G_LIKELY (result))
734     gst_object_ref (result);
735   GST_OBJECT_UNLOCK (object);
736
737   return result;
738 }
739
740 /**
741  * gst_object_unparent:
742  * @object: a #GstObject to unparent
743  *
744  * Clear the parent of @object, removing the associated reference.
745  * This function decreases the refcount of @object.
746  *
747  * MT safe. Grabs and releases @object's lock.
748  */
749 void
750 gst_object_unparent (GstObject * object)
751 {
752   GstObject *parent;
753
754   g_return_if_fail (GST_IS_OBJECT (object));
755
756   GST_OBJECT_LOCK (object);
757   parent = object->parent;
758
759   if (G_LIKELY (parent != NULL)) {
760     GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "unparent");
761     object->parent = NULL;
762     GST_OBJECT_UNLOCK (object);
763
764     /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
765
766     gst_object_unref (object);
767   } else {
768     GST_OBJECT_UNLOCK (object);
769   }
770 }
771
772 /**
773  * gst_object_has_as_parent:
774  * @object: a #GstObject to check
775  * @parent: a #GstObject to check as parent
776  *
777  * Check if @parent is the parent of @object.
778  * E.g. a #GstElement can check if it owns a given #GstPad.
779  *
780  * Returns: %FALSE if either @object or @parent is %NULL. %TRUE if @parent is
781  *          the parent of @object. Otherwise %FALSE.
782  *
783  * MT safe. Grabs and releases @object's locks.
784  * Since: 1.6
785  */
786 gboolean
787 gst_object_has_as_parent (GstObject * object, GstObject * parent)
788 {
789   gboolean result = FALSE;
790
791   if (G_LIKELY (GST_IS_OBJECT (object) && GST_IS_OBJECT (parent))) {
792     GST_OBJECT_LOCK (object);
793     result = GST_OBJECT_PARENT (object) == parent;
794     GST_OBJECT_UNLOCK (object);
795   }
796
797   return result;
798 }
799
800 /**
801  * gst_object_has_as_ancestor:
802  * @object: a #GstObject to check
803  * @ancestor: a #GstObject to check as ancestor
804  *
805  * Check if @object has an ancestor @ancestor somewhere up in
806  * the hierarchy. One can e.g. check if a #GstElement is inside a #GstPipeline.
807  *
808  * Returns: %TRUE if @ancestor is an ancestor of @object.
809  *
810  * MT safe. Grabs and releases @object's locks.
811  */
812 gboolean
813 gst_object_has_as_ancestor (GstObject * object, GstObject * ancestor)
814 {
815   GstObject *parent, *tmp;
816
817   if (!ancestor || !object)
818     return FALSE;
819
820   parent = gst_object_ref (object);
821   do {
822     if (parent == ancestor) {
823       gst_object_unref (parent);
824       return TRUE;
825     }
826
827     tmp = gst_object_get_parent (parent);
828     gst_object_unref (parent);
829     parent = tmp;
830   } while (parent);
831
832   return FALSE;
833 }
834
835 /**
836  * gst_object_has_ancestor:
837  * @object: a #GstObject to check
838  * @ancestor: a #GstObject to check as ancestor
839  *
840  * Check if @object has an ancestor @ancestor somewhere up in
841  * the hierarchy. One can e.g. check if a #GstElement is inside a #GstPipeline.
842  *
843  * Returns: %TRUE if @ancestor is an ancestor of @object.
844  *
845  * Deprecated: Use gst_object_has_as_ancestor() instead.
846  *
847  * MT safe. Grabs and releases @object's locks.
848  */
849 /* FIXME 2.0: remove */
850 #ifndef GST_REMOVE_DEPRECATED
851 #ifdef GST_DISABLE_DEPRECATED
852 gboolean gst_object_has_ancestor (GstObject * object, GstObject * ancestor);
853 #endif
854 gboolean
855 gst_object_has_ancestor (GstObject * object, GstObject * ancestor)
856 {
857   return gst_object_has_as_ancestor (object, ancestor);
858 }
859 #endif
860
861 /**
862  * gst_object_check_uniqueness:
863  * @list: (transfer none) (element-type Gst.Object): a list of #GstObject to
864  *      check through
865  * @name: the name to search for
866  *
867  * Checks to see if there is any object named @name in @list. This function
868  * does not do any locking of any kind. You might want to protect the
869  * provided list with the lock of the owner of the list. This function
870  * will lock each #GstObject in the list to compare the name, so be
871  * careful when passing a list with a locked object.
872  *
873  * Returns: %TRUE if a #GstObject named @name does not appear in @list,
874  * %FALSE if it does.
875  *
876  * MT safe. Grabs and releases the LOCK of each object in the list.
877  */
878 gboolean
879 gst_object_check_uniqueness (GList * list, const gchar * name)
880 {
881   gboolean result = TRUE;
882
883   g_return_val_if_fail (name != NULL, FALSE);
884
885   for (; list; list = g_list_next (list)) {
886     GstObject *child;
887     gboolean eq;
888
889     child = GST_OBJECT_CAST (list->data);
890
891     GST_OBJECT_LOCK (child);
892     eq = strcmp (GST_OBJECT_NAME (child), name) == 0;
893     GST_OBJECT_UNLOCK (child);
894
895     if (G_UNLIKELY (eq)) {
896       result = FALSE;
897       break;
898     }
899   }
900   return result;
901 }
902
903
904 static void
905 gst_object_set_property (GObject * object, guint prop_id,
906     const GValue * value, GParamSpec * pspec)
907 {
908   GstObject *gstobject;
909
910   gstobject = GST_OBJECT_CAST (object);
911
912   switch (prop_id) {
913     case PROP_NAME:
914       gst_object_set_name (gstobject, g_value_get_string (value));
915       break;
916     case PROP_PARENT:
917       gst_object_set_parent (gstobject, g_value_get_object (value));
918       break;
919     default:
920       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
921       break;
922   }
923 }
924
925 static void
926 gst_object_get_property (GObject * object, guint prop_id,
927     GValue * value, GParamSpec * pspec)
928 {
929   GstObject *gstobject;
930
931   gstobject = GST_OBJECT_CAST (object);
932
933   switch (prop_id) {
934     case PROP_NAME:
935       g_value_take_string (value, gst_object_get_name (gstobject));
936       break;
937     case PROP_PARENT:
938       g_value_take_object (value, gst_object_get_parent (gstobject));
939       break;
940     default:
941       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
942       break;
943   }
944 }
945
946 /**
947  * gst_object_get_path_string:
948  * @object: a #GstObject
949  *
950  * Generates a string describing the path of @object in
951  * the object hierarchy. Only useful (or used) for debugging.
952  *
953  * Free-function: g_free
954  *
955  * Returns: (transfer full): a string describing the path of @object. You must
956  *          g_free() the string after usage.
957  *
958  * MT safe. Grabs and releases the #GstObject's LOCK for all objects
959  *          in the hierarchy.
960  */
961 gchar *
962 gst_object_get_path_string (GstObject * object)
963 {
964   GSList *parentage;
965   GSList *parents;
966   void *parent;
967   gchar *prevpath, *path;
968   const gchar *typename;
969   gchar *component;
970   const gchar *separator;
971
972   /* ref object before adding to list */
973   gst_object_ref (object);
974   parentage = g_slist_prepend (NULL, object);
975
976   path = g_strdup ("");
977
978   /* first walk the object hierarchy to build a list of the parents,
979    * be careful here with refcounting. */
980   do {
981     if (GST_IS_OBJECT (object)) {
982       parent = gst_object_get_parent (object);
983       /* add parents to list, refcount remains increased while
984        * we handle the object */
985       if (parent)
986         parentage = g_slist_prepend (parentage, parent);
987     } else {
988       break;
989     }
990     object = parent;
991   } while (object != NULL);
992
993   /* then walk the parent list and print them out. we need to
994    * decrease the refcounting on each element after we handled
995    * it. */
996   for (parents = parentage; parents; parents = g_slist_next (parents)) {
997     if (G_IS_OBJECT (parents->data)) {
998       typename = G_OBJECT_TYPE_NAME (parents->data);
999     } else {
1000       typename = NULL;
1001     }
1002     if (GST_IS_OBJECT (parents->data)) {
1003       GstObject *item = GST_OBJECT_CAST (parents->data);
1004       GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item);
1005       gchar *objname = gst_object_get_name (item);
1006
1007       component = g_strdup_printf ("%s:%s", typename, objname);
1008       separator = oclass->path_string_separator;
1009       /* and unref now */
1010       gst_object_unref (item);
1011       g_free (objname);
1012     } else {
1013       if (typename) {
1014         component = g_strdup_printf ("%s:%p", typename, parents->data);
1015       } else {
1016         component = g_strdup_printf ("%p", parents->data);
1017       }
1018       separator = "/";
1019     }
1020
1021     prevpath = path;
1022     path = g_strjoin (separator, prevpath, component, NULL);
1023     g_free (prevpath);
1024     g_free (component);
1025   }
1026
1027   g_slist_free (parentage);
1028
1029   return path;
1030 }
1031
1032 /* controller helper functions */
1033
1034 /*
1035  * gst_object_find_control_binding:
1036  * @self: the gobject to search for a property in
1037  * @name: the gobject property name to look for
1038  *
1039  * Searches the list of properties under control.
1040  *
1041  * Returns: (nullable): a #GstControlBinding or %NULL if the property
1042  * is not being controlled.
1043  */
1044 static GstControlBinding *
1045 gst_object_find_control_binding (GstObject * self, const gchar * name)
1046 {
1047   GstControlBinding *binding;
1048   GList *node;
1049
1050   for (node = self->control_bindings; node; node = g_list_next (node)) {
1051     binding = node->data;
1052     /* FIXME: eventually use GQuark to speed it up */
1053     if (!strcmp (binding->name, name)) {
1054       GST_DEBUG_OBJECT (self, "found control binding for property '%s'", name);
1055       return binding;
1056     }
1057   }
1058   GST_DEBUG_OBJECT (self, "controller does not manage property '%s'", name);
1059
1060   return NULL;
1061 }
1062
1063 /* controller functions */
1064
1065 /**
1066  * gst_object_suggest_next_sync:
1067  * @object: the object that has controlled properties
1068  *
1069  * Returns a suggestion for timestamps where buffers should be split
1070  * to get best controller results.
1071  *
1072  * Returns: Returns the suggested timestamp or %GST_CLOCK_TIME_NONE
1073  * if no control-rate was set.
1074  */
1075 GstClockTime
1076 gst_object_suggest_next_sync (GstObject * object)
1077 {
1078   GstClockTime ret;
1079
1080   g_return_val_if_fail (GST_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
1081   g_return_val_if_fail (object->control_rate != GST_CLOCK_TIME_NONE,
1082       GST_CLOCK_TIME_NONE);
1083
1084   GST_OBJECT_LOCK (object);
1085
1086   /* TODO: Implement more logic, depending on interpolation mode and control
1087    * points
1088    * FIXME: we need playback direction
1089    */
1090   ret = object->last_sync + object->control_rate;
1091
1092   GST_OBJECT_UNLOCK (object);
1093
1094   return ret;
1095 }
1096
1097 /**
1098  * gst_object_sync_values:
1099  * @object: the object that has controlled properties
1100  * @timestamp: the time that should be processed
1101  *
1102  * Sets the properties of the object, according to the #GstControlSources that
1103  * (maybe) handle them and for the given timestamp.
1104  *
1105  * If this function fails, it is most likely the application developers fault.
1106  * Most probably the control sources are not setup correctly.
1107  *
1108  * Returns: %TRUE if the controller values could be applied to the object
1109  * properties, %FALSE otherwise
1110  */
1111 gboolean
1112 gst_object_sync_values (GstObject * object, GstClockTime timestamp)
1113 {
1114   GList *node;
1115   gboolean ret = TRUE;
1116
1117   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1118   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1119
1120   GST_LOG_OBJECT (object, "sync_values");
1121   if (!object->control_bindings)
1122     return TRUE;
1123
1124   /* FIXME: this deadlocks */
1125   /* GST_OBJECT_LOCK (object); */
1126   g_object_freeze_notify ((GObject *) object);
1127   for (node = object->control_bindings; node; node = g_list_next (node)) {
1128     ret &= gst_control_binding_sync_values ((GstControlBinding *) node->data,
1129         object, timestamp, object->last_sync);
1130   }
1131   object->last_sync = timestamp;
1132   g_object_thaw_notify ((GObject *) object);
1133   /* GST_OBJECT_UNLOCK (object); */
1134
1135   return ret;
1136 }
1137
1138
1139 /**
1140  * gst_object_has_active_control_bindings:
1141  * @object: the object that has controlled properties
1142  *
1143  * Check if the @object has active controlled properties.
1144  *
1145  * Returns: %TRUE if the object has active controlled properties
1146  */
1147 gboolean
1148 gst_object_has_active_control_bindings (GstObject * object)
1149 {
1150   gboolean res = FALSE;
1151   GList *node;
1152
1153   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1154
1155   GST_OBJECT_LOCK (object);
1156   for (node = object->control_bindings; node; node = g_list_next (node)) {
1157     res |= !gst_control_binding_is_disabled ((GstControlBinding *) node->data);
1158   }
1159   GST_OBJECT_UNLOCK (object);
1160   return res;
1161 }
1162
1163 /**
1164  * gst_object_set_control_bindings_disabled:
1165  * @object: the object that has controlled properties
1166  * @disabled: boolean that specifies whether to disable the controller
1167  * or not.
1168  *
1169  * This function is used to disable all controlled properties of the @object for
1170  * some time, i.e. gst_object_sync_values() will do nothing.
1171  */
1172 void
1173 gst_object_set_control_bindings_disabled (GstObject * object, gboolean disabled)
1174 {
1175   GList *node;
1176
1177   g_return_if_fail (GST_IS_OBJECT (object));
1178
1179   GST_OBJECT_LOCK (object);
1180   for (node = object->control_bindings; node; node = g_list_next (node)) {
1181     gst_control_binding_set_disabled ((GstControlBinding *) node->data,
1182         disabled);
1183   }
1184   GST_OBJECT_UNLOCK (object);
1185 }
1186
1187 /**
1188  * gst_object_set_control_binding_disabled:
1189  * @object: the object that has controlled properties
1190  * @property_name: property to disable
1191  * @disabled: boolean that specifies whether to disable the controller
1192  * or not.
1193  *
1194  * This function is used to disable the control bindings on a property for
1195  * some time, i.e. gst_object_sync_values() will do nothing for the
1196  * property.
1197  */
1198 void
1199 gst_object_set_control_binding_disabled (GstObject * object,
1200     const gchar * property_name, gboolean disabled)
1201 {
1202   GstControlBinding *binding;
1203
1204   g_return_if_fail (GST_IS_OBJECT (object));
1205   g_return_if_fail (property_name);
1206
1207   GST_OBJECT_LOCK (object);
1208   if ((binding = gst_object_find_control_binding (object, property_name))) {
1209     gst_control_binding_set_disabled (binding, disabled);
1210   }
1211   GST_OBJECT_UNLOCK (object);
1212 }
1213
1214
1215 /**
1216  * gst_object_add_control_binding:
1217  * @object: the controller object
1218  * @binding: (transfer full): the #GstControlBinding that should be used
1219  *
1220  * Attach the #GstControlBinding to the object. If there already was a
1221  * #GstControlBinding for this property it will be replaced.
1222  *
1223  * The @object will take ownership of the @binding.
1224  *
1225  * Returns: %FALSE if the given @binding has not been setup for this object or
1226  * has been setup for a non suitable property, %TRUE otherwise.
1227  */
1228 gboolean
1229 gst_object_add_control_binding (GstObject * object, GstControlBinding * binding)
1230 {
1231   GstControlBinding *old;
1232
1233   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1234   g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
1235   g_return_val_if_fail (binding->pspec, FALSE);
1236
1237   GST_OBJECT_LOCK (object);
1238   if ((old = gst_object_find_control_binding (object, binding->name))) {
1239     GST_DEBUG_OBJECT (object, "controlled property %s removed", old->name);
1240     object->control_bindings = g_list_remove (object->control_bindings, old);
1241     gst_object_unparent (GST_OBJECT_CAST (old));
1242   }
1243   object->control_bindings = g_list_prepend (object->control_bindings, binding);
1244   gst_object_set_parent (GST_OBJECT_CAST (binding), object);
1245   GST_DEBUG_OBJECT (object, "controlled property %s added", binding->name);
1246   GST_OBJECT_UNLOCK (object);
1247
1248   return TRUE;
1249 }
1250
1251 /**
1252  * gst_object_get_control_binding:
1253  * @object: the object
1254  * @property_name: name of the property
1255  *
1256  * Gets the corresponding #GstControlBinding for the property. This should be
1257  * unreferenced again after use.
1258  *
1259  * Returns: (transfer full) (nullable): the #GstControlBinding for
1260  * @property_name or %NULL if the property is not controlled.
1261  */
1262 GstControlBinding *
1263 gst_object_get_control_binding (GstObject * object, const gchar * property_name)
1264 {
1265   GstControlBinding *binding;
1266
1267   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
1268   g_return_val_if_fail (property_name, NULL);
1269
1270   GST_OBJECT_LOCK (object);
1271   if ((binding = gst_object_find_control_binding (object, property_name))) {
1272     gst_object_ref (binding);
1273   }
1274   GST_OBJECT_UNLOCK (object);
1275
1276   return binding;
1277 }
1278
1279 /**
1280  * gst_object_remove_control_binding:
1281  * @object: the object
1282  * @binding: the binding
1283  *
1284  * Removes the corresponding #GstControlBinding. If it was the
1285  * last ref of the binding, it will be disposed.  
1286  *
1287  * Returns: %TRUE if the binding could be removed.
1288  */
1289 gboolean
1290 gst_object_remove_control_binding (GstObject * object,
1291     GstControlBinding * binding)
1292 {
1293   GList *node;
1294   gboolean ret = FALSE;
1295
1296   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1297   g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
1298
1299   GST_OBJECT_LOCK (object);
1300   if ((node = g_list_find (object->control_bindings, binding))) {
1301     GST_DEBUG_OBJECT (object, "controlled property %s removed", binding->name);
1302     object->control_bindings =
1303         g_list_delete_link (object->control_bindings, node);
1304     gst_object_unparent (GST_OBJECT_CAST (binding));
1305     ret = TRUE;
1306   }
1307   GST_OBJECT_UNLOCK (object);
1308
1309   return ret;
1310 }
1311
1312 /**
1313  * gst_object_get_value:
1314  * @object: the object that has controlled properties
1315  * @property_name: the name of the property to get
1316  * @timestamp: the time the control-change should be read from
1317  *
1318  * Gets the value for the given controlled property at the requested time.
1319  *
1320  * Returns: (nullable): the GValue of the property at the given time,
1321  * or %NULL if the property isn't controlled.
1322  */
1323 GValue *
1324 gst_object_get_value (GstObject * object, const gchar * property_name,
1325     GstClockTime timestamp)
1326 {
1327   GstControlBinding *binding;
1328   GValue *val = NULL;
1329
1330   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
1331   g_return_val_if_fail (property_name, NULL);
1332   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);
1333
1334   GST_OBJECT_LOCK (object);
1335   if ((binding = gst_object_find_control_binding (object, property_name))) {
1336     val = gst_control_binding_get_value (binding, timestamp);
1337   }
1338   GST_OBJECT_UNLOCK (object);
1339
1340   return val;
1341 }
1342
1343 /**
1344  * gst_object_get_value_array:
1345  * @object: the object that has controlled properties
1346  * @property_name: the name of the property to get
1347  * @timestamp: the time that should be processed
1348  * @interval: the time spacing between subsequent values
1349  * @n_values: the number of values
1350  * @values: array to put control-values in
1351  *
1352  * Gets a number of values for the given controlled property starting at the
1353  * requested time. The array @values need to hold enough space for @n_values of
1354  * the same type as the objects property's type.
1355  *
1356  * This function is useful if one wants to e.g. draw a graph of the control
1357  * curve or apply a control curve sample by sample.
1358  *
1359  * The values are unboxed and ready to be used. The similar function 
1360  * gst_object_get_g_value_array() returns the array as #GValues and is
1361  * better suites for bindings.
1362  *
1363  * Returns: %TRUE if the given array could be filled, %FALSE otherwise
1364  */
1365 gboolean
1366 gst_object_get_value_array (GstObject * object, const gchar * property_name,
1367     GstClockTime timestamp, GstClockTime interval, guint n_values,
1368     gpointer values)
1369 {
1370   gboolean res = FALSE;
1371   GstControlBinding *binding;
1372
1373   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1374   g_return_val_if_fail (property_name, FALSE);
1375   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1376   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
1377   g_return_val_if_fail (values, FALSE);
1378
1379   GST_OBJECT_LOCK (object);
1380   if ((binding = gst_object_find_control_binding (object, property_name))) {
1381     res = gst_control_binding_get_value_array (binding, timestamp, interval,
1382         n_values, values);
1383   }
1384   GST_OBJECT_UNLOCK (object);
1385   return res;
1386 }
1387
1388 /**
1389  * gst_object_get_g_value_array:
1390  * @object: the object that has controlled properties
1391  * @property_name: the name of the property to get
1392  * @timestamp: the time that should be processed
1393  * @interval: the time spacing between subsequent values
1394  * @n_values: the number of values
1395  * @values: array to put control-values in
1396  *
1397  * Gets a number of #GValues for the given controlled property starting at the
1398  * requested time. The array @values need to hold enough space for @n_values of
1399  * #GValue.
1400  *
1401  * This function is useful if one wants to e.g. draw a graph of the control
1402  * curve or apply a control curve sample by sample.
1403  *
1404  * Returns: %TRUE if the given array could be filled, %FALSE otherwise
1405  */
1406 gboolean
1407 gst_object_get_g_value_array (GstObject * object, const gchar * property_name,
1408     GstClockTime timestamp, GstClockTime interval, guint n_values,
1409     GValue * values)
1410 {
1411   gboolean res = FALSE;
1412   GstControlBinding *binding;
1413
1414   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1415   g_return_val_if_fail (property_name, FALSE);
1416   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
1417   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
1418   g_return_val_if_fail (values, FALSE);
1419
1420   GST_OBJECT_LOCK (object);
1421   if ((binding = gst_object_find_control_binding (object, property_name))) {
1422     res = gst_control_binding_get_g_value_array (binding, timestamp, interval,
1423         n_values, values);
1424   }
1425   GST_OBJECT_UNLOCK (object);
1426   return res;
1427 }
1428
1429
1430 /**
1431  * gst_object_get_control_rate:
1432  * @object: the object that has controlled properties
1433  *
1434  * Obtain the control-rate for this @object. Audio processing #GstElement
1435  * objects will use this rate to sub-divide their processing loop and call
1436  * gst_object_sync_values() inbetween. The length of the processing segment
1437  * should be up to @control-rate nanoseconds.
1438  *
1439  * If the @object is not under property control, this will return
1440  * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
1441  *
1442  * The control-rate is not expected to change if the element is in
1443  * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
1444  *
1445  * Returns: the control rate in nanoseconds
1446  */
1447 GstClockTime
1448 gst_object_get_control_rate (GstObject * object)
1449 {
1450   g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
1451
1452   return object->control_rate;
1453 }
1454
1455 /**
1456  * gst_object_set_control_rate:
1457  * @object: the object that has controlled properties
1458  * @control_rate: the new control-rate in nanoseconds.
1459  *
1460  * Change the control-rate for this @object. Audio processing #GstElement
1461  * objects will use this rate to sub-divide their processing loop and call
1462  * gst_object_sync_values() inbetween. The length of the processing segment
1463  * should be up to @control-rate nanoseconds.
1464  *
1465  * The control-rate should not change if the element is in %GST_STATE_PAUSED or
1466  * %GST_STATE_PLAYING.
1467  */
1468 void
1469 gst_object_set_control_rate (GstObject * object, GstClockTime control_rate)
1470 {
1471   g_return_if_fail (GST_IS_OBJECT (object));
1472
1473   object->control_rate = control_rate;
1474 }