/* GStreamer
 *
 * unit testing helper lib
 *
 * Copyright (C) 2006 Andy Wingo <wingo at pobox.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:gstcheckbufferstraw
 * @short_description: Buffer interception code for GStreamer unit tests
 *
 * These macros and functions are for internal use of the unit tests found
 * inside the 'check' directories of various GStreamer packages.
 */

#include "gstbufferstraw.h"

static GCond *cond = NULL;
static GMutex *lock = NULL;
static GstBuffer *buf = NULL;
static gulong id;

/* called for every buffer.  Waits until the global "buf" variable is unset,
 * then sets it to the buffer received, and signals. */
static GstPadProbeReturn
buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer unused)
{
  GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);

  g_mutex_lock (lock);

  while (buf != NULL)
    g_cond_wait (cond, lock);

  /* increase the refcount because we store it globally for others to use */
  buf = gst_buffer_ref (buffer);

  g_cond_signal (cond);

  g_mutex_unlock (lock);

  return GST_PAD_PROBE_OK;
}

/**
 * gst_buffer_straw_start_pipeline:
 * @bin: the pipeline to run
 * @pad: a pad on an element in @bin
 *
 * Sets up a pipeline for buffer sucking. This will allow you to call
 * gst_buffer_straw_get_buffer() to access buffers as they pass over @pad.
 *
 * This function is normally used in unit tests that want to verify that a
 * particular element is outputting correct buffers. For example, you would make
 * a pipeline via gst_parse_launch(), pull out the pad you want to monitor, then
 * call gst_buffer_straw_get_buffer() to get the buffers that pass through @pad.
 * The pipeline will block until you have sucked off the buffers.
 *
 * This function will set the state of @bin to PLAYING; to clean up, be sure to
 * call gst_buffer_straw_stop_pipeline().
 *
 * Note that you may not start two buffer straws at the same time. This function
 * is intended for unit tests, not general API use. In fact it calls fail_if
 * from libcheck, so you cannot use it outside unit tests.
 */
void
gst_buffer_straw_start_pipeline (GstElement * bin, GstPad * pad)
{
  GstStateChangeReturn ret;

  id = gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
      buffer_probe, NULL, NULL);

  cond = g_cond_new ();
  lock = g_mutex_new ();

  ret = gst_element_set_state (bin, GST_STATE_PLAYING);
  fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not start test pipeline");
  if (ret == GST_STATE_CHANGE_ASYNC) {
    ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE);
    fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not start test pipeline");
  }
}

/**
 * gst_buffer_straw_get_buffer:
 * @bin: the pipeline previously started via gst_buffer_straw_start_pipeline()
 * @pad: the pad previously passed to gst_buffer_straw_start_pipeline()
 *
 * Get one buffer from @pad. Implemented via buffer probes. This function will
 * block until the pipeline passes a buffer over @pad, so for robust behavior
 * in unit tests, you need to use check's timeout to fail out in the case that a
 * buffer never arrives.
 *
 * You must have previously called gst_buffer_straw_start_pipeline() on
 * @pipeline and @pad.
 *
 * Returns: the captured #GstBuffer.
 */
GstBuffer *
gst_buffer_straw_get_buffer (GstElement * bin, GstPad * pad)
{
  GstBuffer *ret;

  g_mutex_lock (lock);

  while (buf == NULL)
    g_cond_wait (cond, lock);

  ret = buf;
  buf = NULL;

  g_cond_signal (cond);

  g_mutex_unlock (lock);

  return ret;
}

/**
 * gst_buffer_straw_stop_pipeline:
 * @bin: the pipeline previously started via gst_buffer_straw_start_pipeline()
 * @pad: the pad previously passed to gst_buffer_straw_start_pipeline()
 *
 * Set @bin to #GST_STATE_NULL and release resource allocated in
 * gst_buffer_straw_start_pipeline().
 *
 * You must have previously called gst_buffer_straw_start_pipeline() on
 * @pipeline and @pad.
 */
void
gst_buffer_straw_stop_pipeline (GstElement * bin, GstPad * pad)
{
  GstStateChangeReturn ret;

  g_mutex_lock (lock);
  if (buf)
    gst_buffer_unref (buf);
  buf = NULL;
  gst_pad_remove_probe (pad, (guint) id);
  id = 0;
  g_cond_signal (cond);
  g_mutex_unlock (lock);

  ret = gst_element_set_state (bin, GST_STATE_NULL);
  fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not stop test pipeline");
  if (ret == GST_STATE_CHANGE_ASYNC) {
    ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE);
    fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not stop test pipeline");
  }

  g_mutex_lock (lock);
  if (buf)
    gst_buffer_unref (buf);
  buf = NULL;
  g_mutex_unlock (lock);

  g_mutex_free (lock);
  g_cond_free (cond);

  lock = NULL;
  cond = NULL;
}
