/* GstHarness - A test-harness for GStreamer testing
 *
 * Copyright (C) 2012-2015 Pexip <pexip.com>
 *
 * 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:gstharness
 * @title: GstHarness
 * @short_description: A test-harness for writing GStreamer unit tests
 * @see_also: #GstTestClock
 *
 * #GstHarness is meant to make writing unit test for GStreamer much easier.
 * It can be thought of as a way of treating a #GstElement as a black box,
 * deterministically feeding it data, and controlling what data it outputs.
 *
 * The basic structure of #GstHarness is two "floating" #GstPads that connect
 * to the harnessed #GstElement src and sink #GstPads like so:
 *
 * |[
 *           __________________________
 *  _____   |  _____            _____  |   _____
 * |     |  | |     |          |     | |  |     |
 * | src |--+-| sink|  Element | src |-+--| sink|
 * |_____|  | |_____|          |_____| |  |_____|
 *          |__________________________|
 *
 * ]|
 *
 * With this, you can now simulate any environment the #GstElement might find
 * itself in. By specifying the #GstCaps of the harness #GstPads, using
 * functions like gst_harness_set_src_caps() or gst_harness_set_sink_caps_str(),
 * you can test how the #GstElement interacts with different caps sets.
 *
 * Your harnessed #GstElement can of course also be a bin, and using
 * gst_harness_new_parse() supporting standard gst-launch syntax, you can
 * easily test a whole pipeline instead of just one element.
 *
 * You can then go on to push #GstBuffers and #GstEvents on to the srcpad,
 * using functions like gst_harness_push() and gst_harness_push_event(), and
 * then pull them out to examine them with gst_harness_pull() and
 * gst_harness_pull_event().
 *
 * ## A simple buffer-in buffer-out example
 *
 * |[<!-- language="C" -->
 *   #include <gst/gst.h>
 *   #include <gst/check/gstharness.h>
 *   GstHarness *h;
 *   GstBuffer *in_buf;
 *   GstBuffer *out_buf;
 *
 *   // attach the harness to the src and sink pad of GstQueue
 *   h = gst_harness_new ("queue");
 *
 *   // we must specify a caps before pushing buffers
 *   gst_harness_set_src_caps_str (h, "mycaps");
 *
 *   // create a buffer of size 42
 *   in_buf = gst_harness_create_buffer (h, 42);
 *
 *   // push the buffer into the queue
 *   gst_harness_push (h, in_buf);
 *
 *   // pull the buffer from the queue
 *   out_buf = gst_harness_pull (h);
 *
 *   // validate the buffer in is the same as buffer out
 *   fail_unless (in_buf == out_buf);
 *
 *   // cleanup
 *   gst_buffer_unref (out_buf);
 *   gst_harness_teardown (h);
 *
 *   ]|
 *
 * Another main feature of the #GstHarness is its integration with the
 * #GstTestClock. Operating the #GstTestClock can be very challenging, but
 * #GstHarness simplifies some of the most desired actions a lot, like wanting
 * to manually advance the clock while at the same time releasing a #GstClockID
 * that is waiting, with functions like gst_harness_crank_single_clock_wait().
 *
 * #GstHarness also supports sub-harnesses, as a way of generating and
 * validating data. A sub-harness is another #GstHarness that is managed by
 * the "parent" harness, and can either be created by using the standard
 * gst_harness_new type functions directly on the (GstHarness *)->src_harness,
 * or using the much more convenient gst_harness_add_src() or
 * gst_harness_add_sink_parse(). If you have a decoder-element you want to test,
 * (like vp8dec) it can be very useful to add a src-harness with both a
 * src-element (videotestsrc) and an encoder (vp8enc) to feed the decoder data
 * with different configurations, by simply doing:
 *
 * |[<!-- language="C" -->
 *   GstHarness * h = gst_harness_new (h, "vp8dec");
 *   gst_harness_add_src_parse (h, "videotestsrc is-live=1 ! vp8enc", TRUE);
 * ]|
 *
 * and then feeding it data with:
 *
 * |[<!-- language="C" -->
 * gst_harness_push_from_src (h);
 * ]|
 *
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

/* we have code with side effects in asserts, so make sure they are active */
#ifdef G_DISABLE_ASSERT
#error "GstHarness must be compiled with G_DISABLE_ASSERT undefined"
#endif

#include "gstharness.h"

#include <stdio.h>
#include <string.h>
#include <math.h>

static void gst_harness_stress_free (GstHarnessThread * t);

#define HARNESS_KEY "harness"
#define HARNESS_REF "harness-ref"
#define HARNESS_LOCK(h) g_mutex_lock (&(h)->priv->priv_mutex)
#define HARNESS_UNLOCK(h) g_mutex_unlock (&(h)->priv->priv_mutex)

static GstStaticPadTemplate hsrctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);
static GstStaticPadTemplate hsinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

struct _GstHarnessPrivate
{
  gchar *element_sinkpad_name;
  gchar *element_srcpad_name;

  GstCaps *src_caps;
  GstCaps *sink_caps;

  gboolean forwarding;
  GstPad *sink_forward_pad;
  GstTestClock *testclock;

  volatile gint recv_buffers;
  volatile gint recv_events;
  volatile gint recv_upstream_events;

  GAsyncQueue *buffer_queue;
  GAsyncQueue *src_event_queue;
  GAsyncQueue *sink_event_queue;

  GstClockTime latency_min;
  GstClockTime latency_max;
  gboolean has_clock_wait;
  gboolean drop_buffers;
  GstClockTime last_push_ts;

  GstBufferPool *pool;
  GstAllocator *allocator;
  GstAllocationParams allocation_params;
  GstAllocator *propose_allocator;
  GstAllocationParams propose_allocation_params;

  gboolean blocking_push_mode;
  GCond blocking_push_cond;
  GMutex blocking_push_mutex;
  GMutex priv_mutex;

  GPtrArray *stress;
};

static GstFlowReturn
gst_harness_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
  GstHarnessPrivate *priv = h->priv;
  (void) parent;
  g_assert (h != NULL);
  g_mutex_lock (&priv->blocking_push_mutex);
  g_atomic_int_inc (&priv->recv_buffers);

  if (priv->drop_buffers)
    gst_buffer_unref (buffer);
  else
    g_async_queue_push (priv->buffer_queue, buffer);

  if (priv->blocking_push_mode) {
    g_cond_wait (&priv->blocking_push_cond, &priv->blocking_push_mutex);
  }
  g_mutex_unlock (&priv->blocking_push_mutex);

  return GST_FLOW_OK;
}

static gboolean
gst_harness_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
  GstHarnessPrivate *priv = h->priv;
  (void) parent;
  g_assert (h != NULL);
  g_atomic_int_inc (&priv->recv_upstream_events);
  g_async_queue_push (priv->src_event_queue, event);
  return TRUE;
}

static gboolean
gst_harness_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
  GstHarnessPrivate *priv = h->priv;
  gboolean ret = TRUE;
  gboolean forward;

  g_assert (h != NULL);
  (void) parent;
  g_atomic_int_inc (&priv->recv_events);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:
    case GST_EVENT_CAPS:
    case GST_EVENT_SEGMENT:
      forward = TRUE;
      break;
    default:
      forward = FALSE;
      break;
  }

  HARNESS_LOCK (h);
  if (priv->forwarding && forward && priv->sink_forward_pad) {
    GstPad *fwdpad = gst_object_ref (priv->sink_forward_pad);
    HARNESS_UNLOCK (h);
    ret = gst_pad_push_event (fwdpad, event);
    gst_object_unref (fwdpad);
    HARNESS_LOCK (h);
  } else {
    g_async_queue_push (priv->sink_event_queue, event);
  }
  HARNESS_UNLOCK (h);

  return ret;
}

static void
gst_harness_decide_allocation (GstHarness * h, GstCaps * caps)
{
  GstHarnessPrivate *priv = h->priv;
  GstQuery *query;
  GstAllocator *allocator;
  GstAllocationParams params;
  GstBufferPool *pool = NULL;
  guint size, min, max;

  query = gst_query_new_allocation (caps, FALSE);
  gst_pad_peer_query (h->srcpad, query);

  if (gst_query_get_n_allocation_params (query) > 0) {
    gst_query_parse_nth_allocation_param (query, 0, &allocator, &params);
  } else {
    allocator = NULL;
    gst_allocation_params_init (&params);
  }

  if (gst_query_get_n_allocation_pools (query) > 0) {
    gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max);
#if 0
    /* Most elements create their own pools if pool == NULL. Not sure if we
     * want to do that in the harness since we may want to test the pool
     * implementation of the elements. Not creating a pool will however ignore
     * the returned size. */
    if (pool == NULL)
      pool = gst_buffer_pool_new ();
#endif
  } else {
    pool = NULL;
    size = min = max = 0;
  }
  gst_query_unref (query);

  if (pool) {
    GstStructure *config = gst_buffer_pool_get_config (pool);
    gst_buffer_pool_config_set_params (config, caps, size, min, max);
    gst_buffer_pool_config_set_allocator (config, allocator, &params);
    gst_buffer_pool_set_config (pool, config);
  }

  if (pool != priv->pool) {
    if (priv->pool != NULL)
      gst_buffer_pool_set_active (priv->pool, FALSE);
    if (pool)
      gst_buffer_pool_set_active (pool, TRUE);
  }

  priv->allocation_params = params;
  if (priv->allocator)
    gst_object_unref (priv->allocator);
  priv->allocator = allocator;
  if (priv->pool)
    gst_object_unref (priv->pool);
  priv->pool = pool;
}

static void
gst_harness_negotiate (GstHarness * h)
{
  GstCaps *caps;

  caps = gst_pad_get_current_caps (h->srcpad);
  if (caps != NULL) {
    gst_harness_decide_allocation (h, caps);
    gst_caps_unref (caps);
  } else {
    GST_FIXME_OBJECT (h, "Cannot negotiate allocation because caps is not set");
  }
}

static gboolean
gst_harness_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
  GstHarnessPrivate *priv = h->priv;
  gboolean res = TRUE;
  g_assert (h != NULL);

  // FIXME: forward all queries?

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
      gst_query_set_latency (query, TRUE, priv->latency_min, priv->latency_max);
      break;
    case GST_QUERY_CAPS:
    {
      GstCaps *caps, *filter = NULL;

      if (priv->sink_caps) {
        caps = gst_caps_ref (priv->sink_caps);
      } else {
        caps = gst_pad_get_pad_template_caps (pad);
      }

      gst_query_parse_caps (query, &filter);
      if (filter != NULL) {
        gst_caps_take (&caps,
            gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST));
      }

      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
    }
      break;
    case GST_QUERY_ALLOCATION:
    {
      HARNESS_LOCK (h);
      if (priv->forwarding && priv->sink_forward_pad != NULL) {
        GstPad *peer = gst_pad_get_peer (priv->sink_forward_pad);
        g_assert (peer != NULL);
        HARNESS_UNLOCK (h);
        res = gst_pad_query (peer, query);
        gst_object_unref (peer);
        HARNESS_LOCK (h);
      } else {
        GstCaps *caps;
        gboolean need_pool;
        guint size;

        gst_query_parse_allocation (query, &caps, &need_pool);

        /* FIXME: Can this be removed? */
        size = gst_query_get_n_allocation_params (query);
        g_assert_cmpuint (0, ==, size);
        gst_query_add_allocation_param (query,
            priv->propose_allocator, &priv->propose_allocation_params);

        GST_DEBUG_OBJECT (pad, "proposing allocation %" GST_PTR_FORMAT,
            priv->propose_allocator);
      }
      HARNESS_UNLOCK (h);
      break;
    }
    default:
      res = gst_pad_query_default (pad, parent, query);
  }

  return res;
}

static gboolean
gst_harness_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstHarness *h = g_object_get_data (G_OBJECT (pad), HARNESS_KEY);
  GstHarnessPrivate *priv = h->priv;
  gboolean res = TRUE;
  g_assert (h != NULL);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_LATENCY:
      gst_query_set_latency (query, TRUE, priv->latency_min, priv->latency_max);
      break;
    case GST_QUERY_CAPS:
    {
      GstCaps *caps, *filter = NULL;

      if (priv->src_caps) {
        caps = gst_caps_ref (priv->src_caps);
      } else {
        caps = gst_pad_get_pad_template_caps (pad);
      }

      gst_query_parse_caps (query, &filter);
      if (filter != NULL) {
        gst_caps_take (&caps,
            gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST));
      }

      gst_query_set_caps_result (query, caps);
      gst_caps_unref (caps);
    }
      break;
    default:
      res = gst_pad_query_default (pad, parent, query);
  }
  return res;
}

static void
gst_harness_element_ref (GstHarness * h)
{
  guint *data;

  GST_OBJECT_LOCK (h->element);
  data = g_object_get_data (G_OBJECT (h->element), HARNESS_REF);
  if (data == NULL) {
    data = g_new0 (guint, 1);
    *data = 1;
    g_object_set_data_full (G_OBJECT (h->element), HARNESS_REF, data, g_free);
  } else {
    (*data)++;
  }
  GST_OBJECT_UNLOCK (h->element);
}

static guint
gst_harness_element_unref (GstHarness * h)
{
  guint *data;
  guint ret;

  GST_OBJECT_LOCK (h->element);
  data = g_object_get_data (G_OBJECT (h->element), HARNESS_REF);
  g_assert (data != NULL);
  (*data)--;
  ret = *data;
  GST_OBJECT_UNLOCK (h->element);

  return ret;
}

static void
gst_harness_link_element_srcpad (GstHarness * h,
    const gchar * element_srcpad_name)
{
  GstHarnessPrivate *priv = h->priv;
  GstPad *srcpad = gst_element_get_static_pad (h->element,
      element_srcpad_name);
  GstPadLinkReturn link;
  if (srcpad == NULL)
    srcpad = gst_element_get_request_pad (h->element, element_srcpad_name);
  g_assert (srcpad);
  link = gst_pad_link (srcpad, h->sinkpad);
  g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
  g_free (priv->element_srcpad_name);
  priv->element_srcpad_name = gst_pad_get_name (srcpad);

  gst_object_unref (srcpad);
}

static void
gst_harness_link_element_sinkpad (GstHarness * h,
    const gchar * element_sinkpad_name)
{
  GstHarnessPrivate *priv = h->priv;
  GstPad *sinkpad = gst_element_get_static_pad (h->element,
      element_sinkpad_name);
  GstPadLinkReturn link;
  if (sinkpad == NULL)
    sinkpad = gst_element_get_request_pad (h->element, element_sinkpad_name);
  g_assert (sinkpad);
  link = gst_pad_link (h->srcpad, sinkpad);
  g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
  g_free (priv->element_sinkpad_name);
  priv->element_sinkpad_name = gst_pad_get_name (sinkpad);

  gst_object_unref (sinkpad);
}

static void
gst_harness_setup_src_pad (GstHarness * h,
    GstStaticPadTemplate * src_tmpl, const gchar * element_sinkpad_name)
{
  GstHarnessPrivate *priv = h->priv;
  g_assert (src_tmpl);
  g_assert (h->srcpad == NULL);

  priv->src_event_queue =
      g_async_queue_new_full ((GDestroyNotify) gst_event_unref);

  /* sending pad */
  h->srcpad = gst_pad_new_from_static_template (src_tmpl, "src");
  g_assert (h->srcpad);
  g_object_set_data (G_OBJECT (h->srcpad), HARNESS_KEY, h);

  gst_pad_set_query_function (h->srcpad, gst_harness_src_query);
  gst_pad_set_event_function (h->srcpad, gst_harness_src_event);

  gst_pad_set_active (h->srcpad, TRUE);

  if (element_sinkpad_name)
    gst_harness_link_element_sinkpad (h, element_sinkpad_name);
}

static void
gst_harness_setup_sink_pad (GstHarness * h,
    GstStaticPadTemplate * sink_tmpl, const gchar * element_srcpad_name)
{
  GstHarnessPrivate *priv = h->priv;
  g_assert (sink_tmpl);
  g_assert (h->sinkpad == NULL);

  priv->buffer_queue = g_async_queue_new_full (
      (GDestroyNotify) gst_buffer_unref);
  priv->sink_event_queue = g_async_queue_new_full (
      (GDestroyNotify) gst_event_unref);

  /* receiving pad */
  h->sinkpad = gst_pad_new_from_static_template (sink_tmpl, "sink");
  g_assert (h->sinkpad);
  g_object_set_data (G_OBJECT (h->sinkpad), HARNESS_KEY, h);

  gst_pad_set_chain_function (h->sinkpad, gst_harness_chain);
  gst_pad_set_query_function (h->sinkpad, gst_harness_sink_query);
  gst_pad_set_event_function (h->sinkpad, gst_harness_sink_event);

  gst_pad_set_active (h->sinkpad, TRUE);

  if (element_srcpad_name)
    gst_harness_link_element_srcpad (h, element_srcpad_name);
}

static void
check_element_type (GstElement * element, gboolean * has_sinkpad,
    gboolean * has_srcpad)
{
  GstElementClass *element_class = GST_ELEMENT_GET_CLASS (element);
  const GList *tmpl_list;

  *has_srcpad = element->numsrcpads > 0;
  *has_sinkpad = element->numsinkpads > 0;

  tmpl_list = gst_element_class_get_pad_template_list (element_class);

  while (tmpl_list) {
    GstPadTemplate *pad_tmpl = (GstPadTemplate *) tmpl_list->data;
    tmpl_list = g_list_next (tmpl_list);
    if (GST_PAD_TEMPLATE_DIRECTION (pad_tmpl) == GST_PAD_SRC)
      *has_srcpad |= TRUE;
    if (GST_PAD_TEMPLATE_DIRECTION (pad_tmpl) == GST_PAD_SINK)
      *has_sinkpad |= TRUE;
  }
}

static void
turn_async_and_sync_off (GstElement * element)
{
  GObjectClass *class = G_OBJECT_GET_CLASS (element);
  if (g_object_class_find_property (class, "async"))
    g_object_set (element, "async", FALSE, NULL);
  if (g_object_class_find_property (class, "sync"))
    g_object_set (element, "sync", FALSE, NULL);
}

static gboolean
gst_pad_is_request_pad (GstPad * pad)
{
  GstPadTemplate *temp;
  gboolean is_request;

  if (pad == NULL)
    return FALSE;
  temp = gst_pad_get_pad_template (pad);
  if (temp == NULL)
    return FALSE;
  is_request = GST_PAD_TEMPLATE_PRESENCE (temp) == GST_PAD_REQUEST;
  gst_object_unref (temp);
  return is_request;
}

/**
 * gst_harness_new_empty: (skip)
 *
 * Creates a new empty harness. Use gst_harness_add_element_full() to add
 * an #GstElement to it.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.8
 */
GstHarness *
gst_harness_new_empty (void)
{
  GstHarness *h;
  GstHarnessPrivate *priv;

  h = g_new0 (GstHarness, 1);
  g_assert (h != NULL);
  h->priv = g_new0 (GstHarnessPrivate, 1);
  priv = h->priv;

  GST_DEBUG_OBJECT (h, "about to create new harness %p", h);
  priv->last_push_ts = GST_CLOCK_TIME_NONE;
  priv->latency_min = 0;
  priv->latency_max = GST_CLOCK_TIME_NONE;
  priv->drop_buffers = FALSE;
  priv->testclock = GST_TEST_CLOCK_CAST (gst_test_clock_new ());

  priv->propose_allocator = NULL;
  gst_allocation_params_init (&priv->propose_allocation_params);

  g_mutex_init (&priv->blocking_push_mutex);
  g_cond_init (&priv->blocking_push_cond);
  g_mutex_init (&priv->priv_mutex);

  priv->stress = g_ptr_array_new_with_free_func (
      (GDestroyNotify) gst_harness_stress_free);

  /* we have forwarding on as a default */
  gst_harness_set_forwarding (h, TRUE);

  return h;
}

/**
 * gst_harness_add_element_full: (skip)
 * @h: a #GstHarness
 * @element: a #GstElement to add to the harness (transfer none)
 * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad.
 * %NULL will not create a harness srcpad.
 * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
 * sinkpad that is then linked to the harness srcpad. Can be a static or request
 * or a sometimes pad that has been added. %NULL will not get/request a sinkpad
 * from the element. (Like if the element is a src.)
 * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad.
 * %NULL will not create a harness sinkpad.
 * @element_srcpad_name: (allow-none): a #gchar with the name of the element
 * srcpad that is then linked to the harness sinkpad, similar to the
 * @element_sinkpad_name.
 *
 * Adds a #GstElement to an empty #GstHarness
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_element_full (GstHarness * h, GstElement * element,
    GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name,
    GstStaticPadTemplate * hsink, const gchar * element_srcpad_name)
{
  GstClock *element_clock;
  gboolean has_sinkpad, has_srcpad;

  g_return_if_fail (element != NULL);
  g_return_if_fail (h->element == NULL);

  element_clock = GST_ELEMENT_CLOCK (element);
  h->element = gst_object_ref (element);
  check_element_type (element, &has_sinkpad, &has_srcpad);

  /* setup the loose srcpad linked to the element sinkpad */
  if (has_sinkpad)
    gst_harness_setup_src_pad (h, hsrc, element_sinkpad_name);

  /* setup the loose sinkpad linked to the element srcpad */
  if (has_srcpad)
    gst_harness_setup_sink_pad (h, hsink, element_srcpad_name);

  /* as a harness sink, we should not need sync and async */
  if (has_sinkpad && !has_srcpad)
    turn_async_and_sync_off (h->element);

  if (h->srcpad != NULL) {
    gboolean handled;
    gchar *stream_id = g_strdup_printf ("%s-%p",
        GST_OBJECT_NAME (h->element), h);
    handled = gst_pad_push_event (h->srcpad,
        gst_event_new_stream_start (stream_id));
    g_assert (handled);
    g_free (stream_id);
  }

  /* if the element already has a testclock attached,
     we replace our own with it, if no clock we attach the testclock */
  if (element_clock) {
    if (GST_IS_TEST_CLOCK (element_clock)) {
      gst_object_replace ((GstObject **) & h->priv->testclock,
          (GstObject *) GST_ELEMENT_CLOCK (element));
    }
  } else {
    gst_harness_use_testclock (h);
  }

  /* don't start sources, they start producing data! */
  if (has_sinkpad)
    gst_harness_play (h);

  gst_harness_element_ref (h);

  GST_DEBUG_OBJECT (h, "added element to harness %p "
      "with element_srcpad_name (%p, %s, %s) and element_sinkpad_name (%p, %s, %s)",
      h, h->srcpad, GST_DEBUG_PAD_NAME (h->srcpad),
      h->sinkpad, GST_DEBUG_PAD_NAME (h->sinkpad));
}

/**
 * gst_harness_new_full: (skip)
 * @element: a #GstElement to attach the harness to (transfer none)
 * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad.
 * %NULL will not create a harness srcpad.
 * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
 * sinkpad that is then linked to the harness srcpad. Can be a static or request
 * or a sometimes pad that has been added. %NULL will not get/request a sinkpad
 * from the element. (Like if the element is a src.)
 * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad.
 * %NULL will not create a harness sinkpad.
 * @element_srcpad_name: (allow-none): a #gchar with the name of the element
 * srcpad that is then linked to the harness sinkpad, similar to the
 * @element_sinkpad_name.
 *
 * Creates a new harness.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new_full (GstElement * element,
    GstStaticPadTemplate * hsrc, const gchar * element_sinkpad_name,
    GstStaticPadTemplate * hsink, const gchar * element_srcpad_name)
{
  GstHarness *h;
  h = gst_harness_new_empty ();
  gst_harness_add_element_full (h, element,
      hsrc, element_sinkpad_name, hsink, element_srcpad_name);
  return h;
}

/**
 * gst_harness_new_with_element: (skip)
 * @element: a #GstElement to attach the harness to (transfer none)
 * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
 * sinkpad that is then linked to the harness srcpad. %NULL does not attach a
 * sinkpad
 * @element_srcpad_name: (allow-none): a #gchar with the name of the element
 * srcpad that is then linked to the harness sinkpad. %NULL does not attach a
 * srcpad
 *
 * Creates a new harness. Works in the same way as gst_harness_new_full(), only
 * that generic padtemplates are used for the harness src and sinkpads, which
 * will be sufficient in most usecases.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new_with_element (GstElement * element,
    const gchar * element_sinkpad_name, const gchar * element_srcpad_name)
{
  return gst_harness_new_full (element,
      &hsrctemplate, element_sinkpad_name, &hsinktemplate, element_srcpad_name);
}

/**
 * gst_harness_new_with_padnames: (skip)
 * @element_name: a #gchar describing the #GstElement name
 * @element_sinkpad_name: (allow-none): a #gchar with the name of the element
 * sinkpad that is then linked to the harness srcpad. %NULL does not attach a
 * sinkpad
 * @element_srcpad_name: (allow-none): a #gchar with the name of the element
 * srcpad that is then linked to the harness sinkpad. %NULL does not attach a
 * srcpad
 *
 * Creates a new harness. Works like gst_harness_new_with_element(),
 * except you specify the factoryname of the #GstElement
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new_with_padnames (const gchar * element_name,
    const gchar * element_sinkpad_name, const gchar * element_srcpad_name)
{
  GstHarness *h;
  GstElement *element = gst_element_factory_make (element_name, NULL);
  g_assert (element != NULL);

  h = gst_harness_new_with_element (element, element_sinkpad_name,
      element_srcpad_name);
  gst_object_unref (element);
  return h;
}

/**
 * gst_harness_new_with_templates: (skip)
 * @element_name: a #gchar describing the #GstElement name
 * @hsrc: (allow-none): a #GstStaticPadTemplate describing the harness srcpad.
 * %NULL will not create a harness srcpad.
 * @hsink: (allow-none): a #GstStaticPadTemplate describing the harness sinkpad.
 * %NULL will not create a harness sinkpad.
 *
 * Creates a new harness, like gst_harness_new_full(), except it
 * assumes the #GstElement sinkpad is named "sink" and srcpad is named "src"
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new_with_templates (const gchar * element_name,
    GstStaticPadTemplate * hsrc, GstStaticPadTemplate * hsink)
{
  GstHarness *h;
  GstElement *element = gst_element_factory_make (element_name, NULL);
  g_assert (element != NULL);

  h = gst_harness_new_full (element, hsrc, "sink", hsink, "src");
  gst_object_unref (element);
  return h;
}

/**
 * gst_harness_new: (skip)
 * @element_name: a #gchar describing the #GstElement name
 *
 * Creates a new harness. Works like gst_harness_new_with_padnames(), except it
 * assumes the #GstElement sinkpad is named "sink" and srcpad is named "src"
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new (const gchar * element_name)
{
  return gst_harness_new_with_padnames (element_name, "sink", "src");
}

/**
 * gst_harness_add_parse: (skip)
 * @h: a #GstHarness
 * @launchline: a #gchar describing a gst-launch type line
 *
 * Parses the @launchline and puts that in a #GstBin,
 * and then attches the supplied #GstHarness to the bin.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_parse (GstHarness * h, const gchar * launchline)
{
  GstBin *bin;
  gchar *desc;
  GstPad *pad;
  GstIterator *iter;
  gboolean done = FALSE;
  GError *error = NULL;

  g_return_if_fail (launchline != NULL);

  desc = g_strdup_printf ("bin.( %s )", launchline);
  bin =
      (GstBin *) gst_parse_launch_full (desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS,
      &error);

  if (G_UNLIKELY (error != NULL)) {
    g_error ("Unable to create pipeline '%s': %s", desc, error->message);
  }
  g_free (desc);

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

  iter = gst_bin_iterate_sinks (bin);
  while (!done) {
    GValue item = { 0, };

    switch (gst_iterator_next (iter, &item)) {
      case GST_ITERATOR_OK:
        turn_async_and_sync_off (GST_ELEMENT (g_value_get_object (&item)));
        g_value_reset (&item);
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_ERROR:
        gst_object_unref (bin);
        gst_iterator_free (iter);
        g_return_if_reached ();
        break;
    }
  }
  gst_iterator_free (iter);

  gst_harness_add_element_full (h, GST_ELEMENT_CAST (bin),
      &hsrctemplate, "sink", &hsinktemplate, "src");
  gst_object_unref (bin);
}

/**
 * gst_harness_new_parse: (skip)
 * @launchline: a #gchar describing a gst-launch type line
 *
 * Creates a new harness, parsing the @launchline and putting that in a #GstBin,
 * and then attches the harness to the bin.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstHarness, or %NULL if the harness could
 * not be created
 *
 * Since: 1.6
 */
GstHarness *
gst_harness_new_parse (const gchar * launchline)
{
  GstHarness *h;
  h = gst_harness_new_empty ();
  gst_harness_add_parse (h, launchline);
  return h;
}

/**
 * gst_harness_teardown:
 * @h: a #GstHarness
 *
 * Tears down a @GstHarness, freeing all resources allocated using it.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_teardown (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;

  if (priv->blocking_push_mode) {
    g_mutex_lock (&priv->blocking_push_mutex);
    priv->blocking_push_mode = FALSE;
    g_cond_signal (&priv->blocking_push_cond);
    g_mutex_unlock (&priv->blocking_push_mutex);
  }

  if (h->src_harness) {
    gst_harness_teardown (h->src_harness);
  }

  gst_object_replace ((GstObject **) & priv->sink_forward_pad, NULL);
  if (h->sink_harness) {
    gst_harness_teardown (h->sink_harness);
  }

  if (priv->src_caps)
    gst_caps_unref (priv->src_caps);

  if (priv->sink_caps)
    gst_caps_unref (priv->sink_caps);

  if (h->srcpad) {
    if (gst_pad_is_request_pad (GST_PAD_PEER (h->srcpad)))
      gst_element_release_request_pad (h->element, GST_PAD_PEER (h->srcpad));
    g_free (priv->element_sinkpad_name);

    gst_pad_set_active (h->srcpad, FALSE);
    gst_object_unref (h->srcpad);

    g_async_queue_unref (priv->src_event_queue);
  }

  if (h->sinkpad) {
    if (gst_pad_is_request_pad (GST_PAD_PEER (h->sinkpad)))
      gst_element_release_request_pad (h->element, GST_PAD_PEER (h->sinkpad));
    g_free (priv->element_srcpad_name);

    gst_pad_set_active (h->sinkpad, FALSE);
    gst_object_unref (h->sinkpad);

    g_async_queue_unref (priv->buffer_queue);
    g_async_queue_unref (priv->sink_event_queue);
  }

  gst_object_replace ((GstObject **) & priv->propose_allocator, NULL);
  gst_object_replace ((GstObject **) & priv->allocator, NULL);
  gst_object_replace ((GstObject **) & priv->pool, NULL);

  /* if we hold the last ref, set to NULL */
  if (gst_harness_element_unref (h) == 0) {
    gboolean state_change;
    GstState state, pending;
    state_change = gst_element_set_state (h->element, GST_STATE_NULL);
    g_assert (state_change == GST_STATE_CHANGE_SUCCESS);
    state_change = gst_element_get_state (h->element, &state, &pending, 0);
    g_assert (state_change == GST_STATE_CHANGE_SUCCESS);
    g_assert (state == GST_STATE_NULL);
  }

  g_cond_clear (&priv->blocking_push_cond);
  g_mutex_clear (&priv->blocking_push_mutex);
  g_mutex_clear (&priv->priv_mutex);

  g_ptr_array_unref (priv->stress);

  gst_object_unref (h->element);

  gst_object_replace ((GstObject **) & priv->testclock, NULL);

  g_free (h->priv);
  g_free (h);
}

/**
 * gst_harness_add_element_src_pad:
 * @h: a #GstHarness
 * @srcpad: a #GstPad to link to the harness sinkpad
 *
 * Links the specifed #GstPad the @GstHarness sinkpad. This can be useful if
 * perhaps the srcpad did not exist at the time of creating the harness,
 * like a demuxer that provides a sometimes-pad after receiving data.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_element_src_pad (GstHarness * h, GstPad * srcpad)
{
  GstHarnessPrivate *priv = h->priv;
  GstPadLinkReturn link;
  if (h->sinkpad == NULL)
    gst_harness_setup_sink_pad (h, &hsinktemplate, NULL);
  link = gst_pad_link (srcpad, h->sinkpad);
  g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
  g_free (priv->element_srcpad_name);
  priv->element_srcpad_name = gst_pad_get_name (srcpad);
}

/**
 * gst_harness_add_element_sink_pad:
 * @h: a #GstHarness
 * @sinkpad: a #GstPad to link to the harness srcpad
 *
 * Links the specifed #GstPad the @GstHarness srcpad.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_element_sink_pad (GstHarness * h, GstPad * sinkpad)
{
  GstHarnessPrivate *priv = h->priv;
  GstPadLinkReturn link;
  if (h->srcpad == NULL)
    gst_harness_setup_src_pad (h, &hsrctemplate, NULL);
  link = gst_pad_link (h->srcpad, sinkpad);
  g_assert_cmpint (link, ==, GST_PAD_LINK_OK);
  g_free (priv->element_sinkpad_name);
  priv->element_sinkpad_name = gst_pad_get_name (sinkpad);
}

/**
 * gst_harness_set_src_caps:
 * @h: a #GstHarness
 * @caps: (transfer full): a #GstCaps to set on the harness srcpad
 *
 * Sets the @GstHarness srcpad caps. This must be done before any buffers
 * can legally be pushed from the harness to the element.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_src_caps (GstHarness * h, GstCaps * caps)
{
  GstHarnessPrivate *priv = h->priv;
  GstSegment segment;
  gboolean handled;

  handled = gst_pad_push_event (h->srcpad, gst_event_new_caps (caps));
  g_assert (handled);
  gst_caps_take (&priv->src_caps, caps);

  gst_segment_init (&segment, GST_FORMAT_TIME);
  handled = gst_pad_push_event (h->srcpad, gst_event_new_segment (&segment));
}

/**
 * gst_harness_set_sink_caps:
 * @h: a #GstHarness
 * @caps: (transfer full): a #GstCaps to set on the harness sinkpad
 *
 * Sets the @GstHarness sinkpad caps.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_sink_caps (GstHarness * h, GstCaps * caps)
{
  GstHarnessPrivate *priv = h->priv;

  gst_caps_take (&priv->sink_caps, caps);
  gst_pad_push_event (h->sinkpad, gst_event_new_reconfigure ());
}

/**
 * gst_harness_set_caps:
 * @h: a #GstHarness
 * @in: (transfer full): a #GstCaps to set on the harness srcpad
 * @out: (transfer full): a #GstCaps to set on the harness sinkpad
 *
 * Sets the @GstHarness srcpad and sinkpad caps.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_caps (GstHarness * h, GstCaps * in, GstCaps * out)
{
  gst_harness_set_sink_caps (h, out);
  gst_harness_set_src_caps (h, in);
}

/**
 * gst_harness_set_src_caps_str:
 * @h: a #GstHarness
 * @str: a @gchar describing a #GstCaps to set on the harness srcpad
 *
 * Sets the @GstHarness srcpad caps using a string. This must be done before
 * any buffers can legally be pushed from the harness to the element.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_src_caps_str (GstHarness * h, const gchar * str)
{
  gst_harness_set_src_caps (h, gst_caps_from_string (str));
}

/**
 * gst_harness_set_sink_caps_str:
 * @h: a #GstHarness
 * @str: a @gchar describing a #GstCaps to set on the harness sinkpad
 *
 * Sets the @GstHarness sinkpad caps using a string.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_sink_caps_str (GstHarness * h, const gchar * str)
{
  gst_harness_set_sink_caps (h, gst_caps_from_string (str));
}

/**
 * gst_harness_set_caps_str:
 * @h: a #GstHarness
 * @in: a @gchar describing a #GstCaps to set on the harness srcpad
 * @out: a @gchar describing a #GstCaps to set on the harness sinkpad
 *
 * Sets the @GstHarness srcpad and sinkpad caps using strings.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_caps_str (GstHarness * h, const gchar * in, const gchar * out)
{
  gst_harness_set_sink_caps_str (h, out);
  gst_harness_set_src_caps_str (h, in);
}

/**
 * gst_harness_use_systemclock:
 * @h: a #GstHarness
 *
 * Sets the system #GstClock on the @GstHarness #GstElement
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_use_systemclock (GstHarness * h)
{
  GstClock *clock = gst_system_clock_obtain ();
  g_assert (clock != NULL);
  gst_element_set_clock (h->element, clock);
  gst_object_unref (clock);
}

/**
 * gst_harness_use_testclock:
 * @h: a #GstHarness
 *
 * Sets the #GstTestClock on the #GstHarness #GstElement
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_use_testclock (GstHarness * h)
{
  gst_element_set_clock (h->element, GST_CLOCK_CAST (h->priv->testclock));
}

/**
 * gst_harness_get_testclock:
 * @h: a #GstHarness
 *
 * Get the #GstTestClock. Useful if specific operations on the testclock is
 * needed.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstTestClock, or %NULL if the testclock is not
 * present.
 *
 * Since: 1.6
 */
GstTestClock *
gst_harness_get_testclock (GstHarness * h)
{
  return gst_object_ref (h->priv->testclock);
}

/**
 * gst_harness_set_time:
 * @h: a #GstHarness
 * @time: a #GstClockTime to advance the clock to
 *
 * Advance the #GstTestClock to a specific time.
 *
 * MT safe.
 *
 * Returns: a @gboolean %TRUE if the time could be set. %FALSE if not.
 *
 * Since: 1.6
 */
gboolean
gst_harness_set_time (GstHarness * h, GstClockTime time)
{
  gst_test_clock_set_time (h->priv->testclock, time);
  return TRUE;
}

/**
 * gst_harness_wait_for_clock_id_waits:
 * @h: a #GstHarness
 * @waits: a #guint describing the numbers of #GstClockID registered with
 * the #GstTestClock
 * @timeout: a #guint describing how many seconds to wait for @waits to be true
 *
 * Waits for @timeout seconds until @waits number of #GstClockID waits is
 * registered with the #GstTestClock. Useful for writing deterministic tests,
 * where you want to make sure that an expected number of waits have been
 * reached.
 *
 * MT safe.
 *
 * Returns: a @gboolean %TRUE if the waits have been registered, %FALSE if not.
 * (Could be that it timed out waiting or that more waits then waits was found)
 *
 * Since: 1.6
 */
gboolean
gst_harness_wait_for_clock_id_waits (GstHarness * h, guint waits, guint timeout)
{
  GstTestClock *testclock = h->priv->testclock;
  gint64 start_time;
  gboolean ret;

  start_time = g_get_monotonic_time ();
  while (gst_test_clock_peek_id_count (testclock) < waits) {
    gint64 time_spent;

    g_usleep (G_USEC_PER_SEC / 1000);
    time_spent = g_get_monotonic_time () - start_time;
    if ((time_spent / G_USEC_PER_SEC) > timeout)
      break;
  }

  ret = (waits == gst_test_clock_peek_id_count (testclock));

  return ret;
}

/**
 * gst_harness_crank_single_clock_wait:
 * @h: a #GstHarness
 *
 * A "crank" consists of three steps:
 * 1: Wait for a #GstClockID to be registered with the #GstTestClock.
 * 2: Advance the #GstTestClock to the time the #GstClockID is waiting for.
 * 3: Release the #GstClockID wait.
 * Together, this provides an easy way to not have to think about the details
 * around clocks and time, but still being able to write deterministic tests
 * that are dependant on this. A "crank" can be though of as the notion of
 * manually driving the clock forward to its next logical step.
 *
 * MT safe.
 *
 * Returns: a @gboolean %TRUE if the "crank" was successful, %FALSE if not.
 *
 * Since: 1.6
 */
gboolean
gst_harness_crank_single_clock_wait (GstHarness * h)
{
  return gst_test_clock_crank (h->priv->testclock);
}

/**
 * gst_harness_crank_multiple_clock_waits:
 * @h: a #GstHarness
 * @waits: a #guint describing the number of #GstClockIDs to crank
 *
 * Similar to gst_harness_crank_single_clock_wait(), this is the function to use
 * if your harnessed element(s) are using more then one gst_clock_id_wait.
 * Failing to do so can (and will) make it racy which #GstClockID you actually
 * are releasing, where as this function will process all the waits at the
 * same time, ensuring that one thread can't register another wait before
 * both are released.
 *
 * MT safe.
 *
 * Returns: a @gboolean %TRUE if the "crank" was successful, %FALSE if not.
 *
 * Since: 1.6
 */
gboolean
gst_harness_crank_multiple_clock_waits (GstHarness * h, guint waits)
{
  GstTestClock *testclock = h->priv->testclock;
  GList *pending;
  guint processed;

  gst_test_clock_wait_for_multiple_pending_ids (testclock, waits, &pending);
  gst_harness_set_time (h, gst_test_clock_id_list_get_latest_time (pending));
  processed = gst_test_clock_process_id_list (testclock, pending);

  g_list_free_full (pending, gst_clock_id_unref);
  return processed == waits;
}

/**
 * gst_harness_play:
 * @h: a #GstHarness
 *
 * This will set the harnessed #GstElement to %GST_STATE_PLAYING.
 * #GstElements without a sink-#GstPad and with the %GST_ELEMENT_FLAG_SOURCE
 * flag set is concidered a src #GstElement
 * Non-src #GstElements (like sinks and filters) are automatically set to
 * playing by the #GstHarness, but src #GstElements are not to avoid them
 * starting to produce buffers.
 * Hence, for src #GstElement you must call gst_harness_play() explicitly.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_play (GstHarness * h)
{
  GstState state, pending;
  gboolean state_change;
  state_change = gst_element_set_state (h->element, GST_STATE_PLAYING);
  g_assert_cmpint (GST_STATE_CHANGE_SUCCESS, ==, state_change);
  state_change = gst_element_get_state (h->element, &state, &pending, 0);
  g_assert_cmpint (GST_STATE_CHANGE_SUCCESS, ==, state_change);
  g_assert_cmpint (GST_STATE_PLAYING, ==, state);
}

/**
 * gst_harness_set_blocking_push_mode:
 * @h: a #GstHarness
 *
 * Setting this will make the harness block in the chain-function, and
 * then release when gst_harness_pull() or gst_harness_try_pull() is called.
 * Can be useful when wanting to control a src-element that is not implementing
 * gst_clock_id_wait() so it can't be controlled by the #GstTestClock, since
 * it otherwise would produce buffers as fast as possible.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_blocking_push_mode (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  priv->blocking_push_mode = TRUE;
}

/**
 * gst_harness_set_forwarding:
 * @h: a #GstHarness
 * @forwarding: a #gboolean to enable/disable forwarding
 *
 * As a convenience, a src-harness will forward %GST_EVENT_STREAM_START,
 * %GST_EVENT_CAPS and %GST_EVENT_SEGMENT to the main-harness if forwarding
 * is enabled, and forward any sticky-events from the main-harness to
 * the sink-harness. It will also forward the %GST_QUERY_ALLOCATION.
 *
 * If forwarding is disabled, the user will have to either manually push
 * these events from the src-harness using gst_harness_src_push_event(), or
 * create and push them manually. While this will allow full control and
 * inspection of these events, for the most cases having forwarding enabled
 * will be sufficient when writing a test where the src-harness' main function
 * is providing data for the main-harness.
 *
 * Forwarding is enabled by default.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_forwarding (GstHarness * h, gboolean forwarding)
{
  GstHarnessPrivate *priv = h->priv;
  priv->forwarding = forwarding;
  if (h->src_harness)
    gst_harness_set_forwarding (h->src_harness, forwarding);
  if (h->sink_harness)
    gst_harness_set_forwarding (h->sink_harness, forwarding);
}

static void
gst_harness_set_forward_pad (GstHarness * h, GstPad * fwdpad)
{
  HARNESS_LOCK (h);
  gst_object_replace ((GstObject **) & h->priv->sink_forward_pad,
      (GstObject *) fwdpad);
  HARNESS_UNLOCK (h);
}

/**
 * gst_harness_create_buffer:
 * @h: a #GstHarness
 * @size: a #gsize specifying the size of the buffer
 *
 * Allocates a buffer using a #GstBufferPool if present, or else using the
 * configured #GstAllocator and #GstAllocationParams
 *
 * MT safe.
 *
 * Returns: a #GstBuffer of size @size
 *
 * Since: 1.6
 */
GstBuffer *
gst_harness_create_buffer (GstHarness * h, gsize size)
{
  GstHarnessPrivate *priv = h->priv;
  GstBuffer *ret = NULL;
  GstFlowReturn flow;

  if (gst_pad_check_reconfigure (h->srcpad))
    gst_harness_negotiate (h);

  if (priv->pool) {
    flow = gst_buffer_pool_acquire_buffer (priv->pool, &ret, NULL);
    g_assert_cmpint (flow, ==, GST_FLOW_OK);
    if (gst_buffer_get_size (ret) != size) {
      GST_DEBUG_OBJECT (h,
          "use fallback, pool is configured with a different size (%zu != %zu)",
          size, gst_buffer_get_size (ret));
      gst_buffer_unref (ret);
      ret = NULL;
    }
  }

  if (!ret)
    ret =
        gst_buffer_new_allocate (priv->allocator, size,
        &priv->allocation_params);

  g_assert (ret != NULL);
  return ret;
}

/**
 * gst_harness_push:
 * @h: a #GstHarness
 * @buffer: (transfer full): a #GstBuffer to push
 *
 * Pushes a #GstBuffer on the #GstHarness srcpad. The standard way of
 * interacting with an harnessed element.
 *
 * MT safe.
 *
 * Returns: a #GstFlowReturn with the result from the push
 *
 * Since: 1.6
 */
GstFlowReturn
gst_harness_push (GstHarness * h, GstBuffer * buffer)
{
  GstHarnessPrivate *priv = h->priv;
  g_assert (buffer != NULL);
  priv->last_push_ts = GST_BUFFER_TIMESTAMP (buffer);
  return gst_pad_push (h->srcpad, buffer);
}

/**
 * gst_harness_pull:
 * @h: a #GstHarness
 *
 * Pulls a #GstBuffer from the #GAsyncQueue on the #GstHarness sinkpad. The pull
 * will timeout in 60 seconds. This is the standard way of getting a buffer
 * from a harnessed #GstElement.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstBuffer or %NULL if timed out.
 *
 * Since: 1.6
 */
GstBuffer *
gst_harness_pull (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  GstBuffer *buf = (GstBuffer *) g_async_queue_timeout_pop (priv->buffer_queue,
      G_USEC_PER_SEC * 60);

  if (priv->blocking_push_mode) {
    g_mutex_lock (&priv->blocking_push_mutex);
    g_cond_signal (&priv->blocking_push_cond);
    g_mutex_unlock (&priv->blocking_push_mutex);
  }

  return buf;
}

/**
 * gst_harness_try_pull:
 * @h: a #GstHarness
 *
 * Pulls a #GstBuffer from the #GAsyncQueue on the #GstHarness sinkpad. Unlike
 * gst_harness_pull this will not wait for any buffers if not any are present,
 * and return %NULL straight away.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstBuffer or %NULL if no buffers are present in the #GAsyncQueue
 *
 * Since: 1.6
 */
GstBuffer *
gst_harness_try_pull (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  GstBuffer *buf = (GstBuffer *) g_async_queue_try_pop (priv->buffer_queue);

  if (priv->blocking_push_mode) {
    g_mutex_lock (&priv->blocking_push_mutex);
    g_cond_signal (&priv->blocking_push_cond);
    g_mutex_unlock (&priv->blocking_push_mutex);
  }

  return buf;
}

/**
 * gst_harness_push_and_pull:
 * @h: a #GstHarness
 * @buffer: (transfer full): a #GstBuffer to push
 *
 * Basically a gst_harness_push and a gst_harness_pull in one line. Reflects
 * the fact that you often want to do exactly this in your test: Push one buffer
 * in, and inspect the outcome.
 *
 * MT safe.
 *
 * Returns: (transfer full): a #GstBuffer or %NULL if timed out.
 *
 * Since: 1.6
 */
GstBuffer *
gst_harness_push_and_pull (GstHarness * h, GstBuffer * buffer)
{
  gst_harness_push (h, buffer);
  return gst_harness_pull (h);
}

/**
 * gst_harness_buffers_received:
 * @h: a #GstHarness
 *
 * The total number of #GstBuffers that has arrived on the #GstHarness sinkpad.
 * This number includes buffers that have been dropped as well as buffers
 * that have already been pulled out.
 *
 * MT safe.
 *
 * Returns: a #guint number of buffers received
 *
 * Since: 1.6
 */
guint
gst_harness_buffers_received (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_atomic_int_get (&priv->recv_buffers);
}

/**
 * gst_harness_buffers_in_queue:
 * @h: a #GstHarness
 *
 * The number of #GstBuffers currently in the #GstHarness sinkpad #GAsyncQueue
 *
 * MT safe.
 *
 * Returns: a #guint number of buffers in the queue
 *
 * Since: 1.6
 */
guint
gst_harness_buffers_in_queue (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_async_queue_length (priv->buffer_queue);
}

/**
 * gst_harness_set_drop_buffers:
 * @h: a #GstHarness
 * @drop_buffers: a #gboolean specifying to drop outgoing buffers or not
 *
 * When set to %TRUE, instead of placing the buffers arriving from the harnessed
 * #GstElement inside the sinkpads #GAsyncQueue, they are instead unreffed.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_drop_buffers (GstHarness * h, gboolean drop_buffers)
{
  GstHarnessPrivate *priv = h->priv;
  priv->drop_buffers = drop_buffers;
}

/**
 * gst_harness_take_all_data_as_buffer:
 * @h: a #GstHarness
 *
 * Pulls all pending data from the harness and returns it as a single buffer.
 *
 * Returns: (transfer full): the data as a buffer. Unref with gst_buffer_unref()
 *     when no longer needed.
 *
 * Since: 1.14
 */
GstBuffer *
gst_harness_take_all_data_as_buffer (GstHarness * h)
{
  GstHarnessPrivate *priv;
  GstBuffer *ret, *buf;

  g_return_val_if_fail (h != NULL, NULL);

  priv = h->priv;

  g_async_queue_lock (priv->buffer_queue);

  ret = g_async_queue_try_pop_unlocked (priv->buffer_queue);

  if (ret == NULL) {
    ret = gst_buffer_new ();
  } else {
    /* buffer appending isn't very efficient for larger numbers of buffers
     * or lots of memories, but this function is not performance critical and
     * we can still improve it if and when the need arises. For now KISS. */
    while ((buf = g_async_queue_try_pop_unlocked (priv->buffer_queue)))
      ret = gst_buffer_append (ret, buf);
  }

  g_async_queue_unlock (priv->buffer_queue);

  return ret;
}

/**
 * gst_harness_take_all_data: (skip)
 * @h: a #GstHarness
 * @size: (out): the size of the data in bytes
 *
 * Pulls all pending data from the harness and returns it as a single
 * data slice.
 *
 * Returns: (transfer full): a pointer to the data, newly allocated. Free
 *     with g_free() when no longer needed. Will return %NULL if there is no
 *     data.
 *
 * Since: 1.14
 */
guint8 *
gst_harness_take_all_data (GstHarness * h, gsize * size)
{
  GstBuffer *buf;
  guint8 *data = NULL;

  g_return_val_if_fail (h != NULL, NULL);
  g_return_val_if_fail (size != NULL, NULL);

  buf = gst_harness_take_all_data_as_buffer (h);
  gst_buffer_extract_dup (buf, 0, -1, (gpointer *) & data, size);
  gst_buffer_unref (buf);
  return data;
}

/**
 * gst_harness_take_all_data_as_bytes: (rename-to gst_harness_take_all_data)
 * @h: a #GstHarness
 *
 * Pulls all pending data from the harness and returns it as a single #GBytes.
 *
 * Returns: (transfer full): a pointer to the data, newly allocated. Free
 *     with g_free() when no longer needed.
 *
 * Since: 1.14
 */
GBytes *
gst_harness_take_all_data_as_bytes (GstHarness * h)
{
  guint8 *data;
  gsize size = 0;

  g_return_val_if_fail (h != NULL, NULL);

  data = gst_harness_take_all_data (h, &size);
  return g_bytes_new_take (data, size);
}


/**
 * gst_harness_dump_to_file:
 * @h: a #GstHarness
 * @filename: a #gchar with a the name of a file
 *
 * Allows you to dump the #GstBuffers the #GstHarness sinkpad #GAsyncQueue
 * to a file.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_dump_to_file (GstHarness * h, const gchar * filename)
{
  GError *err = NULL;
  gpointer data;
  gsize size;

  data = gst_harness_take_all_data (h, &size);
  if (!g_file_set_contents (filename, data ? data : "", size, &err)) {
    g_error ("GstHarness: Failed to write data to file: %s", err->message);
    g_clear_error (&err);
  }
  g_free (data);
}

/**
 * gst_harness_get_last_pushed_timestamp:
 * @h: a #GstHarness
 *
 * Get the timestamp of the last #GstBuffer pushed on the #GstHarness srcpad,
 * typically with gst_harness_push or gst_harness_push_from_src.
 *
 * MT safe.
 *
 * Returns: a #GstClockTime with the timestamp or %GST_CLOCK_TIME_NONE if no
 * #GstBuffer has been pushed on the #GstHarness srcpad
 *
 * Since: 1.6
 */
GstClockTime
gst_harness_get_last_pushed_timestamp (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return priv->last_push_ts;
}

/**
 * gst_harness_push_event:
 * @h: a #GstHarness
 * @event: a #GstEvent to push
 *
 * Pushes an #GstEvent on the #GstHarness srcpad.
 *
 * MT safe.
 *
 * Returns: a #gboolean with the result from the push
 *
 * Since: 1.6
 */
gboolean
gst_harness_push_event (GstHarness * h, GstEvent * event)
{
  return gst_pad_push_event (h->srcpad, event);
}

/**
 * gst_harness_pull_event:
 * @h: a #GstHarness
 *
 * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness sinkpad.
 * Timeouts after 60 seconds similar to gst_harness_pull.
 *
 * MT safe.
 *
 * Returns: a #GstEvent or %NULL if timed out.
 *
 * Since: 1.6
 */
GstEvent *
gst_harness_pull_event (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return (GstEvent *) g_async_queue_timeout_pop (priv->sink_event_queue,
      G_USEC_PER_SEC * 60);
}

/**
 * gst_harness_try_pull_event:
 * @h: a #GstHarness
 *
 * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness sinkpad.
 * See gst_harness_try_pull for details.
 *
 * MT safe.
 *
 * Returns: a #GstEvent or %NULL if no buffers are present in the #GAsyncQueue
 *
 * Since: 1.6
 */
GstEvent *
gst_harness_try_pull_event (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return (GstEvent *) g_async_queue_try_pop (priv->sink_event_queue);
}

/**
 * gst_harness_events_received:
 * @h: a #GstHarness
 *
 * The total number of #GstEvents that has arrived on the #GstHarness sinkpad
 * This number includes events handled by the harness as well as events
 * that have already been pulled out.
 *
 * MT safe.
 *
 * Returns: a #guint number of events received
 *
 * Since: 1.6
 */
guint
gst_harness_events_received (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_atomic_int_get (&priv->recv_events);
}

/**
 * gst_harness_events_in_queue:
 * @h: a #GstHarness
 *
 * The number of #GstEvents currently in the #GstHarness sinkpad #GAsyncQueue
 *
 * MT safe.
 *
 * Returns: a #guint number of events in the queue
 *
 * Since: 1.6
 */
guint
gst_harness_events_in_queue (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_async_queue_length (priv->sink_event_queue);
}

/**
 * gst_harness_push_upstream_event:
 * @h: a #GstHarness
 * @event: a #GstEvent to push
 *
 * Pushes an #GstEvent on the #GstHarness sinkpad.
 *
 * MT safe.
 *
 * Returns: a #gboolean with the result from the push
 *
 * Since: 1.6
 */
gboolean
gst_harness_push_upstream_event (GstHarness * h, GstEvent * event)
{
  g_return_val_if_fail (event != NULL, FALSE);
  g_return_val_if_fail (GST_EVENT_IS_UPSTREAM (event), FALSE);

  return gst_pad_push_event (h->sinkpad, event);
}

/**
 * gst_harness_pull_upstream_event:
 * @h: a #GstHarness
 *
 * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness srcpad.
 * Timeouts after 60 seconds similar to gst_harness_pull.
 *
 * MT safe.
 *
 * Returns: a #GstEvent or %NULL if timed out.
 *
 * Since: 1.6
 */
GstEvent *
gst_harness_pull_upstream_event (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return (GstEvent *) g_async_queue_timeout_pop (priv->src_event_queue,
      G_USEC_PER_SEC * 60);
}

/**
 * gst_harness_try_pull_upstream_event:
 * @h: a #GstHarness
 *
 * Pulls an #GstEvent from the #GAsyncQueue on the #GstHarness srcpad.
 * See gst_harness_try_pull for details.
 *
 * MT safe.
 *
 * Returns: a #GstEvent or %NULL if no buffers are present in the #GAsyncQueue
 *
 * Since: 1.6
 */
GstEvent *
gst_harness_try_pull_upstream_event (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return (GstEvent *) g_async_queue_try_pop (priv->src_event_queue);
}

/**
 * gst_harness_upstream_events_received:
 * @h: a #GstHarness
 *
 * The total number of #GstEvents that has arrived on the #GstHarness srcpad
 * This number includes events handled by the harness as well as events
 * that have already been pulled out.
 *
 * MT safe.
 *
 * Returns: a #guint number of events received
 *
 * Since: 1.6
 */
guint
gst_harness_upstream_events_received (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_atomic_int_get (&priv->recv_upstream_events);
}

/**
 * gst_harness_upstream_events_in_queue:
 * @h: a #GstHarness
 *
 * The number of #GstEvents currently in the #GstHarness srcpad #GAsyncQueue
 *
 * MT safe.
 *
 * Returns: a #guint number of events in the queue
 *
 * Since: 1.6
 */
guint
gst_harness_upstream_events_in_queue (GstHarness * h)
{
  GstHarnessPrivate *priv = h->priv;
  return g_async_queue_length (priv->src_event_queue);
}

/**
 * gst_harness_query_latency:
 * @h: a #GstHarness
 *
 * Get the min latency reported by any harnessed #GstElement.
 *
 * MT safe.
 *
 * Returns: a #GstClockTime with min latency
 *
 * Since: 1.6
 */
GstClockTime
gst_harness_query_latency (GstHarness * h)
{
  GstQuery *query;
  gboolean is_live;
  GstClockTime min = GST_CLOCK_TIME_NONE;
  GstClockTime max;

  query = gst_query_new_latency ();

  if (gst_pad_peer_query (h->sinkpad, query)) {
    gst_query_parse_latency (query, &is_live, &min, &max);
  }
  gst_query_unref (query);

  return min;
}

/**
 * gst_harness_set_upstream_latency:
 * @h: a #GstHarness
 * @latency: a #GstClockTime specifying the latency
 *
 * Sets the min latency reported by #GstHarness when receiving a latency-query
 *
 * Since: 1.6
 */
void
gst_harness_set_upstream_latency (GstHarness * h, GstClockTime latency)
{
  GstHarnessPrivate *priv = h->priv;
  priv->latency_min = latency;
}

/**
 * gst_harness_get_allocator:
 * @h: a #GstHarness
 * @allocator: (out) (allow-none) (transfer none): the #GstAllocator used
 * @params: (out) (allow-none) (transfer full): the #GstAllocationParams of
 *   @allocator
 *
 * Gets the @allocator and its @params that has been decided to use after an
 * allocation query.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_get_allocator (GstHarness * h, GstAllocator ** allocator,
    GstAllocationParams * params)
{
  GstHarnessPrivate *priv = h->priv;
  if (allocator)
    *allocator = priv->allocator;
  if (params)
    *params = priv->allocation_params;
}


/**
 * gst_harness_set_propose_allocator:
 * @h: a #GstHarness
 * @allocator: (allow-none) (transfer full): a #GstAllocator
 * @params: (allow-none) (transfer none): a #GstAllocationParams
 *
 * Sets the @allocator and @params to propose when receiving an allocation
 * query.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set_propose_allocator (GstHarness * h, GstAllocator * allocator,
    const GstAllocationParams * params)
{
  GstHarnessPrivate *priv = h->priv;
  if (allocator)
    priv->propose_allocator = allocator;
  if (params)
    priv->propose_allocation_params = *params;
}

/**
 * gst_harness_add_src_harness:
 * @h: a #GstHarness
 * @src_harness: (transfer full): a #GstHarness to be added as a src-harness.
 * @has_clock_wait: a #gboolean specifying if the #GstElement uses
 * gst_clock_wait_id internally.
 *
 * A src-harness is a great way of providing the #GstHarness with data.
 * By adding a src-type #GstElement, it is then easy to use functions like
 * gst_harness_push_from_src or gst_harness_src_crank_and_push_many
 * to provide your harnessed element with input. The @has_clock_wait variable
 * is a greate way to control you src-element with, in that you can have it
 * produce a buffer for you by simply cranking the clock, and not have it
 * spin out of control producing buffers as fast as possible.
 *
 * If a src-harness already exists it will be replaced.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_src_harness (GstHarness * h,
    GstHarness * src_harness, gboolean has_clock_wait)
{
  if (h->src_harness)
    gst_harness_teardown (h->src_harness);
  h->src_harness = src_harness;
  gst_harness_set_forward_pad (h->src_harness, h->srcpad);
  h->src_harness->priv->has_clock_wait = has_clock_wait;
  gst_harness_set_forwarding (h->src_harness, h->priv->forwarding);
}

/**
 * gst_harness_add_src:
 * @h: a #GstHarness
 * @src_element_name: a #gchar with the name of a #GstElement
 * @has_clock_wait: a #gboolean specifying if the #GstElement uses
 * gst_clock_wait_id internally.
 *
 * Similar to gst_harness_add_src_harness, this is a convenience to
 * directly create a src-harness using the @src_element_name name specified.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_src (GstHarness * h,
    const gchar * src_element_name, gboolean has_clock_wait)
{
  GstHarness *src_harness = gst_harness_new (src_element_name);
  gst_harness_add_src_harness (h, src_harness, has_clock_wait);
}

/**
 * gst_harness_add_src_parse:
 * @h: a #GstHarness
 * @launchline: a #gchar describing a gst-launch type line
 * @has_clock_wait: a #gboolean specifying if the #GstElement uses
 * gst_clock_wait_id internally.
 *
 * Similar to gst_harness_add_src, this allows you to specify a launch-line,
 * which can be useful for both having more then one #GstElement acting as your
 * src (Like a src producing raw buffers, and then an encoder, providing encoded
 * data), but also by allowing you to set properties like "is-live" directly on
 * the elements.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_src_parse (GstHarness * h,
    const gchar * launchline, gboolean has_clock_wait)
{
  GstHarness *src_harness = gst_harness_new_parse (launchline);
  gst_harness_add_src_harness (h, src_harness, has_clock_wait);
}

/**
 * gst_harness_push_from_src:
 * @h: a #GstHarness
 *
 * Transfer data from the src-#GstHarness to the main-#GstHarness. It consists
 * of 4 steps:
 * 1: Make sure the src is started. (see: gst_harness_play)
 * 2: Crank the clock (see: gst_harness_crank_single_clock_wait)
 * 3: Pull a #GstBuffer from the src-#GstHarness (see: gst_harness_pull)
 * 4: Push the same #GstBuffer into the main-#GstHarness (see: gst_harness_push)
 *
 * MT safe.
 *
 * Returns: a #GstFlowReturn with the result of the push
 *
 * Since: 1.6
 */
GstFlowReturn
gst_harness_push_from_src (GstHarness * h)
{
  GstBuffer *buf;
  gboolean crank;

  g_assert (h->src_harness);

  /* FIXME: this *is* the right time to start the src,
     but maybe a flag so we don't keep telling it to play? */
  gst_harness_play (h->src_harness);

  if (h->src_harness->priv->has_clock_wait) {
    crank = gst_harness_crank_single_clock_wait (h->src_harness);
    g_assert (crank);
  }

  buf = gst_harness_pull (h->src_harness);
  g_assert (buf != NULL);
  return gst_harness_push (h, buf);
}

/**
 * gst_harness_src_crank_and_push_many:
 * @h: a #GstHarness
 * @cranks: a #gint with the number of calls to gst_harness_crank_single_clock_wait
 * @pushes: a #gint with the number of calls to gst_harness_push
 *
 * Transfer data from the src-#GstHarness to the main-#GstHarness. Similar to
 * gst_harness_push_from_src, this variant allows you to specify how many cranks
 * and how many pushes to perform. This can be useful for both moving a lot
 * of data at the same time, as well as cases when one crank does not equal one
 * buffer to push and v.v.
 *
 * MT safe.
 *
 * Returns: a #GstFlowReturn with the result of the push
 *
 * Since: 1.6
 */
GstFlowReturn
gst_harness_src_crank_and_push_many (GstHarness * h, gint cranks, gint pushes)
{
  GstFlowReturn ret = GST_FLOW_OK;
  gboolean crank;
  int i;

  g_assert (h->src_harness);
  gst_harness_play (h->src_harness);

  for (i = 0; i < cranks; i++) {
    crank = gst_harness_crank_single_clock_wait (h->src_harness);
    g_assert (crank);
  }

  for (i = 0; i < pushes; i++) {
    GstBuffer *buf;
    buf = gst_harness_pull (h->src_harness);
    g_assert (buf != NULL);
    ret = gst_harness_push (h, buf);
    if (ret != GST_FLOW_OK)
      break;
  }

  return ret;
}

/**
 * gst_harness_src_push_event:
 * @h: a #GstHarness
 *
 * Similar to what gst_harness_src_push does with #GstBuffers, this transfers
 * a #GstEvent from the src-#GstHarness to the main-#GstHarness. Note that
 * some #GstEvents are being transferred automagically. Look at sink_forward_pad
 * for details.
 *
 * MT safe.
 *
 * Returns: a #gboolean with the result of the push
 *
 * Since: 1.6
 */
gboolean
gst_harness_src_push_event (GstHarness * h)
{
  return gst_harness_push_event (h, gst_harness_pull_event (h->src_harness));
}


static gboolean
forward_sticky_events (GstPad * pad, GstEvent ** ev, gpointer user_data)
{
  GstHarness *h = user_data;
  return gst_pad_push_event (h->priv->sink_forward_pad, gst_event_ref (*ev));
}

/**
 * gst_harness_add_sink_harness:
 * @h: a #GstHarness
 * @sink_harness: (transfer full): a #GstHarness to be added as a sink-harness.
 *
 * Similar to gst_harness_add_src, this allows you to send the data coming out
 * of your harnessed #GstElement to a sink-element, allowing to test different
 * responses the element output might create in sink elements. An example might
 * be an existing sink providing some analytical data on the input it receives that
 * can be useful to your testing. If the goal is to test a sink-element itself,
 * this is better acheived using gst_harness_new directly on the sink.
 *
 * If a sink-harness already exists it will be replaced.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_sink_harness (GstHarness * h, GstHarness * sink_harness)
{
  GstHarnessPrivate *priv = h->priv;

  if (h->sink_harness) {
    gst_harness_set_forward_pad (h, NULL);
    gst_harness_teardown (h->sink_harness);
  }
  h->sink_harness = sink_harness;
  gst_harness_set_forward_pad (h, h->sink_harness->srcpad);
  if (priv->forwarding && h->sinkpad)
    gst_pad_sticky_events_foreach (h->sinkpad, forward_sticky_events, h);
  gst_harness_set_forwarding (h->sink_harness, priv->forwarding);
}

/**
 * gst_harness_add_sink:
 * @h: a #GstHarness
 * @sink_element_name: a #gchar with the name of a #GstElement
 *
 * Similar to gst_harness_add_sink_harness, this is a convenience to
 * directly create a sink-harness using the @sink_element_name name specified.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_sink (GstHarness * h, const gchar * sink_element_name)
{
  GstHarness *sink_harness = gst_harness_new (sink_element_name);
  gst_harness_add_sink_harness (h, sink_harness);
}

/**
 * gst_harness_add_sink_parse:
 * @h: a #GstHarness
 * @launchline: a #gchar with the name of a #GstElement
 *
 * Similar to gst_harness_add_sink, this allows you to specify a launch-line
 * instead of just an element name. See gst_harness_add_src_parse for details.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_sink_parse (GstHarness * h, const gchar * launchline)
{
  GstHarness *sink_harness = gst_harness_new_parse (launchline);
  gst_harness_add_sink_harness (h, sink_harness);
}

/**
 * gst_harness_push_to_sink:
 * @h: a #GstHarness
 *
 * Transfer one #GstBuffer from the main-#GstHarness to the sink-#GstHarness.
 * See gst_harness_push_from_src for details.
 *
 * MT safe.
 *
 * Returns: a #GstFlowReturn with the result of the push
 *
 * Since: 1.6
 */
GstFlowReturn
gst_harness_push_to_sink (GstHarness * h)
{
  GstBuffer *buf;
  g_assert (h->sink_harness);
  buf = gst_harness_pull (h);
  g_assert (buf != NULL);
  return gst_harness_push (h->sink_harness, buf);
}

/**
 * gst_harness_sink_push_many:
 * @h: a #GstHarness
 * @pushes: a #gint with the number of calls to gst_harness_push_to_sink
 *
 * Convenience that calls gst_harness_push_to_sink @pushes number of times.
 * Will abort the pushing if any one push fails.
 *
 * MT safe.
 *
 * Returns: a #GstFlowReturn with the result of the push
 *
 * Since: 1.6
 */
GstFlowReturn
gst_harness_sink_push_many (GstHarness * h, gint pushes)
{
  GstFlowReturn ret = GST_FLOW_OK;
  int i;
  g_assert (h->sink_harness);
  for (i = 0; i < pushes; i++) {
    ret = gst_harness_push_to_sink (h);
    if (ret != GST_FLOW_OK)
      break;
  }
  return ret;
}

/**
 * gst_harness_find_element:
 * @h: a #GstHarness
 * @element_name: a #gchar with a #GstElementFactory name
 *
 * Most useful in conjunction with gst_harness_new_parse, this will scan the
 * #GstElements inside the #GstHarness, and check if any of them matches
 * @element_name. Typical usecase being that you need to access one of the
 * harnessed elements for properties and/or signals.
 *
 * MT safe.
 *
 * Returns: (transfer full) (allow-none): a #GstElement or %NULL if not found
 *
 * Since: 1.6
 */
GstElement *
gst_harness_find_element (GstHarness * h, const gchar * element_name)
{
  gboolean done = FALSE;
  GstIterator *iter;
  GValue data = G_VALUE_INIT;

  iter = gst_bin_iterate_elements (GST_BIN (h->element));
  done = FALSE;

  while (!done) {
    switch (gst_iterator_next (iter, &data)) {
      case GST_ITERATOR_OK:
      {
        GstElement *element = g_value_get_object (&data);
        GstPluginFeature *feature =
            GST_PLUGIN_FEATURE (gst_element_get_factory (element));
        if (!strcmp (element_name, gst_plugin_feature_get_name (feature))) {
          gst_iterator_free (iter);
          return element;
        }
        g_value_reset (&data);
        break;
      }
      case GST_ITERATOR_RESYNC:
        gst_iterator_resync (iter);
        break;
      case GST_ITERATOR_ERROR:
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }
  gst_iterator_free (iter);

  return NULL;
}

/**
 * gst_harness_set:
 * @h: a #GstHarness
 * @element_name: a #gchar with a #GstElementFactory name
 * @first_property_name: a #gchar with the first property name
 * @...: value for the first property, followed optionally by more
 *  name/value pairs, followed by %NULL
 *
 * A convenience function to allows you to call g_object_set on a #GstElement
 * that are residing inside the #GstHarness, by using normal g_object_set
 * syntax.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_set (GstHarness * h,
    const gchar * element_name, const gchar * first_property_name, ...)
{
  va_list var_args;
  GstElement *element = gst_harness_find_element (h, element_name);
  va_start (var_args, first_property_name);
  g_object_set_valist (G_OBJECT (element), first_property_name, var_args);
  va_end (var_args);
  gst_object_unref (element);
}

/**
 * gst_harness_get:
 * @h: a #GstHarness
 * @element_name: a #gchar with a #GstElementFactory name
 * @first_property_name: a #gchar with the first property name
 * @...: return location for the first property, followed optionally by more
 *  name/return location pairs, followed by %NULL
 *
 * A convenience function to allows you to call g_object_get on a #GstElement
 * that are residing inside the #GstHarness, by using normal g_object_get
 * syntax.
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_get (GstHarness * h,
    const gchar * element_name, const gchar * first_property_name, ...)
{
  va_list var_args;
  GstElement *element = gst_harness_find_element (h, element_name);
  va_start (var_args, first_property_name);
  g_object_get_valist (G_OBJECT (element), first_property_name, var_args);
  va_end (var_args);
  gst_object_unref (element);
}

/**
 * gst_harness_add_probe:
 * @h: a #GstHarness
 * @element_name: a #gchar with a #GstElementFactory name
 * @pad_name: a #gchar with the name of the pad to attach the probe to
 * @mask: a #GstPadProbeType (see gst_pad_add_probe)
 * @callback: a #GstPadProbeCallback (see gst_pad_add_probe)
 * @user_data: a #gpointer (see gst_pad_add_probe)
 * @destroy_data: a #GDestroyNotify (see gst_pad_add_probe)
 *
 * A convenience function to allows you to call gst_pad_add_probe on a
 * #GstPad of a #GstElement that are residing inside the #GstHarness,
 * by using normal gst_pad_add_probe syntax
 *
 * MT safe.
 *
 * Since: 1.6
 */
void
gst_harness_add_probe (GstHarness * h,
    const gchar * element_name, const gchar * pad_name, GstPadProbeType mask,
    GstPadProbeCallback callback, gpointer user_data,
    GDestroyNotify destroy_data)
{
  GstElement *element = gst_harness_find_element (h, element_name);
  GstPad *pad = gst_element_get_static_pad (element, pad_name);
  gst_pad_add_probe (pad, mask, callback, user_data, destroy_data);
  gst_object_unref (pad);
  gst_object_unref (element);
}

/******************************************************************************/
/*       STRESS                                                               */
/******************************************************************************/
struct _GstHarnessThread
{
  GstHarness *h;
  GThread *thread;
  gboolean running;

  gulong sleep;

  GDestroyNotify freefunc;
};

typedef struct
{
  GstHarnessThread t;

  GFunc init;
  GFunc callback;
  gpointer data;
} GstHarnessCustomThread;

typedef struct
{
  GstHarnessThread t;

  GstCaps *caps;
  GstSegment segment;
  GstHarnessPrepareBufferFunc func;
  gpointer data;
  GDestroyNotify notify;
} GstHarnessPushBufferThread;

typedef struct
{
  GstHarnessThread t;

  GstHarnessPrepareEventFunc func;
  gpointer data;
  GDestroyNotify notify;
} GstHarnessPushEventThread;

typedef struct
{
  GstHarnessThread t;

  gchar *name;
  GValue value;
} GstHarnessPropThread;

typedef struct
{
  GstHarnessThread t;

  GstPadTemplate *templ;
  gchar *name;
  GstCaps *caps;
  gboolean release;

  GSList *pads;
} GstHarnessReqPadThread;

static void
gst_harness_thread_init (GstHarnessThread * t, GDestroyNotify freefunc,
    GstHarness * h, gulong sleep)
{
  t->freefunc = freefunc;
  t->h = h;
  t->sleep = sleep;

  g_ptr_array_add (h->priv->stress, t);
}

static void
gst_harness_thread_free (GstHarnessThread * t)
{
  g_slice_free (GstHarnessThread, t);
}

static void
gst_harness_custom_thread_free (GstHarnessCustomThread * t)
{
  g_slice_free (GstHarnessCustomThread, t);
}

static void
gst_harness_push_buffer_thread_free (GstHarnessPushBufferThread * t)
{
  if (t != NULL) {
    gst_caps_replace (&t->caps, NULL);
    if (t->notify != NULL)
      t->notify (t->data);
    g_slice_free (GstHarnessPushBufferThread, t);
  }
}

static void
gst_harness_push_event_thread_free (GstHarnessPushEventThread * t)
{
  if (t != NULL) {
    if (t->notify != NULL)
      t->notify (t->data);
    g_slice_free (GstHarnessPushEventThread, t);
  }
}

static void
gst_harness_property_thread_free (GstHarnessPropThread * t)
{
  if (t != NULL) {
    g_free (t->name);
    g_value_unset (&t->value);
    g_slice_free (GstHarnessPropThread, t);
  }
}

static void
gst_harness_requestpad_release (GstPad * pad, GstElement * element)
{
  gst_element_release_request_pad (element, pad);
  gst_object_unref (pad);
}

static void
gst_harness_requestpad_release_pads (GstHarnessReqPadThread * rpt)
{
  g_slist_foreach (rpt->pads, (GFunc) gst_harness_requestpad_release,
      rpt->t.h->element);
  g_slist_free (rpt->pads);
  rpt->pads = NULL;
}

static void
gst_harness_requestpad_thread_free (GstHarnessReqPadThread * t)
{
  if (t != NULL) {
    gst_object_replace ((GstObject **) & t->templ, NULL);
    g_free (t->name);
    gst_caps_replace (&t->caps, NULL);

    gst_harness_requestpad_release_pads (t);
    g_slice_free (GstHarnessReqPadThread, t);
  }
}

#define GST_HARNESS_THREAD_START(ID, t)                                        \
  (((GstHarnessThread *)t)->running = TRUE,                                    \
  ((GstHarnessThread *)t)->thread = g_thread_new (                             \
      "gst-harness-stress-"G_STRINGIFY(ID),                                    \
      (GThreadFunc)gst_harness_stress_##ID##_func, t))
#define GST_HARNESS_THREAD_END(t)                                              \
   (t->running = FALSE,                                                        \
   GPOINTER_TO_UINT (g_thread_join (t->thread)))

static void
gst_harness_stress_free (GstHarnessThread * t)
{
  if (t != NULL && t->freefunc != NULL)
    t->freefunc (t);
}

static gpointer
gst_harness_stress_custom_func (GstHarnessThread * t)
{
  GstHarnessCustomThread *ct = (GstHarnessCustomThread *) t;
  guint count = 0;

  if (ct->init != NULL)
    ct->init (ct, ct->data);

  while (t->running) {
    ct->callback (ct, ct->data);

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}


static gpointer
gst_harness_stress_statechange_func (GstHarnessThread * t)
{
  guint count = 0;

  while (t->running) {
    GstClock *clock = gst_element_get_clock (t->h->element);
    GstIterator *it;
    gboolean done = FALSE;
    gboolean change;

    change = gst_element_set_state (t->h->element, GST_STATE_NULL);
    g_assert (change == GST_STATE_CHANGE_SUCCESS);
    g_thread_yield ();

    it = gst_element_iterate_sink_pads (t->h->element);
    while (!done) {
      GValue item = G_VALUE_INIT;
      switch (gst_iterator_next (it, &item)) {
        case GST_ITERATOR_OK:
        {
          GstPad *sinkpad = g_value_get_object (&item);
          GstPad *srcpad = gst_pad_get_peer (sinkpad);
          if (srcpad != NULL) {
            gst_pad_unlink (srcpad, sinkpad);
            gst_pad_link (srcpad, sinkpad);
            gst_object_unref (srcpad);
          }
          g_value_reset (&item);
          break;
        }
        case GST_ITERATOR_RESYNC:
          gst_iterator_resync (it);
          break;
        case GST_ITERATOR_ERROR:
          g_assert_not_reached ();
        case GST_ITERATOR_DONE:
          done = TRUE;
          break;
      }
      g_value_unset (&item);
    }
    gst_iterator_free (it);

    if (clock != NULL) {
      gst_element_set_clock (t->h->element, clock);
      gst_object_unref (clock);
    }
    change = gst_element_set_state (t->h->element, GST_STATE_PLAYING);
    g_assert (change == GST_STATE_CHANGE_SUCCESS);

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

static gpointer
gst_harness_stress_buffer_func (GstHarnessThread * t)
{
  GstHarnessPushBufferThread *pt = (GstHarnessPushBufferThread *) t;
  guint count = 0;
  gchar *sid;
  gboolean handled;

  /* Push stream start, caps and segment events */
  sid = g_strdup_printf ("%s-%p", GST_OBJECT_NAME (t->h->element), t->h);
  handled = gst_pad_push_event (t->h->srcpad, gst_event_new_stream_start (sid));
  g_assert (handled);
  g_free (sid);
  handled = gst_pad_push_event (t->h->srcpad, gst_event_new_caps (pt->caps));
  g_assert (handled);
  handled = gst_pad_push_event (t->h->srcpad,
      gst_event_new_segment (&pt->segment));
  g_assert (handled);

  while (t->running) {
    gst_harness_push (t->h, pt->func (t->h, pt->data));

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

static gpointer
gst_harness_stress_event_func (GstHarnessThread * t)
{
  GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
  guint count = 0;

  while (t->running) {
    gst_harness_push_event (t->h, pet->func (t->h, pet->data));

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

static gpointer
gst_harness_stress_upstream_event_func (GstHarnessThread * t)
{
  GstHarnessPushEventThread *pet = (GstHarnessPushEventThread *) t;
  guint count = 0;

  while (t->running) {
    gst_harness_push_upstream_event (t->h, pet->func (t->h, pet->data));

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

static gpointer
gst_harness_stress_property_func (GstHarnessThread * t)
{
  GstHarnessPropThread *pt = (GstHarnessPropThread *) t;
  guint count = 0;

  while (t->running) {
    GValue value = G_VALUE_INIT;

    g_object_set_property (G_OBJECT (t->h->element), pt->name, &pt->value);

    g_value_init (&value, G_VALUE_TYPE (&pt->value));
    g_object_get_property (G_OBJECT (t->h->element), pt->name, &value);
    g_value_reset (&value);

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

static gpointer
gst_harness_stress_requestpad_func (GstHarnessThread * t)
{
  GstHarnessReqPadThread *rpt = (GstHarnessReqPadThread *) t;
  guint count = 0;

  while (t->running) {
    GstPad *reqpad;

    if (rpt->release)
      gst_harness_requestpad_release_pads (rpt);

    g_thread_yield ();

    reqpad = gst_element_request_pad (t->h->element,
        rpt->templ, rpt->name, rpt->caps);

    g_assert (reqpad != NULL);

    rpt->pads = g_slist_prepend (rpt->pads, reqpad);

    count++;
    g_usleep (t->sleep);
  }
  return GUINT_TO_POINTER (count);
}

/**
 * gst_harness_stress_thread_stop:
 * @t: a #GstHarnessThread
 *
 * Stop the running #GstHarnessThread
 *
 * MT safe.
 *
 * Since: 1.6
 */
guint
gst_harness_stress_thread_stop (GstHarnessThread * t)
{
  guint ret;

  g_return_val_if_fail (t != NULL, 0);

  ret = GST_HARNESS_THREAD_END (t);
  g_ptr_array_remove (t->h->priv->stress, t);
  return ret;
}

/**
 * gst_harness_stress_custom_start: (skip)
 * @h: a #GstHarness
 * @init: (allow-none): a #GFunc that is called initially and only once
 * @callback: a #GFunc that is called as often as possible
 * @data: a #gpointer with custom data to pass to the @callback function
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each call to the @callback
 *
 * Start a custom stress-thread that will call your @callback for every
 * iteration allowing you to do something nasty.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_custom_start (GstHarness * h,
    GFunc init, GFunc callback, gpointer data, gulong sleep)
{
  GstHarnessCustomThread *t = g_slice_new0 (GstHarnessCustomThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_custom_thread_free, h, sleep);

  t->init = init;
  t->callback = callback;
  t->data = data;

  GST_HARNESS_THREAD_START (custom, t);
  return &t->t;
}

/**
 * gst_harness_stress_statechange_start_full: (skip)
 * @h: a #GstHarness
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each state-change
 *
 * Change the state of your harnessed #GstElement from NULL to PLAYING and
 * back again, only pausing for @sleep microseconds every time.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_statechange_start_full (GstHarness * h, gulong sleep)
{
  GstHarnessThread *t = g_slice_new0 (GstHarnessThread);
  gst_harness_thread_init (t,
      (GDestroyNotify) gst_harness_thread_free, h, sleep);
  GST_HARNESS_THREAD_START (statechange, t);
  return t;
}

static GstBuffer *
gst_harness_ref_buffer (GstHarness * h, gpointer data)
{
  (void) h;
  return gst_buffer_ref (GST_BUFFER_CAST (data));
}

static GstEvent *
gst_harness_ref_event (GstHarness * h, gpointer data)
{
  (void) h;
  return gst_event_ref (GST_EVENT_CAST (data));
}

/**
 * gst_harness_stress_push_buffer_start_full: (skip)
 * @h: a #GstHarness
 * @caps: a #GstCaps for the #GstBuffer
 * @segment: a #GstSegment
 * @buf: a #GstBuffer to push
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each call to gst_pad_push
 *
 * Push a #GstBuffer in intervals of @sleep microseconds.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_push_buffer_start_full (GstHarness * h,
    GstCaps * caps, const GstSegment * segment, GstBuffer * buf, gulong sleep)
{
  return gst_harness_stress_push_buffer_with_cb_start_full (h, caps, segment,
      gst_harness_ref_buffer, gst_buffer_ref (buf),
      (GDestroyNotify) gst_buffer_unref, sleep);
}

/**
 * gst_harness_stress_push_buffer_with_cb_start_full: (skip)
 * @h: a #GstHarness
 * @caps: a #GstCaps for the #GstBuffer
 * @segment: a #GstSegment
 * @func: a #GstHarnessPrepareBufferFunc function called before every iteration
 * to prepare / create a #GstBuffer for pushing
 * @data: a #gpointer with data to the #GstHarnessPrepareBufferFunc function
 * @notify: a #GDestroyNotify that is called when thread is stopped
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each call to gst_pad_push
 *
 * Push a #GstBuffer returned by @func in intervals of @sleep microseconds.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_push_buffer_with_cb_start_full (GstHarness * h,
    GstCaps * caps, const GstSegment * segment,
    GstHarnessPrepareBufferFunc func, gpointer data, GDestroyNotify notify,
    gulong sleep)
{
  GstHarnessPushBufferThread *t = g_slice_new0 (GstHarnessPushBufferThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_push_buffer_thread_free, h, sleep);

  gst_caps_replace (&t->caps, caps);
  t->segment = *segment;
  t->func = func;
  t->data = data;
  t->notify = notify;

  GST_HARNESS_THREAD_START (buffer, t);
  return &t->t;
}

/**
 * gst_harness_stress_push_event_start_full: (skip)
 * @h: a #GstHarness
 * @event: a #GstEvent to push
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each gst_event_push with @event
 *
 * Push the @event onto the harnessed #GstElement sinkpad in intervals of
 * @sleep microseconds
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_push_event_start_full (GstHarness * h,
    GstEvent * event, gulong sleep)
{
  return gst_harness_stress_push_event_with_cb_start_full (h,
      gst_harness_ref_event, gst_event_ref (event),
      (GDestroyNotify) gst_event_unref, sleep);
}

/**
 * gst_harness_stress_push_event_with_cb_start_full: (skip)
 * @h: a #GstHarness
 * @func: a #GstHarnessPrepareEventFunc function called before every iteration
 * to prepare / create a #GstEvent for pushing
 * @data: a #gpointer with data to the #GstHarnessPrepareEventFunc function
 * @notify: a #GDestroyNotify that is called when thread is stopped
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each call to gst_pad_push
 *
 * Push a #GstEvent returned by @func onto the harnessed #GstElement sinkpad
 * in intervals of @sleep microseconds.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.8
 */
GstHarnessThread *
gst_harness_stress_push_event_with_cb_start_full (GstHarness * h,
    GstHarnessPrepareEventFunc func, gpointer data, GDestroyNotify notify,
    gulong sleep)
{
  GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);

  t->func = func;
  t->data = data;
  t->notify = notify;

  GST_HARNESS_THREAD_START (event, t);
  return &t->t;
}

/**
 * gst_harness_stress_push_upstream_event_start_full: (skip)
 * @h: a #GstHarness
 * @event: a #GstEvent to push
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each gst_event_push with @event
 *
 * Push the @event onto the harnessed #GstElement srcpad in intervals of
 * @sleep microseconds.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_push_upstream_event_start_full (GstHarness * h,
    GstEvent * event, gulong sleep)
{
  return gst_harness_stress_push_upstream_event_with_cb_start_full (h,
      gst_harness_ref_event, gst_event_ref (event),
      (GDestroyNotify) gst_event_unref, sleep);
}

/**
 * gst_harness_stress_push_upstream_event_with_cb_start_full: (skip)
 * @h: a #GstHarness
 * @func: a #GstHarnessPrepareEventFunc function called before every iteration
 * to prepare / create a #GstEvent for pushing
 * @data: a #gpointer with data to the #GstHarnessPrepareEventFunc function
 * @notify: a #GDestroyNotify that is called when thread is stopped
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each call to gst_pad_push
 *
 * Push a #GstEvent returned by @func onto the harnessed #GstElement srcpad
 * in intervals of @sleep microseconds.
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.8
 */
GstHarnessThread *
gst_harness_stress_push_upstream_event_with_cb_start_full (GstHarness * h,
    GstHarnessPrepareEventFunc func, gpointer data, GDestroyNotify notify,
    gulong sleep)
{
  GstHarnessPushEventThread *t = g_slice_new0 (GstHarnessPushEventThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_push_event_thread_free, h, sleep);

  t->func = func;
  t->data = data;
  t->notify = notify;

  GST_HARNESS_THREAD_START (upstream_event, t);
  return &t->t;
}

/**
 * gst_harness_stress_property_start_full: (skip)
 * @h: a #GstHarness
 * @name: a #gchar specifying a property name
 * @value: a #GValue to set the property to
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each g_object_set with @name and @value
 *
 * Call g_object_set with @name and @value in intervals of @sleep microseconds
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_property_start_full (GstHarness * h,
    const gchar * name, const GValue * value, gulong sleep)
{
  GstHarnessPropThread *t = g_slice_new0 (GstHarnessPropThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_property_thread_free, h, sleep);

  t->name = g_strdup (name);
  g_value_init (&t->value, G_VALUE_TYPE (value));
  g_value_copy (value, &t->value);

  GST_HARNESS_THREAD_START (property, t);
  return &t->t;
}

/**
 * gst_harness_stress_requestpad_start_full: (skip)
 * @h: a #GstHarness
 * @templ: a #GstPadTemplate
 * @name: a #gchar
 * @caps: a #GstCaps
 * @release: a #gboolean
 * @sleep: a #gulong specifying how long to sleep in (microseconds) for
 * each gst_element_request_pad
 *
 * Call gst_element_request_pad in intervals of @sleep microseconds
 *
 * MT safe.
 *
 * Returns: a #GstHarnessThread
 *
 * Since: 1.6
 */
GstHarnessThread *
gst_harness_stress_requestpad_start_full (GstHarness * h,
    GstPadTemplate * templ, const gchar * name, GstCaps * caps,
    gboolean release, gulong sleep)
{
  GstHarnessReqPadThread *t = g_slice_new0 (GstHarnessReqPadThread);
  gst_harness_thread_init (&t->t,
      (GDestroyNotify) gst_harness_requestpad_thread_free, h, sleep);

  t->templ = gst_object_ref (templ);
  t->name = g_strdup (name);
  gst_caps_replace (&t->caps, caps);
  t->release = release;

  GST_HARNESS_THREAD_START (requestpad, t);
  return &t->t;
}
