2 * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
4 * gstevents.c: Unit test for event handling
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include "../gstcheck.h"
25 GST_START_TEST (create_custom_events)
27 GstEvent *event, *event2;
28 GstStructure *structure;
32 event = gst_event_new_flush_start ();
33 fail_if (event == NULL);
34 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_START);
35 fail_unless (GST_EVENT_IS_UPSTREAM (event));
36 fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
37 fail_if (GST_EVENT_IS_SERIALIZED (event));
38 gst_event_unref (event);
42 event = gst_event_new_flush_stop ();
43 fail_if (event == NULL);
44 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
45 fail_unless (GST_EVENT_IS_UPSTREAM (event));
46 fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
47 fail_if (GST_EVENT_IS_SERIALIZED (event));
48 gst_event_unref (event);
52 event = gst_event_new_eos ();
53 fail_if (event == NULL);
54 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
55 fail_if (GST_EVENT_IS_UPSTREAM (event));
56 fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
57 fail_unless (GST_EVENT_IS_SERIALIZED (event));
58 gst_event_unref (event);
64 gint64 start, end, base;
66 event = gst_event_new_newsegment (0.5, GST_FORMAT_TIME, 1, G_MAXINT64,
68 fail_if (event == NULL);
69 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
70 fail_if (GST_EVENT_IS_UPSTREAM (event));
71 fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
72 fail_unless (GST_EVENT_IS_SERIALIZED (event));
74 gst_event_parse_newsegment (event, &rate, &format, &start, &end, &base);
75 fail_unless (rate == 0.5);
76 fail_unless (format == GST_FORMAT_TIME);
77 fail_unless (start == 1);
78 fail_unless (end == G_MAXINT64);
79 fail_unless (base == 0xdeadbeef);
81 gst_event_unref (event);
85 GstTagList *taglist = gst_tag_list_new ();
86 GstTagList *tl2 = NULL;
88 event = gst_event_new_tag (taglist);
89 fail_if (taglist == NULL);
90 fail_if (event == NULL);
91 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
92 fail_if (GST_EVENT_IS_UPSTREAM (event));
93 fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
94 fail_unless (GST_EVENT_IS_SERIALIZED (event));
96 gst_event_parse_tag (event, &tl2);
97 fail_unless (taglist == tl2);
98 gst_event_unref (event);
101 /* FIXME: Add tests for FILLERS and QOS when they are implemented. */
108 GstSeekType cur_type, stop_type;
111 event = gst_event_new_seek (0.5, GST_FORMAT_BYTES,
112 GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
113 GST_SEEK_TYPE_SET, 1, GST_SEEK_TYPE_NONE, 0xdeadbeef);
115 fail_if (event == NULL);
116 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
117 fail_unless (GST_EVENT_IS_UPSTREAM (event));
118 fail_if (GST_EVENT_IS_DOWNSTREAM (event));
119 fail_if (GST_EVENT_IS_SERIALIZED (event));
121 gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
123 fail_unless (rate == 0.5);
124 fail_unless (format == GST_FORMAT_BYTES);
125 fail_unless (flags == (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE));
126 fail_unless (cur_type == GST_SEEK_TYPE_SET);
127 fail_unless (cur == 1);
128 fail_unless (stop_type == GST_SEEK_TYPE_NONE);
129 fail_unless (stop == 0xdeadbeef);
131 gst_event_unref (event);
136 structure = gst_structure_new ("application/x-gst-navigation", "event",
137 G_TYPE_STRING, "key-press", "key", G_TYPE_STRING, "mon", NULL);
138 fail_if (structure == NULL);
139 event = gst_event_new_navigation (structure);
140 fail_if (event == NULL);
141 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION);
142 fail_unless (GST_EVENT_IS_UPSTREAM (event));
143 fail_if (GST_EVENT_IS_DOWNSTREAM (event));
144 fail_if (GST_EVENT_IS_SERIALIZED (event));
146 fail_unless (gst_event_get_structure (event) == structure);
147 gst_event_unref (event);
150 /* Custom event types */
152 structure = gst_structure_empty_new ("application/x-custom");
153 fail_if (structure == NULL);
154 event = gst_event_new_custom (GST_EVENT_CUSTOM_UP, structure);
155 fail_if (event == NULL);
156 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UP);
157 fail_unless (GST_EVENT_IS_UPSTREAM (event));
158 fail_if (GST_EVENT_IS_DOWNSTREAM (event));
159 fail_if (GST_EVENT_IS_SERIALIZED (event));
160 fail_unless (gst_event_get_structure (event) == structure);
161 gst_event_unref (event);
163 /* Decided not to test the other custom enum types, as they
164 * only differ by the value of the enum passed to gst_event_new_custom
170 structure = gst_structure_empty_new ("application/x-custom");
171 fail_if (structure == NULL);
172 event = gst_event_new_custom (GST_EVENT_CUSTOM_BOTH, structure);
174 fail_if (event == NULL);
175 event2 = gst_event_copy (event);
176 fail_if (event2 == NULL);
177 fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TYPE (event2));
179 /* The structure should have been duplicated */
180 fail_if (gst_event_get_structure (event) ==
181 gst_event_get_structure (event2));
182 gst_event_unref (event);
183 gst_event_unref (event2);
187 GST_END_TEST GTimeVal sent_event_time;
188 GstEvent *got_event_before_q, *got_event_after_q;
189 GTimeVal got_event_time;
192 event_probe (GstPad * pad, GstMiniObject ** data, gpointer user_data)
194 gboolean before_q = (gboolean) user_data;
196 fail_unless (GST_IS_EVENT (data));
199 switch (GST_EVENT_TYPE (GST_EVENT (data))) {
200 case GST_EVENT_CUSTOM_UP:
201 case GST_EVENT_CUSTOM_BOTH:
202 case GST_EVENT_CUSTOM_BOTH_OOB:
203 gst_event_ref (data);
204 g_get_current_time (&got_event_time);
205 got_event_before_q = GST_EVENT (data);
211 switch (GST_EVENT_TYPE (GST_EVENT (data))) {
212 case GST_EVENT_CUSTOM_DS:
213 case GST_EVENT_CUSTOM_DS_OOB:
214 case GST_EVENT_CUSTOM_BOTH:
215 case GST_EVENT_CUSTOM_BOTH_OOB:
216 gst_event_ref (data);
217 g_get_current_time (&got_event_time);
218 got_event_after_q = GST_EVENT (data);
228 static void test_event
229 (GstEventType type, GstPad * pad, gboolean expect_before_q)
234 got_event_before_q = got_event_after_q = NULL;
236 event = gst_event_new_custom (type,
237 gst_structure_empty_new ("application/x-custom"));
238 g_get_current_time (&sent_event_time);
239 got_event_time.tv_sec = 0;
240 got_event_time.tv_usec = 0;
242 gst_pad_push_event (pad, event);
244 /* Wait up to 5 seconds for the event to appear */
245 if (expect_before_q) {
246 for (i = 0; i < 50; i++) {
247 g_usleep (G_USEC_PER_SEC / 10);
248 if (got_event_before_q != NULL)
251 fail_if (got_event_before_q == NULL);
252 fail_unless (GST_EVENT_TYPE (got_event_before_q) == type);
254 for (i = 0; i < 50; i++) {
255 g_usleep (G_USEC_PER_SEC / 10);
256 if (got_event_after_q != NULL)
259 fail_if (got_event_after_q == NULL);
260 fail_unless (GST_EVENT_TYPE (got_event_after_q) == type);
265 timediff (GTimeVal * end, GTimeVal * start)
267 return (end->tv_sec - start->tv_sec) * G_USEC_PER_SEC +
268 (end->tv_usec - start->tv_usec);
271 GST_START_TEST (send_custom_events)
273 /* Run some tests on custom events. Checking for serialisation and whatnot.
274 * pipeline is fakesrc ! queue ! fakesink */
276 GstElement *fakesrc, *fakesink, *queue;
277 GstPad *srcpad, *sinkpad;
279 fail_if ((pipeline = (GstBin *) gst_pipeline_new ("testpipe")) == NULL);
280 fail_if ((fakesrc = gst_element_factory_make ("fakesrc", NULL)) == NULL);
281 fail_if ((fakesink = gst_element_factory_make ("fakesink", NULL)) == NULL);
282 fail_if ((queue = gst_element_factory_make ("queue", NULL)) == NULL);
284 gst_bin_add_many (pipeline, fakesrc, queue, fakesink, NULL);
285 fail_unless (gst_element_link_many (fakesrc, queue, fakesink, NULL));
287 /* Send 25 buffers per sec */
288 g_object_set (G_OBJECT (fakesrc), "silent", TRUE, "datarate", 25,
289 "sizemax", 1, "sizetype", 2, NULL);
290 g_object_set (G_OBJECT (queue), "max-size-buffers", 0, "max-size-time",
291 (guint64) 1.1 * GST_SECOND, "max-size-bytes", 0, NULL);
292 g_object_set (G_OBJECT (fakesink), "silent", TRUE, "sync", TRUE, NULL);
294 fail_if ((srcpad = gst_element_get_pad (fakesrc, "src")) == NULL);
295 gst_pad_add_event_probe (srcpad, (GCallback) event_probe,
296 GINT_TO_POINTER (TRUE));
298 fail_if ((sinkpad = gst_element_get_pad (fakesink, "sink")) == NULL);
299 gst_pad_add_event_probe (sinkpad, (GCallback) event_probe,
300 GINT_TO_POINTER (FALSE));
302 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
304 /* Upstream events */
305 test_event (GST_EVENT_CUSTOM_UP, sinkpad, TRUE);
306 fail_unless (timediff (&got_event_time, &sent_event_time) < G_USEC_PER_SEC,
307 "GST_EVENT_CUSTOM_UP took to long to reach source");
309 test_event (GST_EVENT_CUSTOM_BOTH, sinkpad, TRUE);
310 fail_unless (timediff (&got_event_time, &sent_event_time) < G_USEC_PER_SEC,
311 "GST_EVENT_CUSTOM_BOTH took to long to reach source");
313 test_event (GST_EVENT_CUSTOM_BOTH_OOB, sinkpad, TRUE);
314 fail_unless (timediff (&got_event_time, &sent_event_time) < G_USEC_PER_SEC,
315 "GST_EVENT_CUSTOM_BOTH_OOB took to long to reach source");
317 /* Out of band downstream events */
318 test_event (GST_EVENT_CUSTOM_DS_OOB, srcpad, FALSE);
319 fail_unless (timediff (&got_event_time, &sent_event_time) < G_USEC_PER_SEC,
320 "GST_EVENT_CUSTOM_DS_OOB took to long to reach source");
322 test_event (GST_EVENT_CUSTOM_BOTH_OOB, srcpad, FALSE);
323 fail_unless (timediff (&got_event_time, &sent_event_time) < G_USEC_PER_SEC,
324 "GST_EVENT_CUSTOM_BOTH_OOB took to long to reach source");
326 /* In-band downstream events are expected to take at least 1 second
327 * to traverse the the queue */
328 test_event (GST_EVENT_CUSTOM_DS, srcpad, FALSE);
329 fail_unless (timediff (&got_event_time, &sent_event_time) >= G_USEC_PER_SEC,
330 "GST_EVENT_CUSTOM_BOTH_OOB arrived at sink too quickly for an in-band event");
332 test_event (GST_EVENT_CUSTOM_BOTH, srcpad, FALSE);
333 fail_unless (timediff (&got_event_time, &sent_event_time) >= G_USEC_PER_SEC,
334 "GST_EVENT_CUSTOM_BOTH_OOB arrived at sink too quickly for an in-band event");
336 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
337 gst_bin_watch_for_state_change (GST_BIN (pipeline));
339 gst_object_unref (pipeline);
342 GST_END_TEST Suite * gstevents_suite (void)
344 Suite *s = suite_create ("GstEvent");
345 TCase *tc_chain = tcase_create ("customevents");
347 tcase_set_timeout (tc_chain, 20);
349 suite_add_tcase (s, tc_chain);
350 tcase_add_test (tc_chain, create_custom_events);
351 tcase_add_test (tc_chain, send_custom_events);
356 main (int argc, char **argv)
360 Suite *s = gstevents_suite ();
361 SRunner *sr = srunner_create (s);
363 gst_check_init (&argc, &argv);
365 srunner_run_all (sr, CK_NORMAL);
366 nf = srunner_ntests_failed (sr);