libs/gst/check/Makefile.am (libgstcheck_@GST_MAJORMINOR@include_HEADERS)
[glsdk/gstreamer0-10.git] / libs / gst / check / gstbufferstraw.c
1 /* GStreamer
2  *
3  * unit testing helper lib
4  *
5  * Copyright (C) 2006 Andy Wingo <wingo at pobox.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
23 #include "gstbufferstraw.h"
25 static GCond *cond = NULL;
26 static GMutex *lock = NULL;
27 static GstBuffer *buf = NULL;
28 static gulong id;
30 /* called for every buffer.  Waits until the global "buf" variable is unset,
31  * then sets it to the buffer received, and signals. */
32 static gboolean
33 buffer_probe (GstPad * pad, GstBuffer * buffer, gpointer unused)
34 {
35   g_mutex_lock (lock);
37   while (buf != NULL)
38     g_cond_wait (cond, lock);
40   /* increase the refcount because we store it globally for others to use */
41   buf = gst_buffer_ref (buffer);
43   g_cond_signal (cond);
45   g_mutex_unlock (lock);
47   return TRUE;
48 }
50 /**
51  * gst_buffer_straw_start_pipeline:
52  * @bin: the pipeline to run
53  * @pad: a pad on an element in @bin
54  *
55  * Sets up a pipeline for buffer sucking. This will allow you to call
56  * gst_buffer_straw_get_buffer() to access buffers as they pass over @pad.
57  *
58  * This function is normally used in unit tests that want to verify that a
59  * particular element is outputting correct buffers. For example, you would make
60  * a pipeline via gst_parse_launch(), pull out the pad you want to monitor, then
61  * call gst_buffer_straw_get_buffer() to get the buffers that pass through @pad.
62  * The pipeline will block until you have sucked off the buffers.
63  *
64  * This function will set the state of @bin to PLAYING; to clean up, be sure to
65  * call gst_buffer_straw_stop_pipeline().
66  *
67  * Note that you may not start two buffer straws at the same time. This function
68  * is intended for unit tests, not general API use. In fact it calls fail_if
69  * from libcheck, so you cannot use it outside unit tests.
70  */
71 void
72 gst_buffer_straw_start_pipeline (GstElement * bin, GstPad * pad)
73 {
74   GstStateChangeReturn ret;
76   id = gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe), NULL);
78   cond = g_cond_new ();
79   lock = g_mutex_new ();
81   ret = gst_element_set_state (bin, GST_STATE_PLAYING);
82   fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not start test pipeline");
83   if (ret == GST_STATE_CHANGE_ASYNC) {
84     ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE);
85     fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not start test pipeline");
86   }
87 }
89 /**
90  * gst_buffer_straw_get_buffer:
91  * @bin: the pipeline previously started via gst_buffer_straw_start_pipeline()
92  * @pad: the pad previously passed to gst_buffer_straw_start_pipeline()
93  *
94  * Get one buffer from @pad. Implemented via buffer probes. This function will
95  * block until the pipeline passes a buffer over @pad, so for robust behavior
96  * in unit tests, you need to use check's timeout to fail out in the case that a
97  * buffer never arrives.
98  *
99  * You must have previously called gst_buffer_straw_start_pipeline() on
100  * @pipeline and @pad.
101  */
102 GstBuffer *
103 gst_buffer_straw_get_buffer (GstElement * bin, GstPad * pad)
105   GstBuffer *ret;
107   g_mutex_lock (lock);
109   while (buf == NULL)
110     g_cond_wait (cond, lock);
112   ret = buf;
113   buf = NULL;
115   g_cond_signal (cond);
117   g_mutex_unlock (lock);
119   return ret;
122 /**
123  * gst_buffer_straw_stop_pipeline:
124  * @bin: the pipeline previously started via gst_buffer_straw_start_pipeline()
125  * @pad: the pad previously passed to gst_buffer_straw_start_pipeline()
126  *
127  * Set @bin to #GST_STATE_NULL and release resource allocated in
128  * gst_buffer_straw_start_pipeline().
129  *
130  * You must have previously called gst_buffer_straw_start_pipeline() on
131  * @pipeline and @pad.
132  */
133 void
134 gst_buffer_straw_stop_pipeline (GstElement * bin, GstPad * pad)
136   GstStateChangeReturn ret;
138   g_mutex_lock (lock);
139   if (buf)
140     gst_buffer_unref (buf);
141   buf = NULL;
142   gst_pad_remove_buffer_probe (pad, (guint) id);
143   id = 0;
144   g_cond_signal (cond);
145   g_mutex_unlock (lock);
147   ret = gst_element_set_state (bin, GST_STATE_NULL);
148   fail_if (ret == GST_STATE_CHANGE_FAILURE, "Could not stop test pipeline");
149   if (ret == GST_STATE_CHANGE_ASYNC) {
150     ret = gst_element_get_state (bin, NULL, NULL, GST_CLOCK_TIME_NONE);
151     fail_if (ret != GST_STATE_CHANGE_SUCCESS, "Could not stop test pipeline");
152   }
154   g_mutex_lock (lock);
155   if (buf)
156     gst_buffer_unref (buf);
157   buf = NULL;
158   g_mutex_unlock (lock);
160   g_mutex_free (lock);
161   g_cond_free (cond);
163   lock = NULL;
164   cond = NULL;