Merge remote-tracking branch 'origin/master' into 0.11
[platform/upstream/gstreamer.git] / tests / check / elements / queue.c
1 /* GStreamer
2  *
3  * unit test for queue
4  *
5  * Copyright (C) <2006> Stefan Kost <ensonic@users.sf.net>
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #include <unistd.h>
24
25 #include <gst/check/gstcheck.h>
26
27 #define UNDERRUN_LOCK() (g_mutex_lock (underrun_mutex))
28 #define UNDERRUN_UNLOCK() (g_mutex_unlock (underrun_mutex))
29 #define UNDERRUN_SIGNAL() (g_cond_signal (underrun_cond))
30 #define UNDERRUN_WAIT() (g_cond_wait (underrun_cond, underrun_mutex))
31
32 static GstElement *queue;
33
34 /* For ease of programming we use globals to keep refs for our floating
35  * src and sink pads we create; otherwise we always have to do get_pad,
36  * get_peer, and then remove references in every test function */
37 static GstPad *mysrcpad;
38 static GstPad *mysinkpad;
39
40 static gint overrun_count;
41
42 static GMutex *underrun_mutex;
43 static GCond *underrun_cond;
44 static gint underrun_count;
45
46 static GList *events;
47
48 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
49     GST_PAD_SINK,
50     GST_PAD_ALWAYS,
51     GST_STATIC_CAPS_ANY);
52 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
53     GST_PAD_SRC,
54     GST_PAD_ALWAYS,
55     GST_STATIC_CAPS_ANY);
56
57 static void
58 queue_overrun (GstElement * queue, gpointer user_data)
59 {
60   GST_DEBUG ("queue overrun");
61   overrun_count++;
62 }
63
64 static void
65 queue_underrun (GstElement * queue, gpointer user_data)
66 {
67   GST_DEBUG ("queue underrun");
68   UNDERRUN_LOCK ();
69   underrun_count++;
70   UNDERRUN_SIGNAL ();
71   UNDERRUN_UNLOCK ();
72 }
73
74 static gboolean
75 event_func (GstPad * pad, GstObject * parent, GstEvent * event)
76 {
77   GST_DEBUG ("%s event", gst_event_type_get_name (GST_EVENT_TYPE (event)));
78   events = g_list_append (events, event);
79
80   return TRUE;
81 }
82
83 static void
84 drop_events (void)
85 {
86   while (events != NULL) {
87     gst_event_unref (GST_EVENT (events->data));
88     events = g_list_delete_link (events, events);
89   }
90 }
91
92 static void
93 setup (void)
94 {
95   GST_DEBUG ("setup_queue");
96
97   queue = gst_check_setup_element ("queue");
98   g_signal_connect (queue, "underrun", G_CALLBACK (queue_underrun), NULL);
99
100   mysrcpad = gst_check_setup_src_pad (queue, &srctemplate);
101   gst_pad_set_active (mysrcpad, TRUE);
102
103   mysinkpad = NULL;
104
105   overrun_count = 0;
106
107   underrun_mutex = g_mutex_new ();
108   underrun_cond = g_cond_new ();
109   underrun_count = 0;
110
111   events = NULL;
112 }
113
114 static void
115 cleanup (void)
116 {
117   GST_DEBUG ("cleanup_queue");
118
119   gst_check_drop_buffers ();
120
121   drop_events ();
122
123   g_cond_free (underrun_cond);
124   underrun_cond = NULL;
125   g_mutex_free (underrun_mutex);
126   underrun_mutex = NULL;
127
128   if (mysinkpad != NULL) {
129     gst_pad_set_active (mysinkpad, FALSE);
130     gst_check_teardown_sink_pad (queue);
131   }
132
133   gst_pad_set_active (mysrcpad, FALSE);
134   gst_check_teardown_src_pad (queue);
135
136   gst_check_teardown_element (queue);
137   queue = NULL;
138 }
139
140 /* setup the sinkpad on a playing queue element. gst_check_setup_sink_pad()
141  * does not work in this case since it does not activate the pad before linking
142  * it. */
143 static GstPad *
144 setup_sink_pad (GstElement * element, GstStaticPadTemplate * tmpl)
145 {
146   GstPad *srcpad;
147   GstPad *sinkpad;
148
149   sinkpad = gst_pad_new_from_static_template (tmpl, "sink");
150   fail_if (sinkpad == NULL);
151   srcpad = gst_element_get_static_pad (element, "src");
152   fail_if (srcpad == NULL);
153   gst_pad_set_chain_function (sinkpad, gst_check_chain_func);
154   gst_pad_set_event_function (sinkpad, event_func);
155   gst_pad_set_active (sinkpad, TRUE);
156   fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
157   gst_object_unref (srcpad);
158
159   return sinkpad;
160 }
161
162 /* set queue size to 2 buffers
163  * pull 1 buffer
164  * check over/underuns
165  */
166 GST_START_TEST (test_non_leaky_underrun)
167 {
168   g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
169   g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
170   mysinkpad = gst_check_setup_sink_pad (queue, &sinktemplate);
171   gst_pad_set_active (mysinkpad, TRUE);
172
173   GST_DEBUG ("starting");
174
175   UNDERRUN_LOCK ();
176   fail_unless (gst_element_set_state (queue,
177           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
178       "could not set to playing");
179   UNDERRUN_WAIT ();
180   UNDERRUN_UNLOCK ();
181
182   fail_unless (overrun_count == 0);
183   fail_unless (underrun_count == 1);
184
185   GST_DEBUG ("stopping");
186   fail_unless (gst_element_set_state (queue,
187           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
188 }
189
190 GST_END_TEST;
191
192 static void
193 queue_overrun_link_and_activate (GstElement * queue, gpointer user_data)
194 {
195   GST_DEBUG ("queue overrun");
196   overrun_count++;
197
198   /* link the src pad of the queue to make it dequeue buffers */
199   mysinkpad = setup_sink_pad (queue, &sinktemplate);
200 }
201
202 /* set queue size to 2 buffers
203  * push 2 buffers
204  * check over/underuns
205  * push 1 more buffer
206  * check over/underuns again
207  */
208 GST_START_TEST (test_non_leaky_overrun)
209 {
210   GstBuffer *buffer1;
211   GstBuffer *buffer2;
212   GstBuffer *buffer3;
213   GstBuffer *buffer;
214
215   g_signal_connect (queue, "overrun",
216       G_CALLBACK (queue_overrun_link_and_activate), NULL);
217   g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
218
219   GST_DEBUG ("starting");
220
221   fail_unless (gst_element_set_state (queue,
222           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
223       "could not set to playing");
224   fail_unless (overrun_count == 0);
225   fail_unless (underrun_count == 0);
226
227   buffer1 = gst_buffer_new_and_alloc (4);
228   /* pushing gives away my reference */
229   gst_pad_push (mysrcpad, buffer1);
230
231   GST_DEBUG ("added 1st");
232   fail_unless (overrun_count == 0);
233   fail_unless (underrun_count == 0);
234
235   buffer2 = gst_buffer_new_and_alloc (4);
236   gst_pad_push (mysrcpad, buffer2);
237
238   GST_DEBUG ("added 2nd");
239   fail_unless (overrun_count == 0);
240   fail_unless (underrun_count == 0);
241
242   buffer3 = gst_buffer_new_and_alloc (4);
243   /* lock the check_mutex to block the first buffer pushed to mysinkpad */
244   g_mutex_lock (check_mutex);
245   /* the next call to gst_pad_push will emit the overrun signal. The signal
246    * handler queue_overrun_link_and_activate() (above) increases overrun_count,
247    * activates and links mysinkpad. The queue task then dequeues a buffer and
248    * gst_pad_push() will return. */
249   gst_pad_push (mysrcpad, buffer3);
250
251   GST_DEBUG ("added 3rd");
252   fail_unless (overrun_count == 1);
253   fail_unless (underrun_count == 0);
254
255   /* now let the queue push all buffers */
256   while (g_list_length (buffers) < 3) {
257     g_cond_wait (check_cond, check_mutex);
258   }
259   g_mutex_unlock (check_mutex);
260
261   fail_unless (overrun_count == 1);
262   /* make sure we get the underrun signal before we check underrun_count */
263   UNDERRUN_LOCK ();
264   while (underrun_count < 1) {
265     UNDERRUN_WAIT ();
266   }
267   UNDERRUN_UNLOCK ();
268   fail_unless (underrun_count == 1);
269
270   buffer = g_list_nth (buffers, 0)->data;
271   fail_unless (buffer == buffer1);
272
273   buffer = g_list_nth (buffers, 1)->data;
274   fail_unless (buffer == buffer2);
275
276   buffer = g_list_nth (buffers, 2)->data;
277   fail_unless (buffer == buffer3);
278
279   GST_DEBUG ("stopping");
280   fail_unless (gst_element_set_state (queue,
281           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
282 }
283
284 GST_END_TEST;
285
286 /* set queue size to 2 buffers
287  * push 2 buffers
288  * check over/underuns
289  * push 1 more buffer
290  * check over/underuns again
291  * check which buffer was leaked
292  */
293 GST_START_TEST (test_leaky_upstream)
294 {
295   GstBuffer *buffer1;
296   GstBuffer *buffer2;
297   GstBuffer *buffer3;
298   GstBuffer *buffer;
299
300   g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
301   g_object_set (G_OBJECT (queue), "max-size-buffers", 2, "leaky", 1, NULL);
302
303   GST_DEBUG ("starting");
304
305   fail_unless (gst_element_set_state (queue,
306           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
307       "could not set to playing");
308   fail_unless (overrun_count == 0);
309   fail_unless (underrun_count == 0);
310
311   buffer1 = gst_buffer_new_and_alloc (4);
312   /* pushing gives away my reference */
313   gst_pad_push (mysrcpad, buffer1);
314
315   GST_DEBUG ("added 1st");
316   fail_unless (overrun_count == 0);
317   fail_unless (underrun_count == 0);
318
319   buffer2 = gst_buffer_new_and_alloc (4);
320   gst_pad_push (mysrcpad, buffer2);
321
322   GST_DEBUG ("added 2nd");
323   fail_unless (overrun_count == 0);
324   fail_unless (underrun_count == 0);
325
326   buffer3 = gst_buffer_new_and_alloc (4);
327   /* buffer3 will be leaked, keep a ref so refcount can be checked below */
328   gst_buffer_ref (buffer3);
329   gst_pad_push (mysrcpad, buffer3);
330
331   GST_DEBUG ("added 3rd");
332   /* it still triggers overrun when leaking */
333   fail_unless (overrun_count == 1);
334   fail_unless (underrun_count == 0);
335
336   /* wait for underrun and check that we got buffer1 and buffer2 only */
337   UNDERRUN_LOCK ();
338   mysinkpad = setup_sink_pad (queue, &sinktemplate);
339   UNDERRUN_WAIT ();
340   UNDERRUN_UNLOCK ();
341
342   fail_unless (overrun_count == 1);
343   fail_unless (underrun_count == 1);
344
345   fail_unless (g_list_length (buffers) == 2);
346
347   buffer = g_list_nth (buffers, 0)->data;
348   fail_unless (buffer == buffer1);
349
350   buffer = g_list_nth (buffers, 1)->data;
351   fail_unless (buffer == buffer2);
352
353   ASSERT_BUFFER_REFCOUNT (buffer3, "buffer", 1);
354   gst_buffer_unref (buffer3);
355
356   GST_DEBUG ("stopping");
357   fail_unless (gst_element_set_state (queue,
358           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
359 }
360
361 GST_END_TEST;
362
363 /* set queue size to 2 buffers
364  * push 2 buffers
365  * check over/underuns
366  * push 1 more buffer
367  * check over/underuns again
368  * check which buffer was leaked
369  */
370 GST_START_TEST (test_leaky_downstream)
371 {
372   GstBuffer *buffer1;
373   GstBuffer *buffer2;
374   GstBuffer *buffer3;
375   GstBuffer *buffer;
376
377   g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
378   g_object_set (G_OBJECT (queue), "max-size-buffers", 2, "leaky", 2, NULL);
379
380   GST_DEBUG ("starting");
381
382   fail_unless (gst_element_set_state (queue,
383           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
384       "could not set to playing");
385   fail_unless (overrun_count == 0);
386   fail_unless (underrun_count == 0);
387
388   buffer1 = gst_buffer_new_and_alloc (4);
389   /* buffer1 will be leaked, keep a ref so refcount can be checked below */
390   gst_buffer_ref (buffer1);
391   /* pushing gives away one reference */
392   gst_pad_push (mysrcpad, buffer1);
393
394   GST_DEBUG ("added 1st");
395   fail_unless (overrun_count == 0);
396   fail_unless (underrun_count == 0);
397
398   buffer2 = gst_buffer_new_and_alloc (4);
399   gst_pad_push (mysrcpad, buffer2);
400
401   GST_DEBUG ("added 2nd");
402   fail_unless (overrun_count == 0);
403   fail_unless (underrun_count == 0);
404
405   buffer3 = gst_buffer_new_and_alloc (4);
406   gst_pad_push (mysrcpad, buffer3);
407
408   GST_DEBUG ("added 3rd");
409   /* it still triggers overrun when leaking */
410   fail_unless (overrun_count == 1);
411   fail_unless (underrun_count == 0);
412
413   /* wait for underrun and check that we got buffer1 and buffer2 only */
414   UNDERRUN_LOCK ();
415   mysinkpad = setup_sink_pad (queue, &sinktemplate);
416   UNDERRUN_WAIT ();
417   UNDERRUN_UNLOCK ();
418
419   fail_unless (overrun_count == 1);
420   fail_unless (underrun_count == 1);
421
422   fail_unless (g_list_length (buffers) == 2);
423
424   ASSERT_BUFFER_REFCOUNT (buffer1, "buffer", 1);
425   gst_buffer_unref (buffer1);
426
427   buffer = g_list_nth (buffers, 0)->data;
428   fail_unless (buffer == buffer2);
429
430   buffer = g_list_nth (buffers, 1)->data;
431   fail_unless (buffer == buffer3);
432
433   GST_DEBUG ("stopping");
434   fail_unless (gst_element_set_state (queue,
435           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
436 }
437
438 GST_END_TEST;
439
440 /* set queue size to 6 buffers and 7 seconds
441  * push 7 buffers with and without duration
442  * check current-level-time
443  */
444 GST_START_TEST (test_time_level)
445 {
446   GstBuffer *buffer = NULL;
447   GstClockTime time;
448
449   g_signal_connect (queue, "overrun",
450       G_CALLBACK (queue_overrun_link_and_activate), NULL);
451   g_object_set (G_OBJECT (queue), "max-size-buffers", 6, NULL);
452   g_object_set (G_OBJECT (queue), "max-size-time", 7 * GST_SECOND, NULL);
453
454   GST_DEBUG ("starting");
455
456   fail_unless (gst_element_set_state (queue,
457           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
458       "could not set to playing");
459
460   /* push buffer without duration */
461   buffer = gst_buffer_new_and_alloc (4);
462   GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND;
463   /* pushing gives away my reference */
464   gst_pad_push (mysrcpad, buffer);
465
466   /* level should be 1 seconds because buffer has no duration and starts at 1
467    * SECOND (sparse stream). */
468   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
469   fail_if (time != GST_SECOND);
470
471   /* second push should set the level to 2 second */
472   buffer = gst_buffer_new_and_alloc (4);
473   GST_BUFFER_TIMESTAMP (buffer) = 2 * GST_SECOND;
474   gst_pad_push (mysrcpad, buffer);
475
476   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
477   fail_if (time != 2 * GST_SECOND);
478
479   /* third push should set the level to 4 seconds, the 1 second diff with the
480    * previous buffer (without duration) and the 1 second duration of this
481    * buffer. */
482   buffer = gst_buffer_new_and_alloc (4);
483   GST_BUFFER_TIMESTAMP (buffer) = 3 * GST_SECOND;
484   GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
485   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
486   gst_pad_push (mysrcpad, buffer);
487
488   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
489   fail_if (time != 4 * GST_SECOND);
490
491   /* fourth push should set the level to 6 seconds, the 2 second diff with the
492    * previous buffer, same duration. */
493   buffer = gst_buffer_new_and_alloc (4);
494   GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
495   GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
496   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
497   gst_pad_push (mysrcpad, buffer);
498
499   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
500   fail_if (time != 6 * GST_SECOND);
501
502   /* fifth push should not adjust the level, the timestamp and duration are the
503    * same, meaning the previous buffer did not really have a duration. */
504   buffer = gst_buffer_new_and_alloc (4);
505   GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
506   GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
507   gst_pad_push (mysrcpad, buffer);
508
509   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
510   fail_if (time != 6 * GST_SECOND);
511
512   /* sixth push should adjust the level with 1 second, we now know the
513    * previous buffer actually had a duration of 2 SECONDS */
514   buffer = gst_buffer_new_and_alloc (4);
515   GST_BUFFER_TIMESTAMP (buffer) = 7 * GST_SECOND;
516   gst_pad_push (mysrcpad, buffer);
517
518   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
519   fail_if (time != 7 * GST_SECOND);
520
521   /* eighth push should cause overrun */
522   fail_unless (overrun_count == 0);
523   buffer = gst_buffer_new_and_alloc (4);
524   GST_BUFFER_TIMESTAMP (buffer) = 8 * GST_SECOND;
525   /* the next call to gst_pad_push will emit the overrun signal. The signal
526    * handler queue_overrun_link_and_activate() (above) increases overrun_count,
527    * activates and links mysinkpad. The queue task then dequeues a buffer and
528    * gst_pad_push() will return. */
529   gst_pad_push (mysrcpad, buffer);
530
531   fail_unless (overrun_count == 1);
532
533   GST_DEBUG ("stopping");
534   fail_unless (gst_element_set_state (queue,
535           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
536 }
537
538 GST_END_TEST;
539
540 GST_START_TEST (test_time_level_task_not_started)
541 {
542   GstEvent *event;
543   GstClockTime time;
544   GstSegment segment;
545
546   GST_DEBUG ("starting");
547
548   fail_unless (gst_element_set_state (queue,
549           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
550       "could not set to playing");
551
552   gst_segment_init (&segment, GST_FORMAT_TIME);
553   segment.start = 1 * GST_SECOND;
554   segment.stop = 5 * GST_SECOND;
555   segment.time = 0;
556   segment.position = 1 * GST_SECOND;
557
558   event = gst_event_new_segment (&segment);
559   gst_pad_push_event (mysrcpad, event);
560
561   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
562   fail_if (time != 0 * GST_SECOND);
563
564   segment.base = 4 * GST_SECOND;
565   event = gst_event_new_segment (&segment);
566   gst_pad_push_event (mysrcpad, event);
567
568   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
569   GST_DEBUG ("time now %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
570   fail_if (time != 4 * GST_SECOND);
571
572   GST_DEBUG ("stopping");
573   fail_unless (gst_element_set_state (queue,
574           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
575 }
576
577 GST_END_TEST;
578
579 #if 0
580 static gboolean
581 event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
582     GstFormat format, gint64 start, gint64 stop, gint64 position)
583 {
584   gboolean ns_update;
585   gdouble ns_rate, ns_arate;
586   GstFormat ns_format;
587   gint64 ns_start;
588   gint64 ns_stop;
589   gint64 ns_position;
590
591   if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT) {
592     return FALSE;
593   }
594
595   gst_event_parse_new_segment (event, &ns_update, &ns_rate, &ns_arate,
596       &ns_format, &ns_start, &ns_stop, &ns_position);
597
598   GST_DEBUG ("update %d, rate %lf, format %s, start %" GST_TIME_FORMAT
599       ", stop %" GST_TIME_FORMAT ", position %" GST_TIME_FORMAT, ns_update,
600       ns_rate, gst_format_get_name (ns_format), GST_TIME_ARGS (ns_start),
601       GST_TIME_ARGS (ns_stop), GST_TIME_ARGS (ns_position));
602
603   return (ns_update == update && ns_rate == rate && ns_format == format &&
604       ns_start == start && ns_stop == stop && ns_position == position);
605 }
606
607 GST_START_TEST (test_newsegment)
608 {
609   GstEvent *event;
610   GstBuffer *buffer1;
611   GstBuffer *buffer2;
612   GstBuffer *buffer;
613
614   g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
615   g_object_set (G_OBJECT (queue), "max-size-buffers", 1, "max-size-time",
616       (guint64) 0, "leaky", 2, NULL);
617
618   GST_DEBUG ("starting");
619
620   fail_unless (gst_element_set_state (queue,
621           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
622       "could not set to playing");
623   fail_unless (overrun_count == 0);
624   fail_unless (underrun_count == 0);
625
626   event = gst_event_new_new_segment (FALSE, 2.0, 1.0, GST_FORMAT_TIME, 0,
627       2 * GST_SECOND, 0);
628   gst_pad_push_event (mysrcpad, event);
629
630   GST_DEBUG ("added 1st newsegment");
631   fail_unless (overrun_count == 0);
632   fail_unless (underrun_count == 0);
633
634   event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0,
635       3 * GST_SECOND, 0);
636   gst_pad_push_event (mysrcpad, event);
637
638   GST_DEBUG ("added 2nd newsegment");
639   fail_unless (overrun_count == 0);
640   fail_unless (underrun_count == 0);
641
642   event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
643       4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND);
644   gst_pad_push_event (mysrcpad, event);
645
646   GST_DEBUG ("added 3rd newsegment");
647   fail_unless (overrun_count == 0);
648   fail_unless (underrun_count == 0);
649
650   buffer1 = gst_buffer_new_and_alloc (4);
651   /* buffer1 will be leaked, keep a ref so refcount can be checked below */
652   gst_buffer_ref (buffer1);
653   /* pushing gives away one reference */
654   gst_pad_push (mysrcpad, buffer1);
655
656   GST_DEBUG ("added 1st buffer");
657   fail_unless (overrun_count == 0);
658   fail_unless (underrun_count == 0);
659
660   buffer2 = gst_buffer_new_and_alloc (4);
661   /* next push will cause overrun and leak all newsegment events and buffer1 */
662   gst_pad_push (mysrcpad, buffer2);
663
664   GST_DEBUG ("added 2nd buffer");
665   /* it still triggers overrun when leaking */
666   fail_unless (overrun_count == 1);
667   fail_unless (underrun_count == 0);
668
669   /* wait for underrun and check that we got one accumulated newsegment event,
670    * one real newsegment event and buffer2 only */
671   UNDERRUN_LOCK ();
672   mysinkpad = setup_sink_pad (queue, &sinktemplate);
673   UNDERRUN_WAIT ();
674   UNDERRUN_UNLOCK ();
675
676   fail_unless (overrun_count == 1);
677   fail_unless (underrun_count == 1);
678
679   fail_unless (g_list_length (events) == 2);
680
681   event = g_list_nth (events, 0)->data;
682   fail_unless (event_equals_newsegment (event, FALSE, 1.0, GST_FORMAT_TIME, 0,
683           4 * GST_SECOND, 0));
684
685   event = g_list_nth (events, 1)->data;
686   fail_unless (event_equals_newsegment (event, FALSE, 1.0, GST_FORMAT_TIME,
687           4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND));
688
689   fail_unless (g_list_length (buffers) == 1);
690
691   ASSERT_BUFFER_REFCOUNT (buffer1, "buffer", 1);
692   gst_buffer_unref (buffer1);
693
694   buffer = g_list_nth (buffers, 0)->data;
695   fail_unless (buffer == buffer2);
696
697   GST_DEBUG ("stopping");
698   fail_unless (gst_element_set_state (queue,
699           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
700 }
701
702 GST_END_TEST;
703 #endif
704
705 static Suite *
706 queue_suite (void)
707 {
708   Suite *s = suite_create ("queue");
709   TCase *tc_chain = tcase_create ("general");
710
711   suite_add_tcase (s, tc_chain);
712   tcase_add_checked_fixture (tc_chain, setup, cleanup);
713   tcase_add_test (tc_chain, test_non_leaky_underrun);
714   tcase_add_test (tc_chain, test_non_leaky_overrun);
715   tcase_add_test (tc_chain, test_leaky_upstream);
716   tcase_add_test (tc_chain, test_leaky_downstream);
717   tcase_add_test (tc_chain, test_time_level);
718   tcase_add_test (tc_chain, test_time_level_task_not_started);
719 #if 0
720   tcase_add_test (tc_chain, test_newsegment);
721 #endif
722
723   return s;
724 }
725
726 GST_CHECK_MAIN (queue);