3 * unit test for fakesink
5 * Copyright (C) <2005> Thomas Vander Stichele <thomas at apestaart dot org>
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.
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.
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.
25 #include <gst/check/gstcheck.h>
36 chain_async_buffer (gpointer data)
38 ChainData *chain_data = (ChainData *) data;
40 chain_data->ret = gst_pad_chain (chain_data->pad, chain_data->buffer);
46 chain_async (GstPad * pad, GstBuffer * buffer)
49 ChainData *chain_data;
52 chain_data = g_new (ChainData, 1);
53 chain_data->pad = pad;
54 chain_data->buffer = buffer;
55 chain_data->ret = GST_FLOW_ERROR;
57 thread = g_thread_create (chain_async_buffer, chain_data, TRUE, &error);
59 g_warning ("could not create thread reason: %s", error->message);
63 chain_data->thread = thread;
69 chain_async_return (ChainData * data)
73 g_thread_join (data->thread);
80 GST_START_TEST (test_clipping)
84 GstStateChangeReturn ret;
87 sink = gst_element_factory_make ("fakesink", "sink");
88 fail_if (sink == NULL);
90 sinkpad = gst_element_get_pad (sink, "sink");
91 fail_if (sinkpad == NULL);
93 /* make element ready to accept data */
94 ret = gst_element_set_state (sink, GST_STATE_PAUSED);
95 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
102 GST_DEBUG ("sending segment");
103 segment = gst_event_new_new_segment (FALSE,
104 1.0, GST_FORMAT_TIME, 1 * GST_SECOND, 5 * GST_SECOND, 1 * GST_SECOND);
106 eret = gst_pad_send_event (sinkpad, segment);
107 fail_if (eret == FALSE);
110 /* new segment should not have finished preroll */
111 ret = gst_element_get_state (sink, NULL, NULL, 0);
112 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
114 /* send buffer that should be dropped */
119 buffer = gst_buffer_new ();
120 GST_BUFFER_TIMESTAMP (buffer) = 0;
121 GST_BUFFER_DURATION (buffer) = 1 * GST_MSECOND;
123 GST_DEBUG ("sending buffer to be dropped");
124 fret = gst_pad_chain (sinkpad, buffer);
125 fail_if (fret != GST_FLOW_OK);
127 /* dropped buffer should not have finished preroll */
128 ret = gst_element_get_state (sink, NULL, NULL, 0);
129 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
131 /* send buffer that should be dropped */
136 buffer = gst_buffer_new ();
137 GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
138 GST_BUFFER_DURATION (buffer) = 1 * GST_MSECOND;
140 GST_DEBUG ("sending buffer to be dropped");
141 fret = gst_pad_chain (sinkpad, buffer);
142 fail_if (fret != GST_FLOW_OK);
144 /* dropped buffer should not have finished preroll */
145 ret = gst_element_get_state (sink, NULL, NULL, 0);
146 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
148 /* send buffer that should block and finish preroll */
153 GstState current, pending;
155 buffer = gst_buffer_new ();
156 GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
157 GST_BUFFER_DURATION (buffer) = 1 * GST_MSECOND;
159 GST_DEBUG ("sending buffer to finish preroll");
160 data = chain_async (sinkpad, buffer);
161 fail_if (data == NULL);
163 /* state should now eventually change to PAUSED */
164 ret = gst_element_get_state (sink, ¤t, &pending, GST_CLOCK_TIME_NONE);
165 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
166 fail_unless (current == GST_STATE_PAUSED);
167 fail_unless (pending == GST_STATE_VOID_PENDING);
169 /* playing should render the buffer */
170 ret = gst_element_set_state (sink, GST_STATE_PLAYING);
171 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
173 /* and we should get a success return value */
174 fret = chain_async_return (data);
175 fail_if (fret != GST_FLOW_OK);
178 /* send some buffer that will be dropped or clipped, this can
179 * only be observed in the debug log. */
184 buffer = gst_buffer_new ();
185 GST_BUFFER_TIMESTAMP (buffer) = 6 * GST_SECOND;
186 GST_BUFFER_DURATION (buffer) = 1 * GST_MSECOND;
188 /* should be dropped */
189 GST_DEBUG ("sending buffer to drop");
190 fret = gst_pad_chain (sinkpad, buffer);
191 fail_if (fret != GST_FLOW_OK);
193 buffer = gst_buffer_new ();
194 GST_BUFFER_TIMESTAMP (buffer) = 0 * GST_SECOND;
195 GST_BUFFER_DURATION (buffer) = 2 * GST_SECOND;
197 /* should be clipped */
198 GST_DEBUG ("sending buffer to clip");
199 fret = gst_pad_chain (sinkpad, buffer);
200 fail_if (fret != GST_FLOW_OK);
202 buffer = gst_buffer_new ();
203 GST_BUFFER_TIMESTAMP (buffer) = 4 * GST_SECOND;
204 GST_BUFFER_DURATION (buffer) = 2 * GST_SECOND;
206 /* should be clipped */
207 GST_DEBUG ("sending buffer to clip");
208 fret = gst_pad_chain (sinkpad, buffer);
209 fail_if (fret != GST_FLOW_OK);
212 gst_element_set_state (sink, GST_STATE_NULL);
213 gst_element_get_state (sink, NULL, NULL, GST_CLOCK_TIME_NONE);
214 gst_object_unref (sinkpad);
215 gst_object_unref (sink);
220 GST_START_TEST (test_preroll_sync)
222 GstElement *pipeline, *sink;
224 GstStateChangeReturn ret;
227 pipeline = gst_pipeline_new ("pipeline");
228 fail_if (pipeline == NULL);
230 sink = gst_element_factory_make ("fakesink", "sink");
231 fail_if (sink == NULL);
232 g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
234 gst_bin_add (GST_BIN (pipeline), sink);
236 sinkpad = gst_element_get_pad (sink, "sink");
237 fail_if (sinkpad == NULL);
239 /* make pipeline and element ready to accept data */
240 ret = gst_element_set_state (pipeline, GST_STATE_PAUSED);
241 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
248 GST_DEBUG ("sending segment");
249 segment = gst_event_new_new_segment (FALSE,
250 1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND, 0 * GST_SECOND);
252 eret = gst_pad_send_event (sinkpad, segment);
253 fail_if (eret == FALSE);
256 /* send buffer that should block and finish preroll */
261 GstState current, pending;
263 buffer = gst_buffer_new ();
264 GST_BUFFER_TIMESTAMP (buffer) = 1 * GST_SECOND;
265 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
267 GST_DEBUG ("sending buffer to finish preroll");
268 data = chain_async (sinkpad, buffer);
269 fail_if (data == NULL);
271 /* state should now eventually change to PAUSED */
273 gst_element_get_state (pipeline, ¤t, &pending,
274 GST_CLOCK_TIME_NONE);
275 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
276 fail_unless (current == GST_STATE_PAUSED);
277 fail_unless (pending == GST_STATE_VOID_PENDING);
279 /* playing should render the buffer */
280 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
281 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
283 /* and we should get a success return value */
284 fret = chain_async_return (data);
285 fail_if (fret != GST_FLOW_OK);
287 gst_element_set_state (pipeline, GST_STATE_NULL);
288 gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
289 gst_object_unref (sinkpad);
290 gst_object_unref (pipeline);
296 fakesink_suite (void)
298 Suite *s = suite_create ("fakesink");
299 TCase *tc_chain = tcase_create ("general");
301 suite_add_tcase (s, tc_chain);
302 tcase_add_test (tc_chain, test_clipping);
303 tcase_add_test (tc_chain, test_preroll_sync);
308 GST_CHECK_MAIN (fakesink);