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