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