2 * collectpads.c - GstCollectPads testsuite
3 * Copyright (C) 2006 Alessandro Decina <alessandro@nnva.org>
6 * Alessandro Decina <alessandro@nnva.org>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
24 #include <gst/check/gstcheck.h>
25 #include <gst/base/gstcollectpads.h>
27 #define fail_unless_collected(expected) \
29 g_mutex_lock (lock); \
30 while (expected == TRUE && collected == FALSE) \
31 g_cond_wait (cond, lock); \
32 fail_unless_equals_int (collected, expected); \
33 g_mutex_unlock (lock); \
49 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
54 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
59 static GstCollectPads *collect;
60 static gboolean collected;
61 static GstPad *srcpad1, *srcpad2;
62 static GstPad *sinkpad1, *sinkpad2;
63 static TestData *data1, *data2;
69 collected_cb (GstCollectPads * pads, gpointer user_data)
74 g_mutex_unlock (lock);
80 push_buffer (gpointer user_data)
82 TestData *test_data = (TestData *) user_data;
84 fail_unless (gst_pad_push (test_data->pad, test_data->buffer)
91 push_event (gpointer user_data)
93 TestData *test_data = (TestData *) user_data;
95 fail_unless (gst_pad_push_event (test_data->pad, test_data->event) == TRUE);
103 collect = gst_collect_pads_new ();
104 gst_collect_pads_set_function (collect, collected_cb, NULL);
106 srcpad1 = gst_pad_new_from_static_template (&srctemplate, "src1");
107 srcpad2 = gst_pad_new_from_static_template (&srctemplate, "src2");
108 sinkpad1 = gst_pad_new_from_static_template (&sinktemplate, "sink1");
109 sinkpad2 = gst_pad_new_from_static_template (&sinktemplate, "sink2");
110 fail_unless (gst_pad_link (srcpad1, sinkpad1) == GST_PAD_LINK_OK);
111 fail_unless (gst_pad_link (srcpad2, sinkpad2) == GST_PAD_LINK_OK);
113 cond = g_cond_new ();
114 lock = g_mutex_new ();
123 gst_object_unref (sinkpad1);
124 gst_object_unref (sinkpad2);
125 gst_object_unref (collect);
130 GST_START_TEST (test_pad_add_remove)
132 ASSERT_CRITICAL (gst_collect_pads_add_pad (collect, sinkpad1,
133 sizeof (BadCollectData)));
135 data1 = (TestData *) gst_collect_pads_add_pad (collect,
136 sinkpad1, sizeof (TestData));
137 fail_unless (data1 != NULL);
139 fail_unless (gst_collect_pads_remove_pad (collect, sinkpad2) == FALSE);
140 fail_unless (gst_collect_pads_remove_pad (collect, sinkpad1) == TRUE);
145 GST_START_TEST (test_collect)
147 GstBuffer *buf1, *buf2, *tmp;
148 GThread *thread1, *thread2;
150 data1 = (TestData *) gst_collect_pads_add_pad (collect,
151 sinkpad1, sizeof (TestData));
152 fail_unless (data1 != NULL);
154 data2 = (TestData *) gst_collect_pads_add_pad (collect,
155 sinkpad2, sizeof (TestData));
156 fail_unless (data2 != NULL);
158 buf1 = gst_buffer_new ();
159 buf2 = gst_buffer_new ();
161 /* start collect pads */
162 gst_collect_pads_start (collect);
164 /* push buffers on the pads */
165 data1->pad = srcpad1;
166 data1->buffer = buf1;
167 thread1 = g_thread_create (push_buffer, data1, TRUE, NULL);
168 /* here thread1 is blocked and srcpad1 has a queued buffer */
169 fail_unless_collected (FALSE);
171 data2->pad = srcpad2;
172 data2->buffer = buf2;
173 thread2 = g_thread_create (push_buffer, data2, TRUE, NULL);
175 /* now both pads have a buffer */
176 fail_unless_collected (TRUE);
178 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data1);
179 fail_unless (tmp == buf1);
180 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data2);
181 fail_unless (tmp == buf2);
183 /* these will return immediately as at this point the threads have been
184 * unlocked and are finished */
185 g_thread_join (thread1);
186 g_thread_join (thread2);
188 gst_collect_pads_stop (collect);
190 gst_buffer_unref (buf1);
191 gst_buffer_unref (buf2);
196 GST_START_TEST (test_collect_eos)
198 GstBuffer *buf1, *tmp;
199 GThread *thread1, *thread2;
201 data1 = (TestData *) gst_collect_pads_add_pad (collect,
202 sinkpad1, sizeof (TestData));
203 fail_unless (data1 != NULL);
205 data2 = (TestData *) gst_collect_pads_add_pad (collect,
206 sinkpad2, sizeof (TestData));
207 fail_unless (data2 != NULL);
209 buf1 = gst_buffer_new ();
211 /* start collect pads */
212 gst_collect_pads_start (collect);
214 /* push a buffer on srcpad1 and EOS on srcpad2 */
215 data1->pad = srcpad1;
216 data1->buffer = buf1;
217 thread1 = g_thread_create (push_buffer, data1, TRUE, NULL);
218 /* here thread1 is blocked and srcpad1 has a queued buffer */
219 fail_unless_collected (FALSE);
221 data2->pad = srcpad2;
222 data2->event = gst_event_new_eos ();
223 thread2 = g_thread_create (push_event, data2, TRUE, NULL);
224 /* now sinkpad1 has a buffer and sinkpad2 has EOS */
225 fail_unless_collected (TRUE);
227 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data1);
228 fail_unless (tmp == buf1);
229 /* sinkpad2 has EOS so a NULL buffer is returned */
230 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data2);
231 fail_unless (tmp == NULL);
233 /* these will return immediately as when the data is popped the threads are
234 * unlocked and will terminate */
235 g_thread_join (thread1);
236 g_thread_join (thread2);
238 gst_collect_pads_stop (collect);
240 gst_buffer_unref (buf1);
245 GST_START_TEST (test_collect_twice)
247 GstBuffer *buf1, *buf2, *tmp;
248 GThread *thread1, *thread2;
250 data1 = (TestData *) gst_collect_pads_add_pad (collect,
251 sinkpad1, sizeof (TestData));
252 fail_unless (data1 != NULL);
254 data2 = (TestData *) gst_collect_pads_add_pad (collect,
255 sinkpad2, sizeof (TestData));
256 fail_unless (data2 != NULL);
258 buf1 = gst_buffer_new ();
260 /* start collect pads */
261 gst_collect_pads_start (collect);
264 data1->pad = srcpad1;
265 data1->buffer = buf1;
266 thread1 = g_thread_create (push_buffer, data1, TRUE, NULL);
267 /* here thread1 is blocked and srcpad1 has a queued buffer */
268 fail_unless_collected (FALSE);
270 /* push EOS on the other pad */
271 data2->pad = srcpad2;
272 data2->event = gst_event_new_eos ();
273 thread2 = g_thread_create (push_event, data2, TRUE, NULL);
275 /* one of the pads has a buffer, the other has EOS */
276 fail_unless_collected (TRUE);
278 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data1);
279 fail_unless (tmp == buf1);
280 /* there's nothing to pop from the one which received EOS */
281 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data2);
282 fail_unless (tmp == NULL);
284 /* these will return immediately as at this point the threads have been
285 * unlocked and are finished */
286 g_thread_join (thread1);
287 g_thread_join (thread2);
289 gst_collect_pads_stop (collect);
292 buf2 = gst_buffer_new ();
294 /* start collect pads */
295 gst_collect_pads_start (collect);
297 /* push buffers on the pads */
298 data1->pad = srcpad1;
299 data1->buffer = buf1;
300 thread1 = g_thread_create (push_buffer, data1, TRUE, NULL);
301 /* here thread1 is blocked and srcpad1 has a queued buffer */
302 fail_unless_collected (FALSE);
304 data2->pad = srcpad2;
305 data2->buffer = buf2;
306 thread2 = g_thread_create (push_buffer, data2, TRUE, NULL);
308 /* now both pads have a buffer */
309 fail_unless_collected (TRUE);
311 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data1);
312 fail_unless (tmp == buf1);
313 tmp = gst_collect_pads_pop (collect, (GstCollectData *) data2);
314 fail_unless (tmp == buf2);
316 /* these will return immediately as at this point the threads have been
317 * unlocked and are finished */
318 g_thread_join (thread1);
319 g_thread_join (thread2);
321 gst_collect_pads_stop (collect);
323 gst_buffer_unref (buf1);
324 gst_buffer_unref (buf2);
331 gst_collect_pads_suite (void)
336 suite = suite_create ("GstCollectPads");
337 general = tcase_create ("general");
338 suite_add_tcase (suite, general);
339 tcase_add_checked_fixture (general, setup, teardown);
340 tcase_add_test (general, test_pad_add_remove);
341 tcase_add_test (general, test_collect);
342 tcase_add_test (general, test_collect_eos);
343 tcase_add_test (general, test_collect_twice);
348 GST_CHECK_MAIN (gst_collect_pads);