gstreamer/libs/gst/check/gstbufferstraw.c
Tim-Philipp Müller 57c8e0146f libs: figure out right export define in configure
Add new GST_API_EXPORT in config.h and use that for GST_*_API
decorators instead of GST_EXPORT.

The right export define depends on the toolchain and whether
we're using -fvisibility=hidden or not, so it's better to set it
to the right thing directly than hard-coding a compiler whitelist
in the public header.

We put the export define into config.h instead of passing it via the
command line to the compiler because it might contain spaces and brackets
and in the autotools scenario we'd have to pass that through multiple
layers of plumbing and Makefile/shell escaping and we're just not going
to be *that* lucky.

The export define is only used if we're compiling our lib, not by external
users of the lib headers, so it's not a problem to put it into config.h

Also, this means all .c files of libs need to include config.h
to get the export marker defined, so fix up a few that didn't
include config.h.

This commit depends on a common submodule commit that makes gst-glib-gen.mak
add an #include "config.h" to generated enum/marshal .c files for the
autotools build.

https://bugzilla.gnome.org/show_bug.cgi?id=797185
2018-09-24 08:39:37 +01:00

173 lines
5.2 KiB
C

/* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/**
* SECTION:gstcheckbufferstraw
* @title: GstBufferStraw
* @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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstbufferstraw.h"
static GCond cond;
static GMutex lock;
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);
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);
}