Initialize Tizen 2.3
[framework/multimedia/gstreamer0.10.git] / wearable / tests / check / libs / collectpads.c
1 /*
2  * collectpads.c - GstCollectPads testsuite
3  * Copyright (C) 2006 Alessandro Decina <alessandro@nnva.org>
4  *
5  * Authors:
6  *   Alessandro Decina <alessandro@nnva.org>
7  *
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.
12  *
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.
17  *
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.
22  */
23
24 #include <gst/check/gstcheck.h>
25 #include <gst/base/gstcollectpads.h>
26
27 #define fail_unless_collected(expected)           \
28 G_STMT_START {                                    \
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);                          \
34 } G_STMT_END;
35
36 typedef struct
37 {
38   char foo;
39 } BadCollectData;
40
41 typedef struct
42 {
43   GstCollectData data;
44   GstPad *pad;
45   GstBuffer *buffer;
46   GstEvent *event;
47 } TestData;
48
49 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
50     GST_PAD_SRC,
51     GST_PAD_ALWAYS,
52     GST_STATIC_CAPS_ANY);
53
54 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
55     GST_PAD_SINK,
56     GST_PAD_ALWAYS,
57     GST_STATIC_CAPS_ANY);
58
59 static GstCollectPads *collect;
60 static gboolean collected;
61 static GstPad *srcpad1, *srcpad2;
62 static GstPad *sinkpad1, *sinkpad2;
63 static TestData *data1, *data2;
64
65 static GMutex *lock;
66 static GCond *cond;
67
68 static GstFlowReturn
69 collected_cb (GstCollectPads * pads, gpointer user_data)
70 {
71   g_mutex_lock (lock);
72   collected = TRUE;
73   g_cond_signal (cond);
74   g_mutex_unlock (lock);
75
76   return GST_FLOW_OK;
77 }
78
79 static gpointer
80 push_buffer (gpointer user_data)
81 {
82   TestData *test_data = (TestData *) user_data;
83
84   fail_unless (gst_pad_push (test_data->pad, test_data->buffer)
85       == GST_FLOW_OK);
86
87   return NULL;
88 }
89
90 static gpointer
91 push_event (gpointer user_data)
92 {
93   TestData *test_data = (TestData *) user_data;
94
95   fail_unless (gst_pad_push_event (test_data->pad, test_data->event) == TRUE);
96
97   return NULL;
98 }
99
100 static void
101 setup (void)
102 {
103   collect = gst_collect_pads_new ();
104   gst_collect_pads_set_function (collect, collected_cb, NULL);
105
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);
112
113   cond = g_cond_new ();
114   lock = g_mutex_new ();
115   data1 = NULL;
116   data2 = NULL;
117   collected = FALSE;
118 }
119
120 static void
121 teardown (void)
122 {
123   gst_object_unref (sinkpad1);
124   gst_object_unref (sinkpad2);
125   gst_object_unref (collect);
126   g_cond_free (cond);
127   g_mutex_free (lock);
128 }
129
130 GST_START_TEST (test_pad_add_remove)
131 {
132   ASSERT_CRITICAL (gst_collect_pads_add_pad (collect, sinkpad1,
133           sizeof (BadCollectData)));
134
135   data1 = (TestData *) gst_collect_pads_add_pad (collect,
136       sinkpad1, sizeof (TestData));
137   fail_unless (data1 != NULL);
138
139   fail_unless (gst_collect_pads_remove_pad (collect, sinkpad2) == FALSE);
140   fail_unless (gst_collect_pads_remove_pad (collect, sinkpad1) == TRUE);
141 }
142
143 GST_END_TEST;
144
145 GST_START_TEST (test_collect)
146 {
147   GstBuffer *buf1, *buf2, *tmp;
148   GThread *thread1, *thread2;
149
150   data1 = (TestData *) gst_collect_pads_add_pad (collect,
151       sinkpad1, sizeof (TestData));
152   fail_unless (data1 != NULL);
153
154   data2 = (TestData *) gst_collect_pads_add_pad (collect,
155       sinkpad2, sizeof (TestData));
156   fail_unless (data2 != NULL);
157
158   buf1 = gst_buffer_new ();
159   buf2 = gst_buffer_new ();
160
161   /* start collect pads */
162   gst_collect_pads_start (collect);
163
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);
170
171   data2->pad = srcpad2;
172   data2->buffer = buf2;
173   thread2 = g_thread_create (push_buffer, data2, TRUE, NULL);
174
175   /* now both pads have a buffer */
176   fail_unless_collected (TRUE);
177
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);
182
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);
187
188   gst_collect_pads_stop (collect);
189
190   gst_buffer_unref (buf1);
191   gst_buffer_unref (buf2);
192 }
193
194 GST_END_TEST;
195
196 GST_START_TEST (test_collect_eos)
197 {
198   GstBuffer *buf1, *tmp;
199   GThread *thread1, *thread2;
200
201   data1 = (TestData *) gst_collect_pads_add_pad (collect,
202       sinkpad1, sizeof (TestData));
203   fail_unless (data1 != NULL);
204
205   data2 = (TestData *) gst_collect_pads_add_pad (collect,
206       sinkpad2, sizeof (TestData));
207   fail_unless (data2 != NULL);
208
209   buf1 = gst_buffer_new ();
210
211   /* start collect pads */
212   gst_collect_pads_start (collect);
213
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);
220
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);
226
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);
232
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);
237
238   gst_collect_pads_stop (collect);
239
240   gst_buffer_unref (buf1);
241 }
242
243 GST_END_TEST;
244
245 GST_START_TEST (test_collect_twice)
246 {
247   GstBuffer *buf1, *buf2, *tmp;
248   GThread *thread1, *thread2;
249
250   data1 = (TestData *) gst_collect_pads_add_pad (collect,
251       sinkpad1, sizeof (TestData));
252   fail_unless (data1 != NULL);
253
254   data2 = (TestData *) gst_collect_pads_add_pad (collect,
255       sinkpad2, sizeof (TestData));
256   fail_unless (data2 != NULL);
257
258   buf1 = gst_buffer_new ();
259
260   /* start collect pads */
261   gst_collect_pads_start (collect);
262
263   /* queue a buffer */
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);
269
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);
274
275   /* one of the pads has a buffer, the other has EOS */
276   fail_unless_collected (TRUE);
277
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);
283
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);
288
289   gst_collect_pads_stop (collect);
290   collected = FALSE;
291
292   buf2 = gst_buffer_new ();
293
294   /* start collect pads */
295   gst_collect_pads_start (collect);
296
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);
303
304   data2->pad = srcpad2;
305   data2->buffer = buf2;
306   thread2 = g_thread_create (push_buffer, data2, TRUE, NULL);
307
308   /* now both pads have a buffer */
309   fail_unless_collected (TRUE);
310
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);
315
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);
320
321   gst_collect_pads_stop (collect);
322
323   gst_buffer_unref (buf1);
324   gst_buffer_unref (buf2);
325
326 }
327
328 GST_END_TEST;
329
330 static Suite *
331 gst_collect_pads_suite (void)
332 {
333   Suite *suite;
334   TCase *general;
335
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);
344
345   return suite;
346 }
347
348 GST_CHECK_MAIN (gst_collect_pads);