Merge remote-tracking branch 'origin/0.10'
[platform/upstream/gstreamer.git] / tests / check / gst / gstevent.c
1 /* GStreamer
2  * Copyright (C) 2005 Jan Schmidt <thaytan@mad.scientist.com>
3  *
4  * gstevent.c: Unit test for event handling
5  *
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.
10  *
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.
15  *
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.
20  */
21
22
23 #include <gst/check/gstcheck.h>
24
25 GST_START_TEST (create_events)
26 {
27   GstEvent *event, *event2;
28   GstStructure *structure;
29
30   /* FLUSH_START */
31   {
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);
39   }
40   /* FLUSH_STOP */
41   {
42     gboolean reset_time;
43
44     event = gst_event_new_flush_stop (TRUE);
45     fail_if (event == NULL);
46     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
47     fail_unless (GST_EVENT_IS_UPSTREAM (event));
48     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
49     fail_unless (GST_EVENT_IS_SERIALIZED (event));
50
51     gst_event_parse_flush_stop (event, &reset_time);
52     fail_unless (reset_time == TRUE);
53     gst_event_unref (event);
54   }
55   /* EOS */
56   {
57     event = gst_event_new_eos ();
58     fail_if (event == NULL);
59     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_EOS);
60     fail_if (GST_EVENT_IS_UPSTREAM (event));
61     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
62     fail_unless (GST_EVENT_IS_SERIALIZED (event));
63     gst_event_unref (event);
64   }
65   /* GAP */
66   {
67     GstClockTime ts = 0, dur = 0;
68
69     ASSERT_CRITICAL (gst_event_new_gap (GST_CLOCK_TIME_NONE, GST_SECOND));
70
71     event = gst_event_new_gap (90 * GST_SECOND, GST_SECOND);
72     fail_if (event == NULL);
73     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_GAP);
74     fail_if (GST_EVENT_IS_UPSTREAM (event));
75     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
76     fail_unless (GST_EVENT_IS_SERIALIZED (event));
77     gst_event_parse_gap (event, &ts, NULL);
78     fail_unless_equals_int64 (ts, 90 * GST_SECOND);
79     gst_event_parse_gap (event, &ts, &dur);
80     fail_unless_equals_int64 (dur, GST_SECOND);
81     gst_event_unref (event);
82   }
83   /* SEGMENT */
84   {
85     GstSegment segment, parsed;
86
87     gst_segment_init (&segment, GST_FORMAT_TIME);
88     segment.rate = 0.5;
89     segment.applied_rate = 1.0;
90     segment.start = 1;
91     segment.stop = G_MAXINT64;
92     segment.time = 0xdeadbeef;
93
94     event = gst_event_new_segment (&segment);
95     fail_if (event == NULL);
96     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
97     fail_if (GST_EVENT_IS_UPSTREAM (event));
98     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
99     fail_unless (GST_EVENT_IS_SERIALIZED (event));
100
101     gst_event_copy_segment (event, &parsed);
102     fail_unless (parsed.rate == 0.5);
103     fail_unless (parsed.applied_rate == 1.0);
104     fail_unless (parsed.format == GST_FORMAT_TIME);
105     fail_unless (parsed.start == 1);
106     fail_unless (parsed.stop == G_MAXINT64);
107     fail_unless (parsed.time == 0xdeadbeef);
108
109     gst_event_unref (event);
110   }
111
112   /* STREAM CONFIG */
113   {
114     GstStreamConfigFlags flags = 0x987654;
115     GstBuffer *buf, *cd, *sh1, *sh2;
116     gpointer dummy;
117
118     event = gst_event_new_stream_config (GST_STREAM_CONFIG_FLAG_NONE);
119
120     gst_event_parse_stream_config (event, &flags);
121     fail_unless_equals_int (flags, GST_STREAM_CONFIG_FLAG_NONE);
122
123     fail_unless_equals_int (gst_event_get_n_stream_config_headers (event), 0);
124
125     /* set buf to something random but guaranteed to be non-NULL */
126     buf = (GstBuffer *) & dummy;
127     gst_event_parse_stream_config_setup_data (event, &buf);
128     fail_unless (buf == NULL);
129
130     buf = (GstBuffer *) & dummy;
131     gst_event_parse_nth_stream_config_header (event, 0, &buf);
132     fail_unless (buf == NULL);
133
134     buf = (GstBuffer *) & dummy;
135     gst_event_parse_nth_stream_config_header (event, 98416, &buf);
136     fail_unless (buf == NULL);
137
138     ASSERT_CRITICAL (gst_event_set_stream_config_setup_data (event, NULL));
139     ASSERT_CRITICAL (gst_event_add_stream_config_header (event, NULL));
140
141     cd = gst_buffer_new_wrapped_full (0, (gpointer) "SetMeUpScottie", 14, 0, 14,
142         NULL, NULL);
143     gst_event_set_stream_config_setup_data (event, cd);
144     gst_buffer_unref (cd);
145
146     buf = (GstBuffer *) & dummy;
147     gst_event_parse_nth_stream_config_header (event, 0, &buf);
148     fail_unless (buf == NULL);
149     gst_event_parse_stream_config_setup_data (event, &buf);
150     fail_unless (buf == cd);
151     fail_unless (GST_IS_BUFFER (buf));
152
153     gst_event_unref (event);
154
155     event = gst_event_new_stream_config (GST_STREAM_CONFIG_FLAG_NONE);
156     fail_unless_equals_int (gst_event_get_n_stream_config_headers (event), 0);
157     sh1 =
158         gst_buffer_new_wrapped_full (0, (gpointer) "Strea", 5, 0, 5, NULL,
159         NULL);
160     gst_event_add_stream_config_header (event, sh1);
161     gst_buffer_unref (sh1);
162     fail_unless_equals_int (gst_event_get_n_stream_config_headers (event), 1);
163     sh2 =
164         gst_buffer_new_wrapped_full (0, (gpointer) "mHeader", 7, 0, 7, NULL,
165         NULL);
166     gst_event_add_stream_config_header (event, sh2);
167     gst_buffer_unref (sh2);
168     fail_unless_equals_int (gst_event_get_n_stream_config_headers (event), 2);
169
170     buf = (GstBuffer *) & dummy;
171     gst_event_parse_nth_stream_config_header (event, 1, &buf);
172     fail_unless (buf == sh2);
173     fail_unless (GST_IS_BUFFER (buf));
174
175     buf = (GstBuffer *) & dummy;
176     gst_event_parse_nth_stream_config_header (event, 0, &buf);
177     fail_unless (buf == sh1);
178     fail_unless (GST_IS_BUFFER (buf));
179
180     gst_event_unref (event);
181   }
182
183   /* TAGS */
184   {
185     GstTagList *taglist = gst_tag_list_new_empty ();
186     GstTagList *tl2 = NULL;
187
188     event = gst_event_new_tag (taglist);
189     fail_if (taglist == NULL);
190     fail_if (event == NULL);
191     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
192     fail_if (GST_EVENT_IS_UPSTREAM (event));
193     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
194     fail_unless (GST_EVENT_IS_SERIALIZED (event));
195
196     gst_event_parse_tag (event, &tl2);
197     fail_unless (taglist == tl2);
198     gst_event_unref (event);
199   }
200
201   /* QOS */
202   {
203     GstQOSType t1 = GST_QOS_TYPE_THROTTLE, t2;
204     gdouble p1 = 1.0, p2;
205     GstClockTimeDiff ctd1 = G_GINT64_CONSTANT (10), ctd2;
206     GstClockTime ct1 = G_GUINT64_CONSTANT (20), ct2;
207
208     event = gst_event_new_qos (t1, p1, ctd1, ct1);
209     fail_if (event == NULL);
210     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
211     fail_unless (GST_EVENT_IS_UPSTREAM (event));
212     fail_if (GST_EVENT_IS_DOWNSTREAM (event));
213     fail_if (GST_EVENT_IS_SERIALIZED (event));
214
215     gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
216     fail_unless (p1 == p2);
217     fail_unless (ctd1 == ctd2);
218     fail_unless (ct1 == ct2);
219     gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
220     fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
221     fail_unless (p1 == p2);
222     fail_unless (ctd1 == ctd2);
223     fail_unless (ct1 == ct2);
224     gst_event_unref (event);
225
226     ctd1 = G_GINT64_CONSTANT (-10);
227     event = gst_event_new_qos (t1, p1, ctd1, ct1);
228     gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
229     fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
230     gst_event_unref (event);
231
232     event = gst_event_new_qos (t1, p1, ctd1, ct1);
233     gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
234     fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
235     fail_unless (p1 == p2);
236     fail_unless (ctd1 == ctd2);
237     fail_unless (ct1 == ct2);
238     gst_event_unref (event);
239   }
240
241   /* SEEK */
242   {
243     gdouble rate;
244     GstFormat format;
245     GstSeekFlags flags;
246     GstSeekType cur_type, stop_type;
247     gint64 cur, stop;
248
249     event = gst_event_new_seek (0.5, GST_FORMAT_BYTES,
250         GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE,
251         GST_SEEK_TYPE_SET, 1, GST_SEEK_TYPE_NONE, 0xdeadbeef);
252
253     fail_if (event == NULL);
254     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
255     fail_unless (GST_EVENT_IS_UPSTREAM (event));
256     fail_if (GST_EVENT_IS_DOWNSTREAM (event));
257     fail_if (GST_EVENT_IS_SERIALIZED (event));
258
259     gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
260         &stop_type, &stop);
261     fail_unless (rate == 0.5);
262     fail_unless (format == GST_FORMAT_BYTES);
263     fail_unless (flags == (GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_ACCURATE));
264     fail_unless (cur_type == GST_SEEK_TYPE_SET);
265     fail_unless (cur == 1);
266     fail_unless (stop_type == GST_SEEK_TYPE_NONE);
267     fail_unless (stop == 0xdeadbeef);
268
269     gst_event_unref (event);
270   }
271
272   /* NAVIGATION */
273   {
274     structure = gst_structure_new ("application/x-gst-navigation", "event",
275         G_TYPE_STRING, "key-press", "key", G_TYPE_STRING, "mon", NULL);
276     fail_if (structure == NULL);
277     event = gst_event_new_navigation (structure);
278     fail_if (event == NULL);
279     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NAVIGATION);
280     fail_unless (GST_EVENT_IS_UPSTREAM (event));
281     fail_if (GST_EVENT_IS_DOWNSTREAM (event));
282     fail_if (GST_EVENT_IS_SERIALIZED (event));
283
284     fail_unless (gst_event_get_structure (event) == structure);
285     gst_event_unref (event);
286   }
287
288   /* Custom event types */
289   {
290     structure = gst_structure_new_empty ("application/x-custom");
291     fail_if (structure == NULL);
292     event = gst_event_new_custom (GST_EVENT_CUSTOM_UPSTREAM, structure);
293     fail_if (event == NULL);
294     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM);
295     fail_unless (GST_EVENT_IS_UPSTREAM (event));
296     fail_if (GST_EVENT_IS_DOWNSTREAM (event));
297     fail_if (GST_EVENT_IS_SERIALIZED (event));
298     fail_unless (gst_event_get_structure (event) == structure);
299     fail_unless (gst_event_has_name (event, "application/x-custom"));
300     gst_event_unref (event);
301
302     /* Decided not to test the other custom enum types, as they
303      * only differ by the value of the enum passed to gst_event_new_custom
304      */
305   }
306
307   /* Event copying */
308   {
309     structure = gst_structure_new_empty ("application/x-custom");
310     fail_if (structure == NULL);
311     event = gst_event_new_custom (GST_EVENT_CUSTOM_BOTH, structure);
312
313     fail_if (event == NULL);
314     event2 = gst_event_copy (event);
315     fail_if (event2 == NULL);
316     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_TYPE (event2));
317     fail_unless (gst_event_has_name (event, "application/x-custom"));
318
319     /* The structure should have been duplicated */
320     fail_if (gst_event_get_structure (event) ==
321         gst_event_get_structure (event2));
322
323     gst_event_unref (event);
324     gst_event_unref (event2);
325   }
326
327   /* Make events writable */
328   {
329     structure = gst_structure_new_empty ("application/x-custom");
330     fail_if (structure == NULL);
331     event = gst_event_new_custom (GST_EVENT_CUSTOM_BOTH, structure);
332     /* ref the event so that it becomes non-writable */
333     gst_event_ref (event);
334     gst_event_ref (event);
335     /* this should fail if the structure isn't writable */
336     ASSERT_CRITICAL (gst_structure_remove_all_fields ((GstStructure *)
337             gst_event_get_structure (event)));
338     fail_unless (gst_event_has_name (event, "application/x-custom"));
339
340     /* now make writable */
341     event2 =
342         GST_EVENT (gst_mini_object_make_writable (GST_MINI_OBJECT (event)));
343     fail_unless (event != event2);
344     /* this fail if the structure isn't writable */
345     gst_structure_remove_all_fields ((GstStructure *)
346         gst_event_get_structure (event2));
347     fail_unless (gst_event_has_name (event2, "application/x-custom"));
348
349     gst_event_unref (event);
350     gst_event_unref (event);
351     gst_event_unref (event2);
352   }
353 }
354
355 GST_END_TEST;
356
357 static GTimeVal sent_event_time;
358 static GstEvent *got_event_before_q, *got_event_after_q;
359 static GTimeVal got_event_time;
360
361 static GstPadProbeReturn
362 event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
363 {
364   GstMiniObject *data = GST_PAD_PROBE_INFO_DATA (info);
365   gboolean before_q = (gboolean) GPOINTER_TO_INT (user_data);
366
367   GST_DEBUG ("event probe called %p", data);
368
369   fail_unless (GST_IS_EVENT (data));
370
371   if (before_q) {
372     switch (GST_EVENT_TYPE (GST_EVENT (data))) {
373       case GST_EVENT_CUSTOM_UPSTREAM:
374       case GST_EVENT_CUSTOM_BOTH:
375       case GST_EVENT_CUSTOM_BOTH_OOB:
376         if (got_event_before_q != NULL)
377           break;
378         gst_event_ref ((GstEvent *) data);
379         g_get_current_time (&got_event_time);
380         got_event_before_q = GST_EVENT (data);
381         break;
382       default:
383         break;
384     }
385   } else {
386     switch (GST_EVENT_TYPE (GST_EVENT (data))) {
387       case GST_EVENT_CUSTOM_DOWNSTREAM:
388       case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
389       case GST_EVENT_CUSTOM_BOTH:
390       case GST_EVENT_CUSTOM_BOTH_OOB:
391         if (got_event_after_q != NULL)
392           break;
393         gst_event_ref ((GstEvent *) data);
394         g_get_current_time (&got_event_time);
395         got_event_after_q = GST_EVENT (data);
396         break;
397       default:
398         break;
399     }
400   }
401
402   return GST_PAD_PROBE_OK;
403 }
404
405
406 typedef struct
407 {
408   GMutex *lock;
409   GCond *cond;
410   gboolean signaled;
411 } SignalData;
412
413 static void
414 signal_data_init (SignalData * data)
415 {
416   GST_DEBUG ("init %p", data);
417   data->lock = g_mutex_new ();
418   data->cond = g_cond_new ();
419   data->signaled = FALSE;
420 }
421
422 static void
423 signal_data_cleanup (SignalData * data)
424 {
425   GST_DEBUG ("free %p", data);
426   g_mutex_free (data->lock);
427   g_cond_free (data->cond);
428 }
429
430 static void
431 signal_data_signal (SignalData * data)
432 {
433   g_mutex_lock (data->lock);
434   data->signaled = TRUE;
435   g_cond_broadcast (data->cond);
436   GST_DEBUG ("signaling %p", data);
437   g_mutex_unlock (data->lock);
438 }
439
440 static void
441 signal_data_wait (SignalData * data)
442 {
443   g_mutex_lock (data->lock);
444   GST_DEBUG ("signal wait %p", data);
445   while (!data->signaled)
446     g_cond_wait (data->cond, data->lock);
447   GST_DEBUG ("signal wait done %p", data);
448   g_mutex_unlock (data->lock);
449 }
450
451 static GstPadProbeReturn
452 signal_blocked (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
453 {
454   SignalData *data = (SignalData *) user_data;
455
456   GST_DEBUG ("signal called %p", data);
457   signal_data_signal (data);
458   GST_DEBUG ("signal done %p", data);
459
460   return GST_PAD_PROBE_OK;
461 }
462
463 static void test_event
464     (GstBin * pipeline, GstEventType type, GstPad * pad,
465     gboolean expect_before_q, GstPad * fake_srcpad)
466 {
467   GstEvent *event;
468   GstPad *peer;
469   gint i;
470   SignalData data;
471   gulong id;
472
473   got_event_before_q = got_event_after_q = NULL;
474
475   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
476   gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL,
477       GST_CLOCK_TIME_NONE);
478
479   GST_DEBUG ("test event called");
480
481   event = gst_event_new_custom (type,
482       gst_structure_new_empty ("application/x-custom"));
483   g_get_current_time (&sent_event_time);
484   got_event_time.tv_sec = 0;
485   got_event_time.tv_usec = 0;
486
487   signal_data_init (&data);
488
489   /* We block the pad so the stream lock is released and we can send the event */
490   id = gst_pad_add_probe (fake_srcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
491       signal_blocked, &data, NULL);
492   fail_unless (id != 0);
493
494   signal_data_wait (&data);
495
496   /* We send on the peer pad, since the pad is blocked */
497   GST_DEBUG ("sending event %p", event);
498   fail_unless ((peer = gst_pad_get_peer (pad)) != NULL);
499   gst_pad_send_event (peer, event);
500   gst_object_unref (peer);
501
502   gst_pad_remove_probe (fake_srcpad, id);
503
504   if (expect_before_q) {
505     /* Wait up to 5 seconds for the event to appear */
506     for (i = 0; i < 500; i++) {
507       g_usleep (G_USEC_PER_SEC / 100);
508       if (got_event_before_q != NULL)
509         break;
510     }
511     fail_if (got_event_before_q == NULL,
512         "Expected event failed to appear upstream of the queue "
513         "within 5 seconds");
514     fail_unless (GST_EVENT_TYPE (got_event_before_q) == type);
515   } else {
516     /* Wait up to 10 seconds for the event to appear */
517     for (i = 0; i < 1000; i++) {
518       g_usleep (G_USEC_PER_SEC / 100);
519       if (got_event_after_q != NULL)
520         break;
521     }
522     fail_if (got_event_after_q == NULL,
523         "Expected event failed to appear after the queue within 10 seconds");
524     fail_unless (GST_EVENT_TYPE (got_event_after_q) == type);
525   }
526
527   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED);
528   gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL,
529       GST_CLOCK_TIME_NONE);
530
531   if (got_event_before_q)
532     gst_event_unref (got_event_before_q);
533   if (got_event_after_q)
534     gst_event_unref (got_event_after_q);
535
536   got_event_before_q = got_event_after_q = NULL;
537
538   signal_data_cleanup (&data);
539 }
540
541 static gint64
542 timediff (GTimeVal * end, GTimeVal * start)
543 {
544   return (end->tv_sec - start->tv_sec) * G_USEC_PER_SEC +
545       (end->tv_usec - start->tv_usec);
546 }
547
548 GST_START_TEST (send_custom_events)
549 {
550   /* Run some tests on custom events. Checking for serialisation and whatnot.
551    * pipeline is fakesrc ! queue ! fakesink */
552   GstBin *pipeline;
553   GstElement *fakesrc, *fakesink, *queue;
554   GstPad *srcpad, *sinkpad;
555
556   fail_if ((pipeline = (GstBin *) gst_pipeline_new ("testpipe")) == NULL);
557   fail_if ((fakesrc = gst_element_factory_make ("fakesrc", NULL)) == NULL);
558   fail_if ((fakesink = gst_element_factory_make ("fakesink", NULL)) == NULL);
559   fail_if ((queue = gst_element_factory_make ("queue", NULL)) == NULL);
560
561   gst_bin_add_many (pipeline, fakesrc, queue, fakesink, NULL);
562   fail_unless (gst_element_link_many (fakesrc, queue, fakesink, NULL));
563
564   g_object_set (G_OBJECT (fakesink), "sync", FALSE, NULL);
565
566   /* Send 100 buffers per sec */
567   g_object_set (G_OBJECT (fakesrc), "silent", TRUE, "datarate", 100,
568       "sizemax", 1, "sizetype", 2, NULL);
569   g_object_set (G_OBJECT (queue), "max-size-buffers", 0, "max-size-time",
570       (guint64) GST_SECOND, "max-size-bytes", 0, NULL);
571   g_object_set (G_OBJECT (fakesink), "silent", TRUE, "sync", TRUE, NULL);
572
573   /* add pad-probes to faksrc.src and fakesink.sink */
574   fail_if ((srcpad = gst_element_get_static_pad (fakesrc, "src")) == NULL);
575   gst_pad_add_probe (srcpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
576       event_probe, GINT_TO_POINTER (TRUE), NULL);
577
578   fail_if ((sinkpad = gst_element_get_static_pad (fakesink, "sink")) == NULL);
579   gst_pad_add_probe (sinkpad, GST_PAD_PROBE_TYPE_EVENT_BOTH,
580       event_probe, GINT_TO_POINTER (FALSE), NULL);
581
582   /* Upstream events */
583   test_event (pipeline, GST_EVENT_CUSTOM_UPSTREAM, sinkpad, TRUE, srcpad);
584   fail_unless (timediff (&got_event_time,
585           &sent_event_time) < G_USEC_PER_SEC / 2,
586       "GST_EVENT_CUSTOM_UP took too long to reach source: %"
587       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
588
589   test_event (pipeline, GST_EVENT_CUSTOM_BOTH, sinkpad, TRUE, srcpad);
590   fail_unless (timediff (&got_event_time,
591           &sent_event_time) < G_USEC_PER_SEC / 2,
592       "GST_EVENT_CUSTOM_BOTH took too long to reach source: %"
593       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
594
595   test_event (pipeline, GST_EVENT_CUSTOM_BOTH_OOB, sinkpad, TRUE, srcpad);
596   fail_unless (timediff (&got_event_time,
597           &sent_event_time) < G_USEC_PER_SEC / 2,
598       "GST_EVENT_CUSTOM_BOTH_OOB took too long to reach source: %"
599       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
600
601   /* Out of band downstream events */
602   test_event (pipeline, GST_EVENT_CUSTOM_DOWNSTREAM_OOB, srcpad, FALSE, srcpad);
603   fail_unless (timediff (&got_event_time,
604           &sent_event_time) < G_USEC_PER_SEC / 2,
605       "GST_EVENT_CUSTOM_DS_OOB took too long to reach source: %"
606       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
607
608   test_event (pipeline, GST_EVENT_CUSTOM_BOTH_OOB, srcpad, FALSE, srcpad);
609   fail_unless (timediff (&got_event_time,
610           &sent_event_time) < G_USEC_PER_SEC / 2,
611       "GST_EVENT_CUSTOM_BOTH_OOB took too long to reach source: %"
612       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
613
614   /* In-band downstream events are expected to take at least 1 second
615    * to traverse the queue */
616   test_event (pipeline, GST_EVENT_CUSTOM_DOWNSTREAM, srcpad, FALSE, srcpad);
617   fail_unless (timediff (&got_event_time,
618           &sent_event_time) >= G_USEC_PER_SEC / 2,
619       "GST_EVENT_CUSTOM_DS arrived too quickly for an in-band event: %"
620       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
621
622   test_event (pipeline, GST_EVENT_CUSTOM_BOTH, srcpad, FALSE, srcpad);
623   fail_unless (timediff (&got_event_time,
624           &sent_event_time) >= G_USEC_PER_SEC / 2,
625       "GST_EVENT_CUSTOM_BOTH arrived too quickly for an in-band event: %"
626       G_GINT64_FORMAT " us", timediff (&got_event_time, &sent_event_time));
627
628   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
629   gst_element_get_state (GST_ELEMENT (pipeline), NULL, NULL,
630       GST_CLOCK_TIME_NONE);
631
632   gst_object_unref (sinkpad);
633   gst_object_unref (srcpad);
634   gst_object_unref (pipeline);
635 }
636
637 GST_END_TEST;
638
639 static Suite *
640 gst_event_suite (void)
641 {
642   Suite *s = suite_create ("GstEvent");
643   TCase *tc_chain = tcase_create ("events");
644
645   tcase_set_timeout (tc_chain, 20);
646
647   suite_add_tcase (s, tc_chain);
648   tcase_add_test (tc_chain, create_events);
649   tcase_add_test (tc_chain, send_custom_events);
650   return s;
651 }
652
653 GST_CHECK_MAIN (gst_event);