/* GStreamer
 * Copyright (C) 2005 Wim Taymans <wim@fluendo.com>
 * Copyright (C) 2008 Mark Nauwelaerts <mnauw@users.sourceforge.net>
 * Copyright (C) 2010 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * gstcollectpads.c:
 *
 * 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:gstcollectpads
 * @short_description: manages a set of pads that operate in collect mode
 * @see_also:
 *
 * Manages a set of pads that operate in collect mode. This means that control
 * is given to the manager of this object when all pads have data.
 * <itemizedlist>
 *   <listitem><para>
 *     Collectpads are created with gst_collect_pads_new(). A callback should then
 *     be installed with gst_collect_pads_set_function ().
 *   </para></listitem>
 *   <listitem><para>
 *     Pads are added to the collection with gst_collect_pads_add_pad()/
 *     gst_collect_pads_remove_pad(). The pad
 *     has to be a sinkpad. The chain and event functions of the pad are
 *     overridden. The element_private of the pad is used to store
 *     private information for the collectpads.
 *   </para></listitem>
 *   <listitem><para>
 *     For each pad, data is queued in the _chain function or by
 *     performing a pull_range.
 *   </para></listitem>
 *   <listitem><para>
 *     When data is queued on all pads in waiting mode, the callback function is called.
 *   </para></listitem>
 *   <listitem><para>
 *     Data can be dequeued from the pad with the gst_collect_pads_pop() method.
 *     One can peek at the data with the gst_collect_pads_peek() function.
 *     These functions will return NULL if the pad received an EOS event. When all
 *     pads return NULL from a gst_collect_pads_peek(), the element can emit an EOS
 *     event itself.
 *   </para></listitem>
 *   <listitem><para>
 *     Data can also be dequeued in byte units using the gst_collect_pads_available(),
 *     gst_collect_pads_read() and gst_collect_pads_flush() calls.
 *   </para></listitem>
 *   <listitem><para>
 *     Elements should call gst_collect_pads_start() and gst_collect_pads_stop() in
 *     their state change functions to start and stop the processing of the collectpads.
 *     The gst_collect_pads_stop() call should be called before calling the parent
 *     element state change function in the PAUSED_TO_READY state change to ensure
 *     no pad is blocked and the element can finish streaming.
 *   </para></listitem>
 *   <listitem><para>
 *     gst_collect_pads_collect() and gst_collect_pads_collect_range() can be used by
 *     elements that start a #GstTask to drive the collect_pads. This feature is however
 *     not yet implemented.
 *   </para></listitem>
 *   <listitem><para>
 *     gst_collect_pads_set_waiting() sets a pad to waiting or non-waiting mode.
 *     CollectPads element is not waiting for data to be collected on non-waiting pads.
 *     Thus these pads may but need not have data when the callback is called.
 *     All pads are in waiting mode by default.
 *   </para></listitem>
 * </itemizedlist>
 *
 * Last reviewed on 2011-10-28 (0.10.36)
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <gst/gst_private.h>

#include "gstcollectpads.h"

#include "../../../gst/glib-compat-private.h"

GST_DEBUG_CATEGORY_STATIC (collect_pads_debug);
#define GST_CAT_DEFAULT collect_pads_debug

#define parent_class gst_collect_pads_parent_class
G_DEFINE_TYPE (GstCollectPads, gst_collect_pads, GST_TYPE_OBJECT);

struct _GstCollectDataPrivate
{
  /* refcounting for struct, and destroy callback */
  GstCollectDataDestroyNotify destroy_notify;
  gint refcount;
};

struct _GstCollectPadsPrivate
{
  /* with LOCK and/or STREAM_LOCK */
  gboolean started;

  /* with STREAM_LOCK */
  guint32 cookie;               /* @data list cookie */
  guint numpads;                /* number of pads in @data */
  guint queuedpads;             /* number of pads with a buffer */
  guint eospads;                /* number of pads that are EOS */
  GstClockTime earliest_time;   /* Current earliest time */
  GstCollectData *earliest_data;        /* Pad data for current earliest time */

  /* with LOCK */
  GSList *pad_list;             /* updated pad list */
  guint32 pad_cookie;           /* updated cookie */

  GstCollectPadsFunction func;  /* function and user_data for callback */
  gpointer user_data;
  GstCollectPadsBufferFunction buffer_func;     /* function and user_data for buffer callback */
  gpointer buffer_user_data;
  GstCollectPadsCompareFunction compare_func;
  gpointer compare_user_data;
  GstCollectPadsEventFunction event_func;       /* function and data for event callback */
  gpointer event_user_data;
  GstCollectPadsQueryFunction query_func;
  gpointer query_user_data;
  GstCollectPadsClipFunction clip_func;
  gpointer clip_user_data;

  /* no other lock needed */
  GMutex evt_lock;              /* these make up sort of poor man's event signaling */
  GCond evt_cond;
  guint32 evt_cookie;
};

static void gst_collect_pads_clear (GstCollectPads * pads,
    GstCollectData * data);
static GstFlowReturn gst_collect_pads_chain (GstPad * pad, GstObject * parent,
    GstBuffer * buffer);
static gboolean gst_collect_pads_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_collect_pads_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static void gst_collect_pads_finalize (GObject * object);
static GstFlowReturn gst_collect_pads_default_collected (GstCollectPads *
    pads, gpointer user_data);
static gint gst_collect_pads_default_compare_func (GstCollectPads * pads,
    GstCollectData * data1, GstClockTime timestamp1, GstCollectData * data2,
    GstClockTime timestamp2, gpointer user_data);
static gboolean gst_collect_pads_recalculate_full (GstCollectPads * pads);
static void ref_data (GstCollectData * data);
static void unref_data (GstCollectData * data);

static gboolean gst_collect_pads_event_default_internal (GstCollectPads *
    pads, GstCollectData * data, GstEvent * event, gpointer user_data);
static gboolean gst_collect_pads_query_default_internal (GstCollectPads *
    pads, GstCollectData * data, GstQuery * query, gpointer user_data);


/* Some properties are protected by LOCK, others by STREAM_LOCK
 * However, manipulating either of these partitions may require
 * to signal/wake a _WAIT, so use a separate (sort of) event to prevent races
 * Alternative implementations are possible, e.g. some low-level re-implementing
 * of the 2 above locks to drop both of them atomically when going into _WAIT.
 */
#define GST_COLLECT_PADS_GET_EVT_COND(pads) (&((GstCollectPads *)pads)->priv->evt_cond)
#define GST_COLLECT_PADS_GET_EVT_LOCK(pads) (&((GstCollectPads *)pads)->priv->evt_lock)
#define GST_COLLECT_PADS_EVT_WAIT(pads, cookie) G_STMT_START {    \
  g_mutex_lock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));            \
  /* should work unless a lot of event'ing and thread starvation */\
  while (cookie == ((GstCollectPads *) pads)->priv->evt_cookie)         \
    g_cond_wait (GST_COLLECT_PADS_GET_EVT_COND (pads),            \
        GST_COLLECT_PADS_GET_EVT_LOCK (pads));                    \
  cookie = ((GstCollectPads *) pads)->priv->evt_cookie;                 \
  g_mutex_unlock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));          \
} G_STMT_END
#define GST_COLLECT_PADS_EVT_WAIT_TIMED(pads, cookie, timeout) G_STMT_START { \
  GTimeVal __tv; \
  \
  g_get_current_time (&tv); \
  g_time_val_add (&tv, timeout); \
  \
  g_mutex_lock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));            \
  /* should work unless a lot of event'ing and thread starvation */\
  while (cookie == ((GstCollectPads *) pads)->priv->evt_cookie)         \
    g_cond_timed_wait (GST_COLLECT_PADS_GET_EVT_COND (pads),            \
        GST_COLLECT_PADS_GET_EVT_LOCK (pads), &tv);                    \
  cookie = ((GstCollectPads *) pads)->priv->evt_cookie;                 \
  g_mutex_unlock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));          \
} G_STMT_END
#define GST_COLLECT_PADS_EVT_BROADCAST(pads) G_STMT_START {       \
  g_mutex_lock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));            \
  /* never mind wrap-around */                                     \
  ++(((GstCollectPads *) pads)->priv->evt_cookie);                      \
  g_cond_broadcast (GST_COLLECT_PADS_GET_EVT_COND (pads));        \
  g_mutex_unlock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));          \
} G_STMT_END
#define GST_COLLECT_PADS_EVT_INIT(cookie) G_STMT_START {          \
  g_mutex_lock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));            \
  cookie = ((GstCollectPads *) pads)->priv->evt_cookie;                 \
  g_mutex_unlock (GST_COLLECT_PADS_GET_EVT_LOCK (pads));          \
} G_STMT_END

static void
gst_collect_pads_class_init (GstCollectPadsClass * klass)
{
  GObjectClass *gobject_class = (GObjectClass *) klass;

  g_type_class_add_private (klass, sizeof (GstCollectPadsPrivate));

  GST_DEBUG_CATEGORY_INIT (collect_pads_debug, "collectpads", 0,
      "GstCollectPads");

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_collect_pads_finalize);
}

static void
gst_collect_pads_init (GstCollectPads * pads)
{
  pads->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (pads, GST_TYPE_COLLECT_PADS,
      GstCollectPadsPrivate);

  pads->data = NULL;
  pads->priv->cookie = 0;
  pads->priv->numpads = 0;
  pads->priv->queuedpads = 0;
  pads->priv->eospads = 0;
  pads->priv->started = FALSE;

  g_rec_mutex_init (&pads->stream_lock);

  pads->priv->func = gst_collect_pads_default_collected;
  pads->priv->user_data = NULL;
  pads->priv->event_func = NULL;
  pads->priv->event_user_data = NULL;

  /* members for default muxing */
  pads->priv->buffer_func = NULL;
  pads->priv->buffer_user_data = NULL;
  pads->priv->compare_func = gst_collect_pads_default_compare_func;
  pads->priv->compare_user_data = NULL;
  pads->priv->earliest_data = NULL;
  pads->priv->earliest_time = GST_CLOCK_TIME_NONE;

  pads->priv->event_func = gst_collect_pads_event_default_internal;
  pads->priv->query_func = gst_collect_pads_query_default_internal;

  /* members to manage the pad list */
  pads->priv->pad_cookie = 0;
  pads->priv->pad_list = NULL;

  /* members for event */
  g_mutex_init (&pads->priv->evt_lock);
  g_cond_init (&pads->priv->evt_cond);
  pads->priv->evt_cookie = 0;
}

static void
gst_collect_pads_finalize (GObject * object)
{
  GstCollectPads *pads = GST_COLLECT_PADS (object);

  GST_DEBUG_OBJECT (object, "finalize");

  g_rec_mutex_clear (&pads->stream_lock);

  g_cond_clear (&pads->priv->evt_cond);
  g_mutex_clear (&pads->priv->evt_lock);

  /* Remove pads and free pads list */
  g_slist_foreach (pads->priv->pad_list, (GFunc) unref_data, NULL);
  g_slist_foreach (pads->data, (GFunc) unref_data, NULL);
  g_slist_free (pads->data);
  g_slist_free (pads->priv->pad_list);

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

/**
 * gst_collect_pads_new:
 *
 * Create a new instance of #GstCollectPads.
 *
 * MT safe.
 *
 * Returns: (transfer full): a new #GstCollectPads, or NULL in case of an error.
 */
GstCollectPads *
gst_collect_pads_new (void)
{
  GstCollectPads *newcoll;

  newcoll = g_object_new (GST_TYPE_COLLECT_PADS, NULL);

  return newcoll;
}

/* Must be called with GstObject lock! */
static void
gst_collect_pads_set_buffer_function_locked (GstCollectPads * pads,
    GstCollectPadsBufferFunction func, gpointer user_data)
{
  pads->priv->buffer_func = func;
  pads->priv->buffer_user_data = user_data;
}

/**
 * gst_collect_pads_set_buffer_function:
 * @pads: the collectpads to use
 * @func: the function to set
 * @user_data: (closure): user data passed to the function
 *
 * Set the callback function and user data that will be called with
 * the oldest buffer when all pads have been collected.
 *
 * MT safe.
 */
void
gst_collect_pads_set_buffer_function (GstCollectPads * pads,
    GstCollectPadsBufferFunction func, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_OBJECT_LOCK (pads);
  gst_collect_pads_set_buffer_function_locked (pads, func, user_data);
  GST_OBJECT_UNLOCK (pads);
}

/**
 * gst_collect_pads_set_compare_function:
 * @pads: the pads to use
 * @func: the function to set
 * @user_data: (closure): user data passed to the function
 *
 * Set the timestamp comparison function.
 *
 * MT safe.
 */
/* NOTE allowing to change comparison seems not advisable;
no known use-case, and collaboration with default algorithm is unpredictable.
If custom compairing/operation is needed, just use a collect function of
your own */
void
gst_collect_pads_set_compare_function (GstCollectPads * pads,
    GstCollectPadsCompareFunction func, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_OBJECT_LOCK (pads);
  pads->priv->compare_func = func;
  pads->priv->compare_user_data = user_data;
  GST_OBJECT_UNLOCK (pads);
}

/**
 * gst_collect_pads_set_function:
 * @pads: the collectpads to use
 * @func: the function to set
 * @user_data: user data passed to the function
 *
 * CollectPads provides a default collection algorithm that will determine
 * the oldest buffer available on all of its pads, and then delegate
 * to a configured callback.
 * However, if circumstances are more complicated and/or more control
 * is desired, this sets a callback that will be invoked instead when
 * all the pads added to the collection have buffers queued.
 * Evidently, this callback is not compatible with
 * gst_collect_pads_set_buffer_function() callback.
 * If this callback is set, the former will be unset.
 *
 * MT safe.
 */
void
gst_collect_pads_set_function (GstCollectPads * pads,
    GstCollectPadsFunction func, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_OBJECT_LOCK (pads);
  pads->priv->func = func;
  pads->priv->user_data = user_data;
  gst_collect_pads_set_buffer_function_locked (pads, NULL, NULL);
  GST_OBJECT_UNLOCK (pads);
}

static void
ref_data (GstCollectData * data)
{
  g_assert (data != NULL);

  g_atomic_int_inc (&(data->priv->refcount));
}

static void
unref_data (GstCollectData * data)
{
  g_assert (data != NULL);
  g_assert (data->priv->refcount > 0);

  if (!g_atomic_int_dec_and_test (&(data->priv->refcount)))
    return;

  if (data->priv->destroy_notify)
    data->priv->destroy_notify (data);

  g_object_unref (data->pad);
  if (data->buffer) {
    gst_buffer_unref (data->buffer);
  }
  g_free (data->priv);
  g_free (data);
}

/**
 * gst_collect_pads_set_event_function:
 * @pads: the collectpads to use
 * @func: the function to set
 * @user_data: user data passed to the function
 *
 * Set the event callback function and user data that will be called when
 * collectpads has received an event originating from one of the collected
 * pads.  If the event being processed is a serialized one, this callback is
 * called with @pads STREAM_LOCK held, otherwise not.  As this lock should be
 * held when calling a number of CollectPads functions, it should be acquired
 * if so (unusually) needed.
 *
 * MT safe.
 */
void
gst_collect_pads_set_event_function (GstCollectPads * pads,
    GstCollectPadsEventFunction func, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_OBJECT_LOCK (pads);
  pads->priv->event_func = func;
  pads->priv->event_user_data = user_data;
  GST_OBJECT_UNLOCK (pads);
}

/**
 * gst_collect_pads_set_query_function:
 * @pads: the collectpads to use
 * @func: the function to set
 * @user_data: user data passed to the function
 *
 * Set the query callback function and user data that will be called after
 * collectpads has received a query originating from one of the collected
 * pads.  If the query being processed is a serialized one, this callback is
 * called with @pads STREAM_LOCK held, otherwise not.  As this lock should be
 * held when calling a number of CollectPads functions, it should be acquired
 * if so (unusually) needed.
 *
 * MT safe.
 */
void
gst_collect_pads_set_query_function (GstCollectPads * pads,
    GstCollectPadsQueryFunction func, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_OBJECT_LOCK (pads);
  pads->priv->query_func = func;
  pads->priv->query_user_data = user_data;
  GST_OBJECT_UNLOCK (pads);
}

/**
* gst_collect_pads_clip_running_time:
* @pads: the collectpads to use
* @cdata: collect data of corresponding pad
* @buf: buffer being clipped
* @outbuf: output buffer with running time, or NULL if clipped
* @user_data: user data (unused)
*
* Convenience clipping function that converts incoming buffer's timestamp
* to running time, or clips the buffer if outside configured segment.
*/
GstFlowReturn
gst_collect_pads_clip_running_time (GstCollectPads * pads,
    GstCollectData * cdata, GstBuffer * buf, GstBuffer ** outbuf,
    gpointer user_data)
{
  GstClockTime time;

  *outbuf = buf;
  time = GST_BUFFER_TIMESTAMP (buf);

  /* invalid left alone and passed */
  if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) {
    time = gst_segment_to_running_time (&cdata->segment, GST_FORMAT_TIME, time);
    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) {
      GST_DEBUG_OBJECT (cdata->pad, "clipping buffer on pad outside segment");
      gst_buffer_unref (buf);
      *outbuf = NULL;
    } else {
      GST_LOG_OBJECT (cdata->pad, "buffer ts %" GST_TIME_FORMAT " -> %"
          GST_TIME_FORMAT " running time",
          GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (time));
      *outbuf = gst_buffer_make_writable (buf);
      GST_BUFFER_TIMESTAMP (*outbuf) = time;
    }
  }

  return GST_FLOW_OK;
}

 /**
 * gst_collect_pads_set_clip_function:
 * @pads: the collectpads to use
 * @clipfunc: clip function to install
 * @user_data: user data to pass to @clip_func
 *
 * Install a clipping function that is called right after a buffer is received
 * on a pad managed by @pads. See #GstCollectPadsClipFunction for more info.
 */
void
gst_collect_pads_set_clip_function (GstCollectPads * pads,
    GstCollectPadsClipFunction clipfunc, gpointer user_data)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  pads->priv->clip_func = clipfunc;
  pads->priv->clip_user_data = user_data;
}

/**
 * gst_collect_pads_add_pad:
 * @pads: the collectpads to use
 * @pad: (transfer none): the pad to add
 * @size: the size of the returned #GstCollectData structure
 * @destroy_notify: function to be called before the returned #GstCollectData
 * structure is freed
 * @lock: whether to lock this pad in usual waiting state
 *
 * Add a pad to the collection of collect pads. The pad has to be
 * a sinkpad. The refcount of the pad is incremented. Use
 * gst_collect_pads_remove_pad() to remove the pad from the collection
 * again.
 *
 * You specify a size for the returned #GstCollectData structure
 * so that you can use it to store additional information.
 *
 * You can also specify a #GstCollectDataDestroyNotify that will be called
 * just before the #GstCollectData structure is freed. It is passed the
 * pointer to the structure and should free any custom memory and resources
 * allocated for it.
 *
 * Keeping a pad locked in waiting state is only relevant when using
 * the default collection algorithm (providing the oldest buffer).
 * It ensures a buffer must be available on this pad for a collection
 * to take place.  This is of typical use to a muxer element where
 * non-subtitle streams should always be in waiting state,
 * e.g. to assure that caps information is available on all these streams
 * when initial headers have to be written.
 *
 * The pad will be automatically activated in push mode when @pads is
 * started.
 *
 * MT safe.
 *
 * Returns: a new #GstCollectData to identify the new pad. Or NULL
 *   if wrong parameters are supplied.
 */
GstCollectData *
gst_collect_pads_add_pad (GstCollectPads * pads, GstPad * pad, guint size,
    GstCollectDataDestroyNotify destroy_notify, gboolean lock)
{
  GstCollectData *data;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (pad != NULL, NULL);
  g_return_val_if_fail (GST_PAD_IS_SINK (pad), NULL);
  g_return_val_if_fail (size >= sizeof (GstCollectData), NULL);

  GST_DEBUG_OBJECT (pads, "adding pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  data = g_malloc0 (size);
  data->priv = g_new0 (GstCollectDataPrivate, 1);
  data->collect = pads;
  data->pad = gst_object_ref (pad);
  data->buffer = NULL;
  data->pos = 0;
  gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED);
  data->state = GST_COLLECT_PADS_STATE_WAITING;
  data->state |= lock ? GST_COLLECT_PADS_STATE_LOCKED : 0;
  data->priv->refcount = 1;
  data->priv->destroy_notify = destroy_notify;

  GST_OBJECT_LOCK (pads);
  GST_OBJECT_LOCK (pad);
  gst_pad_set_element_private (pad, data);
  GST_OBJECT_UNLOCK (pad);
  pads->priv->pad_list = g_slist_append (pads->priv->pad_list, data);
  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_chain));
  gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_event));
  gst_pad_set_query_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_query));
  /* backward compat, also add to data if stopped, so that the element already
   * has this in the public data list before going PAUSED (typically)
   * this can only be done when we are stopped because we don't take the
   * STREAM_LOCK to protect the pads->data list. */
  if (!pads->priv->started) {
    pads->data = g_slist_append (pads->data, data);
    ref_data (data);
  }
  /* activate the pad when needed */
  if (pads->priv->started)
    gst_pad_set_active (pad, TRUE);
  pads->priv->pad_cookie++;
  GST_OBJECT_UNLOCK (pads);

  return data;
}

static gint
find_pad (GstCollectData * data, GstPad * pad)
{
  if (data->pad == pad)
    return 0;
  return 1;
}

/**
 * gst_collect_pads_remove_pad:
 * @pads: the collectpads to use
 * @pad: (transfer none): the pad to remove
 *
 * Remove a pad from the collection of collect pads. This function will also
 * free the #GstCollectData and all the resources that were allocated with
 * gst_collect_pads_add_pad().
 *
 * The pad will be deactivated automatically when @pads is stopped.
 *
 * MT safe.
 *
 * Returns: %TRUE if the pad could be removed.
 */
gboolean
gst_collect_pads_remove_pad (GstCollectPads * pads, GstPad * pad)
{
  GstCollectData *data;
  GSList *list;

  g_return_val_if_fail (pads != NULL, FALSE);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), FALSE);
  g_return_val_if_fail (pad != NULL, FALSE);
  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);

  GST_DEBUG_OBJECT (pads, "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  GST_OBJECT_LOCK (pads);
  list =
      g_slist_find_custom (pads->priv->pad_list, pad, (GCompareFunc) find_pad);
  if (!list)
    goto unknown_pad;

  data = (GstCollectData *) list->data;

  GST_DEBUG_OBJECT (pads, "found pad %s:%s at %p", GST_DEBUG_PAD_NAME (pad),
      data);

  /* clear the stuff we configured */
  gst_pad_set_chain_function (pad, NULL);
  gst_pad_set_event_function (pad, NULL);
  GST_OBJECT_LOCK (pad);
  gst_pad_set_element_private (pad, NULL);
  GST_OBJECT_UNLOCK (pad);

  /* backward compat, also remove from data if stopped, note that this function
   * can only be called when we are stopped because we don't take the
   * STREAM_LOCK to protect the pads->data list. */
  if (!pads->priv->started) {
    GSList *dlist;

    dlist = g_slist_find_custom (pads->data, pad, (GCompareFunc) find_pad);
    if (dlist) {
      GstCollectData *pdata = dlist->data;

      pads->data = g_slist_delete_link (pads->data, dlist);
      unref_data (pdata);
    }
  }
  /* remove from the pad list */
  pads->priv->pad_list = g_slist_delete_link (pads->priv->pad_list, list);
  pads->priv->pad_cookie++;

  /* signal waiters because something changed */
  GST_COLLECT_PADS_EVT_BROADCAST (pads);

  /* deactivate the pad when needed */
  if (!pads->priv->started)
    gst_pad_set_active (pad, FALSE);

  /* clean and free the collect data */
  unref_data (data);

  GST_OBJECT_UNLOCK (pads);

  return TRUE;

unknown_pad:
  {
    GST_WARNING_OBJECT (pads, "cannot remove unknown pad %s:%s",
        GST_DEBUG_PAD_NAME (pad));
    GST_OBJECT_UNLOCK (pads);
    return FALSE;
  }
}

/*
 * Must be called with STREAM_LOCK.
 */
static void
gst_collect_pads_set_flushing_unlocked (GstCollectPads * pads,
    gboolean flushing)
{
  GSList *walk = NULL;

  /* Update the pads flushing flag */
  for (walk = pads->data; walk; walk = g_slist_next (walk)) {
    GstCollectData *cdata = walk->data;

    if (GST_IS_PAD (cdata->pad)) {
      GST_OBJECT_LOCK (cdata->pad);
      if (flushing)
        GST_PAD_SET_FLUSHING (cdata->pad);
      else
        GST_PAD_UNSET_FLUSHING (cdata->pad);
      if (flushing)
        GST_COLLECT_PADS_STATE_SET (cdata, GST_COLLECT_PADS_STATE_FLUSHING);
      else
        GST_COLLECT_PADS_STATE_UNSET (cdata, GST_COLLECT_PADS_STATE_FLUSHING);
      gst_collect_pads_clear (pads, cdata);
      GST_OBJECT_UNLOCK (cdata->pad);
    }
  }

  /* inform _chain of changes */
  GST_COLLECT_PADS_EVT_BROADCAST (pads);
}

/**
 * gst_collect_pads_set_flushing:
 * @pads: the collectpads to use
 * @flushing: desired state of the pads
 *
 * Change the flushing state of all the pads in the collection. No pad
 * is able to accept anymore data when @flushing is %TRUE. Calling this
 * function with @flushing %FALSE makes @pads accept data again.
 * Caller must ensure that downstream streaming (thread) is not blocked,
 * e.g. by sending a FLUSH_START downstream.
 *
 * MT safe.
 */
void
gst_collect_pads_set_flushing (GstCollectPads * pads, gboolean flushing)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  /* NOTE since this eventually calls _pop, some (STREAM_)LOCK is needed here */
  GST_COLLECT_PADS_STREAM_LOCK (pads);
  gst_collect_pads_set_flushing_unlocked (pads, flushing);
  GST_COLLECT_PADS_STREAM_UNLOCK (pads);
}

/**
 * gst_collect_pads_start:
 * @pads: the collectpads to use
 *
 * Starts the processing of data in the collect_pads.
 *
 * MT safe.
 */
void
gst_collect_pads_start (GstCollectPads * pads)
{
  GSList *collected;

  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_DEBUG_OBJECT (pads, "starting collect pads");

  /* make sure stop and collect cannot be called anymore */
  GST_COLLECT_PADS_STREAM_LOCK (pads);

  /* make pads streamable */
  GST_OBJECT_LOCK (pads);

  /* loop over the master pad list and reset the segment */
  collected = pads->priv->pad_list;
  for (; collected; collected = g_slist_next (collected)) {
    GstCollectData *data;

    data = collected->data;
    gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED);
  }

  gst_collect_pads_set_flushing_unlocked (pads, FALSE);

  /* Start collect pads */
  pads->priv->started = TRUE;
  GST_OBJECT_UNLOCK (pads);
  GST_COLLECT_PADS_STREAM_UNLOCK (pads);
}

/**
 * gst_collect_pads_stop:
 * @pads: the collectpads to use
 *
 * Stops the processing of data in the collect_pads. this function
 * will also unblock any blocking operations.
 *
 * MT safe.
 */
void
gst_collect_pads_stop (GstCollectPads * pads)
{
  GSList *collected;

  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));

  GST_DEBUG_OBJECT (pads, "stopping collect pads");

  /* make sure collect and start cannot be called anymore */
  GST_COLLECT_PADS_STREAM_LOCK (pads);

  /* make pads not accept data anymore */
  GST_OBJECT_LOCK (pads);
  gst_collect_pads_set_flushing_unlocked (pads, TRUE);

  /* Stop collect pads */
  pads->priv->started = FALSE;
  pads->priv->eospads = 0;
  pads->priv->queuedpads = 0;

  /* loop over the master pad list and flush buffers */
  collected = pads->priv->pad_list;
  for (; collected; collected = g_slist_next (collected)) {
    GstCollectData *data;
    GstBuffer **buffer_p;

    data = collected->data;
    if (data->buffer) {
      buffer_p = &data->buffer;
      gst_buffer_replace (buffer_p, NULL);
      data->pos = 0;
    }
    GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_EOS);
  }

  if (pads->priv->earliest_data)
    unref_data (pads->priv->earliest_data);
  pads->priv->earliest_data = NULL;
  pads->priv->earliest_time = GST_CLOCK_TIME_NONE;

  GST_OBJECT_UNLOCK (pads);
  /* Wake them up so they can end the chain functions. */
  GST_COLLECT_PADS_EVT_BROADCAST (pads);

  GST_COLLECT_PADS_STREAM_UNLOCK (pads);
}

/**
 * gst_collect_pads_peek:
 * @pads: the collectpads to peek
 * @data: the data to use
 *
 * Peek at the buffer currently queued in @data. This function
 * should be called with the @pads STREAM_LOCK held, such as in the callback
 * handler.
 *
 * MT safe.
 *
 * Returns: The buffer in @data or NULL if no buffer is queued.
 *  should unref the buffer after usage.
 */
GstBuffer *
gst_collect_pads_peek (GstCollectPads * pads, GstCollectData * data)
{
  GstBuffer *result;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (data != NULL, NULL);

  if ((result = data->buffer))
    gst_buffer_ref (result);

  GST_DEBUG_OBJECT (pads, "Peeking at pad %s:%s: buffer=%p",
      GST_DEBUG_PAD_NAME (data->pad), result);

  return result;
}

/**
 * gst_collect_pads_pop:
 * @pads: the collectpads to pop
 * @data: the data to use
 *
 * Pop the buffer currently queued in @data. This function
 * should be called with the @pads STREAM_LOCK held, such as in the callback
 * handler.
 *
 * MT safe.
 *
 * Returns: (transfer full): The buffer in @data or NULL if no buffer was
 *   queued. You should unref the buffer after usage.
 */
GstBuffer *
gst_collect_pads_pop (GstCollectPads * pads, GstCollectData * data)
{
  GstBuffer *result;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (data != NULL, NULL);

  if ((result = data->buffer)) {
    data->buffer = NULL;
    data->pos = 0;
    /* one less pad with queued data now */
    if (GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_WAITING))
      pads->priv->queuedpads--;
  }

  GST_COLLECT_PADS_EVT_BROADCAST (pads);

  GST_DEBUG_OBJECT (pads, "Pop buffer on pad %s:%s: buffer=%p",
      GST_DEBUG_PAD_NAME (data->pad), result);

  return result;
}

/* pop and unref the currently queued buffer, should be called with STREAM_LOCK
 * held */
static void
gst_collect_pads_clear (GstCollectPads * pads, GstCollectData * data)
{
  GstBuffer *buf;

  if ((buf = gst_collect_pads_pop (pads, data)))
    gst_buffer_unref (buf);
}

/**
 * gst_collect_pads_available:
 * @pads: the collectpads to query
 *
 * Query how much bytes can be read from each queued buffer. This means
 * that the result of this call is the maximum number of bytes that can
 * be read from each of the pads.
 *
 * This function should be called with @pads STREAM_LOCK held, such as
 * in the callback.
 *
 * MT safe.
 *
 * Returns: The maximum number of bytes queued on all pads. This function
 * returns 0 if a pad has no queued buffer.
 */
/* we might pre-calculate this in some struct field,
 * but would then have to maintain this in _chain and particularly _pop, etc,
 * even if element is never interested in this information */
guint
gst_collect_pads_available (GstCollectPads * pads)
{
  GSList *collected;
  guint result = G_MAXUINT;

  g_return_val_if_fail (pads != NULL, 0);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);

  collected = pads->data;
  for (; collected; collected = g_slist_next (collected)) {
    GstCollectData *pdata;
    GstBuffer *buffer;
    gint size;

    pdata = (GstCollectData *) collected->data;

    /* ignore pad with EOS */
    if (G_UNLIKELY (GST_COLLECT_PADS_STATE_IS_SET (pdata,
                GST_COLLECT_PADS_STATE_EOS))) {
      GST_DEBUG_OBJECT (pads, "pad %p is EOS", pdata);
      continue;
    }

    /* an empty buffer without EOS is weird when we get here.. */
    if (G_UNLIKELY ((buffer = pdata->buffer) == NULL)) {
      GST_WARNING_OBJECT (pads, "pad %p has no buffer", pdata);
      goto not_filled;
    }

    /* this is the size left of the buffer */
    size = gst_buffer_get_size (buffer) - pdata->pos;
    GST_DEBUG_OBJECT (pads, "pad %p has %d bytes left", pdata, size);

    /* need to return the min of all available data */
    if (size < result)
      result = size;
  }
  /* nothing changed, all must be EOS then, return 0 */
  if (G_UNLIKELY (result == G_MAXUINT))
    result = 0;

  return result;

not_filled:
  {
    return 0;
  }
}

/**
 * gst_collect_pads_flush:
 * @pads: the collectpads to query
 * @data: the data to use
 * @size: the number of bytes to flush
 *
 * Flush @size bytes from the pad @data.
 *
 * This function should be called with @pads STREAM_LOCK held, such as
 * in the callback.
 *
 * MT safe.
 *
 * Returns: The number of bytes flushed This can be less than @size and
 * is 0 if the pad was end-of-stream.
 */
guint
gst_collect_pads_flush (GstCollectPads * pads, GstCollectData * data,
    guint size)
{
  guint flushsize;
  gsize bsize;
  GstBuffer *buffer;

  g_return_val_if_fail (pads != NULL, 0);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);
  g_return_val_if_fail (data != NULL, 0);

  /* no buffer, must be EOS */
  if ((buffer = data->buffer) == NULL)
    return 0;

  bsize = gst_buffer_get_size (buffer);

  /* this is what we can flush at max */
  flushsize = MIN (size, bsize - data->pos);

  data->pos += size;

  if (data->pos >= bsize)
    /* _clear will also reset data->pos to 0 */
    gst_collect_pads_clear (pads, data);

  return flushsize;
}

/**
 * gst_collect_pads_read_buffer:
 * @pads: the collectpads to query
 * @data: the data to use
 * @size: the number of bytes to read
 *
 * Get a subbuffer of @size bytes from the given pad @data.
 *
 * This function should be called with @pads STREAM_LOCK held, such as in the
 * callback.
 *
 * MT safe.
 *
 * Returns: (transfer full): A sub buffer. The size of the buffer can be less that requested.
 * A return of NULL signals that the pad is end-of-stream.
 * Unref the buffer after use.
 */
GstBuffer *
gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
    guint size)
{
  guint readsize;
  GstBuffer *buffer;

  g_return_val_if_fail (pads != NULL, NULL);
  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);
  g_return_val_if_fail (data != NULL, NULL);

  /* no buffer, must be EOS */
  if ((buffer = data->buffer) == NULL)
    return NULL;

  readsize = MIN (size, gst_buffer_get_size (buffer) - data->pos);

  return gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, data->pos,
      readsize);
}

/**
 * gst_collect_pads_take_buffer:
 * @pads: the collectpads to query
 * @data: the data to use
 * @size: the number of bytes to read
 *
 * Get a subbuffer of @size bytes from the given pad @data. Flushes the amount
 * of read bytes.
 *
 * This function should be called with @pads STREAM_LOCK held, such as in the
 * callback.
 *
 * MT safe.
 *
 * Returns: A sub buffer. The size of the buffer can be less that requested.
 * A return of NULL signals that the pad is end-of-stream.
 * Unref the buffer after use.
 */
GstBuffer *
gst_collect_pads_take_buffer (GstCollectPads * pads, GstCollectData * data,
    guint size)
{
  GstBuffer *buffer = gst_collect_pads_read_buffer (pads, data, size);

  if (buffer) {
    gst_collect_pads_flush (pads, data, gst_buffer_get_size (buffer));
  }
  return buffer;
}

/**
 * gst_collect_pads_set_waiting:
 * @pads: the collectpads
 * @data: the data to use
 * @waiting: boolean indicating whether this pad should operate
 *           in waiting or non-waiting mode
 *
 * Sets a pad to waiting or non-waiting mode, if at least this pad
 * has not been created with locked waiting state,
 * in which case nothing happens.
 *
 * This function should be called with @pads STREAM_LOCK held, such as
 * in the callback.
 *
 * MT safe.
 */
void
gst_collect_pads_set_waiting (GstCollectPads * pads, GstCollectData * data,
    gboolean waiting)
{
  g_return_if_fail (pads != NULL);
  g_return_if_fail (GST_IS_COLLECT_PADS (pads));
  g_return_if_fail (data != NULL);

  GST_DEBUG_OBJECT (pads, "Setting pad %s to waiting %d, locked %d",
      GST_PAD_NAME (data->pad), waiting,
      GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_LOCKED));

  /* Do something only on a change and if not locked */
  if (!GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_LOCKED) &&
      (GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_WAITING) !=
          ! !waiting)) {
    /* Set waiting state for this pad */
    if (waiting)
      GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_WAITING);
    else
      GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_WAITING);
    /* Update number of queued pads if needed */
    if (!data->buffer &&
        !GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_EOS)) {
      if (waiting)
        pads->priv->queuedpads--;
      else
        pads->priv->queuedpads++;
    }

    /* signal waiters because something changed */
    GST_COLLECT_PADS_EVT_BROADCAST (pads);
  }
}

/* see if pads were added or removed and update our stats. Any pad
 * added after releasing the LOCK will get collected in the next
 * round.
 *
 * We can do a quick check by checking the cookies, that get changed
 * whenever the pad list is updated.
 *
 * Must be called with STREAM_LOCK.
 */
static void
gst_collect_pads_check_pads (GstCollectPads * pads)
{
  /* the master list and cookie are protected with LOCK */
  GST_OBJECT_LOCK (pads);
  if (G_UNLIKELY (pads->priv->pad_cookie != pads->priv->cookie)) {
    GSList *collected;

    /* clear list and stats */
    g_slist_foreach (pads->data, (GFunc) unref_data, NULL);
    g_slist_free (pads->data);
    pads->data = NULL;
    pads->priv->numpads = 0;
    pads->priv->queuedpads = 0;
    pads->priv->eospads = 0;
    if (pads->priv->earliest_data)
      unref_data (pads->priv->earliest_data);
    pads->priv->earliest_data = NULL;
    pads->priv->earliest_time = GST_CLOCK_TIME_NONE;

    /* loop over the master pad list */
    collected = pads->priv->pad_list;
    for (; collected; collected = g_slist_next (collected)) {
      GstCollectData *data;

      /* update the stats */
      pads->priv->numpads++;
      data = collected->data;
      if (GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_EOS))
        pads->priv->eospads++;
      else if (data->buffer || !GST_COLLECT_PADS_STATE_IS_SET (data,
              GST_COLLECT_PADS_STATE_WAITING))
        pads->priv->queuedpads++;

      /* add to the list of pads to collect */
      ref_data (data);
      /* preserve order of adding/requesting pads */
      pads->data = g_slist_append (pads->data, data);
    }
    /* and update the cookie */
    pads->priv->cookie = pads->priv->pad_cookie;
  }
  GST_OBJECT_UNLOCK (pads);
}

/* checks if all the pads are collected and call the collectfunction
 *
 * Should be called with STREAM_LOCK.
 *
 * Returns: The #GstFlowReturn of collection.
 */
static GstFlowReturn
gst_collect_pads_check_collected (GstCollectPads * pads)
{
  GstFlowReturn flow_ret = GST_FLOW_OK;
  GstCollectPadsFunction func;
  gpointer user_data;

  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), GST_FLOW_ERROR);

  GST_OBJECT_LOCK (pads);
  func = pads->priv->func;
  user_data = pads->priv->user_data;
  GST_OBJECT_UNLOCK (pads);

  g_return_val_if_fail (pads->priv->func != NULL, GST_FLOW_NOT_SUPPORTED);

  /* check for new pads, update stats etc.. */
  gst_collect_pads_check_pads (pads);

  if (G_UNLIKELY (pads->priv->eospads == pads->priv->numpads)) {
    /* If all our pads are EOS just collect once to let the element
     * do its final EOS handling. */
    GST_DEBUG_OBJECT (pads, "All active pads (%d) are EOS, calling %s",
        pads->priv->numpads, GST_DEBUG_FUNCPTR_NAME (func));

    flow_ret = func (pads, user_data);
  } else {
    gboolean collected = FALSE;

    /* We call the collected function as long as our condition matches. */
    while (((pads->priv->queuedpads + pads->priv->eospads) >=
            pads->priv->numpads)) {
      GST_DEBUG_OBJECT (pads,
          "All active pads (%d + %d >= %d) have data, " "calling %s",
          pads->priv->queuedpads, pads->priv->eospads, pads->priv->numpads,
          GST_DEBUG_FUNCPTR_NAME (func));

      flow_ret = func (pads, user_data);
      collected = TRUE;

      /* break on error */
      if (flow_ret != GST_FLOW_OK)
        break;
      /* Don't keep looping after telling the element EOS or flushing */
      if (pads->priv->queuedpads == 0)
        break;
    }
    if (!collected)
      GST_DEBUG_OBJECT (pads, "Not all active pads (%d) have data, continuing",
          pads->priv->numpads);
  }
  return flow_ret;
}


/* General overview:
 * - only pad with a buffer can determine earliest_data (and earliest_time)
 * - only segment info determines (non-)waiting state
 * - ? perhaps use _stream_time for comparison
 *   (which muxers might have use as well ?)
 */

/*
 * Function to recalculate the waiting state of all pads.
 *
 * Must be called with STREAM_LOCK.
 *
 * Returns TRUE if a pad was set to waiting
 * (from non-waiting state).
 */
static gboolean
gst_collect_pads_recalculate_waiting (GstCollectPads * pads)
{
  GSList *collected;
  gboolean result = FALSE;

  /* If earliest time is not known, there is nothing to do. */
  if (pads->priv->earliest_data == NULL)
    return FALSE;

  for (collected = pads->data; collected; collected = g_slist_next (collected)) {
    GstCollectData *data = (GstCollectData *) collected->data;
    int cmp_res;
    GstClockTime comp_time;

    /* check if pad has a segment */
    if (data->segment.format == GST_FORMAT_UNDEFINED) {
      GST_WARNING_OBJECT (pads,
          "GstCollectPads has no time segment, assuming 0 based.");
      gst_segment_init (&data->segment, GST_FORMAT_TIME);
      GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_NEW_SEGMENT);
    }

    /* check segment format */
    if (data->segment.format != GST_FORMAT_TIME) {
      GST_ERROR_OBJECT (pads, "GstCollectPads can handle only time segments.");
      continue;
    }

    /* check if the waiting state should be changed */
    comp_time = data->segment.position;
    cmp_res = pads->priv->compare_func (pads, data, comp_time,
        pads->priv->earliest_data, pads->priv->earliest_time,
        pads->priv->compare_user_data);
    if (cmp_res > 0)
      /* stop waiting */
      gst_collect_pads_set_waiting (pads, data, FALSE);
    else {
      if (!GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_WAITING)) {
        /* start waiting */
        gst_collect_pads_set_waiting (pads, data, TRUE);
        result = TRUE;
      }
    }
  }

  return result;
}

/**
 * gst_collect_pads_find_best_pad:
 * @pads: the collectpads to use
 * @data: returns the collectdata for earliest data
 * @time: returns the earliest available buffertime
 *
 * Find the oldest/best pad, i.e. pad holding the oldest buffer and
 * and return the corresponding #GstCollectData and buffertime.
 *
 * This function should be called with STREAM_LOCK held,
 * such as in the callback.
 */
static void
gst_collect_pads_find_best_pad (GstCollectPads * pads,
    GstCollectData ** data, GstClockTime * time)
{
  GSList *collected;
  GstCollectData *best = NULL;
  GstClockTime best_time = GST_CLOCK_TIME_NONE;

  g_return_if_fail (data != NULL);
  g_return_if_fail (time != NULL);

  for (collected = pads->data; collected; collected = g_slist_next (collected)) {
    GstBuffer *buffer;
    GstCollectData *data = (GstCollectData *) collected->data;
    GstClockTime timestamp;

    buffer = gst_collect_pads_peek (pads, data);
    /* if we have a buffer check if it is better then the current best one */
    if (buffer != NULL) {
      timestamp = GST_BUFFER_TIMESTAMP (buffer);
      gst_buffer_unref (buffer);
      if (best == NULL || pads->priv->compare_func (pads, data, timestamp,
              best, best_time, pads->priv->compare_user_data) < 0) {
        best = data;
        best_time = timestamp;
      }
    }
  }

  /* set earliest time */
  *data = best;
  *time = best_time;

  GST_DEBUG_OBJECT (pads, "best pad %s, best time %" GST_TIME_FORMAT,
      best ? GST_PAD_NAME (((GstCollectData *) best)->pad) : "(nil)",
      GST_TIME_ARGS (best_time));
}

/*
 * Function to recalculate earliest_data and earliest_timestamp. This also calls
 * gst_collect_pads_recalculate_waiting
 *
 * Must be called with STREAM_LOCK.
 */
static gboolean
gst_collect_pads_recalculate_full (GstCollectPads * pads)
{
  if (pads->priv->earliest_data)
    unref_data (pads->priv->earliest_data);
  gst_collect_pads_find_best_pad (pads, &pads->priv->earliest_data,
      &pads->priv->earliest_time);
  if (pads->priv->earliest_data)
    ref_data (pads->priv->earliest_data);
  return gst_collect_pads_recalculate_waiting (pads);
}

/*
 * Default collect callback triggered when #GstCollectPads gathered all data.
 *
 * Called with STREAM_LOCK.
 */
static GstFlowReturn
gst_collect_pads_default_collected (GstCollectPads * pads, gpointer user_data)
{
  GstCollectData *best = NULL;
  GstBuffer *buffer;
  GstFlowReturn ret = GST_FLOW_OK;
  GstCollectPadsBufferFunction func;
  gpointer buffer_user_data;

  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), GST_FLOW_ERROR);

  GST_OBJECT_LOCK (pads);
  func = pads->priv->buffer_func;
  buffer_user_data = pads->priv->buffer_user_data;
  GST_OBJECT_UNLOCK (pads);

  g_return_val_if_fail (func != NULL, GST_FLOW_NOT_SUPPORTED);

  /* Find the oldest pad at all cost */
  if (gst_collect_pads_recalculate_full (pads)) {
    /* waiting was switched on,
     * so give another thread a chance to deliver a possibly
     * older buffer; don't charge on yet with the current oldest */
    ret = GST_FLOW_OK;
    goto done;
  }

  best = pads->priv->earliest_data;

  /* No data collected means EOS. */
  if (G_UNLIKELY (best == NULL)) {
    ret = func (pads, best, NULL, buffer_user_data);
    if (ret == GST_FLOW_OK)
      ret = GST_FLOW_EOS;
    goto done;
  }

  /* make sure that the pad we take a buffer from is waiting;
   * otherwise popping a buffer will seem not to have happened
   * and collectpads can get into a busy loop */
  gst_collect_pads_set_waiting (pads, best, TRUE);

  /* Send buffer */
  buffer = gst_collect_pads_pop (pads, best);
  ret = func (pads, best, buffer, buffer_user_data);

  /* maybe non-waiting was forced to waiting above due to
   * newsegment events coming too sparsely,
   * so re-check to restore state to avoid hanging/waiting */
  gst_collect_pads_recalculate_full (pads);

done:
  return ret;
}

/*
 * Default timestamp compare function.
 */
static gint
gst_collect_pads_default_compare_func (GstCollectPads * pads,
    GstCollectData * data1, GstClockTime timestamp1,
    GstCollectData * data2, GstClockTime timestamp2, gpointer user_data)
{

  GST_LOG_OBJECT (pads, "comparing %" GST_TIME_FORMAT
      " and %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp1),
      GST_TIME_ARGS (timestamp2));
  /* non-valid timestamps go first as they are probably headers or so */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp1)))
    return GST_CLOCK_TIME_IS_VALID (timestamp2) ? -1 : 0;

  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (timestamp2)))
    return 1;

  /* compare timestamp */
  if (timestamp1 < timestamp2)
    return -1;

  if (timestamp1 > timestamp2)
    return 1;

  return 0;
}

/* called with STREAM_LOCK */
static void
gst_collect_pads_handle_position_update (GstCollectPads * pads,
    GstCollectData * data, GstClockTime new_pos)
{
  gint cmp_res;

  /* If oldest time is not known, or current pad got newsegment;
   * recalculate the state */
  if (!pads->priv->earliest_data || pads->priv->earliest_data == data) {
    gst_collect_pads_recalculate_full (pads);
    goto exit;
  }

  /* Check if the waiting state of the pad should change. */
  cmp_res =
      pads->priv->compare_func (pads, data, new_pos,
      pads->priv->earliest_data, pads->priv->earliest_time,
      pads->priv->compare_user_data);

  if (cmp_res > 0)
    /* Stop waiting */
    gst_collect_pads_set_waiting (pads, data, FALSE);

exit:
  return;

}

static GstClockTime
gst_collect_pads_clip_time (GstCollectPads * pads, GstCollectData * data,
    GstClockTime time)
{
  GstClockTime otime = time;
  GstBuffer *in, *out = NULL;

  if (pads->priv->clip_func) {
    in = gst_buffer_new ();
    GST_BUFFER_TIMESTAMP (in) = time;
    pads->priv->clip_func (pads, data, in, &out, pads->priv->clip_user_data);
    if (out) {
      otime = GST_BUFFER_TIMESTAMP (out);
      gst_buffer_unref (out);
    } else {
      /* FIXME should distinguish between ahead or after segment,
       * let's assume after segment and use some large time ... */
      otime = G_MAXINT64 / 2;
    }
  }

  return otime;
}

/**
 * gst_collect_pads_event_default:
 * @pads: the collectpads to use
 * @data: collect data of corresponding pad
 * @event: event being processed
 * @discard: process but do not send event downstream
 *
 * Default GstCollectPads event handling that elements should always
 * chain up to to ensure proper operation.  Element might however indicate
 * event should not be forwarded downstream.
 */
gboolean
gst_collect_pads_event_default (GstCollectPads * pads, GstCollectData * data,
    GstEvent * event, gboolean discard)
{
  gboolean res = TRUE;
  GstCollectPadsBufferFunction buffer_func;
  GstObject *parent;
  GstPad *pad;

  GST_OBJECT_LOCK (pads);
  buffer_func = pads->priv->buffer_func;
  GST_OBJECT_UNLOCK (pads);

  pad = data->pad;
  parent = GST_OBJECT_PARENT (pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_START:
    {
      /* forward event to unblock check_collected */
      GST_DEBUG_OBJECT (pad, "forwarding flush start");
      res = gst_pad_event_default (pad, parent, event);
      event = NULL;

      /* now unblock the chain function.
       * no cond per pad, so they all unblock,
       * non-flushing block again */
      GST_COLLECT_PADS_STREAM_LOCK (pads);
      GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_FLUSHING);
      gst_collect_pads_clear (pads, data);

      /* cater for possible default muxing functionality */
      if (buffer_func) {
        /* restore to initial state */
        gst_collect_pads_set_waiting (pads, data, TRUE);
        /* if the current pad is affected, reset state, recalculate later */
        if (pads->priv->earliest_data == data) {
          unref_data (data);
          pads->priv->earliest_data = NULL;
          pads->priv->earliest_time = GST_CLOCK_TIME_NONE;
        }
      }

      GST_COLLECT_PADS_STREAM_UNLOCK (pads);

      goto eat;
    }
    case GST_EVENT_FLUSH_STOP:
    {
      /* flush the 1 buffer queue */
      GST_COLLECT_PADS_STREAM_LOCK (pads);
      GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_FLUSHING);
      gst_collect_pads_clear (pads, data);
      /* we need new segment info after the flush */
      gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED);
      GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_NEW_SEGMENT);
      /* if the pad was EOS, remove the EOS flag and
       * decrement the number of eospads */
      if (G_UNLIKELY (GST_COLLECT_PADS_STATE_IS_SET (data,
                  GST_COLLECT_PADS_STATE_EOS))) {
        if (!GST_COLLECT_PADS_STATE_IS_SET (data,
                GST_COLLECT_PADS_STATE_WAITING))
          pads->priv->queuedpads++;
        pads->priv->eospads--;
        GST_COLLECT_PADS_STATE_UNSET (data, GST_COLLECT_PADS_STATE_EOS);
      }
      GST_COLLECT_PADS_STREAM_UNLOCK (pads);

      goto forward;
    }
    case GST_EVENT_EOS:
    {
      GST_COLLECT_PADS_STREAM_LOCK (pads);
      /* if the pad was not EOS, make it EOS and so we
       * have one more eospad */
      if (G_LIKELY (!GST_COLLECT_PADS_STATE_IS_SET (data,
                  GST_COLLECT_PADS_STATE_EOS))) {
        GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_EOS);
        if (!GST_COLLECT_PADS_STATE_IS_SET (data,
                GST_COLLECT_PADS_STATE_WAITING))
          pads->priv->queuedpads--;
        pads->priv->eospads++;
      }
      /* check if we need collecting anything, we ignore the result. */
      gst_collect_pads_check_collected (pads);
      GST_COLLECT_PADS_STREAM_UNLOCK (pads);

      goto eat;
    }
    case GST_EVENT_SEGMENT:
    {
      GstSegment seg;

      GST_COLLECT_PADS_STREAM_LOCK (pads);

      gst_event_copy_segment (event, &seg);

      GST_DEBUG_OBJECT (data->pad, "got segment %" GST_SEGMENT_FORMAT, &seg);

      /* default collection can not handle other segment formats than time */
      if (buffer_func && seg.format != GST_FORMAT_TIME) {
        GST_WARNING_OBJECT (pads, "GstCollectPads default collecting "
            "can only handle time segments. Non time segment ignored.");
        goto newsegment_done;
      }

      /* need to update segment first */
      data->segment = seg;
      GST_COLLECT_PADS_STATE_SET (data, GST_COLLECT_PADS_STATE_NEW_SEGMENT);

      /* now we can use for e.g. running time */
      seg.position = gst_collect_pads_clip_time (pads, data, seg.start);
      /* update again */
      data->segment = seg;

      /* default muxing functionality */
      if (!buffer_func)
        goto newsegment_done;

      gst_collect_pads_handle_position_update (pads, data, seg.position);

    newsegment_done:
      GST_COLLECT_PADS_STREAM_UNLOCK (pads);
      /* we must not forward this event since multiple segments will be
       * accumulated and this is certainly not what we want. */
      goto eat;
    }
    case GST_EVENT_GAP:
    {
      GstClockTime start, duration;

      GST_COLLECT_PADS_STREAM_LOCK (pads);

      gst_event_parse_gap (event, &start, &duration);
      if (GST_CLOCK_TIME_IS_VALID (duration))
        start += duration;
      /* we do not expect another buffer until after gap,
       * so that is our position now */
      data->segment.position = gst_collect_pads_clip_time (pads, data, start);

      gst_collect_pads_handle_position_update (pads, data,
          data->segment.position);

      GST_COLLECT_PADS_STREAM_UNLOCK (pads);
      goto eat;
    }
    case GST_EVENT_STREAM_START:
      /* drop stream start events, element must create its own start event,
       * we can't just forward the first random stream start event we get */
      goto eat;
    case GST_EVENT_CAPS:
      goto eat;
    default:
      /* forward other events */
      goto forward;
  }

eat:
  if (event)
    gst_event_unref (event);
  return res;

forward:
  if (discard)
    goto eat;
  else
    return gst_pad_event_default (pad, parent, event);
}

static gboolean
gst_collect_pads_event_default_internal (GstCollectPads * pads,
    GstCollectData * data, GstEvent * event, gpointer user_data)
{
  return gst_collect_pads_event_default (pads, data, event, FALSE);
}

static gboolean
gst_collect_pads_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  gboolean res = FALSE, need_unlock = FALSE;
  GstCollectData *data;
  GstCollectPads *pads;
  GstCollectPadsEventFunction event_func;
  gpointer event_user_data;

  /* some magic to get the managing collect_pads */
  GST_OBJECT_LOCK (pad);
  data = (GstCollectData *) gst_pad_get_element_private (pad);
  if (G_UNLIKELY (data == NULL))
    goto pad_removed;
  ref_data (data);
  GST_OBJECT_UNLOCK (pad);

  res = FALSE;

  pads = data->collect;

  GST_DEBUG_OBJECT (data->pad, "Got %s event on sink pad",
      GST_EVENT_TYPE_NAME (event));

  GST_OBJECT_LOCK (pads);
  event_func = pads->priv->event_func;
  event_user_data = pads->priv->event_user_data;
  GST_OBJECT_UNLOCK (pads);

  if (GST_EVENT_IS_SERIALIZED (event)) {
    GST_COLLECT_PADS_STREAM_LOCK (pads);
    need_unlock = TRUE;
  }

  if (G_LIKELY (event_func)) {
    res = event_func (pads, data, event, event_user_data);
  }

  if (need_unlock)
    GST_COLLECT_PADS_STREAM_UNLOCK (pads);

  unref_data (data);
  return res;

  /* ERRORS */
pad_removed:
  {
    GST_DEBUG ("%s got removed from collectpads", GST_OBJECT_NAME (pad));
    GST_OBJECT_UNLOCK (pad);
    return FALSE;
  }
}

/**
 * gst_collect_pads_query_default:
 * @pads: the collectpads to use
 * @data: collect data of corresponding pad
 * @query: query being processed
 * @discard: process but do not send event downstream
 *
 * Default GstCollectPads query handling that elements should always
 * chain up to to ensure proper operation.  Element might however indicate
 * query should not be forwarded downstream.
 */
gboolean
gst_collect_pads_query_default (GstCollectPads * pads, GstCollectData * data,
    GstQuery * query, gboolean discard)
{
  gboolean res = TRUE;
  GstObject *parent;
  GstPad *pad;

  pad = data->pad;
  parent = GST_OBJECT_PARENT (pad);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_SEEKING:
    {
      GstFormat format;

      /* don't pass it along as some (file)sink might claim it does
       * whereas with a collectpads in between that will not likely work */
      gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
      gst_query_set_seeking (query, format, FALSE, 0, -1);
      res = TRUE;
      discard = TRUE;
      break;
    }
    default:
      break;
  }

  if (!discard)
    return gst_pad_query_default (pad, parent, query);
  else
    return res;
}

static gboolean
gst_collect_pads_query_default_internal (GstCollectPads * pads,
    GstCollectData * data, GstQuery * query, gpointer user_data)
{
  return gst_collect_pads_query_default (pads, data, query, FALSE);
}

static gboolean
gst_collect_pads_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  gboolean res = FALSE, need_unlock = FALSE;
  GstCollectData *data;
  GstCollectPads *pads;
  GstCollectPadsQueryFunction query_func;
  gpointer query_user_data;

  GST_DEBUG_OBJECT (pad, "Got %s query on sink pad",
      GST_QUERY_TYPE_NAME (query));

  /* some magic to get the managing collect_pads */
  GST_OBJECT_LOCK (pad);
  data = (GstCollectData *) gst_pad_get_element_private (pad);
  if (G_UNLIKELY (data == NULL))
    goto pad_removed;
  ref_data (data);
  GST_OBJECT_UNLOCK (pad);

  pads = data->collect;

  GST_OBJECT_LOCK (pads);
  query_func = pads->priv->query_func;
  query_user_data = pads->priv->query_user_data;
  GST_OBJECT_UNLOCK (pads);

  if (GST_QUERY_IS_SERIALIZED (query)) {
    GST_COLLECT_PADS_STREAM_LOCK (pads);
    need_unlock = TRUE;
  }

  if (G_LIKELY (query_func)) {
    res = query_func (pads, data, query, query_user_data);
  }

  if (need_unlock)
    GST_COLLECT_PADS_STREAM_UNLOCK (pads);

  unref_data (data);
  return res;

  /* ERRORS */
pad_removed:
  {
    GST_DEBUG ("%s got removed from collectpads", GST_OBJECT_NAME (pad));
    GST_OBJECT_UNLOCK (pad);
    return FALSE;
  }
}


/* For each buffer we receive we check if our collected condition is reached
 * and if so we call the collected function. When this is done we check if
 * data has been unqueued. If data is still queued we wait holding the stream
 * lock to make sure no EOS event can happen while we are ready to be
 * collected 
 */
static GstFlowReturn
gst_collect_pads_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstCollectData *data;
  GstCollectPads *pads;
  GstFlowReturn ret;
  GstBuffer **buffer_p;
  guint32 cookie;

  GST_DEBUG ("Got buffer for pad %s:%s", GST_DEBUG_PAD_NAME (pad));

  /* some magic to get the managing collect_pads */
  GST_OBJECT_LOCK (pad);
  data = (GstCollectData *) gst_pad_get_element_private (pad);
  if (G_UNLIKELY (data == NULL))
    goto no_data;
  ref_data (data);
  GST_OBJECT_UNLOCK (pad);

  pads = data->collect;

  GST_COLLECT_PADS_STREAM_LOCK (pads);
  /* if not started, bail out */
  if (G_UNLIKELY (!pads->priv->started))
    goto not_started;
  /* check if this pad is flushing */
  if (G_UNLIKELY (GST_COLLECT_PADS_STATE_IS_SET (data,
              GST_COLLECT_PADS_STATE_FLUSHING)))
    goto flushing;
  /* pad was EOS, we can refuse this data */
  if (G_UNLIKELY (GST_COLLECT_PADS_STATE_IS_SET (data,
              GST_COLLECT_PADS_STATE_EOS)))
    goto eos;

  /* see if we need to clip */
  if (pads->priv->clip_func) {
    GstBuffer *outbuf = NULL;
    ret =
        pads->priv->clip_func (pads, data, buffer, &outbuf,
        pads->priv->clip_user_data);
    buffer = outbuf;

    if (G_UNLIKELY (outbuf == NULL))
      goto clipped;

    if (G_UNLIKELY (ret == GST_FLOW_EOS))
      goto eos;
    else if (G_UNLIKELY (ret != GST_FLOW_OK))
      goto error;
  }

  GST_DEBUG_OBJECT (pads, "Queuing buffer %p for pad %s:%s", buffer,
      GST_DEBUG_PAD_NAME (pad));

  /* One more pad has data queued */
  if (GST_COLLECT_PADS_STATE_IS_SET (data, GST_COLLECT_PADS_STATE_WAITING))
    pads->priv->queuedpads++;
  buffer_p = &data->buffer;
  gst_buffer_replace (buffer_p, buffer);

  /* update segment last position if in TIME */
  if (G_LIKELY (data->segment.format == GST_FORMAT_TIME)) {
    GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);

    if (GST_CLOCK_TIME_IS_VALID (timestamp))
      data->segment.position = timestamp;
  }

  /* While we have data queued on this pad try to collect stuff */
  do {
    /* Check if our collected condition is matched and call the collected
     * function if it is */
    ret = gst_collect_pads_check_collected (pads);
    /* when an error occurs, we want to report this back to the caller ASAP
     * without having to block if the buffer was not popped */
    if (G_UNLIKELY (ret != GST_FLOW_OK))
      goto error;

    /* data was consumed, we can exit and accept new data */
    if (data->buffer == NULL)
      break;

    /* Having the _INIT here means we don't care about any broadcast up to here
     * (most of which occur with STREAM_LOCK held, so could not have happened
     * anyway).  We do care about e.g. a remove initiated broadcast as of this
     * point.  Putting it here also makes this thread ignores any evt it raised
     * itself (as is a usual WAIT semantic).
     */
    GST_COLLECT_PADS_EVT_INIT (cookie);

    /* pad could be removed and re-added */
    unref_data (data);
    GST_OBJECT_LOCK (pad);
    if (G_UNLIKELY ((data = gst_pad_get_element_private (pad)) == NULL))
      goto pad_removed;
    ref_data (data);
    GST_OBJECT_UNLOCK (pad);

    GST_DEBUG_OBJECT (pads, "Pad %s:%s has a buffer queued, waiting",
        GST_DEBUG_PAD_NAME (pad));

    /* wait to be collected, this must happen from another thread triggered
     * by the _chain function of another pad. We release the lock so we
     * can get stopped or flushed as well. We can however not get EOS
     * because we still hold the STREAM_LOCK.
     */
    GST_COLLECT_PADS_STREAM_UNLOCK (pads);
    GST_COLLECT_PADS_EVT_WAIT (pads, cookie);
    GST_COLLECT_PADS_STREAM_LOCK (pads);

    GST_DEBUG_OBJECT (pads, "Pad %s:%s resuming", GST_DEBUG_PAD_NAME (pad));

    /* after a signal, we could be stopped */
    if (G_UNLIKELY (!pads->priv->started))
      goto not_started;
    /* check if this pad is flushing */
    if (G_UNLIKELY (GST_COLLECT_PADS_STATE_IS_SET (data,
                GST_COLLECT_PADS_STATE_FLUSHING)))
      goto flushing;
  }
  while (data->buffer != NULL);

unlock_done:
  GST_COLLECT_PADS_STREAM_UNLOCK (pads);
  unref_data (data);
  if (buffer)
    gst_buffer_unref (buffer);
  return ret;

pad_removed:
  {
    GST_WARNING ("%s got removed from collectpads", GST_OBJECT_NAME (pad));
    GST_OBJECT_UNLOCK (pad);
    ret = GST_FLOW_NOT_LINKED;
    goto unlock_done;
  }
  /* ERRORS */
no_data:
  {
    GST_DEBUG ("%s got removed from collectpads", GST_OBJECT_NAME (pad));
    GST_OBJECT_UNLOCK (pad);
    gst_buffer_unref (buffer);
    return GST_FLOW_NOT_LINKED;
  }
not_started:
  {
    GST_DEBUG ("not started");
    gst_collect_pads_clear (pads, data);
    ret = GST_FLOW_FLUSHING;
    goto unlock_done;
  }
flushing:
  {
    GST_DEBUG ("pad %s:%s is flushing", GST_DEBUG_PAD_NAME (pad));
    gst_collect_pads_clear (pads, data);
    ret = GST_FLOW_FLUSHING;
    goto unlock_done;
  }
eos:
  {
    /* we should not post an error for this, just inform upstream that
     * we don't expect anything anymore */
    GST_DEBUG ("pad %s:%s is eos", GST_DEBUG_PAD_NAME (pad));
    ret = GST_FLOW_EOS;
    goto unlock_done;
  }
clipped:
  {
    GST_DEBUG ("clipped buffer on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
    ret = GST_FLOW_OK;
    goto unlock_done;
  }
error:
  {
    /* we print the error, the element should post a reasonable error
     * message for fatal errors */
    GST_DEBUG ("collect failed, reason %d (%s)", ret, gst_flow_get_name (ret));
    gst_collect_pads_clear (pads, data);
    goto unlock_done;
  }
}
