/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *                    2005 Andy Wingo <wingo@pobox.com>
 *		      2006 Edward Hervey <bilboed@bilboed.com>
 *
 * gstghostpad.c: Proxy pads
 *
 * 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:gstghostpad
 * @short_description: Pseudo link pads
 * @see_also: #GstPad
 *
 * GhostPads are useful when organizing pipelines with #GstBin like elements.
 * The idea here is to create hierarchical element graphs. The bin element
 * contains a sub-graph. Now one would like to treat the bin-element like any
 * other #GstElement. This is where GhostPads come into play. A GhostPad acts as
 * a proxy for another pad. Thus the bin can have sink and source ghost-pads
 * that are associated with sink and source pads of the child elements.
 *
 * If the target pad is known at creation time, gst_ghost_pad_new() is the
 * function to use to get a ghost-pad. Otherwise one can use gst_ghost_pad_new_no_target()
 * to create the ghost-pad and use gst_ghost_pad_set_target() to establish the
 * association later on.
 *
 * Note that GhostPads add overhead to the data processing of a pipeline.
 *
 * Last reviewed on 2005-11-18 (0.9.5)
 */

#include "gst_private.h"
#include "gstinfo.h"

#include "gstghostpad.h"
#include "gst.h"

#define GST_CAT_DEFAULT GST_CAT_PADS

#define GST_PROXY_PAD_CAST(obj)         ((GstProxyPad *)obj)
#define GST_PROXY_PAD_PRIVATE(obj)      (GST_PROXY_PAD_CAST (obj)->priv)
#define GST_PROXY_PAD_TARGET(pad)       (GST_PROXY_PAD_PRIVATE (pad)->target)
#define GST_PROXY_PAD_INTERNAL(pad)     (GST_PROXY_PAD_PRIVATE (pad)->internal)
#define GST_PROXY_PAD_RETARGET(pad)     (GST_PROXY_PAD_PRIVATE (pad)->retarget)
#define GST_PROXY_GET_LOCK(pad) (GST_PROXY_PAD_PRIVATE (pad)->proxy_lock)
#define GST_PROXY_LOCK(pad)     (g_mutex_lock (GST_PROXY_GET_LOCK (pad)))
#define GST_PROXY_UNLOCK(pad)   (g_mutex_unlock (GST_PROXY_GET_LOCK (pad)))

struct _GstProxyPadPrivate
{
  /* with PROXY_LOCK */
  GMutex *proxy_lock;
  GstPad *target;
  GstPad *internal;
  gboolean retarget;
};

G_DEFINE_TYPE (GstProxyPad, gst_proxy_pad, GST_TYPE_PAD);

static GstPad *gst_proxy_pad_get_target (GstPad * pad);

static void gst_proxy_pad_dispose (GObject * object);
static void gst_proxy_pad_finalize (GObject * object);

/**
 * gst_proxy_pad_query_type_default:
 * @pad: a #GstPad.
 *
 * Invoke the default query type handler of the proxy pad.
 *
 * Returns: (transfer none) (array zero-terminated=1): a zero-terminated array
 *     of #GstQueryType.
 *
 * Since: 0.10.35
 */
const GstQueryType *
gst_proxy_pad_query_type_default (GstPad * pad)
{
  GstPad *target;
  const GstQueryType *res = NULL;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);

  if (!(target = gst_proxy_pad_get_target (pad)))
    goto no_target;

  res = gst_pad_get_query_types (target);
  gst_object_unref (target);

  return res;

  /* ERRORS */
no_target:
  {
    GST_DEBUG_OBJECT (pad, "no target pad");
    return FALSE;
  }
}

/**
 * gst_proxy_pad_event_default:
 * @pad: a #GstPad to push the event to.
 * @event: (transfer full): the #GstEvent to send to the pad.
 *
 * Invoke the default event of the proxy pad.
 *
 * Returns: TRUE if the event was handled.
 *
 * Since: 0.10.35
 */
gboolean
gst_proxy_pad_event_default (GstPad * pad, GstEvent * event)
{
  gboolean res;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
  g_return_val_if_fail (GST_IS_EVENT (event), FALSE);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  res = gst_pad_push_event (internal, event);

  return res;
}

/**
 * gst_proxy_pad_query_default:
 * @pad: a #GstPad to invoke the default query on.
 * @query: (transfer none): the #GstQuery to perform.
 *
 * Invoke the default query function of the proxy pad.
 *
 * Returns: TRUE if the query could be performed.
 *
 * Since: 0.10.35
 */
gboolean
gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
{
  gboolean res;
  GstPad *target;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
  g_return_val_if_fail (GST_IS_QUERY (query), FALSE);

  if (!(target = gst_proxy_pad_get_target (pad)))
    goto no_target;

  res = gst_pad_query (target, query);
  gst_object_unref (target);

  return res;

  /* ERRORS */
no_target:
  {
    GST_DEBUG_OBJECT (pad, "no target pad");
    return FALSE;
  }
}

/**
 * gst_proyx_pad_iterate_internal_links_default:
 * @pad: the #GstPad to get the internal links of.
 *
 * Invoke the default iterate internal links function of the proxy pad.
 *
 * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
 * returned pad with gst_object_unref().
 *
 * Since: 0.10.35
 */
GstIterator *
gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
{
  GstIterator *res = NULL;
  GstPad *internal;
  GValue v = { 0, };

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  g_value_init (&v, GST_TYPE_PAD);
  g_value_set_object (&v, internal);
  res = gst_iterator_new_single (GST_TYPE_PAD, &v);
  g_value_unset (&v);
  gst_object_unref (internal);

  return res;
}

/**
 * gst_proxy_pad_chain_default:
 * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
 * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
 *     if not.
 *
 * Invoke the default chain function of the proxy pad.
 *
 * Returns: a #GstFlowReturn from the pad.
 *
 * Since: 0.10.35
 */
GstFlowReturn
gst_proxy_pad_chain_default (GstPad * pad, GstBuffer * buffer)
{
  GstFlowReturn res;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
  g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  res = gst_pad_push (internal, buffer);

  return res;
}

/**
 * gst_proxy_pad_chain_list_default:
 * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
 * @list: (transfer full): the #GstBufferList to send, return GST_FLOW_ERROR
 *     if not.
 *
 * Invoke the default chain list function of the proxy pad.
 *
 * Returns: a #GstFlowReturn from the pad.
 *
 * Since: 0.10.35
 */
GstFlowReturn
gst_proxy_pad_chain_list_default (GstPad * pad, GstBufferList * list)
{
  GstFlowReturn res;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  res = gst_pad_push_list (internal, list);

  return res;
}

/**
 * gst_proxy_pad_get_range_default:
 * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
 * @offset: The start offset of the buffer
 * @size: The length of the buffer
 * @buffer: (out callee-allocates): a pointer to hold the #GstBuffer,
 *     returns #GST_FLOW_ERROR if %NULL.
 *
 * Invoke the default getrange function of the proxy pad.
 *
 * Returns: a #GstFlowReturn from the pad.
 *
 * Since: 0.10.35
 */
GstFlowReturn
gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
    GstBuffer ** buffer)
{
  GstFlowReturn res;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
  g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);

  internal = GST_PROXY_PAD_INTERNAL (pad);
  res = gst_pad_pull_range (internal, offset, size, buffer);

  return res;
}

/**
 * gst_proxy_pad_getcaps_default:
 * @pad: a #GstPad to get the capabilities of.
 * @filter: a #GstCaps filter.
 *
 * Invoke the default getcaps function of the proxy pad.
 *
 * Returns: (transfer full): the caps of the pad with incremented ref-count
 *
 * Since: 0.10.35
 */
GstCaps *
gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
{
  GstPad *target;
  GstCaps *res;
  GstPadTemplate *templ;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);

  templ = GST_PAD_PAD_TEMPLATE (pad);
  target = gst_proxy_pad_get_target (pad);
  if (target) {
    /* if we have a real target, proxy the call */
    res = gst_pad_get_caps (target, filter);

    GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
        GST_DEBUG_PAD_NAME (target), res);

    gst_object_unref (target);

    /* filter against the template */
    if (templ && res) {
      GstCaps *filt, *tmp;

      filt = GST_PAD_TEMPLATE_CAPS (templ);
      if (filt) {
        tmp = gst_caps_intersect_full (res, filt, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (res);
        res = tmp;
        GST_DEBUG_OBJECT (pad,
            "filtered against template gives %" GST_PTR_FORMAT, res);
      }
    }
  } else {
    /* else, if we have a template, use its caps. */
    if (templ) {
      res = GST_PAD_TEMPLATE_CAPS (templ);
      GST_DEBUG_OBJECT (pad,
          "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, res,
          res);
      res = gst_caps_ref (res);

      if (filter) {
        GstCaps *intersection =
            gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);

        gst_caps_unref (res);
        res = intersection;
      }

      goto done;
    }

    /* last resort, any caps */
    GST_DEBUG_OBJECT (pad, "pad has no template, returning ANY");
    res = gst_caps_new_any ();
  }

done:
  return res;
}

/**
 * gst_proxy_pad_acceptcaps_default:
 * @pad: a #GstPad to check
 * @caps: a #GstCaps to check on the pad
 *
 * Invoke the default acceptcaps function of the proxy pad.
 *
 * Returns: TRUE if the pad can accept the caps.
 *
 * Since: 0.10.35
 */
gboolean
gst_proxy_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
{
  GstPad *target;
  gboolean res;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
  g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);

  target = gst_proxy_pad_get_target (pad);
  if (target) {
    res = gst_pad_accept_caps (target, caps);
    gst_object_unref (target);
  } else {
    GST_DEBUG_OBJECT (pad, "no target");
    /* We don't have a target, we return TRUE and we assume that any future
     * target will be able to deal with any configured caps. */
    res = TRUE;
  }

  return res;
}

/**
 * gst_proxy_pad_fixatecaps_default:
 * @pad: a  #GstPad to fixate
 * @caps: the  #GstCaps to fixate
 *
 * Invoke the default fixatecaps function of the proxy pad.
 *
 * Since: 0.10.35
 */
void
gst_proxy_pad_fixatecaps_default (GstPad * pad, GstCaps * caps)
{
  GstPad *target;

  g_return_if_fail (GST_IS_PROXY_PAD (pad));
  g_return_if_fail (GST_IS_CAPS (caps));

  if (!(target = gst_proxy_pad_get_target (pad)))
    goto no_target;

  gst_pad_fixate_caps (target, caps);
  gst_object_unref (target);

  return;

  /* ERRORS */
no_target:
  {
    GST_DEBUG_OBJECT (pad, "no target");
    return;
  }
}

static gboolean
gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
{
  GstPad *oldtarget;

  if (target) {
    GST_LOG_OBJECT (pad, "setting target %s:%s", GST_DEBUG_PAD_NAME (target));

    if (G_UNLIKELY (GST_PAD_DIRECTION (pad) != GST_PAD_DIRECTION (target)))
      goto wrong_direction;
  } else
    GST_LOG_OBJECT (pad, "clearing target");

  /* clear old target */
  if ((oldtarget = GST_PROXY_PAD_TARGET (pad)))
    gst_object_unref (oldtarget);

  /* set and ref new target if any */
  if (target)
    GST_PROXY_PAD_TARGET (pad) = gst_object_ref (target);
  else
    GST_PROXY_PAD_TARGET (pad) = NULL;

  return TRUE;

  /* ERRORS */
wrong_direction:
  {
    GST_ERROR_OBJECT (pad,
        "target pad doesn't have the same direction as ourself");
    return FALSE;
  }
}

static gboolean
gst_proxy_pad_set_target (GstPad * pad, GstPad * target)
{
  gboolean result;

  GST_PROXY_LOCK (pad);
  result = gst_proxy_pad_set_target_unlocked (pad, target);
  GST_PROXY_UNLOCK (pad);

  return result;
}

static GstPad *
gst_proxy_pad_get_target (GstPad * pad)
{
  GstPad *target;

  GST_PROXY_LOCK (pad);
  target = GST_PROXY_PAD_TARGET (pad);
  if (target)
    gst_object_ref (target);
  GST_PROXY_UNLOCK (pad);

  return target;
}

/**
 * gst_proxy_pad_get_internal:
 * @pad: the #GstProxyPad
 *
 * Get the internal pad of @pad. Unref target pad after usage.
 *
 * The internal pad of a #GstGhostPad is the internally used
 * pad of opposite direction, which is used to link to the target.
 *
 * Returns: (transfer full): the target #GstProxyPad, can be NULL.
 * Unref target pad after usage.
 *
 * Since: 0.10.35
 */
GstProxyPad *
gst_proxy_pad_get_internal (GstProxyPad * pad)
{
  GstPad *internal;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);
  if (internal)
    gst_object_ref (internal);
  GST_PROXY_UNLOCK (pad);

  return GST_PROXY_PAD_CAST (internal);
}

/**
 * gst_proxy_pad_unlink_default:
 * @pad: a #GstPad to unlink
 *
 * Invoke the default unlink function of the proxy pad.
 *
 * Since: 0.10.35
 */
void
gst_proxy_pad_unlink_default (GstPad * pad)
{
  GstPad *internal;

  /* don't do anything if this unlink resulted from retargeting the pad
   * controlled by the ghostpad. We only want to invalidate the target pad when
   * the element suddenly unlinked with our internal pad. */
  if (GST_PROXY_PAD_RETARGET (pad))
    return;

  internal = GST_PROXY_PAD_INTERNAL (pad);

  GST_DEBUG_OBJECT (pad, "pad is unlinked");

  gst_proxy_pad_set_target (internal, NULL);
}

static void
gst_proxy_pad_class_init (GstProxyPadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstProxyPadPrivate));

  gobject_class->dispose = gst_proxy_pad_dispose;
  gobject_class->finalize = gst_proxy_pad_finalize;

  /* Register common function pointer descriptions */
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_type_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getcaps_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_acceptcaps_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_fixatecaps_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getrange_default);
}

static void
gst_proxy_pad_dispose (GObject * object)
{
  GstPad *pad = GST_PAD (object);
  GstPad **target_p;

  GST_PROXY_LOCK (pad);
  /* remove and unref the target */
  target_p = &GST_PROXY_PAD_TARGET (pad);
  gst_object_replace ((GstObject **) target_p, NULL);
  /* The internal is only cleared by GstGhostPad::dispose, since it is the 
   * parent of non-ghost GstProxyPad and owns the refcount on the internal.
   */
  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_proxy_pad_parent_class)->dispose (object);
}

static void
gst_proxy_pad_finalize (GObject * object)
{
  GstProxyPad *pad = GST_PROXY_PAD (object);

  g_mutex_free (GST_PROXY_GET_LOCK (pad));
  GST_PROXY_GET_LOCK (pad) = NULL;

  G_OBJECT_CLASS (gst_proxy_pad_parent_class)->finalize (object);
}

static void
gst_proxy_pad_init (GstProxyPad * ppad)
{
  GstPad *pad = (GstPad *) ppad;

  GST_PROXY_PAD_PRIVATE (ppad) = G_TYPE_INSTANCE_GET_PRIVATE (ppad,
      GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
  GST_PROXY_GET_LOCK (pad) = g_mutex_new ();

  gst_pad_set_query_type_function (pad, gst_proxy_pad_query_type_default);
  gst_pad_set_event_function (pad, gst_proxy_pad_event_default);
  gst_pad_set_query_function (pad, gst_proxy_pad_query_default);
  gst_pad_set_iterate_internal_links_function (pad,
      gst_proxy_pad_iterate_internal_links_default);

  gst_pad_set_getcaps_function (pad, gst_proxy_pad_getcaps_default);
  gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_acceptcaps_default);
  gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_fixatecaps_default);
  gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
}


/***********************************************************************
 * Ghost pads, implemented as a pair of proxy pads (sort of)
 */


#define GST_GHOST_PAD_PRIVATE(obj)	(GST_GHOST_PAD_CAST (obj)->priv)

struct _GstGhostPadPrivate
{
  /* with PROXY_LOCK */
  gboolean constructed;
};

G_DEFINE_TYPE (GstGhostPad, gst_ghost_pad, GST_TYPE_PROXY_PAD);

static void gst_ghost_pad_dispose (GObject * object);

/**
 * gst_ghost_pad_internal_activate_push_default:
 * @pad: the #GstPad to activate or deactivate.
 * @active: whether the pad should be active or not.
 *
 * Invoke the default activate push function of a proxy pad that is
 * owned by a ghost pad.
 *
 * Returns: %TRUE if the operation was successful.
 *
 * Since: 0.10.35
 */
gboolean
gst_ghost_pad_internal_activate_push_default (GstPad * pad, gboolean active)
{
  gboolean ret;
  GstPad *other;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);

  GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, we're ok",
      (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));

  /* in both cases (SRC and SINK) we activate just the internal pad. The targets
   * will be activated later (or already in case of a ghost sinkpad). */
  other = GST_PROXY_PAD_INTERNAL (pad);
  ret = gst_pad_activate_push (other, active);

  return ret;
}

/**
 * gst_ghost_pad_internal_activate_pull_default:
 * @pad: the #GstPad to activate or deactivate.
 * @active: whether the pad should be active or not.
 *
 * Invoke the default activate pull function of a proxy pad that is
 * owned by a ghost pad.
 *
 * Returns: %TRUE if the operation was successful.
 *
 * Since: 0.10.35
 */
gboolean
gst_ghost_pad_internal_activate_pull_default (GstPad * pad, gboolean active)
{
  gboolean ret;
  GstPad *other;

  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);

  GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
      GST_DEBUG_PAD_NAME (pad));

  if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
    /* we are activated in pull mode by our peer element, which is a sinkpad
     * that wants to operate in pull mode. This activation has to propagate
     * upstream through the pipeline. We call the internal activation function,
     * which will trigger gst_ghost_pad_activate_pull_default, which propagates even
     * further upstream */
    GST_LOG_OBJECT (pad, "pad is src, activate internal");
    other = GST_PROXY_PAD_INTERNAL (pad);
    ret = gst_pad_activate_pull (other, active);
  } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
    /* We are SINK, the ghostpad is SRC, we propagate the activation upstream
     * since we hold a pointer to the upstream peer. */
    GST_LOG_OBJECT (pad, "activating peer");
    ret = gst_pad_activate_pull (other, active);
    gst_object_unref (other);
  } else {
    /* this is failure, we can't activate pull if there is no peer */
    GST_LOG_OBJECT (pad, "not src and no peer, failing");
    ret = FALSE;
  }

  return ret;
}

/**
 * gst_ghost_pad_activate_push_default:
 * @pad: the #GstPad to activate or deactivate.
 * @active: whether the pad should be active or not.
 *
 * Invoke the default activate push function of a ghost pad.
 *
 * Returns: %TRUE if the operation was successful.
 *
 * Since: 0.10.35
 */
gboolean
gst_ghost_pad_activate_push_default (GstPad * pad, gboolean active)
{
  gboolean ret;
  GstPad *other;

  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);

  GST_LOG_OBJECT (pad, "%sactivate push on %s:%s, proxy internal",
      (active ? "" : "de"), GST_DEBUG_PAD_NAME (pad));

  /* just activate the internal pad */
  other = GST_PROXY_PAD_INTERNAL (pad);
  ret = gst_pad_activate_push (other, active);

  return ret;
}

/**
 * gst_ghost_pad_activate_pull_default:
 * @pad: the #GstPad to activate or deactivate.
 * @active: whether the pad should be active or not.
 *
 * Invoke the default activate pull function of a ghost pad.
 *
 * Returns: %TRUE if the operation was successful.
 *
 * Since: 0.10.35
 */
gboolean
gst_ghost_pad_activate_pull_default (GstPad * pad, gboolean active)
{
  gboolean ret;
  GstPad *other;

  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);

  GST_LOG_OBJECT (pad, "%sactivate pull on %s:%s", (active ? "" : "de"),
      GST_DEBUG_PAD_NAME (pad));

  if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) {
    /* the ghostpad is SRC and activated in pull mode by its peer, call the
     * activation function of the internal pad to propagate the activation
     * upstream */
    GST_LOG_OBJECT (pad, "pad is src, activate internal");
    other = GST_PROXY_PAD_INTERNAL (pad);
    ret = gst_pad_activate_pull (other, active);
  } else if (G_LIKELY ((other = gst_pad_get_peer (pad)))) {
    /* We are SINK and activated by the internal pad, propagate activation
     * upstream because we hold a ref to the upstream peer */
    GST_LOG_OBJECT (pad, "activating peer");
    ret = gst_pad_activate_pull (other, active);
    gst_object_unref (other);
  } else {
    /* no peer, we fail */
    GST_LOG_OBJECT (pad, "pad not src and no peer, failing");
    ret = FALSE;
  }

  return ret;
}

/**
 * gst_ghost_pad_link_default:
 * @pad: the #GstPad to link.
 * @peer: the #GstPad peer
 *
 * Invoke the default link function of a ghost pad.
 *
 * Returns: #GstPadLinkReturn of the operation
 *
 * Since: 0.10.35
 */
GstPadLinkReturn
gst_ghost_pad_link_default (GstPad * pad, GstPad * peer)
{
  GstPadLinkReturn ret;
  GstPad *internal;

  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), GST_PAD_LINK_REFUSED);
  g_return_val_if_fail (GST_IS_PAD (peer), GST_PAD_LINK_REFUSED);

  GST_DEBUG_OBJECT (pad, "linking ghostpad");

  internal = GST_PROXY_PAD_INTERNAL (pad);
  if (!gst_proxy_pad_set_target (internal, peer))
    goto target_failed;

  ret = GST_PAD_LINK_OK;
  /* if we are a source pad, we should call the peer link function
   * if the peer has one, see design docs. */
  if (GST_PAD_IS_SRC (pad)) {
    if (GST_PAD_LINKFUNC (peer)) {
      ret = GST_PAD_LINKFUNC (peer) (peer, pad);
      if (ret != GST_PAD_LINK_OK)
        goto link_failed;
    }
  }
  return ret;

  /* ERRORS */
target_failed:
  {
    GST_DEBUG_OBJECT (pad, "setting target failed");
    return GST_PAD_LINK_REFUSED;
  }
link_failed:
  {
    GST_DEBUG_OBJECT (pad, "linking failed");
    /* clear target again */
    gst_proxy_pad_set_target (internal, NULL);
    return ret;
  }
}

/**
 * gst_ghost_pad_unlink_default:
 * @pad: the #GstPad to link.
 *
 * Invoke the default unlink function of a ghost pad.
 *
 * Since: 0.10.35
 */
void
gst_ghost_pad_unlink_default (GstPad * pad)
{
  GstPad *internal;

  g_return_if_fail (GST_IS_GHOST_PAD (pad));

  internal = GST_PROXY_PAD_INTERNAL (pad);

  GST_DEBUG_OBJECT (pad, "unlinking ghostpad");

  /* The target of the internal pad is no longer valid */
  gst_proxy_pad_set_target (internal, NULL);
}

static void
gst_ghost_pad_class_init (GstGhostPadClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstGhostPadPrivate));

  gobject_class->dispose = gst_ghost_pad_dispose;

  GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_push_default);
  GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_link_default);
}

static void
gst_ghost_pad_init (GstGhostPad * pad)
{
  GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
      GST_TYPE_GHOST_PAD, GstGhostPadPrivate);

  gst_pad_set_activatepull_function (GST_PAD_CAST (pad),
      gst_ghost_pad_activate_pull_default);
  gst_pad_set_activatepush_function (GST_PAD_CAST (pad),
      gst_ghost_pad_activate_push_default);
}

static void
gst_ghost_pad_dispose (GObject * object)
{
  GstPad *pad;
  GstPad *internal;
  GstPad *peer;

  pad = GST_PAD (object);

  GST_DEBUG_OBJECT (pad, "dispose");

  gst_ghost_pad_set_target (GST_GHOST_PAD (pad), NULL);

  /* Unlink here so that gst_pad_dispose doesn't. That would lead to a call to
   * gst_ghost_pad_unlink_default when the ghost pad is in an inconsistent state */
  peer = gst_pad_get_peer (pad);
  if (peer) {
    if (GST_PAD_IS_SRC (pad))
      gst_pad_unlink (pad, peer);
    else
      gst_pad_unlink (peer, pad);

    gst_object_unref (peer);
  }

  GST_PROXY_LOCK (pad);
  internal = GST_PROXY_PAD_INTERNAL (pad);

  gst_pad_set_activatepull_function (internal, NULL);
  gst_pad_set_activatepush_function (internal, NULL);

  /* disposes of the internal pad, since the ghostpad is the only possible object
   * that has a refcount on the internal pad. */
  gst_object_unparent (GST_OBJECT_CAST (internal));
  GST_PROXY_PAD_INTERNAL (pad) = NULL;

  GST_PROXY_UNLOCK (pad);

  G_OBJECT_CLASS (gst_ghost_pad_parent_class)->dispose (object);
}

/**
 * gst_ghost_pad_construct:
 * @gpad: the newly allocated ghost pad
 *
 * Finish initialization of a newly allocated ghost pad.
 *
 * This function is most useful in language bindings and when subclassing
 * #GstGhostPad; plugin and application developers normally will not call this
 * function. Call this function directly after a call to g_object_new
 * (GST_TYPE_GHOST_PAD, "direction", @dir, ..., NULL).
 *
 * Returns: %TRUE if the construction succeeds, %FALSE otherwise.
 *
 * Since: 0.10.22
 */
gboolean
gst_ghost_pad_construct (GstGhostPad * gpad)
{
  GstPadDirection dir, otherdir;
  GstPadTemplate *templ;
  GstPad *pad, *internal;

  g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
  g_return_val_if_fail (GST_GHOST_PAD_PRIVATE (gpad)->constructed == FALSE,
      FALSE);

  g_object_get (gpad, "direction", &dir, "template", &templ, NULL);

  g_return_val_if_fail (dir != GST_PAD_UNKNOWN, FALSE);

  pad = GST_PAD (gpad);

  /* Set directional padfunctions for ghostpad */
  if (dir == GST_PAD_SINK) {
    gst_pad_set_chain_function (pad, gst_proxy_pad_chain_default);
    gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default);
  } else {
    gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default);
  }

  /* link/unlink functions */
  gst_pad_set_link_function (pad, gst_ghost_pad_link_default);
  gst_pad_set_unlink_function (pad, gst_ghost_pad_unlink_default);

  /* INTERNAL PAD, it always exists and is child of the ghostpad */
  otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
  if (templ) {
    internal =
        g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
        "direction", otherdir, "template", templ, NULL);
    /* release ref obtained via g_object_get */
    gst_object_unref (templ);
  } else {
    internal =
        g_object_new (GST_TYPE_PROXY_PAD, "name", NULL,
        "direction", otherdir, NULL);
  }
  GST_PAD_UNSET_FLUSHING (internal);

  /* Set directional padfunctions for internal pad */
  if (dir == GST_PAD_SRC) {
    gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default);
    gst_pad_set_chain_list_function (internal,
        gst_proxy_pad_chain_list_default);
  } else {
    gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default);
  }

  GST_PROXY_LOCK (pad);

  /* now make the ghostpad a parent of the internal pad */
  if (!gst_object_set_parent (GST_OBJECT_CAST (internal),
          GST_OBJECT_CAST (pad)))
    goto parent_failed;

  /* The ghostpad is the parent of the internal pad and is the only object that
   * can have a refcount on the internal pad.
   * At this point, the GstGhostPad has a refcount of 1, and the internal pad has
   * a refcount of 1.
   * When the refcount of the GstGhostPad drops to 0, the ghostpad will dispose
   * its refcount on the internal pad in the dispose method by un-parenting it.
   * This is why we don't take extra refcounts in the assignments below
   */
  GST_PROXY_PAD_INTERNAL (pad) = internal;
  GST_PROXY_PAD_INTERNAL (internal) = pad;

  /* special activation functions for the internal pad */
  gst_pad_set_activatepull_function (internal,
      gst_ghost_pad_internal_activate_pull_default);
  gst_pad_set_activatepush_function (internal,
      gst_ghost_pad_internal_activate_push_default);

  GST_PROXY_UNLOCK (pad);

  GST_GHOST_PAD_PRIVATE (gpad)->constructed = TRUE;
  return TRUE;

  /* ERRORS */
parent_failed:
  {
    GST_WARNING_OBJECT (gpad, "Could not set internal pad %s:%s",
        GST_DEBUG_PAD_NAME (internal));
    g_critical ("Could not set internal pad %s:%s",
        GST_DEBUG_PAD_NAME (internal));
    GST_PROXY_UNLOCK (pad);
    gst_object_unref (internal);
    return FALSE;
  }
}

static GstPad *
gst_ghost_pad_new_full (const gchar * name, GstPadDirection dir,
    GstPadTemplate * templ)
{
  GstGhostPad *ret;

  g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);

  /* OBJECT CREATION */
  if (templ) {
    ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
        "direction", dir, "template", templ, NULL);
  } else {
    ret = g_object_new (GST_TYPE_GHOST_PAD, "name", name,
        "direction", dir, NULL);
  }

  if (!gst_ghost_pad_construct (ret))
    goto construct_failed;

  return GST_PAD_CAST (ret);

construct_failed:
  /* already logged */
  gst_object_unref (ret);
  return NULL;
}

/**
 * gst_ghost_pad_new_no_target:
 * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
 * @dir: the direction of the ghostpad
 *
 * Create a new ghostpad without a target with the given direction.
 * A target can be set on the ghostpad later with the
 * gst_ghost_pad_set_target() function.
 *
 * The created ghostpad will not have a padtemplate.
 *
 * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
 */
GstPad *
gst_ghost_pad_new_no_target (const gchar * name, GstPadDirection dir)
{
  GstPad *ret;

  g_return_val_if_fail (dir != GST_PAD_UNKNOWN, NULL);

  GST_LOG ("name:%s, direction:%d", GST_STR_NULL (name), dir);

  ret = gst_ghost_pad_new_full (name, dir, NULL);

  return ret;
}

/**
 * gst_ghost_pad_new:
 * @name: (allow-none): the name of the new pad, or NULL to assign a default name
 * @target: (transfer none): the pad to ghost.
 *
 * Create a new ghostpad with @target as the target. The direction will be taken
 * from the target pad. @target must be unlinked.
 *
 * Will ref the target.
 *
 * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
 */
GstPad *
gst_ghost_pad_new (const gchar * name, GstPad * target)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);

  GST_LOG ("name:%s, target:%s:%s", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target));

  if ((ret = gst_ghost_pad_new_no_target (name, GST_PAD_DIRECTION (target))))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}

/**
 * gst_ghost_pad_new_from_template:
 * @name: (allow-none): the name of the new pad, or NULL to assign a default name.
 * @target: (transfer none): the pad to ghost.
 * @templ: (transfer none): the #GstPadTemplate to use on the ghostpad.
 *
 * Create a new ghostpad with @target as the target. The direction will be taken
 * from the target pad. The template used on the ghostpad will be @template.
 *
 * Will ref the target.
 *
 * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
 *
 * Since: 0.10.10
 */

GstPad *
gst_ghost_pad_new_from_template (const gchar * name, GstPad * target,
    GstPadTemplate * templ)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_PAD (target), NULL);
  g_return_val_if_fail (!gst_pad_is_linked (target), NULL);
  g_return_val_if_fail (templ != NULL, NULL);
  g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) ==
      GST_PAD_DIRECTION (target), NULL);

  GST_LOG ("name:%s, target:%s:%s, templ:%p", GST_STR_NULL (name),
      GST_DEBUG_PAD_NAME (target), templ);

  if ((ret = gst_ghost_pad_new_full (name, GST_PAD_DIRECTION (target), templ)))
    if (!gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ret), target))
      goto set_target_failed;

  return ret;

  /* ERRORS */
set_target_failed:
  {
    GST_WARNING_OBJECT (ret, "failed to set target %s:%s",
        GST_DEBUG_PAD_NAME (target));
    gst_object_unref (ret);
    return NULL;
  }
}

/**
 * gst_ghost_pad_new_no_target_from_template:
 * @name: (allow-none): the name of the new pad, or NULL to assign a default name
 * @templ: (transfer none): the #GstPadTemplate to create the ghostpad from.
 *
 * Create a new ghostpad based on @templ, without setting a target. The
 * direction will be taken from the @templ.
 *
 * Returns: (transfer full): a new #GstPad, or NULL in case of an error.
 *
 * Since: 0.10.10
 */
GstPad *
gst_ghost_pad_new_no_target_from_template (const gchar * name,
    GstPadTemplate * templ)
{
  GstPad *ret;

  g_return_val_if_fail (templ != NULL, NULL);

  ret =
      gst_ghost_pad_new_full (name, GST_PAD_TEMPLATE_DIRECTION (templ), templ);

  return ret;
}

/**
 * gst_ghost_pad_get_target:
 * @gpad: the #GstGhostPad
 *
 * Get the target pad of @gpad. Unref target pad after usage.
 *
 * Returns: (transfer full): the target #GstPad, can be NULL if the ghostpad
 * has no target set. Unref target pad after usage.
 */
GstPad *
gst_ghost_pad_get_target (GstGhostPad * gpad)
{
  GstPad *ret;

  g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), NULL);

  ret = gst_proxy_pad_get_target (GST_PAD_CAST (gpad));

  GST_DEBUG_OBJECT (gpad, "get target %s:%s", GST_DEBUG_PAD_NAME (ret));

  return ret;
}

/**
 * gst_ghost_pad_set_target:
 * @gpad: the #GstGhostPad
 * @newtarget: (transfer none) (allow-none): the new pad target
 *
 * Set the new target of the ghostpad @gpad. Any existing target
 * is unlinked and links to the new target are established. if @newtarget is
 * NULL the target will be cleared.
 *
 * Returns: (transfer full): TRUE if the new target could be set. This function
 *     can return FALSE when the internal pads could not be linked.
 */
gboolean
gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
{
  GstPad *internal;
  GstPad *oldtarget;
  gboolean result;
  GstPadLinkReturn lret;

  g_return_val_if_fail (GST_IS_GHOST_PAD (gpad), FALSE);
  g_return_val_if_fail (GST_PAD_CAST (gpad) != newtarget, FALSE);
  g_return_val_if_fail (newtarget != GST_PROXY_PAD_INTERNAL (gpad), FALSE);

  /* no need for locking, the internal pad's lifecycle is directly linked to the
   * ghostpad's */
  internal = GST_PROXY_PAD_INTERNAL (gpad);

  if (newtarget)
    GST_DEBUG_OBJECT (gpad, "set target %s:%s", GST_DEBUG_PAD_NAME (newtarget));
  else
    GST_DEBUG_OBJECT (gpad, "clearing target");

  /* clear old target */
  GST_PROXY_LOCK (gpad);
  if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {

    GST_PROXY_PAD_RETARGET (internal) = TRUE;

    /* unlink internal pad */
    if (GST_PAD_IS_SRC (internal))
      gst_pad_unlink (internal, oldtarget);
    else
      gst_pad_unlink (oldtarget, internal);

    GST_PROXY_PAD_RETARGET (internal) = FALSE;
  }

  result = gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), newtarget);
  GST_PROXY_UNLOCK (gpad);

  if (result && newtarget) {
    /* and link to internal pad without any checks */
    GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");

    if (GST_PAD_IS_SRC (internal))
      lret =
          gst_pad_link_full (internal, newtarget, GST_PAD_LINK_CHECK_NOTHING);
    else
      lret =
          gst_pad_link_full (newtarget, internal, GST_PAD_LINK_CHECK_NOTHING);

    if (lret != GST_PAD_LINK_OK)
      goto link_failed;
  }

  return result;

  /* ERRORS */
link_failed:
  {
    GST_WARNING_OBJECT (gpad, "could not link internal and target, reason:%d",
        lret);
    /* and unset target again */
    GST_PROXY_LOCK (gpad);
    gst_proxy_pad_set_target_unlocked (GST_PAD_CAST (gpad), NULL);
    GST_PROXY_UNLOCK (gpad);
    return FALSE;
  }
}
