/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *                    2005 Wim Taymans <wim@fluendo.com>
 *
 * gstobject.c: Fundamental class used for all of GStreamer
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gstobject
 * @short_description: Base class for the GStreamer object hierarchy
 *
 * #GstObject provides a root for the object hierarchy tree filed in by the
 * GStreamer library.  It is currently a thin wrapper on top of
 * #GInitiallyUnowned. It is an abstract class that is not very usable on its own.
 *
 * #GstObject gives us basic refcounting, parenting functionality and locking.
 * Most of the function are just extended for special GStreamer needs and can be
 * found under the same name in the base class of #GstObject which is #GObject
 * (e.g. g_object_ref() becomes gst_object_ref()).
 *
 * Since #GstObject dereives from #GInitiallyUnowned, it also inherits the
 * floating reference. Be aware that functions such as gst_bin_add() and
 * gst_element_add_pad() take ownership of the floating reference.
 *
 * In contrast to #GObject instances, #GstObject adds a name property. The functions
 * gst_object_set_name() and gst_object_get_name() are used to set/get the name
 * of the object.
 *
 * <refsect2>
 * <title>controlled properties</title>
 * <para>
 * Controlled properties offers a lightweight way to adjust gobject
 * properties over stream-time. It works by using time-stamped value pairs that
 * are queued for element-properties. At run-time the elements continously pull
 * values changes for the current stream-time.
 *
 * What needs to be changed in a #GstElement?
 * Very little - it is just two steps to make a plugin controllable!
 * <orderedlist>
 *   <listitem><para>
 *     mark gobject-properties paramspecs that make sense to be controlled,
 *     by GST_PARAM_CONTROLLABLE.
 *   </para></listitem>
 *   <listitem><para>
 *     when processing data (get, chain, loop function) at the beginning call
 *     gst_object_sync_values(element,timestamp).
 *     This will made the controller to update all gobject properties that are under
 *     control with the current values based on timestamp.
 *   </para></listitem>
 * </orderedlist>
 *
 * What needs to be done in applications?
 * Again its not a lot to change.
 * <orderedlist>
 *   <listitem><para>
 *     first put some properties under control, by calling
 *     gst_object_control_properties (object, "prop1", "prop2",...);
 *   </para></listitem>
 *   <listitem><para>
 *     create a #GstControlSource.
 *     csource = gst_interpolation_control_source_new ();
 *     g_object_set (csource, "mode", GST_INTERPOLATION_MODE_LINEAR, NULL);
 *   </para></listitem>
 *   <listitem><para>
 *     Attach the #GstControlSource on the controller to a property.
 *     gst_object_add_control_binding (object, gst_direct_control_binding_new (objetct, "prop1", csource));
 *   </para></listitem>
 *   <listitem><para>
 *     Set the control values
 *     gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,0 * GST_SECOND, value1);
 *     gst_timed_value_control_source_set ((GstTimedValueControlSource *)csource,1 * GST_SECOND, value2);
 *   </para></listitem>
 *   <listitem><para>
 *     start your pipeline
 *   </para></listitem>
 * </orderedlist>
 * </para>
 * </refsect2>
 *
 * Last reviewed on 2012-03-29 (0.11.3)
 */

#include "gst_private.h"
#include "glib-compat-private.h"

#include "gstobject.h"
#include "gstclock.h"
#include "gstcontrolbinding.h"
#include "gstcontrolsource.h"
#include "gstinfo.h"
#include "gstparamspecs.h"
#include "gstutils.h"

#ifndef GST_DISABLE_TRACE
#include "gsttrace.h"
static GstAllocTrace *_gst_object_trace;
#endif

#define DEBUG_REFCOUNT

/* Object signals and args */
enum
{
  DEEP_NOTIFY,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_NAME,
  PROP_PARENT,
  PROP_LAST
};

enum
{
  SO_OBJECT_LOADED,
  SO_LAST_SIGNAL
};

/* maps type name quark => count */
static GData *object_name_counts = NULL;

G_LOCK_DEFINE_STATIC (object_name_mutex);

static void gst_object_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_object_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static void gst_object_dispatch_properties_changed (GObject * object,
    guint n_pspecs, GParamSpec ** pspecs);

static void gst_object_dispose (GObject * object);
static void gst_object_finalize (GObject * object);

static gboolean gst_object_set_name_default (GstObject * object);

static guint gst_object_signals[LAST_SIGNAL] = { 0 };

static GParamSpec *properties[PROP_LAST];

G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_INITIALLY_UNOWNED);

static void
gst_object_class_init (GstObjectClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

#ifndef GST_DISABLE_TRACE
  _gst_object_trace =
      _gst_alloc_trace_register (g_type_name (GST_TYPE_OBJECT), -2);
#endif

  gobject_class->set_property = gst_object_set_property;
  gobject_class->get_property = gst_object_get_property;

  properties[PROP_NAME] =
      g_param_spec_string ("name", "Name", "The name of the object", NULL,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  properties[PROP_PARENT] =
      g_param_spec_object ("parent", "Parent", "The parent of the object",
      GST_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, PROP_LAST, properties);

  /**
   * GstObject::deep-notify:
   * @gstobject: a #GstObject
   * @prop_object: the object that originated the signal
   * @prop: the property that changed
   *
   * The deep notify signal is used to be notified of property changes. It is
   * typically attached to the toplevel bin to receive notifications from all
   * the elements contained in that bin.
   */
  gst_object_signals[DEEP_NOTIFY] =
      g_signal_new ("deep-notify", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED |
      G_SIGNAL_NO_HOOKS, G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL,
      NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 2, GST_TYPE_OBJECT,
      G_TYPE_PARAM);

  klass->path_string_separator = "/";

  /* see the comments at gst_object_dispatch_properties_changed */
  gobject_class->dispatch_properties_changed
      = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed);

  gobject_class->dispose = gst_object_dispose;
  gobject_class->finalize = gst_object_finalize;
}

static void
gst_object_init (GstObject * object)
{
  g_mutex_init (&object->lock);
  object->parent = NULL;
  object->name = NULL;
  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p new", object);

#ifndef GST_DISABLE_TRACE
  _gst_alloc_trace_new (_gst_object_trace, object);
#endif

  object->flags = 0;

  object->control_rate = 100 * GST_MSECOND;
  object->last_sync = GST_CLOCK_TIME_NONE;
}

/**
 * gst_object_ref:
 * @object: a #GstObject to reference
 *
 * Increments the reference count on @object. This function
 * does not take the lock on @object because it relies on
 * atomic refcounting.
 *
 * This object returns the input parameter to ease writing
 * constructs like :
 *  result = gst_object_ref (object->parent);
 *
 * Returns: (transfer full): A pointer to @object
 */
gpointer
gst_object_ref (gpointer object)
{
  g_return_val_if_fail (object != NULL, NULL);

#ifdef DEBUG_REFCOUNT
  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref %d->%d", object,
      ((GObject *) object)->ref_count, ((GObject *) object)->ref_count + 1);
#endif
  g_object_ref (object);

  return object;
}

/**
 * gst_object_unref:
 * @object: a #GstObject to unreference
 *
 * Decrements the reference count on @object.  If reference count hits
 * zero, destroy @object. This function does not take the lock
 * on @object as it relies on atomic refcounting.
 *
 * The unref method should never be called with the LOCK held since
 * this might deadlock the dispose function.
 */
void
gst_object_unref (gpointer object)
{
  g_return_if_fail (object != NULL);
  g_return_if_fail (((GObject *) object)->ref_count > 0);

#ifdef DEBUG_REFCOUNT
  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p unref %d->%d", object,
      ((GObject *) object)->ref_count, ((GObject *) object)->ref_count - 1);
#endif
  g_object_unref (object);
}

/**
 * gst_object_ref_sink: (skip)
 * @object: a #GstObject to sink
 *
 * Increase the reference count of @object, and possibly remove the floating
 * reference, if @object has a floating reference.
 *
 * In other words, if the object is floating, then this call "assumes ownership"
 * of the floating reference, converting it to a normal reference by clearing
 * the floating flag while leaving the reference count unchanged. If the object
 * is not floating, then this call adds a new normal reference increasing the
 * reference count by one.
 */
gpointer
gst_object_ref_sink (gpointer object)
{
  g_return_val_if_fail (object != NULL, NULL);

#ifdef DEBUG_REFCOUNT
  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref_sink %d->%d",
      object, ((GObject *) object)->ref_count,
      ((GObject *) object)->ref_count + 1);
#endif
  return g_object_ref_sink (object);
}

/**
 * gst_object_replace:
 * @oldobj: (inout) (transfer full): pointer to a place of a #GstObject to
 *     replace
 * @newobj: (transfer none): a new #GstObject
 *
 * Atomically modifies a pointer to point to a new object.
 * The reference count of @oldobj is decreased and the reference count of
 * @newobj is increased.
 *
 * Either @newobj and the value pointed to by @oldobj may be NULL.
 *
 * Returns: TRUE if @newobj was different from @oldobj
 */
gboolean
gst_object_replace (GstObject ** oldobj, GstObject * newobj)
{
  GstObject *oldptr;

  g_return_val_if_fail (oldobj != NULL, FALSE);

#ifdef DEBUG_REFCOUNT
  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p %s (%d) with %p %s (%d)",
      *oldobj, *oldobj ? GST_STR_NULL (GST_OBJECT_NAME (*oldobj)) : "(NONE)",
      *oldobj ? G_OBJECT (*oldobj)->ref_count : 0,
      newobj, newobj ? GST_STR_NULL (GST_OBJECT_NAME (newobj)) : "(NONE)",
      newobj ? G_OBJECT (newobj)->ref_count : 0);
#endif

  oldptr = g_atomic_pointer_get ((gpointer *) oldobj);

  if (G_UNLIKELY (oldptr == newobj))
    return FALSE;

  if (newobj)
    g_object_ref (newobj);

  while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
              oldobj, oldptr, newobj))) {
    oldptr = g_atomic_pointer_get ((gpointer *) oldobj);
    if (G_UNLIKELY (oldptr == newobj))
      break;
  }

  if (oldptr)
    g_object_unref (oldptr);

  return oldptr != newobj;
}

/* dispose is called when the object has to release all links
 * to other objects */
static void
gst_object_dispose (GObject * object)
{
  GstObject *self = (GstObject *) object;
  GstObject *parent;

  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");

  GST_OBJECT_LOCK (object);
  if ((parent = GST_OBJECT_PARENT (object)))
    goto have_parent;
  GST_OBJECT_PARENT (object) = NULL;
  GST_OBJECT_UNLOCK (object);

  if (self->control_bindings) {
    GList *node;

    for (node = self->control_bindings; node; node = g_list_next (node)) {
      gst_object_unparent (node->data);
    }
    g_list_free (self->control_bindings);
    self->control_bindings = NULL;
  }

  ((GObjectClass *) gst_object_parent_class)->dispose (object);

  return;

  /* ERRORS */
have_parent:
  {
    g_critical ("\nTrying to dispose object \"%s\", but it still has a "
        "parent \"%s\".\nYou need to let the parent manage the "
        "object instead of unreffing the object directly.\n",
        GST_OBJECT_NAME (object), GST_OBJECT_NAME (parent));
    GST_OBJECT_UNLOCK (object);
    /* ref the object again to revive it in this error case */
    gst_object_ref (object);
    return;
  }
}

/* finalize is called when the object has to free its resources */
static void
gst_object_finalize (GObject * object)
{
  GstObject *gstobject = GST_OBJECT_CAST (object);

  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "finalize");

  g_signal_handlers_destroy (object);

  g_free (gstobject->name);
  g_mutex_clear (&gstobject->lock);

#ifndef GST_DISABLE_TRACE
  _gst_alloc_trace_free (_gst_object_trace, object);
#endif

  ((GObjectClass *) gst_object_parent_class)->finalize (object);
}

/* Changing a GObject property of a GstObject will result in "deep-notify"
 * signals being emitted by the object itself, as well as in each parent
 * object. This is so that an application can connect a listener to the
 * top-level bin to catch property-change notifications for all contained
 * elements.
 *
 * MT safe.
 */
static void
gst_object_dispatch_properties_changed (GObject * object,
    guint n_pspecs, GParamSpec ** pspecs)
{
  GstObject *gst_object, *parent, *old_parent;
  guint i;
#ifndef GST_DISABLE_GST_DEBUG
  gchar *name = NULL;
  const gchar *debug_name;
#endif

  /* do the standard dispatching */
  ((GObjectClass *)
      gst_object_parent_class)->dispatch_properties_changed (object, n_pspecs,
      pspecs);

  gst_object = GST_OBJECT_CAST (object);
#ifndef GST_DISABLE_GST_DEBUG
  if (G_UNLIKELY (_gst_debug_min >= GST_LEVEL_LOG)) {
    name = gst_object_get_name (gst_object);
    debug_name = GST_STR_NULL (name);
  } else
    debug_name = "";
#endif

  /* now let the parent dispatch those, too */
  parent = gst_object_get_parent (gst_object);
  while (parent) {
    for (i = 0; i < n_pspecs; i++) {
      GST_CAT_LOG_OBJECT (GST_CAT_PROPERTIES, parent,
          "deep notification from %s (%s)", debug_name, pspecs[i]->name);

      g_signal_emit (parent, gst_object_signals[DEEP_NOTIFY],
          g_quark_from_string (pspecs[i]->name), gst_object, pspecs[i]);
    }

    old_parent = parent;
    parent = gst_object_get_parent (old_parent);
    gst_object_unref (old_parent);
  }
#ifndef GST_DISABLE_GST_DEBUG
  g_free (name);
#endif
}

/**
 * gst_object_default_deep_notify:
 * @object: the #GObject that signalled the notify.
 * @orig: a #GstObject that initiated the notify.
 * @pspec: a #GParamSpec of the property.
 * @excluded_props: (array zero-terminated=1) (element-type gchar*)
 *     (allow-none):a set of user-specified properties to exclude or
 *     NULL to show all changes.
 *
 * A default deep_notify signal callback for an object. The user data
 * should contain a pointer to an array of strings that should be excluded
 * from the notify. The default handler will print the new value of the property
 * using g_print.
 *
 * MT safe. This function grabs and releases @object's LOCK for getting its
 *          path string.
 */
void
gst_object_default_deep_notify (GObject * object, GstObject * orig,
    GParamSpec * pspec, gchar ** excluded_props)
{
  GValue value = { 0, };        /* the important thing is that value.type = 0 */
  gchar *str = NULL;
  gchar *name = NULL;

  if (pspec->flags & G_PARAM_READABLE) {
    /* let's not print these out for excluded properties... */
    while (excluded_props != NULL && *excluded_props != NULL) {
      if (strcmp (pspec->name, *excluded_props) == 0)
        return;
      excluded_props++;
    }
    g_value_init (&value, pspec->value_type);
    g_object_get_property (G_OBJECT (orig), pspec->name, &value);

    /* FIXME: handle flags */
    if (G_IS_PARAM_SPEC_ENUM (pspec)) {
      GEnumValue *enum_value;
      GEnumClass *klass = G_ENUM_CLASS (g_type_class_ref (pspec->value_type));

      enum_value = g_enum_get_value (klass, g_value_get_enum (&value));

      str = g_strdup_printf ("%s (%d)", enum_value->value_nick,
          enum_value->value);
      g_type_class_unref (klass);
    } else {
      str = g_strdup_value_contents (&value);
    }
    name = gst_object_get_path_string (orig);
    g_print ("%s: %s = %s\n", name, pspec->name, str);
    g_free (name);
    g_free (str);
    g_value_unset (&value);
  } else {
    name = gst_object_get_path_string (orig);
    g_warning ("Parameter %s not readable in %s.", pspec->name, name);
    g_free (name);
  }
}

static gboolean
gst_object_set_name_default (GstObject * object)
{
  const gchar *type_name;
  gint count;
  gchar *name;
  GQuark q;
  guint i, l;

  /* to ensure guaranteed uniqueness across threads, only one thread
   * may ever assign a name */
  G_LOCK (object_name_mutex);

  if (!object_name_counts) {
    g_datalist_init (&object_name_counts);
  }

  q = g_type_qname (G_OBJECT_TYPE (object));
  count = GPOINTER_TO_INT (g_datalist_id_get_data (&object_name_counts, q));
  g_datalist_id_set_data (&object_name_counts, q, GINT_TO_POINTER (count + 1));

  G_UNLOCK (object_name_mutex);

  /* GstFooSink -> foosink<N> */
  type_name = g_quark_to_string (q);
  if (strncmp (type_name, "Gst", 3) == 0)
    type_name += 3;
  name = g_strdup_printf ("%s%d", type_name, count);
  l = strlen (name);
  for (i = 0; i < l; i++)
    name[i] = g_ascii_tolower (name[i]);

  GST_OBJECT_LOCK (object);
  if (G_UNLIKELY (object->parent != NULL))
    goto had_parent;

  g_free (object->name);
  object->name = name;

  GST_OBJECT_UNLOCK (object);

  return TRUE;

had_parent:
  {
    g_free (name);
    GST_WARNING ("parented objects can't be renamed");
    GST_OBJECT_UNLOCK (object);
    return FALSE;
  }
}

/**
 * gst_object_set_name:
 * @object: a #GstObject
 * @name:   new name of object
 *
 * Sets the name of @object, or gives @object a guaranteed unique
 * name (if @name is NULL).
 * This function makes a copy of the provided name, so the caller
 * retains ownership of the name it sent.
 *
 * Returns: TRUE if the name could be set. Since Objects that have
 * a parent cannot be renamed, this function returns FALSE in those
 * cases.
 *
 * MT safe.  This function grabs and releases @object's LOCK.
 */
gboolean
gst_object_set_name (GstObject * object, const gchar * name)
{
  gboolean result;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);

  GST_OBJECT_LOCK (object);

  /* parented objects cannot be renamed */
  if (G_UNLIKELY (object->parent != NULL))
    goto had_parent;

  if (name != NULL) {
    g_free (object->name);
    object->name = g_strdup (name);
    GST_OBJECT_UNLOCK (object);
    result = TRUE;
  } else {
    GST_OBJECT_UNLOCK (object);
    result = gst_object_set_name_default (object);
  }
  /* FIXME-0.11: this misses a g_object_notify (object, "name"); unless called
   * from gst_object_set_property.
   * Ideally remove such custom setters (or make it static).
   */
  return result;

  /* error */
had_parent:
  {
    GST_WARNING ("parented objects can't be renamed");
    GST_OBJECT_UNLOCK (object);
    return FALSE;
  }
}

/**
 * gst_object_get_name:
 * @object: a #GstObject
 *
 * Returns a copy of the name of @object.
 * Caller should g_free() the return value after usage.
 * For a nameless object, this returns NULL, which you can safely g_free()
 * as well.
 *
 * Free-function: g_free
 *
 * Returns: (transfer full): the name of @object. g_free() after usage.
 *
 * MT safe. This function grabs and releases @object's LOCK.
 */
gchar *
gst_object_get_name (GstObject * object)
{
  gchar *result = NULL;

  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);

  GST_OBJECT_LOCK (object);
  result = g_strdup (object->name);
  GST_OBJECT_UNLOCK (object);

  return result;
}

/**
 * gst_object_set_parent:
 * @object: a #GstObject
 * @parent: new parent of object
 *
 * Sets the parent of @object to @parent. The object's reference count will
 * be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
 *
 * Returns: TRUE if @parent could be set or FALSE when @object
 * already had a parent or @object and @parent are the same.
 *
 * MT safe. Grabs and releases @object's LOCK.
 */
gboolean
gst_object_set_parent (GstObject * object, GstObject * parent)
{
  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
  g_return_val_if_fail (object != parent, FALSE);

  GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
      "set parent (ref and sink)");

  GST_OBJECT_LOCK (object);
  if (G_UNLIKELY (object->parent != NULL))
    goto had_parent;

  object->parent = parent;
  gst_object_ref_sink (object);
  GST_OBJECT_UNLOCK (object);

  /* FIXME, this does not work, the deep notify takes the lock from the parent
   * object and deadlocks when the parent holds its lock when calling this
   * function (like _element_add_pad()) */
  /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */

  return TRUE;

  /* ERROR handling */
had_parent:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
        "set parent failed, object already had a parent");
    GST_OBJECT_UNLOCK (object);
    return FALSE;
  }
}

/**
 * gst_object_get_parent:
 * @object: a #GstObject
 *
 * Returns the parent of @object. This function increases the refcount
 * of the parent object so you should gst_object_unref() it after usage.
 *
 * Returns: (transfer full): parent of @object, this can be NULL if @object
 *   has no parent. unref after usage.
 *
 * MT safe. Grabs and releases @object's LOCK.
 */
GstObject *
gst_object_get_parent (GstObject * object)
{
  GstObject *result = NULL;

  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);

  GST_OBJECT_LOCK (object);
  result = object->parent;
  if (G_LIKELY (result))
    gst_object_ref (result);
  GST_OBJECT_UNLOCK (object);

  return result;
}

/**
 * gst_object_unparent:
 * @object: a #GstObject to unparent
 *
 * Clear the parent of @object, removing the associated reference.
 * This function decreases the refcount of @object.
 *
 * MT safe. Grabs and releases @object's lock.
 */
void
gst_object_unparent (GstObject * object)
{
  GstObject *parent;

  g_return_if_fail (GST_IS_OBJECT (object));

  GST_OBJECT_LOCK (object);
  parent = object->parent;

  if (G_LIKELY (parent != NULL)) {
    GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "unparent");
    object->parent = NULL;
    GST_OBJECT_UNLOCK (object);

    /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */

    gst_object_unref (object);
  } else {
    GST_OBJECT_UNLOCK (object);
  }
}

/**
 * gst_object_has_ancestor:
 * @object: a #GstObject to check
 * @ancestor: a #GstObject to check as ancestor
 *
 * Check if @object has an ancestor @ancestor somewhere up in
 * the hierarchy. One can e.g. check if a #GstElement is inside a #GstPipeline.
 *
 * Returns: TRUE if @ancestor is an ancestor of @object.
 *
 * MT safe. Grabs and releases @object's locks.
 */
gboolean
gst_object_has_ancestor (GstObject * object, GstObject * ancestor)
{
  GstObject *parent, *tmp;

  if (!ancestor || !object)
    return FALSE;

  parent = gst_object_ref (object);
  do {
    if (parent == ancestor) {
      gst_object_unref (parent);
      return TRUE;
    }

    tmp = gst_object_get_parent (parent);
    gst_object_unref (parent);
    parent = tmp;
  } while (parent);

  return FALSE;
}

/**
 * gst_object_check_uniqueness:
 * @list: (transfer none) (element-type Gst.Object): a list of #GstObject to
 *      check through
 * @name: the name to search for
 *
 * Checks to see if there is any object named @name in @list. This function
 * does not do any locking of any kind. You might want to protect the
 * provided list with the lock of the owner of the list. This function
 * will lock each #GstObject in the list to compare the name, so be
 * carefull when passing a list with a locked object.
 *
 * Returns: TRUE if a #GstObject named @name does not appear in @list,
 * FALSE if it does.
 *
 * MT safe. Grabs and releases the LOCK of each object in the list.
 */
gboolean
gst_object_check_uniqueness (GList * list, const gchar * name)
{
  gboolean result = TRUE;

  g_return_val_if_fail (name != NULL, FALSE);

  for (; list; list = g_list_next (list)) {
    GstObject *child;
    gboolean eq;

    child = GST_OBJECT_CAST (list->data);

    GST_OBJECT_LOCK (child);
    eq = strcmp (GST_OBJECT_NAME (child), name) == 0;
    GST_OBJECT_UNLOCK (child);

    if (G_UNLIKELY (eq)) {
      result = FALSE;
      break;
    }
  }
  return result;
}


static void
gst_object_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstObject *gstobject;

  gstobject = GST_OBJECT_CAST (object);

  switch (prop_id) {
    case PROP_NAME:
      gst_object_set_name (gstobject, g_value_get_string (value));
      break;
    case PROP_PARENT:
      gst_object_set_parent (gstobject, g_value_get_object (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_object_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstObject *gstobject;

  gstobject = GST_OBJECT_CAST (object);

  switch (prop_id) {
    case PROP_NAME:
      g_value_take_string (value, gst_object_get_name (gstobject));
      break;
    case PROP_PARENT:
      g_value_take_object (value, gst_object_get_parent (gstobject));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

/**
 * gst_object_get_path_string:
 * @object: a #GstObject
 *
 * Generates a string describing the path of @object in
 * the object hierarchy. Only useful (or used) for debugging.
 *
 * Free-function: g_free
 *
 * Returns: (transfer full): a string describing the path of @object. You must
 *          g_free() the string after usage.
 *
 * MT safe. Grabs and releases the #GstObject's LOCK for all objects
 *          in the hierarchy.
 */
gchar *
gst_object_get_path_string (GstObject * object)
{
  GSList *parentage;
  GSList *parents;
  void *parent;
  gchar *prevpath, *path;
  const gchar *typename;
  gchar *component;
  const gchar *separator;

  /* ref object before adding to list */
  gst_object_ref (object);
  parentage = g_slist_prepend (NULL, object);

  path = g_strdup ("");

  /* first walk the object hierarchy to build a list of the parents,
   * be carefull here with refcounting. */
  do {
    if (GST_IS_OBJECT (object)) {
      parent = gst_object_get_parent (object);
      /* add parents to list, refcount remains increased while
       * we handle the object */
      if (parent)
        parentage = g_slist_prepend (parentage, parent);
    } else {
      break;
    }
    object = parent;
  } while (object != NULL);

  /* then walk the parent list and print them out. we need to
   * decrease the refcounting on each element after we handled
   * it. */
  for (parents = parentage; parents; parents = g_slist_next (parents)) {
    if (G_IS_OBJECT (parents->data)) {
      typename = G_OBJECT_TYPE_NAME (parents->data);
    } else {
      typename = NULL;
    }
    if (GST_IS_OBJECT (parents->data)) {
      GstObject *item = GST_OBJECT_CAST (parents->data);
      GstObjectClass *oclass = GST_OBJECT_GET_CLASS (item);
      gchar *objname = gst_object_get_name (item);

      component = g_strdup_printf ("%s:%s", typename, objname);
      separator = oclass->path_string_separator;
      /* and unref now */
      gst_object_unref (item);
      g_free (objname);
    } else {
      if (typename) {
        component = g_strdup_printf ("%s:%p", typename, parents->data);
      } else {
        component = g_strdup_printf ("%p", parents->data);
      }
      separator = "/";
    }

    prevpath = path;
    path = g_strjoin (separator, prevpath, component, NULL);
    g_free (prevpath);
    g_free (component);
  }

  g_slist_free (parentage);

  return path;
}

/* controller helper functions */

/*
 * gst_object_find_control_binding:
 * @self: the gobject to search for a property in
 * @name: the gobject property name to look for
 *
 * Searches the list of properties under control.
 *
 * Returns: a #GstControlBinding or %NULL if the property is not being
 * controlled.
 */
static GstControlBinding *
gst_object_find_control_binding (GstObject * self, const gchar * name)
{
  GstControlBinding *binding;
  GList *node;

  for (node = self->control_bindings; node; node = g_list_next (node)) {
    binding = node->data;
    /* FIXME: eventually use GQuark to speed it up */
    if (!strcmp (binding->name, name)) {
      GST_DEBUG_OBJECT (self, "found control binding for property '%s'", name);
      return binding;
    }
  }
  GST_DEBUG_OBJECT (self, "controller does not manage property '%s'", name);

  return NULL;
}

/* controller functions */

/**
 * gst_object_suggest_next_sync:
 * @object: the object that has controlled properties
 *
 * Returns a suggestion for timestamps where buffers should be split
 * to get best controller results.
 *
 * Returns: Returns the suggested timestamp or %GST_CLOCK_TIME_NONE
 * if no control-rate was set.
 */
GstClockTime
gst_object_suggest_next_sync (GstObject * object)
{
  GstClockTime ret;

  g_return_val_if_fail (GST_IS_OBJECT (object), GST_CLOCK_TIME_NONE);
  g_return_val_if_fail (object->control_rate != GST_CLOCK_TIME_NONE,
      GST_CLOCK_TIME_NONE);

  GST_OBJECT_LOCK (object);

  /* TODO: Implement more logic, depending on interpolation mode and control
   * points
   * FIXME: we need playback direction
   */
  ret = object->last_sync + object->control_rate;

  GST_OBJECT_UNLOCK (object);

  return ret;
}

/**
 * gst_object_sync_values:
 * @object: the object that has controlled properties
 * @timestamp: the time that should be processed
 *
 * Sets the properties of the object, according to the #GstControlSources that
 * (maybe) handle them and for the given timestamp.
 *
 * If this function fails, it is most likely the application developers fault.
 * Most probably the control sources are not setup correctly.
 *
 * Returns: %TRUE if the controller values could be applied to the object
 * properties, %FALSE otherwise
 */
gboolean
gst_object_sync_values (GstObject * object, GstClockTime timestamp)
{
  GList *node;
  gboolean ret = TRUE;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);

  GST_LOG_OBJECT (object, "sync_values");
  if (!object->control_bindings)
    return TRUE;

  /* FIXME: this deadlocks */
  /* GST_OBJECT_LOCK (object); */
  g_object_freeze_notify ((GObject *) object);
  for (node = object->control_bindings; node; node = g_list_next (node)) {
    ret &= gst_control_binding_sync_values ((GstControlBinding *) node->data,
        object, timestamp, object->last_sync);
  }
  object->last_sync = timestamp;
  g_object_thaw_notify ((GObject *) object);
  /* GST_OBJECT_UNLOCK (object); */

  return ret;
}


/**
 * gst_object_has_active_control_bindings:
 * @object: the object that has controlled properties
 *
 * Check if the @object has an active controlled properties.
 *
 * Returns: %TRUE if the object has active controlled properties
 */
gboolean
gst_object_has_active_control_bindings (GstObject * object)
{
  gboolean res = FALSE;
  GList *node;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);

  GST_OBJECT_LOCK (object);
  for (node = object->control_bindings; node; node = g_list_next (node)) {
    res |= !gst_control_binding_is_disabled ((GstControlBinding *) node->data);
  }
  GST_OBJECT_UNLOCK (object);
  return res;
}

/**
 * gst_object_set_control_bindings_disabled:
 * @object: the object that has controlled properties
 * @disabled: boolean that specifies whether to disable the controller
 * or not.
 *
 * This function is used to disable all controlled properties of the @object for
 * some time, i.e. gst_object_sync_values() will do nothing.
 */
void
gst_object_set_control_bindings_disabled (GstObject * object, gboolean disabled)
{
  GList *node;

  g_return_if_fail (GST_IS_OBJECT (object));

  GST_OBJECT_LOCK (object);
  for (node = object->control_bindings; node; node = g_list_next (node)) {
    gst_control_binding_set_disabled ((GstControlBinding *) node->data,
        disabled);
  }
  GST_OBJECT_UNLOCK (object);
}

/**
 * gst_object_set_control_binding_disabled:
 * @object: the object that has controlled properties
 * @property_name: property to disable
 * @disabled: boolean that specifies whether to disable the controller
 * or not.
 *
 * This function is used to disable the #GstController on a property for
 * some time, i.e. gst_controller_sync_values() will do nothing for the
 * property.
 */
void
gst_object_set_control_binding_disabled (GstObject * object,
    const gchar * property_name, gboolean disabled)
{
  GstControlBinding *binding;

  g_return_if_fail (GST_IS_OBJECT (object));
  g_return_if_fail (property_name);

  GST_OBJECT_LOCK (object);
  if ((binding = gst_object_find_control_binding (object, property_name))) {
    gst_control_binding_set_disabled (binding, disabled);
  }
  GST_OBJECT_UNLOCK (object);
}


/**
 * gst_object_add_control_binding:
 * @object: the controller object
 * @binding: (transfer full): the #GstControlBinding that should be used
 *
 * Sets the #GstControlBinding. If there already was a #GstControlBinding
 * for this property it will be replaced.
 * The @object will take ownership of the @binding.
 *
 * Returns: %FALSE if the given @binding has not been setup for this object  or
 * %TRUE otherwise.
 */
gboolean
gst_object_add_control_binding (GstObject * object, GstControlBinding * binding)
{
  GstControlBinding *old;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);
  //g_return_val_if_fail (g_type_is_a (binding->pspec->owner_type,
  //        G_OBJECT_TYPE (object)), FALSE);

  GST_OBJECT_LOCK (object);
  if ((old = gst_object_find_control_binding (object, binding->name))) {
    GST_DEBUG_OBJECT (object, "controlled property %s removed", old->name);
    object->control_bindings = g_list_remove (object->control_bindings, old);
    gst_object_unparent (GST_OBJECT_CAST (old));
  }
  object->control_bindings = g_list_prepend (object->control_bindings, binding);
  gst_object_set_parent (GST_OBJECT_CAST (binding), object);
  GST_DEBUG_OBJECT (object, "controlled property %s added", binding->name);
  GST_OBJECT_UNLOCK (object);

  return TRUE;
}

/**
 * gst_object_get_control_binding:
 * @object: the object
 * @property_name: name of the property
 *
 * Gets the corresponding #GstControlBinding for the property. This should be
 * unreferenced again after use.
 *
 * Returns: (transfer full): the #GstControlBinding for @property_name or %NULL if
 * the property is not controlled.
 */
GstControlBinding *
gst_object_get_control_binding (GstObject * object, const gchar * property_name)
{
  GstControlBinding *binding;

  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
  g_return_val_if_fail (property_name, NULL);

  GST_OBJECT_LOCK (object);
  if ((binding = gst_object_find_control_binding (object, property_name))) {
    g_object_ref (binding);
  }
  GST_OBJECT_UNLOCK (object);

  return binding;
}

/**
 * gst_object_remove_control_binding:
 * @object: the object
 * @binding: the binding
 *
 * Removes the corresponding #GstControlBinding. If it was the
 * last ref of the binding, it will be disposed.  
 *
 * Returns: %TRUE if the binding could be removed.
 */
gboolean
gst_object_remove_control_binding (GstObject * object,
    GstControlBinding * binding)
{
  GList *node;
  gboolean ret = FALSE;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_IS_CONTROL_BINDING (binding), FALSE);

  GST_OBJECT_LOCK (object);
  if ((node = g_list_find (object->control_bindings, binding))) {
    GST_DEBUG_OBJECT (object, "controlled property %s removed", binding->name);
    object->control_bindings =
        g_list_delete_link (object->control_bindings, node);
    gst_object_unparent (GST_OBJECT_CAST (binding));
    ret = TRUE;
  }
  GST_OBJECT_UNLOCK (object);

  return ret;
}

/**
 * gst_object_get_value:
 * @object: the object that has controlled properties
 * @property_name: the name of the property to get
 * @timestamp: the time the control-change should be read from
 *
 * Gets the value for the given controlled property at the requested time.
 *
 * Returns: the GValue of the property at the given time, or %NULL if the
 * property isn't controlled.
 */
GValue *
gst_object_get_value (GstObject * object, const gchar * property_name,
    GstClockTime timestamp)
{
  GstControlBinding *binding;
  GValue *val = NULL;

  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
  g_return_val_if_fail (property_name, NULL);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);

  GST_OBJECT_LOCK (object);
  if ((binding = gst_object_find_control_binding (object, property_name))) {
    val = gst_control_binding_get_value (binding, timestamp);
  }
  GST_OBJECT_UNLOCK (object);

  return val;
}

/**
 * gst_object_get_value_array:
 * @object: the object that has controlled properties
 * @property_name: the name of the property to get
 * @timestamp: the time that should be processed
 * @interval: the time spacing between subsequent values
 * @n_values: the number of values
 * @values: array to put control-values in
 *
 * Gets a number of values for the given controllered property starting at the
 * requested time. The array @values need to hold enough space for @n_values of
 * the same type as the objects property's type.
 *
 * This function is useful if one wants to e.g. draw a graph of the control
 * curve or apply a control curve sample by sample.
 *
 * Returns: %TRUE if the given array could be filled, %FALSE otherwise
 */
gboolean
gst_object_get_value_array (GstObject * object, const gchar * property_name,
    GstClockTime timestamp, GstClockTime interval, guint n_values,
    GValue * values)
{
  gboolean res = FALSE;
  GstControlBinding *binding;

  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (property_name, FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), FALSE);
  g_return_val_if_fail (values, FALSE);

  GST_OBJECT_LOCK (object);
  if ((binding = gst_object_find_control_binding (object, property_name))) {
    res = gst_control_binding_get_value_array (binding, timestamp, interval,
        n_values, values);
  }
  GST_OBJECT_UNLOCK (object);
  return res;
}


/**
 * gst_object_get_control_rate:
 * @object: the object that has controlled properties
 *
 * Obtain the control-rate for this @object. Audio processing #GstElement
 * objects will use this rate to sub-divide their processing loop and call
 * gst_object_sync_values() inbetween. The length of the processing segment
 * should be up to @control-rate nanoseconds.
 *
 * If the @object is not under property control, this will return
 * %GST_CLOCK_TIME_NONE. This allows the element to avoid the sub-dividing.
 *
 * The control-rate is not expected to change if the element is in
 * %GST_STATE_PAUSED or %GST_STATE_PLAYING.
 *
 * Returns: the control rate in nanoseconds
 */
GstClockTime
gst_object_get_control_rate (GstObject * object)
{
  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);

  return object->control_rate;
}

/**
 * gst_object_set_control_rate:
 * @object: the object that has controlled properties
 * @control_rate: the new control-rate in nanoseconds.
 *
 * Change the control-rate for this @object. Audio processing #GstElement
 * objects will use this rate to sub-divide their processing loop and call
 * gst_object_sync_values() inbetween. The length of the processing segment
 * should be up to @control-rate nanoseconds.
 *
 * The control-rate should not change if the element is in %GST_STATE_PAUSED or
 * %GST_STATE_PLAYING.
 */
void
gst_object_set_control_rate (GstObject * object, GstClockTime control_rate)
{
  g_return_if_fail (GST_IS_OBJECT (object));

  object->control_rate = control_rate;
}
