/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *                    2002 Thomas Vander Stichele <thomas@apestaart.org>
 *
 * gstutils.c: Utility functions: gtk_get_property stuff, etc.
 *
 * 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:gstutils
 * @short_description: Various utility functions
 *
 * When defining own plugins, use the GST_BOILERPLATE ease gobject creation.
 */

#include "gst_private.h"
#include <stdio.h>
#include <string.h>

#include "gstghostpad.h"
#include "gstutils.h"
#include "gsterror.h"
#include "gstinfo.h"
#include "gstparse.h"
#include "gst-i18n-lib.h"


/**
 * gst_util_dump_mem:
 * @mem: a pointer to the memory to dump
 * @size: the size of the memory block to dump
 *
 * Dumps the memory block into a hex representation. Useful for debugging.
 */
void
gst_util_dump_mem (const guchar * mem, guint size)
{
  guint i, j;
  GString *string = g_string_sized_new (50);
  GString *chars = g_string_sized_new (18);

  i = j = 0;
  while (i < size) {
    if (g_ascii_isprint (mem[i]))
      g_string_append_c (chars, mem[i]);
    else
      g_string_append_c (chars, '.');

    g_string_append_printf (string, "%02x ", mem[i]);

    j++;
    i++;

    if (j == 16 || i == size) {
      g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
          string->str, chars->str);
      g_string_set_size (string, 0);
      g_string_set_size (chars, 0);
      j = 0;
    }
  }
  g_string_free (string, TRUE);
  g_string_free (chars, TRUE);
}


/**
 * gst_util_set_value_from_string:
 * @value: the value to set
 * @value_str: the string to get the value from
 *
 * Converts the string to the type of the value and
 * sets the value with it.
 */
void
gst_util_set_value_from_string (GValue * value, const gchar * value_str)
{
  gint sscanf_ret;

  g_return_if_fail (value != NULL);
  g_return_if_fail (value_str != NULL);

  GST_CAT_DEBUG (GST_CAT_PARAMS, "parsing '%s' to type %s", value_str,
      g_type_name (G_VALUE_TYPE (value)));

  switch (G_VALUE_TYPE (value)) {
    case G_TYPE_STRING:
      g_value_set_string (value, value_str);
      break;
    case G_TYPE_ENUM:
    case G_TYPE_INT:{
      gint i;

      sscanf_ret = sscanf (value_str, "%d", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_int (value, i);
      break;
    }
    case G_TYPE_UINT:{
      guint i;

      sscanf_ret = sscanf (value_str, "%u", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_uint (value, i);
      break;
    }
    case G_TYPE_LONG:{
      glong i;

      sscanf_ret = sscanf (value_str, "%ld", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_long (value, i);
      break;
    }
    case G_TYPE_ULONG:{
      gulong i;

      sscanf_ret = sscanf (value_str, "%lu", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_ulong (value, i);
      break;
    }
    case G_TYPE_BOOLEAN:{
      gboolean i = FALSE;

      if (!g_ascii_strncasecmp ("true", value_str, 4))
        i = TRUE;
      g_value_set_boolean (value, i);
      break;
    }
    case G_TYPE_CHAR:{
      gchar i;

      sscanf_ret = sscanf (value_str, "%c", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_char (value, i);
      break;
    }
    case G_TYPE_UCHAR:{
      guchar i;

      sscanf_ret = sscanf (value_str, "%c", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_uchar (value, i);
      break;
    }
    case G_TYPE_FLOAT:{
      gfloat i;

      sscanf_ret = sscanf (value_str, "%f", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_float (value, i);
      break;
    }
    case G_TYPE_DOUBLE:{
      gfloat i;

      sscanf_ret = sscanf (value_str, "%g", &i);
      g_return_if_fail (sscanf_ret == 1);
      g_value_set_double (value, (gdouble) i);
      break;
    }
    default:
      break;
  }
}

/**
 * gst_util_set_object_arg:
 * @object: the object to set the argument of
 * @name: the name of the argument to set
 * @value: the string value to set
 *
 * Convertes the string value to the type of the objects argument and
 * sets the argument with it.
 */
void
gst_util_set_object_arg (GObject * object, const gchar * name,
    const gchar * value)
{
  gboolean sscanf_ret;

  if (name && value) {
    GParamSpec *paramspec;

    paramspec =
        g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);

    if (!paramspec) {
      return;
    }

    GST_DEBUG ("paramspec->flags is %d, paramspec->value_type is %d",
        paramspec->flags, (gint) paramspec->value_type);

    if (paramspec->flags & G_PARAM_WRITABLE) {
      switch (paramspec->value_type) {
        case G_TYPE_STRING:
          g_object_set (G_OBJECT (object), name, value, NULL);
          break;
        case G_TYPE_ENUM:
        case G_TYPE_INT:{
          gint i;

          sscanf_ret = sscanf (value, "%d", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_UINT:{
          guint i;

          sscanf_ret = sscanf (value, "%u", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_LONG:{
          glong i;

          sscanf_ret = sscanf (value, "%ld", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_ULONG:{
          gulong i;

          sscanf_ret = sscanf (value, "%lu", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_BOOLEAN:{
          gboolean i = FALSE;

          if (!g_ascii_strncasecmp ("true", value, 4))
            i = TRUE;
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_CHAR:{
          gchar i;

          sscanf_ret = sscanf (value, "%c", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_UCHAR:{
          guchar i;

          sscanf_ret = sscanf (value, "%c", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_FLOAT:{
          gfloat i;

          sscanf_ret = sscanf (value, "%f", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, i, NULL);
          break;
        }
        case G_TYPE_DOUBLE:{
          gfloat i;

          sscanf_ret = sscanf (value, "%g", &i);
          g_return_if_fail (sscanf_ret == 1);
          g_object_set (G_OBJECT (object), name, (gdouble) i, NULL);
          break;
        }
        default:
          if (G_IS_PARAM_SPEC_ENUM (paramspec)) {
            gint i;

            sscanf_ret = sscanf (value, "%d", &i);
            g_return_if_fail (sscanf_ret == 1);
            g_object_set (G_OBJECT (object), name, i, NULL);
          }
          break;
      }
    }
  }
}

/* work around error C2520: conversion from unsigned __int64 to double
 * not implemented, use signed __int64
 *
 * These are implemented as functions because on some platforms a 64bit int to
 * double conversion is not defined/implemented.
 */

gdouble
gst_util_guint64_to_gdouble (guint64 value)
{
  if (value & G_GINT64_CONSTANT (0x8000000000000000))
    return (gdouble) ((gint64) value) + (gdouble) 18446744073709551616.;
  else
    return (gdouble) ((gint64) value);
}

guint64
gst_util_gdouble_to_guint64 (gdouble value)
{
  if (value < (gdouble) 9223372036854775808.)   /* 1 << 63 */
    return ((guint64) ((gint64) value));

  value -= (gdouble) 18446744073709551616.;
  return ((guint64) ((gint64) value));
}

/* convenience struct for getting high and low uint32 parts of
 * a guint64 */
typedef union
{
  guint64 ll;
  struct
  {
#if G_BYTE_ORDER == G_BIG_ENDIAN
    guint32 high, low;
#else
    guint32 low, high;
#endif
  } l;
} GstUInt64;

/* based on Hacker's Delight p152 */
static guint64
gst_util_div128_64 (GstUInt64 c1, GstUInt64 c0, guint64 denom)
{
  GstUInt64 q1, q0, rhat;
  GstUInt64 v, cmp1, cmp2;
  guint s;

  v.ll = denom;

  /* count number of leading zeroes, we know they must be in the high
   * part of denom since denom > G_MAXUINT32. */
  s = v.l.high | (v.l.high >> 1);
  s |= (s >> 2);
  s |= (s >> 4);
  s |= (s >> 8);
  s = ~(s | (s >> 16));
  s = s - ((s >> 1) & 0x55555555);
  s = (s & 0x33333333) + ((s >> 2) & 0x33333333);
  s = (s + (s >> 4)) & 0x0f0f0f0f;
  s += (s >> 8);
  s = (s + (s >> 16)) & 0x3f;

  if (s > 0) {
    /* normalize divisor and dividend */
    v.ll <<= s;
    c1.ll = (c1.ll << s) | (c0.l.high >> (32 - s));
    c0.ll <<= s;
  }

  q1.ll = c1.ll / v.l.high;
  rhat.ll = c1.ll - q1.ll * v.l.high;

  cmp1.l.high = rhat.l.low;
  cmp1.l.low = c0.l.high;
  cmp2.ll = q1.ll * v.l.low;

  while (q1.l.high || cmp2.ll > cmp1.ll) {
    q1.ll--;
    rhat.ll += v.l.high;
    if (rhat.l.high)
      break;
    cmp1.l.high = rhat.l.low;
    cmp2.ll -= v.l.low;
  }
  c1.l.high = c1.l.low;
  c1.l.low = c0.l.high;
  c1.ll -= q1.ll * v.ll;
  q0.ll = c1.ll / v.l.high;
  rhat.ll = c1.ll - q0.ll * v.l.high;

  cmp1.l.high = rhat.l.low;
  cmp1.l.low = c0.l.low;
  cmp2.ll = q0.ll * v.l.low;

  while (q0.l.high || cmp2.ll > cmp1.ll) {
    q0.ll--;
    rhat.ll += v.l.high;
    if (rhat.l.high)
      break;
    cmp1.l.high = rhat.l.low;
    cmp2.ll -= v.l.low;
  }
  q0.l.high += q1.l.low;

  return q0.ll;
}

static guint64
gst_util_uint64_scale_int64 (guint64 val, guint64 num, guint64 denom)
{
  GstUInt64 a0, a1, b0, b1, c0, ct, c1, result;
  GstUInt64 v, n;

  /* prepare input */
  v.ll = val;
  n.ll = num;

  /* do 128 bits multiply
   *                   nh   nl
   *                *  vh   vl
   *                ----------
   * a0 =              vl * nl
   * a1 =         vl * nh
   * b0 =         vh * nl
   * b1 =  + vh * nh
   *       -------------------
   * c1,c0
   */
  a0.ll = (guint64) v.l.low * n.l.low;
  a1.ll = (guint64) v.l.low * n.l.high;
  b0.ll = (guint64) v.l.high * n.l.low;
  b1.ll = (guint64) v.l.high * n.l.high;

  /* and sum together with carry into 128 bits c1, c0 */
  c0.l.low = a0.l.low;
  ct.ll = (guint64) a0.l.high + a1.l.low + b0.l.low;
  c0.l.high = ct.l.low;
  c1.ll = (guint64) a1.l.high + b0.l.high + ct.l.high + b1.ll;

  /* if high bits bigger than denom, we overflow */
  if (c1.ll >= denom)
    goto overflow;

  /* shortcut for division by 1, c1.ll should be 0 because of the
   * overflow check above. */
  if (denom == 1)
    return c0.ll;

  /* and 128/64 bits division, result fits 64 bits */
  if (denom <= G_MAXUINT32) {
    guint32 den = (guint32) denom;

    /* easy case, (c1,c0)128/(den)32 division */
    c1.l.high %= den;
    c1.l.high = c1.ll % den;
    c1.l.low = c0.l.high;
    c0.l.high = c1.ll % den;
    result.l.high = c1.ll / den;
    result.l.low = c0.ll / den;
  } else {
    result.ll = gst_util_div128_64 (c1, c0, denom);
  }
  return result.ll;

overflow:
  {
    return G_MAXUINT64;
  }
}

/**
 * gst_util_uint64_scale:
 * @val: the number to scale
 * @num: the numerator of the scale ratio
 * @denom: the denominator of the scale ratio
 *
 * Scale @val by @num / @denom, trying to avoid overflows.
 *
 * This function can potentially be very slow if denom > G_MAXUINT32.
 *
 * Returns: @val * @num / @denom, trying to avoid overflows.
 * In the case of an overflow, this function returns G_MAXUINT64.
 */
guint64
gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom)
{
  g_return_val_if_fail (denom != 0, G_MAXUINT64);

  if (num == 0)
    return 0;

  if (num == 1 && denom == 1)
    return val;

  /* if the denom is high, we need to do a 64 muldiv */
  if (denom > G_MAXINT32)
    goto do_int64;

  /* if num and denom are low we can do a 32 bit muldiv */
  if (num <= G_MAXINT32)
    goto do_int32;

  /* val and num are high, we need 64 muldiv */
  if (val > G_MAXINT32)
    goto do_int64;

  /* val is low and num is high, we can swap them and do 32 muldiv */
  return gst_util_uint64_scale_int (num, (gint) val, (gint) denom);

do_int32:
  return gst_util_uint64_scale_int (val, (gint) num, (gint) denom);

do_int64:
  /* to the more heavy implementations... */
  return gst_util_uint64_scale_int64 (val, num, denom);
}

/**
 * gst_util_uint64_scale_int:
 * @val: guint64 (such as a #GstClockTime) to scale.
 * @num: numerator of the scale factor.
 * @denom: denominator of the scale factor.
 *
 * Scale a guint64 by a factor expressed as a fraction (num/denom), avoiding
 * overflows and loss of precision.
 *
 * @num and @denom must be positive integers. @denom cannot be 0.
 *
 * Returns: @val * @num / @denom, avoiding overflow and loss of precision.
 * In the case of an overflow, this function returns G_MAXUINT64.
 */
guint64
gst_util_uint64_scale_int (guint64 val, gint num, gint denom)
{
  GstUInt64 result;
  GstUInt64 low, high;

  g_return_val_if_fail (denom > 0, G_MAXUINT64);
  g_return_val_if_fail (num >= 0, G_MAXUINT64);

  if (num == 0)
    return 0;

  if (num == 1 && denom == 1)
    return val;

  if (val <= G_MAXUINT32)
    /* simple case */
    return val * num / denom;

  /* do 96 bits mult/div */
  low.ll = val;
  result.ll = ((guint64) low.l.low) * num;
  high.ll = ((guint64) low.l.high) * num + (result.l.high);

  low.ll = high.ll / denom;
  result.l.high = high.ll % denom;
  result.ll /= denom;

  /* avoid overflow */
  if (low.ll + result.l.high > G_MAXUINT32)
    goto overflow;

  result.l.high += low.l.low;

  return result.ll;

overflow:
  {
    return G_MAXUINT64;
  }
}

/* -----------------------------------------------------
 *
 *  The following code will be moved out of the main
 * gstreamer library someday.
 */

#include "gstpad.h"

static void
string_append_indent (GString * str, gint count)
{
  gint xx;

  for (xx = 0; xx < count; xx++)
    g_string_append_c (str, ' ');
}

/**
 * gst_print_pad_caps:
 * @buf: the buffer to print the caps in
 * @indent: initial indentation
 * @pad: the pad to print the caps from
 *
 * Write the pad capabilities in a human readable format into
 * the given GString.
 */
void
gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
{
  GstCaps *caps;

  caps = pad->caps;

  if (!caps) {
    string_append_indent (buf, indent);
    g_string_printf (buf, "%s:%s has no capabilities",
        GST_DEBUG_PAD_NAME (pad));
  } else {
    char *s;

    s = gst_caps_to_string (caps);
    g_string_append (buf, s);
    g_free (s);
  }
}

/**
 * gst_print_element_args:
 * @buf: the buffer to print the args in
 * @indent: initial indentation
 * @element: the element to print the args of
 *
 * Print the element argument in a human readable format in the given
 * GString.
 */
void
gst_print_element_args (GString * buf, gint indent, GstElement * element)
{
  guint width;
  GValue value = { 0, };        /* the important thing is that value.type = 0 */
  gchar *str = NULL;
  GParamSpec *spec, **specs, **walk;

  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), NULL);

  width = 0;
  for (walk = specs; *walk; walk++) {
    spec = *walk;
    if (width < strlen (spec->name))
      width = strlen (spec->name);
  }

  for (walk = specs; *walk; walk++) {
    spec = *walk;

    if (spec->flags & G_PARAM_READABLE) {
      g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
      g_object_get_property (G_OBJECT (element), spec->name, &value);
      str = g_strdup_value_contents (&value);
      g_value_unset (&value);
    } else {
      str = g_strdup ("Parameter not readable.");
    }

    string_append_indent (buf, indent);
    g_string_append (buf, spec->name);
    string_append_indent (buf, 2 + width - strlen (spec->name));
    g_string_append (buf, str);
    g_string_append_c (buf, '\n');

    g_free (str);
  }

  g_free (specs);
}

/**
 * gst_element_create_all_pads:
 * @element: a #GstElement to create pads for
 *
 * Creates a pad for each pad template that is always available.
 * This function is only useful during object intialization of
 * subclasses of #GstElement.
 */
void
gst_element_create_all_pads (GstElement * element)
{
  GList *padlist;

  /* FIXME: lock element */

  padlist =
      gst_element_class_get_pad_template_list (GST_ELEMENT_CLASS
      (G_OBJECT_GET_CLASS (element)));

  while (padlist) {
    GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;

    if (padtempl->presence == GST_PAD_ALWAYS) {
      GstPad *pad;

      pad = gst_pad_new_from_template (padtempl, padtempl->name_template);

      gst_element_add_pad (element, pad);
    }
    padlist = padlist->next;
  }
}

/**
 * gst_element_get_compatible_pad_template:
 * @element: a #GstElement to get a compatible pad template for.
 * @compattempl: the #GstPadTemplate to find a compatible template for.
 *
 * Retrieves a pad template from @element that is compatible with @compattempl.
 * Pads from compatible templates can be linked together.
 *
 * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
 * unreferencing is necessary.
 */
GstPadTemplate *
gst_element_get_compatible_pad_template (GstElement * element,
    GstPadTemplate * compattempl)
{
  GstPadTemplate *newtempl = NULL;
  GList *padlist;
  GstElementClass *class;

  g_return_val_if_fail (element != NULL, NULL);
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (compattempl != NULL, NULL);

  class = GST_ELEMENT_GET_CLASS (element);

  padlist = gst_element_class_get_pad_template_list (class);

  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
      "Looking for a suitable pad template in %s out of %d templates...",
      GST_ELEMENT_NAME (element), g_list_length (padlist));

  while (padlist) {
    GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
    GstCaps *intersection;

    /* Ignore name
     * Ignore presence
     * Check direction (must be opposite)
     * Check caps
     */
    GST_CAT_LOG (GST_CAT_CAPS,
        "checking pad template %s", padtempl->name_template);
    if (padtempl->direction != compattempl->direction) {
      GST_CAT_DEBUG (GST_CAT_CAPS,
          "compatible direction: found %s pad template \"%s\"",
          padtempl->direction == GST_PAD_SRC ? "src" : "sink",
          padtempl->name_template);

      GST_CAT_DEBUG (GST_CAT_CAPS,
          "intersecting %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (compattempl));
      GST_CAT_DEBUG (GST_CAT_CAPS,
          "..and %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (padtempl));

      intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
          GST_PAD_TEMPLATE_CAPS (padtempl));

      GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible %" GST_PTR_FORMAT,
          (intersection ? "" : "not "), intersection);

      if (!gst_caps_is_empty (intersection))
        newtempl = padtempl;
      gst_caps_unref (intersection);
      if (newtempl)
        break;
    }

    padlist = g_list_next (padlist);
  }
  if (newtempl)
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
        "Returning new pad template %p", newtempl);
  else
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "No compatible pad template found");

  return newtempl;
}

static GstPad *
gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
    const gchar * name)
{
  GstPad *newpad = NULL;
  GstElementClass *oclass;

  oclass = GST_ELEMENT_GET_CLASS (element);

  if (oclass->request_new_pad)
    newpad = (oclass->request_new_pad) (element, templ, name);

  if (newpad)
    gst_object_ref (newpad);

  return newpad;
}



/**
 * gst_element_get_pad_from_template:
 * @element: a #GstElement.
 * @templ: a #GstPadTemplate belonging to @element.
 *
 * Gets a pad from @element described by @templ. If the presence of @templ is
 * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
 * templates.
 *
 * Returns: the #GstPad, or NULL if one could not be found or created.
 */
static GstPad *
gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
{
  GstPad *ret = NULL;
  GstPadPresence presence;

  /* If this function is ever exported, we need check the validity of `element'
   * and `templ', and to make sure the template actually belongs to the
   * element. */

  presence = GST_PAD_TEMPLATE_PRESENCE (templ);

  switch (presence) {
    case GST_PAD_ALWAYS:
    case GST_PAD_SOMETIMES:
      ret = gst_element_get_static_pad (element, templ->name_template);
      if (!ret && presence == GST_PAD_ALWAYS)
        g_warning
            ("Element %s has an ALWAYS template %s, but no pad of the same name",
            GST_OBJECT_NAME (element), templ->name_template);
      break;

    case GST_PAD_REQUEST:
      ret = gst_element_request_pad (element, templ, NULL);
      break;
  }

  return ret;
}

/**
 * gst_element_request_compatible_pad:
 * @element: a #GstElement.
 * @templ: the #GstPadTemplate to which the new pad should be able to link.
 *
 * Requests a pad from @element. The returned pad should be unlinked and
 * compatible with @templ. Might return an existing pad, or request a new one.
 *
 * Returns: a #GstPad, or %NULL if one could not be found or created.
 */
GstPad *
gst_element_request_compatible_pad (GstElement * element,
    GstPadTemplate * templ)
{
  GstPadTemplate *templ_new;
  GstPad *pad = NULL;

  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);

  /* FIXME: should really loop through the templates, testing each for
   *      compatibility and pad availability. */
  templ_new = gst_element_get_compatible_pad_template (element, templ);
  if (templ_new)
    pad = gst_element_get_pad_from_template (element, templ_new);

  /* This can happen for non-request pads. No need to unref. */
  if (pad && GST_PAD_PEER (pad))
    pad = NULL;

  return pad;
}

/**
 * gst_element_get_compatible_pad:
 * @element: a #GstElement in which the pad should be found.
 * @pad: the #GstPad to find a compatible one for.
 * @caps: the #GstCaps to use as a filter.
 *
 * Looks for an unlinked pad to which the given pad can link. It is not
 * guaranteed that linking the pads will work, though it should work in most
 * cases.
 *
 * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
 * found. gst_object_unref() after usage.
 */
GstPad *
gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
    const GstCaps * caps)
{
  GstIterator *pads;
  GstPadTemplate *templ;
  GstCaps *templcaps;
  GstPad *foundpad = NULL;
  gboolean done;

  /* FIXME check for caps compatibility */

  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
      "finding pad in %s compatible with %s:%s",
      GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));

  g_return_val_if_fail (GST_PAD_PEER (pad) == NULL, NULL);

  done = FALSE;
  /* try to get an existing unlinked pad */
  pads = gst_element_iterate_pads (element);
  while (!done) {
    gpointer padptr;

    switch (gst_iterator_next (pads, &padptr)) {
      case GST_ITERATOR_OK:
      {
        GstPad *peer;
        GstPad *current;

        current = GST_PAD (padptr);

        GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
            GST_DEBUG_PAD_NAME (current));

        peer = gst_pad_get_peer (current);

        if (peer == NULL && gst_pad_can_link (pad, current)) {

          GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
              "found existing unlinked pad %s:%s",
              GST_DEBUG_PAD_NAME (current));

          gst_iterator_free (pads);

          return current;
        } else {
          GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads");

          gst_object_unref (current);
          if (peer)
            gst_object_unref (peer);
        }
        break;
      }
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (pads);
        break;
      case GST_ITERATOR_ERROR:
        g_assert_not_reached ();
        break;
    }
  }
  gst_iterator_free (pads);

  GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
      "Could not find a compatible unlinked always pad to link to %s:%s, now checking request pads",
      GST_DEBUG_PAD_NAME (pad));

  /* try to create a new one */
  /* requesting is a little crazy, we need a template. Let's create one */
  templcaps = gst_pad_get_caps (pad);

  templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
      GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
  foundpad = gst_element_request_compatible_pad (element, templ);
  gst_object_unref (templ);

  if (foundpad) {
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
        "found existing request pad %s:%s", GST_DEBUG_PAD_NAME (foundpad));
    return foundpad;
  }

  GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
      "Could not find a compatible pad to link to %s:%s",
      GST_DEBUG_PAD_NAME (pad));
  return NULL;
}

/**
 * gst_element_state_get_name:
 * @state: a #GstState to get the name of.
 *
 * Gets a string representing the given state.
 *
 * Returns: a string with the name of the state.
 */
G_CONST_RETURN gchar *
gst_element_state_get_name (GstState state)
{
  switch (state) {
#ifdef GST_DEBUG_COLOR
    case GST_STATE_VOID_PENDING:
      return "VOID_PENDING";
    case GST_STATE_NULL:
      return "\033[01;34mNULL\033[00m";
    case GST_STATE_READY:
      return "\033[01;31mREADY\033[00m";
    case GST_STATE_PLAYING:
      return "\033[01;32mPLAYING\033[00m";
    case GST_STATE_PAUSED:
      return "\033[01;33mPAUSED\033[00m";
    default:
      /* This is a memory leak */
      return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
#else
    case GST_STATE_VOID_PENDING:
      return "VOID_PENDING";
    case GST_STATE_NULL:
      return "NULL";
    case GST_STATE_READY:
      return "READY";
    case GST_STATE_PLAYING:
      return "PLAYING";
    case GST_STATE_PAUSED:
      return "PAUSED";
    default:
      /* This is a memory leak */
      return g_strdup_printf ("UNKNOWN!(%d)", state);
#endif
  }
}

/**
 * gst_element_state_change_return_get_name:
 * @state_ret: a #GstStateChangeReturn to get the name of.
 *
 * Gets a string representing the given state change result.
 *
 * Returns: a string with the name of the state change result.
 *
 * Since: 0.10.11
 */
G_CONST_RETURN gchar *
gst_element_state_change_return_get_name (GstStateChangeReturn state_ret)
{
  switch (state_ret) {
#ifdef GST_DEBUG_COLOR
    case GST_STATE_CHANGE_FAILURE:
      return "\033[01;31mFAILURE\033[00m";
    case GST_STATE_CHANGE_SUCCESS:
      return "\033[01;32mSUCCESS\033[00m";
    case GST_STATE_CHANGE_ASYNC:
      return "\033[01;33mASYNC\033[00m";
    case GST_STATE_CHANGE_NO_PREROLL:
      return "\033[01;34mNO_PREROLL\033[00m";
    default:
      /* This is a memory leak */
      return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state_ret);
#else
    case GST_STATE_CHANGE_FAILURE:
      return "FAILURE";
    case GST_STATE_CHANGE_SUCCESS:
      return "SUCCESS";
    case GST_STATE_CHANGE_ASYNC:
      return "ASYNC";
    case GST_STATE_CHANGE_NO_PREROLL:
      return "NO PREROLL";
    default:
      /* This is a memory leak */
      return g_strdup_printf ("UNKNOWN!(%d)", state_ret);
#endif
  }
}


/**
 * gst_element_factory_can_src_caps :
 * @factory: factory to query
 * @caps: the caps to check
 *
 * Checks if the factory can source the given capability.
 *
 * Returns: true if it can src the capabilities
 */
gboolean
gst_element_factory_can_src_caps (GstElementFactory * factory,
    const GstCaps * caps)
{
  GList *templates;

  g_return_val_if_fail (factory != NULL, FALSE);
  g_return_val_if_fail (caps != NULL, FALSE);

  templates = factory->staticpadtemplates;

  while (templates) {
    GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;

    if (template->direction == GST_PAD_SRC) {
      if (gst_caps_is_always_compatible (gst_static_caps_get (&template->
                  static_caps), caps))
        return TRUE;
    }
    templates = g_list_next (templates);
  }

  return FALSE;
}

/**
 * gst_element_factory_can_sink_caps :
 * @factory: factory to query
 * @caps: the caps to check
 *
 * Checks if the factory can sink the given capability.
 *
 * Returns: true if it can sink the capabilities
 */
gboolean
gst_element_factory_can_sink_caps (GstElementFactory * factory,
    const GstCaps * caps)
{
  GList *templates;

  g_return_val_if_fail (factory != NULL, FALSE);
  g_return_val_if_fail (caps != NULL, FALSE);

  templates = factory->staticpadtemplates;

  while (templates) {
    GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;

    if (template->direction == GST_PAD_SINK) {
      if (gst_caps_is_always_compatible (caps,
              gst_static_caps_get (&template->static_caps)))
        return TRUE;
    }
    templates = g_list_next (templates);
  }

  return FALSE;
}


/* if return val is true, *direct_child is a caller-owned ref on the direct
 * child of ancestor that is part of object's ancestry */
static gboolean
object_has_ancestor (GstObject * object, GstObject * ancestor,
    GstObject ** direct_child)
{
  GstObject *child, *parent;

  if (direct_child)
    *direct_child = NULL;

  child = gst_object_ref (object);
  parent = gst_object_get_parent (object);

  while (parent) {
    if (ancestor == parent) {
      if (direct_child)
        *direct_child = child;
      else
        gst_object_unref (child);
      gst_object_unref (parent);
      return TRUE;
    }

    gst_object_unref (child);
    child = parent;
    parent = gst_object_get_parent (parent);
  }

  gst_object_unref (child);

  return FALSE;
}

/* caller owns return */
static GstObject *
find_common_root (GstObject * o1, GstObject * o2)
{
  GstObject *top = o1;
  GstObject *kid1, *kid2;
  GstObject *root = NULL;

  while (GST_OBJECT_PARENT (top))
    top = GST_OBJECT_PARENT (top);

  /* the itsy-bitsy spider... */

  if (!object_has_ancestor (o2, top, &kid2))
    return NULL;

  root = gst_object_ref (top);
  while (TRUE) {
    if (!object_has_ancestor (o1, kid2, &kid1)) {
      gst_object_unref (kid2);
      return root;
    }
    root = kid2;
    if (!object_has_ancestor (o2, kid1, &kid2)) {
      gst_object_unref (kid1);
      return root;
    }
    root = kid1;
  }
}

/* caller does not own return */
static GstPad *
ghost_up (GstElement * e, GstPad * pad)
{
  static gint ghost_pad_index = 0;
  GstPad *gpad;
  gchar *name;
  GstObject *parent = GST_OBJECT_PARENT (e);

  name = g_strdup_printf ("ghost%d", ghost_pad_index++);
  gpad = gst_ghost_pad_new (name, pad);
  g_free (name);

  if (!gst_element_add_pad ((GstElement *) parent, gpad)) {
    g_warning ("Pad named %s already exists in element %s\n",
        GST_OBJECT_NAME (gpad), GST_OBJECT_NAME (parent));
    gst_object_unref ((GstObject *) gpad);
    return NULL;
  }

  return gpad;
}

static void
remove_pad (gpointer ppad, gpointer unused)
{
  GstPad *pad = ppad;

  if (!gst_element_remove_pad ((GstElement *) GST_OBJECT_PARENT (pad), pad))
    g_warning ("Couldn't remove pad %s from element %s",
        GST_OBJECT_NAME (pad), GST_OBJECT_NAME (GST_OBJECT_PARENT (pad)));
}

static gboolean
prepare_link_maybe_ghosting (GstPad ** src, GstPad ** sink,
    GSList ** pads_created)
{
  GstObject *root;
  GstObject *e1, *e2;
  GSList *pads_created_local = NULL;

  g_assert (pads_created);

  e1 = GST_OBJECT_PARENT (*src);
  e2 = GST_OBJECT_PARENT (*sink);

  if (G_UNLIKELY (e1 == NULL)) {
    GST_WARNING ("Trying to ghost a pad that doesn't have a parent: %"
        GST_PTR_FORMAT, *src);
    return FALSE;
  }
  if (G_UNLIKELY (e2 == NULL)) {
    GST_WARNING ("Trying to ghost a pad that doesn't have a parent: %"
        GST_PTR_FORMAT, *sink);
    return FALSE;
  }

  if (GST_OBJECT_PARENT (e1) == GST_OBJECT_PARENT (e2)) {
    GST_CAT_INFO (GST_CAT_PADS, "%s and %s in same bin, no need for ghost pads",
        GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
    return TRUE;
  }

  GST_CAT_INFO (GST_CAT_PADS, "%s and %s not in same bin, making ghost pads",
      GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));

  /* we need to setup some ghost pads */
  root = find_common_root (e1, e2);
  if (!root) {
    g_warning ("Trying to connect elements that don't share a common "
        "ancestor: %s and %s", GST_ELEMENT_NAME (e1), GST_ELEMENT_NAME (e2));
    return FALSE;
  }

  while (GST_OBJECT_PARENT (e1) != root) {
    *src = ghost_up ((GstElement *) e1, *src);
    if (!*src)
      goto cleanup_fail;
    e1 = GST_OBJECT_PARENT (*src);
    pads_created_local = g_slist_prepend (pads_created_local, *src);
  }
  while (GST_OBJECT_PARENT (e2) != root) {
    *sink = ghost_up ((GstElement *) e2, *sink);
    if (!*sink)
      goto cleanup_fail;
    e2 = GST_OBJECT_PARENT (*sink);
    pads_created_local = g_slist_prepend (pads_created_local, *sink);
  }

  gst_object_unref (root);
  *pads_created = g_slist_concat (*pads_created, pads_created_local);
  return TRUE;

cleanup_fail:
  gst_object_unref (root);
  g_slist_foreach (pads_created_local, remove_pad, NULL);
  g_slist_free (pads_created_local);
  return FALSE;
}

static gboolean
pad_link_maybe_ghosting (GstPad * src, GstPad * sink)
{
  GSList *pads_created = NULL;
  gboolean ret;

  if (!prepare_link_maybe_ghosting (&src, &sink, &pads_created)) {
    ret = FALSE;
  } else {
    ret = (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
  }

  if (!ret) {
    g_slist_foreach (pads_created, remove_pad, NULL);
  }
  g_slist_free (pads_created);

  return ret;
}

/**
 * gst_element_link_pads:
 * @src: a #GstElement containing the source pad.
 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
 * @dest: the #GstElement containing the destination pad.
 * @destpadname: the name of the #GstPad in destination element,
 * or NULL for any pad.
 *
 * Links the two named pads of the source and destination elements.
 * Side effect is that if one of the pads has no parent, it becomes a
 * child of the parent of the other element.  If they have different
 * parents, the link fails.
 *
 * Returns: TRUE if the pads could be linked, FALSE otherwise.
 */
gboolean
gst_element_link_pads (GstElement * src, const gchar * srcpadname,
    GstElement * dest, const gchar * destpadname)
{
  const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
  GstPad *srcpad, *destpad;
  GstPadTemplate *srctempl, *desttempl;
  GstElementClass *srcclass, *destclass;

  /* checks */
  g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
  g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);

  srcclass = GST_ELEMENT_GET_CLASS (src);
  destclass = GST_ELEMENT_GET_CLASS (dest);

  GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
      "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
      srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
      destpadname ? destpadname : "(any)");

  /* get a src pad */
  if (srcpadname) {
    /* name specified, look it up */
    if (!(srcpad = gst_element_get_static_pad (src, srcpadname)))
      srcpad = gst_element_get_request_pad (src, srcpadname);
    if (!srcpad) {
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
          GST_ELEMENT_NAME (src), srcpadname);
      return FALSE;
    } else {
      if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
        GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
            GST_DEBUG_PAD_NAME (srcpad));
        gst_object_unref (srcpad);
        return FALSE;
      }
      if (GST_PAD_PEER (srcpad) != NULL) {
        GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
            GST_DEBUG_PAD_NAME (srcpad));
        gst_object_unref (srcpad);
        return FALSE;
      }
    }
    srcpads = NULL;
  } else {
    /* no name given, get the first available pad */
    GST_OBJECT_LOCK (src);
    srcpads = GST_ELEMENT_PADS (src);
    srcpad = srcpads ? GST_PAD_CAST (srcpads->data) : NULL;
    if (srcpad)
      gst_object_ref (srcpad);
    GST_OBJECT_UNLOCK (src);
  }

  /* get a destination pad */
  if (destpadname) {
    /* name specified, look it up */
    if (!(destpad = gst_element_get_static_pad (dest, destpadname)))
      destpad = gst_element_get_request_pad (dest, destpadname);
    if (!destpad) {
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
          GST_ELEMENT_NAME (dest), destpadname);
      return FALSE;
    } else {
      if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
        GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
            GST_DEBUG_PAD_NAME (destpad));
        gst_object_unref (destpad);
        return FALSE;
      }
      if (GST_PAD_PEER (destpad) != NULL) {
        GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
            GST_DEBUG_PAD_NAME (destpad));
        gst_object_unref (destpad);
        return FALSE;
      }
    }
    destpads = NULL;
  } else {
    /* no name given, get the first available pad */
    GST_OBJECT_LOCK (dest);
    destpads = GST_ELEMENT_PADS (dest);
    destpad = destpads ? GST_PAD_CAST (destpads->data) : NULL;
    if (destpad)
      gst_object_ref (destpad);
    GST_OBJECT_UNLOCK (dest);
  }

  if (srcpadname && destpadname) {
    gboolean result;

    /* two explicitly specified pads */
    result = pad_link_maybe_ghosting (srcpad, destpad);

    gst_object_unref (srcpad);
    gst_object_unref (destpad);

    return result;
  }

  if (srcpad) {
    /* loop through the allowed pads in the source, trying to find a
     * compatible destination pad */
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
        "looping through allowed src and dest pads");
    do {
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
          GST_DEBUG_PAD_NAME (srcpad));
      if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
          (GST_PAD_PEER (srcpad) == NULL)) {
        GstPad *temp;

        if (destpadname) {
          temp = destpad;
          gst_object_ref (temp);
        } else {
          temp = gst_element_get_compatible_pad (dest, srcpad, NULL);
        }

        if (temp && pad_link_maybe_ghosting (srcpad, temp)) {
          GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
              GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
          if (destpad)
            gst_object_unref (destpad);
          gst_object_unref (srcpad);
          gst_object_unref (temp);
          return TRUE;
        }

        if (temp) {
          gst_object_unref (temp);
        }
      }
      /* find a better way for this mess */
      if (srcpads) {
        srcpads = g_list_next (srcpads);
        if (srcpads) {
          gst_object_unref (srcpad);
          srcpad = GST_PAD_CAST (srcpads->data);
          gst_object_ref (srcpad);
        }
      }
    } while (srcpads);
  }
  if (srcpadname) {
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
        GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
    if (destpad)
      gst_object_unref (destpad);
    destpad = NULL;
  }
  if (srcpad)
    gst_object_unref (srcpad);
  srcpad = NULL;

  if (destpad) {
    /* loop through the existing pads in the destination */
    do {
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
          GST_DEBUG_PAD_NAME (destpad));
      if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
          (GST_PAD_PEER (destpad) == NULL)) {
        GstPad *temp = gst_element_get_compatible_pad (src, destpad, NULL);

        if (temp && pad_link_maybe_ghosting (temp, destpad)) {
          GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
              GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
          gst_object_unref (temp);
          gst_object_unref (destpad);
          return TRUE;
        }
        if (temp) {
          gst_object_unref (temp);
        }
      }
      if (destpads) {
        destpads = g_list_next (destpads);
        if (destpads) {
          gst_object_unref (destpad);
          destpad = GST_PAD_CAST (destpads->data);
          gst_object_ref (destpad);
        }
      }
    } while (destpads);
  }

  if (destpadname) {
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
        GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
    gst_object_unref (destpad);
    return FALSE;
  } else {
    if (destpad)
      gst_object_unref (destpad);
    destpad = NULL;
  }

  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
      "we might have request pads on both sides, checking...");
  srctempls = gst_element_class_get_pad_template_list (srcclass);
  desttempls = gst_element_class_get_pad_template_list (destclass);

  if (srctempls && desttempls) {
    while (srctempls) {
      srctempl = (GstPadTemplate *) srctempls->data;
      if (srctempl->presence == GST_PAD_REQUEST) {
        for (l = desttempls; l; l = l->next) {
          desttempl = (GstPadTemplate *) l->data;
          if (desttempl->presence == GST_PAD_REQUEST &&
              desttempl->direction != srctempl->direction) {
            if (gst_caps_is_always_compatible (gst_pad_template_get_caps
                    (srctempl), gst_pad_template_get_caps (desttempl))) {
              srcpad =
                  gst_element_get_request_pad (src, srctempl->name_template);
              destpad =
                  gst_element_get_request_pad (dest, desttempl->name_template);
              if (srcpad && destpad
                  && pad_link_maybe_ghosting (srcpad, destpad)) {
                GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
                    "linked pad %s:%s to pad %s:%s",
                    GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
                gst_object_unref (srcpad);
                gst_object_unref (destpad);
                return TRUE;
              }
              /* it failed, so we release the request pads */
              if (srcpad)
                gst_element_release_request_pad (src, srcpad);
              if (destpad)
                gst_element_release_request_pad (dest, destpad);
            }
          }
        }
      }
      srctempls = srctempls->next;
    }
  }

  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
      GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
  return FALSE;
}

/**
 * gst_element_link_pads_filtered:
 * @src: a #GstElement containing the source pad.
 * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
 * @dest: the #GstElement containing the destination pad.
 * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
 * @filter: the #GstCaps to filter the link, or #NULL for no filter.
 *
 * Links the two named pads of the source and destination elements. Side effect
 * is that if one of the pads has no parent, it becomes a child of the parent of
 * the other element. If they have different parents, the link fails. If @caps
 * is not #NULL, makes sure that the caps of the link is a subset of @caps.
 *
 * Returns: TRUE if the pads could be linked, FALSE otherwise.
 */
gboolean
gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
    GstElement * dest, const gchar * destpadname, GstCaps * filter)
{
  /* checks */
  g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
  g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
  g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), FALSE);

  if (filter) {
    GstElement *capsfilter;
    GstObject *parent;
    GstState state, pending;

    capsfilter = gst_element_factory_make ("capsfilter", NULL);
    if (!capsfilter) {
      GST_ERROR ("Could not make a capsfilter");
      return FALSE;
    }

    parent = gst_object_get_parent (GST_OBJECT (src));
    g_return_val_if_fail (GST_IS_BIN (parent), FALSE);

    gst_element_get_state (GST_ELEMENT_CAST (parent), &state, &pending, 0);

    if (!gst_bin_add (GST_BIN (parent), capsfilter)) {
      GST_ERROR ("Could not add capsfilter");
      gst_object_unref (capsfilter);
      gst_object_unref (parent);
      return FALSE;
    }

    if (pending != GST_STATE_VOID_PENDING)
      state = pending;

    gst_element_set_state (capsfilter, state);

    gst_object_unref (parent);

    g_object_set (capsfilter, "caps", filter, NULL);

    if (gst_element_link_pads (src, srcpadname, capsfilter, "sink")
        && gst_element_link_pads (capsfilter, "src", dest, destpadname)) {
      return TRUE;
    } else {
      GST_INFO ("Could not link elements");
      gst_element_set_state (capsfilter, GST_STATE_NULL);
      /* this will unlink and unref as appropriate */
      gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (capsfilter)), capsfilter);
      return FALSE;
    }
  } else {
    return gst_element_link_pads (src, srcpadname, dest, destpadname);
  }
}

/**
 * gst_element_link:
 * @src: a #GstElement containing the source pad.
 * @dest: the #GstElement containing the destination pad.
 *
 * Links @src to @dest. The link must be from source to
 * destination; the other direction will not be tried. The function looks for
 * existing pads that aren't linked yet. It will request new pads if necessary.
 * Such pads need to be released manualy when unlinking.
 * If multiple links are possible, only one is established.
 *
 * Make sure you have added your elements to a bin or pipeline with
 * gst_bin_add() before trying to link them.
 *
 * Returns: TRUE if the elements could be linked, FALSE otherwise.
 */
gboolean
gst_element_link (GstElement * src, GstElement * dest)
{
  return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
}

/**
 * gst_element_link_many:
 * @element_1: the first #GstElement in the link chain.
 * @element_2: the second #GstElement in the link chain.
 * @...: the NULL-terminated list of elements to link in order.
 *
 * Chain together a series of elements. Uses gst_element_link().
 * Make sure you have added your elements to a bin or pipeline with
 * gst_bin_add() before trying to link them.
 *
 * Returns: TRUE on success, FALSE otherwise.
 */
gboolean
gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
{
  va_list args;

  g_return_val_if_fail (GST_IS_ELEMENT (element_1), FALSE);
  g_return_val_if_fail (GST_IS_ELEMENT (element_2), FALSE);

  va_start (args, element_2);

  while (element_2) {
    if (!gst_element_link (element_1, element_2))
      return FALSE;

    element_1 = element_2;
    element_2 = va_arg (args, GstElement *);
  }

  va_end (args);

  return TRUE;
}

/**
 * gst_element_link_filtered:
 * @src: a #GstElement containing the source pad.
 * @dest: the #GstElement containing the destination pad.
 * @filter: the #GstCaps to filter the link, or #NULL for no filter.
 *
 * Links @src to @dest using the given caps as filtercaps.
 * The link must be from source to
 * destination; the other direction will not be tried. The function looks for
 * existing pads that aren't linked yet. It will request new pads if necessary.
 * If multiple links are possible, only one is established.
 *
 * Make sure you have added your elements to a bin or pipeline with
 * gst_bin_add() before trying to link them.
 *
 * Returns: TRUE if the pads could be linked, FALSE otherwise.
 */
gboolean
gst_element_link_filtered (GstElement * src, GstElement * dest,
    GstCaps * filter)
{
  return gst_element_link_pads_filtered (src, NULL, dest, NULL, filter);
}

/**
 * gst_element_unlink_pads:
 * @src: a #GstElement containing the source pad.
 * @srcpadname: the name of the #GstPad in source element.
 * @dest: a #GstElement containing the destination pad.
 * @destpadname: the name of the #GstPad in destination element.
 *
 * Unlinks the two named pads of the source and destination elements.
 */
void
gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
    GstElement * dest, const gchar * destpadname)
{
  GstPad *srcpad, *destpad;
  gboolean srcrequest, destrequest;

  srcrequest = destrequest = FALSE;

  g_return_if_fail (src != NULL);
  g_return_if_fail (GST_IS_ELEMENT (src));
  g_return_if_fail (srcpadname != NULL);
  g_return_if_fail (dest != NULL);
  g_return_if_fail (GST_IS_ELEMENT (dest));
  g_return_if_fail (destpadname != NULL);

  /* obtain the pads requested */
  if (!(srcpad = gst_element_get_static_pad (src, srcpadname)))
    if ((srcpad = gst_element_get_request_pad (src, srcpadname)))
      srcrequest = TRUE;
  if (srcpad == NULL) {
    GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
    return;
  }
  if (!(destpad = gst_element_get_static_pad (dest, destpadname)))
    if ((destpad = gst_element_get_request_pad (dest, destpadname)))
      destrequest = TRUE;
  if (destpad == NULL) {
    GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
        destpadname);
    goto free_src;
  }

  /* we're satisified they can be unlinked, let's do it */
  gst_pad_unlink (srcpad, destpad);

  if (destrequest)
    gst_element_release_request_pad (dest, destpad);
  gst_object_unref (destpad);

free_src:
  if (srcrequest)
    gst_element_release_request_pad (src, srcpad);
  gst_object_unref (srcpad);
}

/**
 * gst_element_unlink_many:
 * @element_1: the first #GstElement in the link chain.
 * @element_2: the second #GstElement in the link chain.
 * @...: the NULL-terminated list of elements to unlink in order.
 *
 * Unlinks a series of elements. Uses gst_element_unlink().
 */
void
gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
{
  va_list args;

  g_return_if_fail (element_1 != NULL && element_2 != NULL);
  g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));

  va_start (args, element_2);

  while (element_2) {
    gst_element_unlink (element_1, element_2);

    element_1 = element_2;
    element_2 = va_arg (args, GstElement *);
  }

  va_end (args);
}

/**
 * gst_element_unlink:
 * @src: the source #GstElement to unlink.
 * @dest: the sink #GstElement to unlink.
 *
 * Unlinks all source pads of the source element with all sink pads
 * of the sink element to which they are linked.
 *
 * If the link has been made using gst_element_link(), it could have created an
 * requestpad, which has to be released using gst_element_release_request_pad().
 */
void
gst_element_unlink (GstElement * src, GstElement * dest)
{
  GstIterator *pads;
  gboolean done = FALSE;

  g_return_if_fail (GST_IS_ELEMENT (src));
  g_return_if_fail (GST_IS_ELEMENT (dest));

  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
      GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));

  pads = gst_element_iterate_pads (src);
  while (!done) {
    gpointer data;

    switch (gst_iterator_next (pads, &data)) {
      case GST_ITERATOR_OK:
      {
        GstPad *pad = GST_PAD_CAST (data);

        if (GST_PAD_IS_SRC (pad)) {
          GstPad *peerpad = gst_pad_get_peer (pad);

          /* see if the pad is linked and is really a pad of dest */
          if (peerpad) {
            GstElement *peerelem;

            peerelem = gst_pad_get_parent_element (peerpad);

            if (peerelem == dest) {
              gst_pad_unlink (pad, peerpad);
            }
            if (peerelem)
              gst_object_unref (peerelem);

            gst_object_unref (peerpad);
          }
        }
        gst_object_unref (pad);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (pads);
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      default:
        g_assert_not_reached ();
        break;
    }
  }
  gst_iterator_free (pads);
}

/**
 * gst_element_query_position:
 * @element: a #GstElement to invoke the position query on.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @cur: A location in which to store the current position, or NULL.
 *
 * Queries an element for the stream position.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_element_query_position (GstElement * element, GstFormat * format,
    gint64 * cur)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  query = gst_query_new_position (*format);
  ret = gst_element_query (element, query);

  if (ret)
    gst_query_parse_position (query, format, cur);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_element_query_duration:
 * @element: a #GstElement to invoke the duration query on.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @duration: A location in which to store the total duration, or NULL.
 *
 * Queries an element for the total stream duration.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_element_query_duration (GstElement * element, GstFormat * format,
    gint64 * duration)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  query = gst_query_new_duration (*format);
  ret = gst_element_query (element, query);

  if (ret)
    gst_query_parse_duration (query, format, duration);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_element_query_convert:
 * @element: a #GstElement to invoke the convert query on.
 * @src_format: a #GstFormat to convert from.
 * @src_val: a value to convert.
 * @dest_format: a pointer to the #GstFormat to convert to.
 * @dest_val: a pointer to the result.
 *
 * Queries an element to convert @src_val in @src_format to @dest_format.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_element_query_convert (GstElement * element, GstFormat src_format,
    gint64 src_val, GstFormat * dest_format, gint64 * dest_val)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_val != NULL, FALSE);

  if (*dest_format == src_format) {
    *dest_val = src_val;
    return TRUE;
  }

  query = gst_query_new_convert (src_format, src_val, *dest_format);
  ret = gst_element_query (element, query);

  if (ret)
    gst_query_parse_convert (query, NULL, NULL, dest_format, dest_val);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_element_seek_simple
 * @element: a #GstElement to seek on
 * @format: a #GstFormat to execute the seek in, such as #GST_FORMAT_TIME
 * @seek_flags: seek options; playback applications will usually want to use
 *            GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT here
 * @seek_pos: position to seek to (relative to the start); if you are doing
 *            a seek in #GST_FORMAT_TIME this value is in nanoseconds -
 *            multiply with #GST_SECOND to convert seconds to nanoseconds or
 *            with #GST_MSECOND to convert milliseconds to nanoseconds.
 *
 * Simple API to perform a seek on the given element, meaning it just seeks
 * to the given position relative to the start of the stream. For more complex
 * operations like segment seeks (e.g. for looping) or changing the playback
 * rate or seeking relative to the last configured playback segment you should
 * use gst_element_seek().
 *
 * In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
 * guaranteed to return %TRUE on a seekable media type or %FALSE when the media
 * type is certainly not seekable (such as a live stream).
 *
 * Some elements allow for seeking in the READY state, in this
 * case they will store the seek event and execute it when they are put to
 * PAUSED. If the element supports seek in READY, it will always return %TRUE when
 * it receives the event in the READY state.
 *
 * Returns: %TRUE if the seek operation succeeded (the seek might not always be
 * executed instantly though)
 *
 * Since: 0.10.7
 */
gboolean
gst_element_seek_simple (GstElement * element, GstFormat format,
    GstSeekFlags seek_flags, gint64 seek_pos)
{
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
  g_return_val_if_fail (seek_pos >= 0, FALSE);

  return gst_element_seek (element, 1.0, format, seek_flags,
      GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_NONE, 0);
}

/**
 * gst_pad_can_link:
 * @srcpad: the source #GstPad to link.
 * @sinkpad: the sink #GstPad to link.
 *
 * Checks if the source pad and the sink pad can be linked.
 * Both @srcpad and @sinkpad must be unlinked.
 *
 * Returns: TRUE if the pads can be linked, FALSE otherwise.
 */
gboolean
gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
{
  /* FIXME This function is gross.  It's almost a direct copy of
   * gst_pad_link_filtered().  Any decent programmer would attempt
   * to merge the two functions, which I will do some day. --ds
   */

  /* generic checks */
  g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
  g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);

  GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));

  /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
  if (GST_PAD_PEER (srcpad) != NULL) {
    GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
        GST_DEBUG_PAD_NAME (srcpad));
    return FALSE;
  }
  if (GST_PAD_PEER (sinkpad) != NULL) {
    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
        GST_DEBUG_PAD_NAME (sinkpad));
    return FALSE;
  }
  if (!GST_PAD_IS_SRC (srcpad)) {
    GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
        GST_DEBUG_PAD_NAME (srcpad));
    return FALSE;
  }
  if (!GST_PAD_IS_SINK (sinkpad)) {
    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
        GST_DEBUG_PAD_NAME (sinkpad));
    return FALSE;
  }
  if (GST_PAD_PARENT (srcpad) == NULL) {
    GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
        GST_DEBUG_PAD_NAME (srcpad));
    return FALSE;
  }
  if (GST_PAD_PARENT (sinkpad) == NULL) {
    GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
        GST_DEBUG_PAD_NAME (srcpad));
    return FALSE;
  }

  return TRUE;
}

/**
 * gst_pad_use_fixed_caps:
 * @pad: the pad to use
 *
 * A helper function you can use that sets the
 * @gst_pad_get_fixed_caps_func as the getcaps function for the
 * pad. This way the function will always return the negotiated caps
 * or in case the pad is not negotiated, the padtemplate caps.
 *
 * Use this function on a pad that, once _set_caps() has been called
 * on it, cannot be renegotiated to something else.
 */
void
gst_pad_use_fixed_caps (GstPad * pad)
{
  gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func);
}

/**
 * gst_pad_get_fixed_caps_func:
 * @pad: the pad to use
 *
 * A helper function you can use as a GetCaps function that
 * will return the currently negotiated caps or the padtemplate
 * when NULL.
 *
 * Returns: The currently negotiated caps or the padtemplate.
 */
GstCaps *
gst_pad_get_fixed_caps_func (GstPad * pad)
{
  GstCaps *result;

  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

  GST_OBJECT_LOCK (pad);
  if (GST_PAD_CAPS (pad)) {
    result = GST_PAD_CAPS (pad);

    GST_CAT_DEBUG (GST_CAT_CAPS,
        "using pad caps %p %" GST_PTR_FORMAT, result, result);

    result = gst_caps_ref (result);
    goto done;
  }
  if (GST_PAD_PAD_TEMPLATE (pad)) {
    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);

    result = GST_PAD_TEMPLATE_CAPS (templ);
    GST_CAT_DEBUG (GST_CAT_CAPS,
        "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
        result);

    result = gst_caps_ref (result);
    goto done;
  }
  GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
  result = gst_caps_new_empty ();

done:
  GST_OBJECT_UNLOCK (pad);

  return result;
}

/**
 * gst_pad_get_parent_element:
 * @pad: a pad
 *
 * Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
 * its parent is not an element, return NULL.
 *
 * Returns: The parent of the pad. The caller has a reference on the parent, so
 * unref when you're finished with it.
 *
 * MT safe.
 */
GstElement *
gst_pad_get_parent_element (GstPad * pad)
{
  GstObject *p;

  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

  p = gst_object_get_parent (GST_OBJECT_CAST (pad));

  if (p && !GST_IS_ELEMENT (p)) {
    gst_object_unref (p);
    p = NULL;
  }
  return GST_ELEMENT_CAST (p);
}

/**
 * gst_object_default_error:
 * @source: the #GstObject that initiated the error.
 * @error: the GError.
 * @debug: an additional debug information string, or NULL.
 *
 * A default error function.
 *
 * The default handler will simply print the error string using g_print.
 */
void
gst_object_default_error (GstObject * source, GError * error, gchar * debug)
{
  gchar *name = gst_object_get_path_string (source);

  g_print (_("ERROR: from element %s: %s\n"), name, error->message);
  if (debug)
    g_print (_("Additional debug info:\n%s\n"), debug);

  g_free (name);
}

/**
 * gst_bin_add_many:
 * @bin: a #GstBin
 * @element_1: the #GstElement element to add to the bin
 * @...: additional elements to add to the bin
 *
 * Adds a NULL-terminated list of elements to a bin.  This function is
 * equivalent to calling gst_bin_add() for each member of the list. The return
 * value of each gst_bin_add() is ignored.
 */
void
gst_bin_add_many (GstBin * bin, GstElement * element_1, ...)
{
  va_list args;

  g_return_if_fail (GST_IS_BIN (bin));
  g_return_if_fail (GST_IS_ELEMENT (element_1));

  va_start (args, element_1);

  while (element_1) {
    gst_bin_add (bin, element_1);

    element_1 = va_arg (args, GstElement *);
  }

  va_end (args);
}

/**
 * gst_bin_remove_many:
 * @bin: a #GstBin
 * @element_1: the first #GstElement to remove from the bin
 * @...: NULL-terminated list of elements to remove from the bin
 *
 * Remove a list of elements from a bin. This function is equivalent
 * to calling gst_bin_remove() with each member of the list.
 */
void
gst_bin_remove_many (GstBin * bin, GstElement * element_1, ...)
{
  va_list args;

  g_return_if_fail (GST_IS_BIN (bin));
  g_return_if_fail (GST_IS_ELEMENT (element_1));

  va_start (args, element_1);

  while (element_1) {
    gst_bin_remove (bin, element_1);

    element_1 = va_arg (args, GstElement *);
  }

  va_end (args);
}

static void
gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
    guint arg_id, GParamFlags flags)
{
  GQuark prop_id = g_quark_from_string (prop_name);
  GParamSpec *pspec;

  static GQuark fd_id = 0;
  static GQuark blocksize_id;
  static GQuark bytesperread_id;
  static GQuark dump_id;
  static GQuark filesize_id;
  static GQuark mmapsize_id;
  static GQuark location_id;
  static GQuark offset_id;
  static GQuark silent_id;
  static GQuark touch_id;

  if (!fd_id) {
    fd_id = g_quark_from_static_string ("fd");
    blocksize_id = g_quark_from_static_string ("blocksize");
    bytesperread_id = g_quark_from_static_string ("bytesperread");
    dump_id = g_quark_from_static_string ("dump");
    filesize_id = g_quark_from_static_string ("filesize");
    mmapsize_id = g_quark_from_static_string ("mmapsize");
    location_id = g_quark_from_static_string ("location");
    offset_id = g_quark_from_static_string ("offset");
    silent_id = g_quark_from_static_string ("silent");
    touch_id = g_quark_from_static_string ("touch");
  }

  if (prop_id == fd_id) {
    pspec = g_param_spec_int ("fd", "File-descriptor",
        "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
  } else if (prop_id == blocksize_id) {
    pspec = g_param_spec_ulong ("blocksize", "Block Size",
        "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);

  } else if (prop_id == bytesperread_id) {
    pspec = g_param_spec_int ("bytesperread", "Bytes per read",
        "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);

  } else if (prop_id == dump_id) {
    pspec = g_param_spec_boolean ("dump", "Dump",
        "Dump bytes to stdout", FALSE, flags);

  } else if (prop_id == filesize_id) {
    pspec = g_param_spec_int64 ("filesize", "File Size",
        "Size of the file being read", 0, G_MAXINT64, 0, flags);

  } else if (prop_id == mmapsize_id) {
    pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
        "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);

  } else if (prop_id == location_id) {
    pspec = g_param_spec_string ("location", "File Location",
        "Location of the file to read", NULL, flags);

  } else if (prop_id == offset_id) {
    pspec = g_param_spec_int64 ("offset", "File Offset",
        "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);

  } else if (prop_id == silent_id) {
    pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
        FALSE, flags);

  } else if (prop_id == touch_id) {
    pspec = g_param_spec_boolean ("touch", "Touch read data",
        "Touch data to force disk read before " "push ()", TRUE, flags);
  } else {
    g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
        prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
    pspec = NULL;
  }

  if (pspec) {
    g_object_class_install_property (klass, arg_id, pspec);
  }
}

/**
 * gst_element_class_install_std_props:
 * @klass: the #GstElementClass to add the properties to.
 * @first_name: the name of the first property.
 * in a NULL terminated
 * @...: the id and flags of the first property, followed by
 * further 'name', 'id', 'flags' triplets and terminated by NULL.
 *
 * Adds a list of standardized properties with types to the @klass.
 * the id is for the property switch in your get_prop method, and
 * the flags determine readability / writeability.
 **/
void
gst_element_class_install_std_props (GstElementClass * klass,
    const gchar * first_name, ...)
{
  const char *name;

  va_list args;

  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));

  va_start (args, first_name);

  name = first_name;

  while (name) {
    int arg_id = va_arg (args, int);
    int flags = va_arg (args, int);

    gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
        flags);

    name = va_arg (args, char *);
  }

  va_end (args);
}


/**
 * gst_buffer_merge:
 * @buf1: the first source #GstBuffer to merge.
 * @buf2: the second source #GstBuffer to merge.
 *
 * Create a new buffer that is the concatenation of the two source
 * buffers.  The original source buffers will not be modified or
 * unref'd.  Make sure you unref the source buffers if they are not used
 * anymore afterwards.
 *
 * If the buffers point to contiguous areas of memory, the buffer
 * is created without copying the data.
 *
 * Returns: the new #GstBuffer which is the concatenation of the source buffers.
 */
GstBuffer *
gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
{
  GstBuffer *result;

  /* we're just a specific case of the more general gst_buffer_span() */
  result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);

  return result;
}

/**
 * gst_buffer_join:
 * @buf1: the first source #GstBuffer.
 * @buf2: the second source #GstBuffer.
 *
 * Create a new buffer that is the concatenation of the two source
 * buffers, and unrefs the original source buffers.
 *
 * If the buffers point to contiguous areas of memory, the buffer
 * is created without copying the data.
 *
 * Returns: the new #GstBuffer which is the concatenation of the source buffers.
 */
GstBuffer *
gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
{
  GstBuffer *result;

  result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
  gst_buffer_unref (buf1);
  gst_buffer_unref (buf2);

  return result;
}


/**
 * gst_buffer_stamp:
 * @dest: buffer to stamp
 * @src: buffer to stamp from
 *
 * Copies additional information (the timestamp, duration, and offset start
 * and end) from one buffer to the other.
 *
 * This function does not copy any buffer flags or caps and is equivalent to
 * gst_buffer_copy_metadata(@dest, @src, GST_BUFFER_COPY_TIMESTAMPS).
 *
 * Deprecated: use gst_buffer_copy_metadata() instead, it provides more
 * control.
 */
#ifndef GST_REMOVE_DEPRECATED
void
gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
{
  gst_buffer_copy_metadata (dest, src, GST_BUFFER_COPY_TIMESTAMPS);
}
#endif /* GST_REMOVE_DEPRECATED */

static gboolean
intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig)
{
  if (pad != orig) {
    GstCaps *peercaps, *existing;

    existing = g_value_get_pointer (ret);
    peercaps = gst_pad_peer_get_caps (pad);
    if (peercaps == NULL)
      peercaps = gst_caps_new_any ();
    g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps));
    gst_caps_unref (existing);
    gst_caps_unref (peercaps);
  }
  gst_object_unref (pad);
  return TRUE;
}

/**
 * gst_pad_proxy_getcaps:
 * @pad: a #GstPad to proxy.
 *
 * Calls gst_pad_get_allowed_caps() for every other pad belonging to the
 * same element as @pad, and returns the intersection of the results.
 *
 * This function is useful as a default getcaps function for an element
 * that can handle any stream format, but requires all its pads to have
 * the same caps.  Two such elements are tee and aggregator.
 *
 * Returns: the intersection of the other pads' allowed caps.
 */
GstCaps *
gst_pad_proxy_getcaps (GstPad * pad)
{
  GstElement *element;
  GstCaps *caps, *intersected;
  GstIterator *iter;
  GstIteratorResult res;
  GValue ret = { 0, };

  g_return_val_if_fail (GST_IS_PAD (pad), NULL);

  GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad));

  element = gst_pad_get_parent_element (pad);
  if (element == NULL)
    return NULL;

  /* value to hold the return, by default it holds ANY, the ref is taken by
   * the GValue. */
  g_value_init (&ret, G_TYPE_POINTER);
  g_value_set_pointer (&ret, gst_caps_new_any ());

  iter = gst_element_iterate_pads (element);
  while (1) {
    res =
        gst_iterator_fold (iter, (GstIteratorFoldFunction) intersect_caps_func,
        &ret, pad);
    switch (res) {
      case GST_ITERATOR_RESYNC:
        /* unref any value stored */
        if ((caps = g_value_get_pointer (&ret)))
          gst_caps_unref (caps);
        /* need to reset the result again to ANY */
        g_value_set_pointer (&ret, gst_caps_new_any ());
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_DONE:
        /* all pads iterated, return collected value */
        goto done;
      default:
        /* iterator returned _ERROR or premature end with _OK,
         * mark an error and exit */
        if ((caps = g_value_get_pointer (&ret)))
          gst_caps_unref (caps);
        g_value_set_pointer (&ret, NULL);
        goto error;
    }
  }
done:
  gst_iterator_free (iter);

  gst_object_unref (element);

  caps = g_value_get_pointer (&ret);
  g_value_unset (&ret);

  intersected = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad));
  gst_caps_unref (caps);

  return intersected;

  /* ERRORS */
error:
  {
    g_warning ("Pad list returned error on element %s",
        GST_ELEMENT_NAME (element));
    gst_iterator_free (iter);
    gst_object_unref (element);
    return NULL;
  }
}

typedef struct
{
  GstPad *orig;
  GstCaps *caps;
} LinkData;

static gboolean
link_fold_func (GstPad * pad, GValue * ret, LinkData * data)
{
  gboolean success = TRUE;

  if (pad != data->orig) {
    success = gst_pad_set_caps (pad, data->caps);
    g_value_set_boolean (ret, success);
  }
  gst_object_unref (pad);

  return success;
}

/**
 * gst_pad_proxy_setcaps
 * @pad: a #GstPad to proxy from
 * @caps: the #GstCaps to link with
 *
 * Calls gst_pad_set_caps() for every other pad belonging to the
 * same element as @pad.  If gst_pad_set_caps() fails on any pad,
 * the proxy setcaps fails. May be used only during negotiation.
 *
 * Returns: TRUE if sucessful
 */
gboolean
gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
{
  GstElement *element;
  GstIterator *iter;
  GstIteratorResult res;
  GValue ret = { 0, };
  LinkData data;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (caps != NULL, FALSE);

  GST_DEBUG ("proxying pad link for %s:%s", GST_DEBUG_PAD_NAME (pad));

  element = gst_pad_get_parent_element (pad);
  if (element == NULL)
    return FALSE;

  iter = gst_element_iterate_pads (element);

  g_value_init (&ret, G_TYPE_BOOLEAN);
  g_value_set_boolean (&ret, TRUE);
  data.orig = pad;
  data.caps = caps;

  res = gst_iterator_fold (iter, (GstIteratorFoldFunction) link_fold_func,
      &ret, &data);
  gst_iterator_free (iter);

  if (res != GST_ITERATOR_DONE)
    goto pads_changed;

  gst_object_unref (element);

  /* ok not to unset the gvalue */
  return g_value_get_boolean (&ret);

  /* ERRORS */
pads_changed:
  {
    g_warning ("Pad list changed during proxy_pad_link for element %s",
        GST_ELEMENT_NAME (element));
    gst_object_unref (element);
    return FALSE;
  }
}

/**
 * gst_pad_query_position:
 * @pad: a #GstPad to invoke the position query on.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @cur: A location in which to store the current position, or NULL.
 *
 * Queries a pad for the stream position.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_position (GstPad * pad, GstFormat * format, gint64 * cur)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  query = gst_query_new_position (*format);
  ret = gst_pad_query (pad, query);

  if (ret)
    gst_query_parse_position (query, format, cur);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_pad_query_peer_position:
 * @pad: a #GstPad on whose peer to invoke the position query on.
 *       Must be a sink pad.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @cur: A location in which to store the current position, or NULL.
 *
 * Queries the peer of a given sink pad for the stream position.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_peer_position (GstPad * pad, GstFormat * format, gint64 * cur)
{
  gboolean ret = FALSE;
  GstPad *peer;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  peer = gst_pad_get_peer (pad);
  if (peer) {
    ret = gst_pad_query_position (peer, format, cur);
    gst_object_unref (peer);
  }

  return ret;
}

/**
 * gst_pad_query_duration:
 * @pad: a #GstPad to invoke the duration query on.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @duration: A location in which to store the total duration, or NULL.
 *
 * Queries a pad for the total stream duration.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_duration (GstPad * pad, GstFormat * format, gint64 * duration)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  query = gst_query_new_duration (*format);
  ret = gst_pad_query (pad, query);

  if (ret)
    gst_query_parse_duration (query, format, duration);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_pad_query_peer_duration:
 * @pad: a #GstPad on whose peer pad to invoke the duration query on.
 *       Must be a sink pad.
 * @format: a pointer to the #GstFormat asked for.
 *          On return contains the #GstFormat used.
 * @duration: A location in which to store the total duration, or NULL.
 *
 * Queries the peer pad of a given sink pad for the total stream duration.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_peer_duration (GstPad * pad, GstFormat * format,
    gint64 * duration)
{
  gboolean ret = FALSE;
  GstPad *peer;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
  g_return_val_if_fail (format != NULL, FALSE);

  peer = gst_pad_get_peer (pad);
  if (peer) {
    ret = gst_pad_query_duration (peer, format, duration);
    gst_object_unref (peer);
  }

  return ret;
}

/**
 * gst_pad_query_convert:
 * @pad: a #GstPad to invoke the convert query on.
 * @src_format: a #GstFormat to convert from.
 * @src_val: a value to convert.
 * @dest_format: a pointer to the #GstFormat to convert to.
 * @dest_val: a pointer to the result.
 *
 * Queries a pad to convert @src_val in @src_format to @dest_format.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
    GstFormat * dest_format, gint64 * dest_val)
{
  GstQuery *query;
  gboolean ret;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (src_val >= 0, FALSE);
  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_val != NULL, FALSE);

  if (*dest_format == src_format) {
    *dest_val = src_val;
    return TRUE;
  }

  query = gst_query_new_convert (src_format, src_val, *dest_format);
  ret = gst_pad_query (pad, query);

  if (ret)
    gst_query_parse_convert (query, NULL, NULL, dest_format, dest_val);

  gst_query_unref (query);

  return ret;
}

/**
 * gst_pad_query_peer_convert:
 * @pad: a #GstPad, on whose peer pad to invoke the convert query on.
 *       Must be a sink pad.
 * @src_format: a #GstFormat to convert from.
 * @src_val: a value to convert.
 * @dest_format: a pointer to the #GstFormat to convert to.
 * @dest_val: a pointer to the result.
 *
 * Queries the peer pad of a given sink pad to convert @src_val in @src_format
 * to @dest_format.
 *
 * Returns: TRUE if the query could be performed.
 */
gboolean
gst_pad_query_peer_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
    GstFormat * dest_format, gint64 * dest_val)
{
  gboolean ret = FALSE;
  GstPad *peer;

  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
  g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
  g_return_val_if_fail (src_val >= 0, FALSE);
  g_return_val_if_fail (dest_format != NULL, FALSE);
  g_return_val_if_fail (dest_val != NULL, FALSE);

  peer = gst_pad_get_peer (pad);
  if (peer) {
    ret = gst_pad_query_convert (peer, src_format, src_val, dest_format,
        dest_val);
    gst_object_unref (peer);
  }

  return ret;
}

/**
 * gst_atomic_int_set:
 * @atomic_int: pointer to an atomic integer
 * @value: value to set
 *
 * Unconditionally sets the atomic integer to @value.
 * 
 * Deprecated: Use g_atomic_int_set().
 *
 */
#ifndef GST_REMOVE_DEPRECATED
void
gst_atomic_int_set (gint * atomic_int, gint value)
{
  g_atomic_int_set (atomic_int, value);
}
#endif

/**
 * gst_pad_add_data_probe:
 * @pad: pad to add the data probe handler to
 * @handler: function to call when data is passed over pad
 * @data: data to pass along with the handler
 *
 * Adds a "data probe" to a pad. This function will be called whenever data
 * passes through a pad. In this case data means both events and buffers. The
 * probe will be called with the data as an argument, meaning @handler should
 * have the same callback signature as the #GstPad::have-data signal.
 * Note that the data will have a reference count greater than 1, so it will
 * be immutable -- you must not change it.
 *
 * For source pads, the probe will be called after the blocking function, if any
 * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
 * to. For sink pads, the probe function will be called before configuring the
 * sink with new caps, if any, and before calling the pad's chain function.
 *
 * Your data probe should return TRUE to let the data continue to flow, or FALSE
 * to drop it. Dropping data is rarely useful, but occasionally comes in handy
 * with events.
 *
 * Although probes are implemented internally by connecting @handler to the
 * have-data signal on the pad, if you want to remove a probe it is insufficient
 * to only call g_signal_handler_disconnect on the returned handler id. To
 * remove a probe, use the appropriate function, such as
 * gst_pad_remove_data_probe().
 *
 * Returns: The handler id.
 */
gulong
gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
{
  return gst_pad_add_data_probe_full (pad, handler, data, NULL);
}

/**
 * gst_pad_add_data_probe_full:
 * @pad: pad to add the data probe handler to
 * @handler: function to call when data is passed over pad
 * @data: data to pass along with the handler
 * @notify: function to call when the probe is disconnected, or NULL
 *
 * Adds a "data probe" to a pad. This function will be called whenever data
 * passes through a pad. In this case data means both events and buffers. The
 * probe will be called with the data as an argument, meaning @handler should
 * have the same callback signature as the #GstPad::have-data signal.
 * Note that the data will have a reference count greater than 1, so it will
 * be immutable -- you must not change it.
 *
 * For source pads, the probe will be called after the blocking function, if any
 * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
 * to. For sink pads, the probe function will be called before configuring the
 * sink with new caps, if any, and before calling the pad's chain function.
 *
 * Your data probe should return TRUE to let the data continue to flow, or FALSE
 * to drop it. Dropping data is rarely useful, but occasionally comes in handy
 * with events.
 *
 * Although probes are implemented internally by connecting @handler to the
 * have-data signal on the pad, if you want to remove a probe it is insufficient
 * to only call g_signal_handler_disconnect on the returned handler id. To
 * remove a probe, use the appropriate function, such as
 * gst_pad_remove_data_probe().
 *
 * The @notify function is called when the probe is disconnected and usually
 * used to free @data.
 *
 * Returns: The handler id.
 *
 * Since: 0.10.20
 */
gulong
gst_pad_add_data_probe_full (GstPad * pad, GCallback handler,
    gpointer data, GDestroyNotify notify)
{
  gulong sigid;

  g_return_val_if_fail (GST_IS_PAD (pad), 0);
  g_return_val_if_fail (handler != NULL, 0);

  GST_OBJECT_LOCK (pad);

  /* we only expose a GDestroyNotify in our API because that's less confusing */
  sigid = g_signal_connect_data (pad, "have-data", handler, data,
      (GClosureNotify) notify, 0);

  GST_PAD_DO_EVENT_SIGNALS (pad)++;
  GST_PAD_DO_BUFFER_SIGNALS (pad)++;
  GST_DEBUG ("adding data probe to pad %s:%s, now %d data, %d event probes",
      GST_DEBUG_PAD_NAME (pad),
      GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);

  return sigid;
}

/**
 * gst_pad_add_event_probe:
 * @pad: pad to add the event probe handler to
 * @handler: function to call when events are passed over pad
 * @data: data to pass along with the handler
 *
 * Adds a probe that will be called for all events passing through a pad. See
 * gst_pad_add_data_probe() for more information.
 *
 * Returns: The handler id
 */
gulong
gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
{
  return gst_pad_add_event_probe_full (pad, handler, data, NULL);
}

/**
 * gst_pad_add_event_probe_full:
 * @pad: pad to add the event probe handler to
 * @handler: function to call when events are passed over pad
 * @data: data to pass along with the handler, or NULL
 * @notify: function to call when probe is disconnected, or NULL
 *
 * Adds a probe that will be called for all events passing through a pad. See
 * gst_pad_add_data_probe() for more information.
 *
 * The @notify function is called when the probe is disconnected and usually
 * used to free @data.
 *
 * Returns: The handler id
 *
 * Since: 0.10.20
 */
gulong
gst_pad_add_event_probe_full (GstPad * pad, GCallback handler,
    gpointer data, GDestroyNotify notify)
{
  gulong sigid;

  g_return_val_if_fail (GST_IS_PAD (pad), 0);
  g_return_val_if_fail (handler != NULL, 0);

  GST_OBJECT_LOCK (pad);

  /* we only expose a GDestroyNotify in our API because that's less confusing */
  sigid = g_signal_connect_data (pad, "have-data::event", handler, data,
      (GClosureNotify) notify, 0);

  GST_PAD_DO_EVENT_SIGNALS (pad)++;
  GST_DEBUG ("adding event probe to pad %s:%s, now %d probes",
      GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);

  return sigid;
}

/**
 * gst_pad_add_buffer_probe:
 * @pad: pad to add the buffer probe handler to
 * @handler: function to call when buffers are passed over pad
 * @data: data to pass along with the handler
 *
 * Adds a probe that will be called for all buffers passing through a pad. See
 * gst_pad_add_data_probe() for more information.
 *
 * Returns: The handler id
 */
gulong
gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
{
  return gst_pad_add_buffer_probe_full (pad, handler, data, NULL);
}

/**
 * gst_pad_add_buffer_probe_full:
 * @pad: pad to add the buffer probe handler to
 * @handler: function to call when buffer are passed over pad
 * @data: data to pass along with the handler
 * @notify: function to call when the probe is disconnected, or NULL
 *
 * Adds a probe that will be called for all buffers passing through a pad. See
 * gst_pad_add_data_probe() for more information.
 *
 * The @notify function is called when the probe is disconnected and usually
 * used to free @data.
 *
 * Returns: The handler id
 *
 * Since: 0.10.20
 */
gulong
gst_pad_add_buffer_probe_full (GstPad * pad, GCallback handler,
    gpointer data, GDestroyNotify notify)
{
  gulong sigid;

  g_return_val_if_fail (GST_IS_PAD (pad), 0);
  g_return_val_if_fail (handler != NULL, 0);

  GST_OBJECT_LOCK (pad);

  /* we only expose a GDestroyNotify in our API because that's less confusing */
  sigid = g_signal_connect_data (pad, "have-data::buffer", handler, data,
      (GClosureNotify) notify, 0);

  GST_PAD_DO_BUFFER_SIGNALS (pad)++;
  GST_DEBUG ("adding buffer probe to pad %s:%s, now %d probes",
      GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);

  return sigid;
}

/**
 * gst_pad_remove_data_probe:
 * @pad: pad to remove the data probe handler from
 * @handler_id: handler id returned from gst_pad_add_data_probe
 *
 * Removes a data probe from @pad.
 */
void
gst_pad_remove_data_probe (GstPad * pad, guint handler_id)
{
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (handler_id > 0);

  GST_OBJECT_LOCK (pad);
  g_signal_handler_disconnect (pad, handler_id);
  GST_PAD_DO_BUFFER_SIGNALS (pad)--;
  GST_PAD_DO_EVENT_SIGNALS (pad)--;
  GST_DEBUG
      ("removed data probe from pad %s:%s, now %d event, %d buffer probes",
      GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad),
      GST_PAD_DO_BUFFER_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);

}

/**
 * gst_pad_remove_event_probe:
 * @pad: pad to remove the event probe handler from
 * @handler_id: handler id returned from gst_pad_add_event_probe
 *
 * Removes an event probe from @pad.
 */
void
gst_pad_remove_event_probe (GstPad * pad, guint handler_id)
{
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (handler_id > 0);

  GST_OBJECT_LOCK (pad);
  g_signal_handler_disconnect (pad, handler_id);
  GST_PAD_DO_EVENT_SIGNALS (pad)--;
  GST_DEBUG ("removed event probe from pad %s:%s, now %d event probes",
      GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);
}

/**
 * gst_pad_remove_buffer_probe:
 * @pad: pad to remove the buffer probe handler from
 * @handler_id: handler id returned from gst_pad_add_buffer_probe
 *
 * Removes a buffer probe from @pad.
 */
void
gst_pad_remove_buffer_probe (GstPad * pad, guint handler_id)
{
  g_return_if_fail (GST_IS_PAD (pad));
  g_return_if_fail (handler_id > 0);

  GST_OBJECT_LOCK (pad);
  g_signal_handler_disconnect (pad, handler_id);
  GST_PAD_DO_BUFFER_SIGNALS (pad)--;
  GST_DEBUG ("removed buffer probe from pad %s:%s, now %d buffer probes",
      GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
  GST_OBJECT_UNLOCK (pad);

}

/**
 * gst_element_found_tags_for_pad:
 * @element: element for which to post taglist to bus.
 * @pad: pad on which to push tag-event.
 * @list: the taglist to post on the bus and create event from.
 *
 * Posts a message to the bus that new tags were found and pushes the
 * tags as event. Takes ownership of the @list.
 *
 * This is a utility method for elements. Applications should use the
 * #GstTagSetter interface.
 */
void
gst_element_found_tags_for_pad (GstElement * element,
    GstPad * pad, GstTagList * list)
{
  g_return_if_fail (element != NULL);
  g_return_if_fail (pad != NULL);
  g_return_if_fail (list != NULL);

  gst_pad_push_event (pad, gst_event_new_tag (gst_tag_list_copy (list)));
  gst_element_post_message (element,
      gst_message_new_tag (GST_OBJECT (element), list));
}

static void
push_and_ref (GstPad * pad, GstEvent * event)
{
  gst_pad_push_event (pad, gst_event_ref (event));
  /* iterator refs pad, we unref when we are done with it */
  gst_object_unref (pad);
}

/**
 * gst_element_found_tags:
 * @element: element for which we found the tags.
 * @list: list of tags.
 *
 * Posts a message to the bus that new tags were found, and pushes an event
 * to all sourcepads. Takes ownership of the @list.
 *
 * This is a utility method for elements. Applications should use the
 * #GstTagSetter interface.
 */
void
gst_element_found_tags (GstElement * element, GstTagList * list)
{
  GstIterator *iter;
  GstEvent *event;

  g_return_if_fail (element != NULL);
  g_return_if_fail (list != NULL);

  iter = gst_element_iterate_src_pads (element);
  event = gst_event_new_tag (gst_tag_list_copy (list));
  gst_iterator_foreach (iter, (GFunc) push_and_ref, event);
  gst_iterator_free (iter);
  gst_event_unref (event);

  gst_element_post_message (element,
      gst_message_new_tag (GST_OBJECT (element), list));
}

static GstPad *
element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
{
  GstIterator *iter;
  GstPad *unlinked_pad = NULL;
  gboolean done;

  switch (direction) {
    case GST_PAD_SRC:
      iter = gst_element_iterate_src_pads (element);
      break;
    case GST_PAD_SINK:
      iter = gst_element_iterate_sink_pads (element);
      break;
    default:
      g_return_val_if_reached (NULL);
  }

  done = FALSE;
  while (!done) {
    gpointer pad;

    switch (gst_iterator_next (iter, &pad)) {
      case GST_ITERATOR_OK:{
        GstPad *peer;

        GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
            GST_DEBUG_PAD_NAME (pad));

        peer = gst_pad_get_peer (GST_PAD (pad));
        if (peer == NULL) {
          unlinked_pad = pad;
          done = TRUE;
          GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
              "found existing unlinked pad %s:%s",
              GST_DEBUG_PAD_NAME (unlinked_pad));
        } else {
          gst_object_unref (pad);
          gst_object_unref (peer);
        }
        break;
      }
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_ERROR:
        g_return_val_if_reached (NULL);
        break;
    }
  }

  gst_iterator_free (iter);

  return unlinked_pad;
}

/**
 * gst_bin_find_unlinked_pad:
 * @bin: bin in which to look for elements with unlinked pads
 * @direction: whether to look for an unlinked source or sink pad
 *
 * Recursively looks for elements with an unlinked pad of the given
 * direction within the specified bin and returns an unlinked pad
 * if one is found, or NULL otherwise. If a pad is found, the caller
 * owns a reference to it and should use gst_object_unref() on the
 * pad when it is not needed any longer.
 *
 * Returns: unlinked pad of the given direction, or NULL.
 *
 * Since: 0.10.20
 */
GstPad *
gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
{
  GstIterator *iter;
  gboolean done;
  GstPad *pad = NULL;

  g_return_val_if_fail (GST_IS_BIN (bin), NULL);
  g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);

  done = FALSE;
  iter = gst_bin_iterate_recurse (bin);
  while (!done) {
    gpointer element;

    switch (gst_iterator_next (iter, &element)) {
      case GST_ITERATOR_OK:
        pad = element_find_unlinked_pad (GST_ELEMENT (element), direction);
        gst_object_unref (element);
        if (pad != NULL)
          done = TRUE;
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_ERROR:
        g_return_val_if_reached (NULL);
        break;
    }
  }

  gst_iterator_free (iter);

  return pad;
}

/**
 * gst_bin_find_unconnected_pad:
 * @bin: bin in which to look for elements with unlinked pads
 * @direction: whether to look for an unlinked source or sink pad
 *
 * Recursively looks for elements with an unlinked pad of the given
 * direction within the specified bin and returns an unlinked pad
 * if one is found, or NULL otherwise. If a pad is found, the caller
 * owns a reference to it and should use gst_object_unref() on the
 * pad when it is not needed any longer.
 *
 * Returns: unlinked pad of the given direction, or NULL.
 *
 * Since: 0.10.3
 *
 * Deprecated: use gst_bin_find_unlinked_pad() instead.
 */
#ifndef GST_REMOVE_DEPRECATED
GstPad *
gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
{
  return gst_bin_find_unlinked_pad (bin, direction);
}
#endif

/**
 * gst_parse_bin_from_description:
 * @bin_description: command line describing the bin
 * @ghost_unlinked_pads: whether to automatically create ghost pads
 *     for unlinked source or sink pads within the bin
 * @err: where to store the error message in case of an error, or NULL
 *
 * This is a convenience wrapper around gst_parse_launch() to create a
 * #GstBin from a gst-launch-style pipeline description. See
 * gst_parse_launch() and the gst-launch man page for details about the
 * syntax. Ghost pads on the bin for unlinked source or sink pads
 * within the bin can automatically be created (but only a maximum of
 * one ghost pad for each direction will be created; if you expect
 * multiple unlinked source pads or multiple unlinked sink pads
 * and want them all ghosted, you will have to create the ghost pads
 * yourself).
 *
 * Returns: a newly-created bin, or NULL if an error occurred.
 *
 * Since: 0.10.3
 */
GstElement *
gst_parse_bin_from_description (const gchar * bin_description,
    gboolean ghost_unlinked_pads, GError ** err)
{
  return gst_parse_bin_from_description_full (bin_description,
      ghost_unlinked_pads, NULL, 0, err);
}

/**
 * gst_parse_bin_from_description_full:
 * @bin_description: command line describing the bin
 * @ghost_unlinked_pads: whether to automatically create ghost pads
 *     for unlinked source or sink pads within the bin
 * @context: a parse context allocated with gst_parse_context_new(), or %NULL
 * @flags: parsing options, or #GST_PARSE_FLAG_NONE
 * @err: where to store the error message in case of an error, or NULL
 *
 * This is a convenience wrapper around gst_parse_launch() to create a
 * #GstBin from a gst-launch-style pipeline description. See
 * gst_parse_launch() and the gst-launch man page for details about the
 * syntax. Ghost pads on the bin for unlinked source or sink pads
 * within the bin can automatically be created (but only a maximum of
 * one ghost pad for each direction will be created; if you expect
 * multiple unlinked source pads or multiple unlinked sink pads
 * and want them all ghosted, you will have to create the ghost pads
 * yourself).
 *
 * Returns: a newly-created bin, or NULL if an error occurred.
 *
 * Since: 0.10.20
 */
GstElement *
gst_parse_bin_from_description_full (const gchar * bin_description,
    gboolean ghost_unlinked_pads, GstParseContext * context,
    GstParseFlags flags, GError ** err)
{
#ifndef GST_DISABLE_PARSE
  GstPad *pad = NULL;
  GstBin *bin;
  gchar *desc;

  g_return_val_if_fail (bin_description != NULL, NULL);
  g_return_val_if_fail (err == NULL || *err == NULL, NULL);

  GST_DEBUG ("Making bin from description '%s'", bin_description);

  /* parse the pipeline to a bin */
  desc = g_strdup_printf ("bin.( %s )", bin_description);
  bin = (GstBin *) gst_parse_launch_full (desc, context, flags, err);
  g_free (desc);

  if (bin == NULL || (err && *err != NULL)) {
    if (bin)
      gst_object_unref (bin);
    return NULL;
  }

  /* find pads and ghost them if necessary */
  if (ghost_unlinked_pads) {
    if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC))) {
      gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("src", pad));
      gst_object_unref (pad);
    }
    if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SINK))) {
      gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad));
      gst_object_unref (pad);
    }
  }

  return GST_ELEMENT (bin);
#else
  gchar *msg;

  GST_WARNING ("Disabled API called");

  msg = gst_error_get_message (GST_CORE_ERROR, GST_CORE_ERROR_DISABLED);
  g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_DISABLED, "%s", msg);
  g_free (msg);

  return NULL;
#endif
}

/**
 * gst_type_register_static_full:
 * @parent_type: The GType of the parent type the newly registered type will 
 *   derive from
 * @type_name: NULL-terminated string used as the name of the new type
 * @class_size: Size of the class structure.
 * @base_init: Location of the base initialization function (optional).
 * @base_finalize: Location of the base finalization function (optional).
 * @class_init: Location of the class initialization function for class types 
 *   Location of the default vtable inititalization function for interface 
 *   types. (optional)
 * @class_finalize: Location of the class finalization function for class types.
 *   Location of the default vtable finalization function for interface types. 
 *   (optional)
 * @class_data: User-supplied data passed to the class init/finalize functions.
 * @instance_size: Size of the instance (object) structure (required for 
 *   instantiatable types only).
 * @n_preallocs: The number of pre-allocated (cached) instances to reserve 
 *   memory for (0 indicates no caching). Ignored on recent GLib's.
 * @instance_init: Location of the instance initialization function (optional, 
 *   for instantiatable types only).
 * @value_table: A GTypeValueTable function table for generic handling of 
 *   GValues of this type (usually only useful for fundamental types). 
 * @flags: #GTypeFlags for this GType. E.g: G_TYPE_FLAG_ABSTRACT
 *
 * Helper function which constructs a #GTypeInfo structure and registers a 
 * GType, but which generates less linker overhead than a static const 
 * #GTypeInfo structure. For further details of the parameters, please see
 * #GTypeInfo in the GLib documentation.
 *
 * Registers type_name as the name of a new static type derived from 
 * parent_type. The value of flags determines the nature (e.g. abstract or 
 * not) of the type. It works by filling a GTypeInfo struct and calling 
 * g_type_info_register_static().
 *
 * Returns: A #GType for the newly-registered type.
 *
 * Since: 0.10.14
 */
GType
gst_type_register_static_full (GType parent_type,
    const gchar * type_name,
    guint class_size,
    GBaseInitFunc base_init,
    GBaseFinalizeFunc base_finalize,
    GClassInitFunc class_init,
    GClassFinalizeFunc class_finalize,
    gconstpointer class_data,
    guint instance_size,
    guint16 n_preallocs,
    GInstanceInitFunc instance_init,
    const GTypeValueTable * value_table, GTypeFlags flags)
{
  GTypeInfo info;

  info.class_size = class_size;
  info.base_init = base_init;
  info.base_finalize = base_finalize;
  info.class_init = class_init;
  info.class_finalize = class_finalize;
  info.class_data = class_data;
  info.instance_size = instance_size;
  info.n_preallocs = n_preallocs;
  info.instance_init = instance_init;
  info.value_table = value_table;

  return g_type_register_static (parent_type, type_name, &info, flags);
}


/**
 * gst_util_get_timestamp:
 *
 * Get a timestamp as GstClockTime to be used for interval meassurements.
 * The timestamp should not be interpreted in any other way.
 *
 * Returns: the timestamp
 *
 * Since: 0.10.16
 */
GstClockTime
gst_util_get_timestamp (void)
{
#if defined (HAVE_POSIX_TIMERS) && defined(HAVE_MONOTONIC_CLOCK)
  struct timespec now;

  clock_gettime (CLOCK_MONOTONIC, &now);
  return GST_TIMESPEC_TO_TIME (now);
#else
  GTimeVal now;

  g_get_current_time (&now);
  return GST_TIMEVAL_TO_TIME (now);
#endif
}
