5 * Copyright (C) <2006> Stefan Kost <ensonic@users.sf.net>
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.
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.
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., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
25 #include <gst/check/gstcheck.h>
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))
32 static GstElement *queue;
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 static GstPad *qsrcpad;
40 static gulong probe_id;
42 static gint overrun_count;
44 static GMutex underrun_mutex;
45 static GCond underrun_cond;
46 static gint underrun_count;
50 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
54 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
60 queue_overrun (GstElement * queue, gpointer user_data)
63 GST_DEBUG ("queue overrun %d", overrun_count);
67 queue_underrun (GstElement * queue, gpointer user_data)
71 GST_DEBUG ("queue underrun %d", underrun_count);
77 event_func (GstPad * pad, GstObject * parent, GstEvent * event)
79 GST_DEBUG ("%s event", gst_event_type_get_name (GST_EVENT_TYPE (event)));
80 events = g_list_append (events, event);
88 while (events != NULL) {
89 gst_event_unref (GST_EVENT (events->data));
90 events = g_list_delete_link (events, events);
97 qsrcpad = gst_element_get_static_pad (queue, "src");
98 probe_id = gst_pad_add_probe (qsrcpad, GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM,
105 gst_pad_remove_probe (qsrcpad, probe_id);
106 gst_object_unref (qsrcpad);
112 GST_DEBUG ("setup_queue");
114 queue = gst_check_setup_element ("queue");
115 g_signal_connect (queue, "underrun", G_CALLBACK (queue_underrun), NULL);
117 mysrcpad = gst_check_setup_src_pad (queue, &srctemplate);
118 gst_pad_set_active (mysrcpad, TRUE);
132 GST_DEBUG ("cleanup_queue");
134 gst_check_drop_buffers ();
138 if (mysinkpad != NULL) {
139 gst_pad_set_active (mysinkpad, FALSE);
140 gst_check_teardown_sink_pad (queue);
143 gst_pad_set_active (mysrcpad, FALSE);
144 gst_check_teardown_src_pad (queue);
146 gst_check_teardown_element (queue);
150 /* setup the sinkpad on a playing queue element. gst_check_setup_sink_pad()
151 * does not work in this case since it does not activate the pad before linking
154 setup_sink_pad (GstElement * element, GstStaticPadTemplate * tmpl)
159 sinkpad = gst_pad_new_from_static_template (tmpl, "sink");
160 fail_if (sinkpad == NULL);
161 srcpad = gst_element_get_static_pad (element, "src");
162 fail_if (srcpad == NULL);
163 gst_pad_set_chain_function (sinkpad, gst_check_chain_func);
164 gst_pad_set_event_function (sinkpad, event_func);
165 gst_pad_set_active (sinkpad, TRUE);
166 fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK);
167 gst_object_unref (srcpad);
172 /* set queue size to 2 buffers
174 * check over/underuns
176 GST_START_TEST (test_non_leaky_underrun)
178 g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
179 g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
180 mysinkpad = gst_check_setup_sink_pad (queue, &sinktemplate);
181 gst_pad_set_active (mysinkpad, TRUE);
183 GST_DEBUG ("starting");
186 fail_unless (gst_element_set_state (queue,
187 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
188 "could not set to playing");
192 fail_unless (overrun_count == 0);
193 fail_unless (underrun_count == 1);
195 GST_DEBUG ("stopping");
196 fail_unless (gst_element_set_state (queue,
197 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
203 queue_overrun_link_and_activate (GstElement * queue, gpointer user_data)
205 GST_DEBUG ("queue overrun");
208 /* link the src pad of the queue to make it dequeue buffers */
209 mysinkpad = setup_sink_pad (queue, &sinktemplate);
214 /* set queue size to 2 buffers
216 * check over/underuns
218 * check over/underuns again
220 GST_START_TEST (test_non_leaky_overrun)
228 g_signal_connect (queue, "overrun",
229 G_CALLBACK (queue_overrun_link_and_activate), NULL);
230 g_object_set (G_OBJECT (queue), "max-size-buffers", 2, NULL);
234 GST_DEBUG ("starting");
237 fail_unless (gst_element_set_state (queue,
238 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
239 "could not set to playing");
243 gst_segment_init (&segment, GST_FORMAT_BYTES);
244 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
245 gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));
247 fail_unless (underrun_count == 1);
248 fail_unless (overrun_count == 0);
250 buffer1 = gst_buffer_new_and_alloc (4);
251 /* pushing gives away my reference */
252 gst_pad_push (mysrcpad, buffer1);
254 GST_DEBUG ("added 1st");
255 fail_unless (overrun_count == 0);
256 fail_unless (underrun_count == 1);
258 buffer2 = gst_buffer_new_and_alloc (4);
259 gst_pad_push (mysrcpad, buffer2);
261 GST_DEBUG ("added 2nd");
262 fail_unless (overrun_count == 0);
263 fail_unless (underrun_count == 1);
265 buffer3 = gst_buffer_new_and_alloc (4);
266 /* the next call to gst_pad_push will emit the overrun signal. The signal
267 * handler queue_overrun_link_and_activate() (above) increases overrun_count,
268 * activates and links mysinkpad. The queue task then dequeues a buffer and
269 * gst_pad_push() will return. */
270 gst_pad_push (mysrcpad, buffer3);
272 GST_DEBUG ("added 3rd");
273 fail_unless (overrun_count == 1);
275 /* lock the check_mutex to block the first buffer pushed to mysinkpad */
276 g_mutex_lock (&check_mutex);
277 /* now let the queue push all buffers */
278 while (g_list_length (buffers) < 3) {
279 g_cond_wait (&check_cond, &check_mutex);
281 g_mutex_unlock (&check_mutex);
283 fail_unless (overrun_count == 1);
284 /* make sure we get the underrun signal before we check underrun_count */
286 while (underrun_count < 2) {
289 /* we can't check the underrun_count here safely because when adding the 3rd
290 * buffer, the queue lock is released to emit the overrun signal and the
291 * downstream part can then push and empty the queue and signal an additional
293 /* fail_unless_equals_int (underrun_count, 2); */
296 buffer = g_list_nth (buffers, 0)->data;
297 fail_unless (buffer == buffer1);
299 buffer = g_list_nth (buffers, 1)->data;
300 fail_unless (buffer == buffer2);
302 GST_DEBUG ("stopping");
303 fail_unless (gst_element_set_state (queue,
304 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
309 /* set queue size to 2 buffers
311 * check over/underuns
313 * check over/underuns again
314 * check which buffer was leaked
316 GST_START_TEST (test_leaky_upstream)
324 g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
325 g_object_set (G_OBJECT (queue), "max-size-buffers", 2, "leaky", 1, NULL);
327 GST_DEBUG ("starting");
332 fail_unless (gst_element_set_state (queue,
333 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
334 "could not set to playing");
338 gst_segment_init (&segment, GST_FORMAT_BYTES);
339 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
340 gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));
342 fail_unless (overrun_count == 0);
343 fail_unless (underrun_count == 1);
345 buffer1 = gst_buffer_new_and_alloc (4);
346 /* pushing gives away my reference */
347 gst_pad_push (mysrcpad, buffer1);
349 GST_DEBUG ("added 1st");
350 fail_unless (overrun_count == 0);
351 fail_unless (underrun_count == 1);
353 buffer2 = gst_buffer_new_and_alloc (4);
354 gst_pad_push (mysrcpad, buffer2);
356 GST_DEBUG ("added 2nd");
357 fail_unless (overrun_count == 0);
358 fail_unless (underrun_count == 1);
360 buffer3 = gst_buffer_new_and_alloc (4);
361 /* buffer4 will be leaked, keep a ref so refcount can be checked below */
362 gst_buffer_ref (buffer3);
363 gst_pad_push (mysrcpad, buffer3);
365 GST_DEBUG ("added 3nd");
366 /* it still triggers overrun when leaking */
367 fail_unless (overrun_count == 1);
368 fail_unless (underrun_count == 1);
370 /* wait for underrun and check that we got buffer1 and buffer2 only */
372 mysinkpad = setup_sink_pad (queue, &sinktemplate);
377 fail_unless (overrun_count == 1);
378 fail_unless (underrun_count == 2);
380 fail_unless (g_list_length (buffers) == 2);
382 buffer = g_list_nth (buffers, 0)->data;
383 fail_unless (buffer == buffer1);
385 buffer = g_list_nth (buffers, 1)->data;
386 fail_unless (buffer == buffer2);
388 ASSERT_BUFFER_REFCOUNT (buffer3, "buffer", 1);
389 gst_buffer_unref (buffer3);
391 GST_DEBUG ("stopping");
392 fail_unless (gst_element_set_state (queue,
393 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
398 /* set queue size to 2 buffers
400 * check over/underuns
402 * check over/underuns again
403 * check which buffer was leaked
405 GST_START_TEST (test_leaky_downstream)
413 g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
414 g_object_set (G_OBJECT (queue), "max-size-buffers", 2, "leaky", 2, NULL);
416 GST_DEBUG ("starting");
421 fail_unless (gst_element_set_state (queue,
422 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
423 "could not set to playing");
427 gst_segment_init (&segment, GST_FORMAT_BYTES);
428 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
429 gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));
431 fail_unless (overrun_count == 0);
432 fail_unless (underrun_count == 1);
434 buffer1 = gst_buffer_new_and_alloc (4);
435 /* pushing gives away one reference */
436 /* buffer1 will be leaked, keep a ref so refcount can be checked below */
437 gst_buffer_ref (buffer1);
438 gst_pad_push (mysrcpad, buffer1);
440 GST_DEBUG ("added 1st");
441 fail_unless (overrun_count == 0);
442 fail_unless (underrun_count == 1);
444 buffer2 = gst_buffer_new_and_alloc (4);
445 gst_pad_push (mysrcpad, buffer2);
447 GST_DEBUG ("added 2nd");
448 fail_unless (overrun_count == 0);
449 fail_unless (underrun_count == 1);
451 buffer3 = gst_buffer_new_and_alloc (4);
452 gst_pad_push (mysrcpad, buffer3);
454 GST_DEBUG ("added 3rd");
455 /* it still triggers overrun when leaking */
456 fail_unless (overrun_count == 1);
457 fail_unless (underrun_count == 1);
459 /* wait for underrun and check that we got buffer1 and buffer2 only */
461 mysinkpad = setup_sink_pad (queue, &sinktemplate);
466 fail_unless (overrun_count == 1);
467 fail_unless (underrun_count == 2);
469 fail_unless (g_list_length (buffers) == 2);
471 ASSERT_BUFFER_REFCOUNT (buffer1, "buffer", 1);
472 gst_buffer_unref (buffer1);
474 buffer = g_list_nth (buffers, 0)->data;
475 fail_unless (buffer == buffer2);
477 buffer = g_list_nth (buffers, 1)->data;
478 fail_unless (buffer == buffer3);
480 GST_DEBUG ("stopping");
481 fail_unless (gst_element_set_state (queue,
482 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
487 /* set queue size to 6 buffers and 7 seconds
488 * push 7 buffers with and without duration
489 * check current-level-time
491 GST_START_TEST (test_time_level)
493 GstBuffer *buffer = NULL;
497 g_signal_connect (queue, "overrun",
498 G_CALLBACK (queue_overrun_link_and_activate), NULL);
499 g_object_set (G_OBJECT (queue), "max-size-buffers", 6, NULL);
500 g_object_set (G_OBJECT (queue), "max-size-time", 7 * GST_SECOND, NULL);
502 GST_DEBUG ("starting");
507 fail_unless (gst_element_set_state (queue,
508 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
509 "could not set to playing");
513 gst_segment_init (&segment, GST_FORMAT_BYTES);
514 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
515 gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment));
517 /* push buffer without duration */
518 buffer = gst_buffer_new_and_alloc (4);
519 GST_BUFFER_TIMESTAMP (buffer) = GST_SECOND;
520 /* pushing gives away my reference */
521 gst_pad_push (mysrcpad, buffer);
523 /* level should be 1 seconds because buffer has no duration and starts at 1
524 * SECOND (sparse stream). */
525 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
526 fail_if (time != GST_SECOND);
528 /* second push should set the level to 2 second */
529 buffer = gst_buffer_new_and_alloc (4);
530 GST_BUFFER_TIMESTAMP (buffer) = 2 * GST_SECOND;
531 gst_pad_push (mysrcpad, buffer);
533 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
534 fail_if (time != 2 * GST_SECOND);
536 /* third push should set the level to 4 seconds, the 1 second diff with the
537 * previous buffer (without duration) and the 1 second duration of this
539 buffer = gst_buffer_new_and_alloc (4);
540 GST_BUFFER_TIMESTAMP (buffer) = 3 * GST_SECOND;
541 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
542 ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
543 gst_pad_push (mysrcpad, buffer);
545 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
546 fail_if (time != 4 * GST_SECOND);
548 /* fourth push should set the level to 6 seconds, the 2 second diff with the
549 * previous buffer, same duration. */
550 buffer = gst_buffer_new_and_alloc (4);
551 GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
552 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
553 ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
554 gst_pad_push (mysrcpad, buffer);
556 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
557 fail_if (time != 6 * GST_SECOND);
559 /* fifth push should not adjust the level, the timestamp and duration are the
560 * same, meaning the previous buffer did not really have a duration. */
561 buffer = gst_buffer_new_and_alloc (4);
562 GST_BUFFER_TIMESTAMP (buffer) = 5 * GST_SECOND;
563 GST_BUFFER_DURATION (buffer) = 1 * GST_SECOND;
564 gst_pad_push (mysrcpad, buffer);
566 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
567 fail_if (time != 6 * GST_SECOND);
569 /* sixth push should adjust the level with 1 second, we now know the
570 * previous buffer actually had a duration of 2 SECONDS */
571 buffer = gst_buffer_new_and_alloc (4);
572 GST_BUFFER_TIMESTAMP (buffer) = 7 * GST_SECOND;
573 gst_pad_push (mysrcpad, buffer);
575 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
576 fail_if (time != 7 * GST_SECOND);
578 /* eighth push should cause overrun */
579 fail_unless (overrun_count == 0);
580 buffer = gst_buffer_new_and_alloc (4);
581 GST_BUFFER_TIMESTAMP (buffer) = 8 * GST_SECOND;
582 /* the next call to gst_pad_push will emit the overrun signal. The signal
583 * handler queue_overrun_link_and_activate() (above) increases overrun_count,
584 * activates and links mysinkpad. The queue task then dequeues a buffer and
585 * gst_pad_push() will return. */
586 gst_pad_push (mysrcpad, buffer);
588 fail_unless (overrun_count == 1);
590 GST_DEBUG ("stopping");
591 fail_unless (gst_element_set_state (queue,
592 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
597 GST_START_TEST (test_time_level_task_not_started)
603 GST_DEBUG ("starting");
608 fail_unless (gst_element_set_state (queue,
609 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
610 "could not set to playing");
614 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
616 gst_segment_init (&segment, GST_FORMAT_TIME);
617 segment.start = 1 * GST_SECOND;
618 segment.stop = 5 * GST_SECOND;
620 segment.position = 1 * GST_SECOND;
622 event = gst_event_new_segment (&segment);
623 gst_pad_push_event (mysrcpad, event);
625 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
626 fail_if (time != 0 * GST_SECOND);
628 segment.base = 4 * GST_SECOND;
629 event = gst_event_new_segment (&segment);
630 gst_pad_push_event (mysrcpad, event);
632 g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
633 GST_DEBUG ("time now %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
634 fail_if (time != 4 * GST_SECOND);
638 GST_DEBUG ("stopping");
639 fail_unless (gst_element_set_state (queue,
640 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
645 GST_START_TEST (test_sticky_not_linked)
650 GstFlowReturn flow_ret;
652 GST_DEBUG ("starting");
654 g_object_set (queue, "max-size-buffers", 1, NULL);
657 fail_unless (gst_element_set_state (queue,
658 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
659 "could not set to playing");
663 gst_pad_push_event (mysrcpad, gst_event_new_stream_start ("test"));
665 gst_segment_init (&segment, GST_FORMAT_TIME);
666 segment.start = 1 * GST_SECOND;
667 segment.stop = 5 * GST_SECOND;
669 segment.position = 1 * GST_SECOND;
671 event = gst_event_new_segment (&segment);
672 ret = gst_pad_push_event (mysrcpad, event);
673 fail_unless (ret == TRUE);
675 /* the first few buffers can return OK as they are queued and gst_queue_loop
676 * is woken up, tries to push and sets ->srcresult to NOT_LINKED
678 flow_ret = GST_FLOW_OK;
679 while (flow_ret != GST_FLOW_NOT_LINKED)
680 flow_ret = gst_pad_push (mysrcpad, gst_buffer_new ());
682 /* send a new sticky event so that it will be pushed on the next gst_pad_push
684 event = gst_event_new_segment (&segment);
685 ret = gst_pad_push_event (mysrcpad, event);
686 fail_unless (ret == TRUE);
688 /* make sure that gst_queue_sink_event doesn't return FALSE if the queue is
689 * unlinked, as that would make gst_pad_push return ERROR
691 flow_ret = gst_pad_push (mysrcpad, gst_buffer_new ());
692 fail_unless_equals_int (flow_ret, GST_FLOW_NOT_LINKED);
694 GST_DEBUG ("stopping");
695 fail_unless (gst_element_set_state (queue,
696 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
703 event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
704 GstFormat format, gint64 start, gint64 stop, gint64 position)
707 gdouble ns_rate, ns_arate;
713 if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT) {
717 gst_event_parse_new_segment (event, &ns_update, &ns_rate, &ns_arate,
718 &ns_format, &ns_start, &ns_stop, &ns_position);
720 GST_DEBUG ("update %d, rate %lf, format %s, start %" GST_TIME_FORMAT
721 ", stop %" GST_TIME_FORMAT ", position %" GST_TIME_FORMAT, ns_update,
722 ns_rate, gst_format_get_name (ns_format), GST_TIME_ARGS (ns_start),
723 GST_TIME_ARGS (ns_stop), GST_TIME_ARGS (ns_position));
725 return (ns_update == update && ns_rate == rate && ns_format == format &&
726 ns_start == start && ns_stop == stop && ns_position == position);
729 GST_START_TEST (test_newsegment)
736 g_signal_connect (queue, "overrun", G_CALLBACK (queue_overrun), NULL);
737 g_object_set (G_OBJECT (queue), "max-size-buffers", 1, "max-size-time",
738 (guint64) 0, "leaky", 2, NULL);
740 GST_DEBUG ("starting");
742 fail_unless (gst_element_set_state (queue,
743 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
744 "could not set to playing");
745 fail_unless (overrun_count == 0);
746 fail_unless (underrun_count == 0);
748 event = gst_event_new_new_segment (FALSE, 2.0, 1.0, GST_FORMAT_TIME, 0,
750 gst_pad_push_event (mysrcpad, event);
752 GST_DEBUG ("added 1st newsegment");
753 fail_unless (overrun_count == 0);
754 fail_unless (underrun_count == 0);
756 event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0,
758 gst_pad_push_event (mysrcpad, event);
760 GST_DEBUG ("added 2nd newsegment");
761 fail_unless (overrun_count == 0);
762 fail_unless (underrun_count == 0);
764 event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
765 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND);
766 gst_pad_push_event (mysrcpad, event);
768 GST_DEBUG ("added 3rd newsegment");
769 fail_unless (overrun_count == 0);
770 fail_unless (underrun_count == 0);
772 buffer1 = gst_buffer_new_and_alloc (4);
773 /* buffer1 will be leaked, keep a ref so refcount can be checked below */
774 gst_buffer_ref (buffer1);
775 /* pushing gives away one reference */
776 gst_pad_push (mysrcpad, buffer1);
778 GST_DEBUG ("added 1st buffer");
779 fail_unless (overrun_count == 0);
780 fail_unless (underrun_count == 0);
782 buffer2 = gst_buffer_new_and_alloc (4);
783 /* next push will cause overrun and leak all newsegment events and buffer1 */
784 gst_pad_push (mysrcpad, buffer2);
786 GST_DEBUG ("added 2nd buffer");
787 /* it still triggers overrun when leaking */
788 fail_unless (overrun_count == 1);
789 fail_unless (underrun_count == 0);
791 /* wait for underrun and check that we got one accumulated newsegment event,
792 * one real newsegment event and buffer2 only */
794 mysinkpad = setup_sink_pad (queue, &sinktemplate);
798 fail_unless (overrun_count == 1);
799 fail_unless (underrun_count == 1);
801 fail_unless (g_list_length (events) == 2);
803 event = g_list_nth (events, 0)->data;
804 fail_unless (event_equals_newsegment (event, FALSE, 1.0, GST_FORMAT_TIME, 0,
807 event = g_list_nth (events, 1)->data;
808 fail_unless (event_equals_newsegment (event, FALSE, 1.0, GST_FORMAT_TIME,
809 4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND));
811 fail_unless (g_list_length (buffers) == 1);
813 ASSERT_BUFFER_REFCOUNT (buffer1, "buffer", 1);
814 gst_buffer_unref (buffer1);
816 buffer = g_list_nth (buffers, 0)->data;
817 fail_unless (buffer == buffer2);
819 GST_DEBUG ("stopping");
820 fail_unless (gst_element_set_state (queue,
821 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
828 thread_func (gpointer data)
831 for (i = 0; i < 100; i++) {
835 caps = gst_caps_new_any ();
836 query = gst_query_new_allocation (caps, FALSE);
837 ok = gst_pad_peer_query (mysrcpad, query);
838 gst_query_unref (query);
839 gst_caps_unref (caps);
850 static gboolean query_func (GstPad * pad, GstObject * parent, GstQuery * query);
853 query_func (GstPad * pad, GstObject * parent, GstQuery * query)
860 GST_START_TEST (test_queries_while_flushing)
866 mysinkpad = gst_check_setup_sink_pad (queue, &sinktemplate);
867 gst_pad_set_query_function (mysinkpad, query_func);
868 gst_pad_set_active (mysinkpad, TRUE);
870 /* hard to reproduce, so just run it a few times in a row */
871 for (i = 0; i < 500; ++i) {
872 GST_DEBUG ("starting");
874 fail_unless (gst_element_set_state (queue,
875 GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
876 "could not set to playing");
880 thread = g_thread_new ("deactivating thread", thread_func, NULL);
883 event = gst_event_new_flush_start ();
884 gst_pad_push_event (mysrcpad, event);
886 g_thread_join (thread);
888 GST_DEBUG ("stopping");
889 fail_unless (gst_element_set_state (queue,
890 GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS,
891 "could not set to null");
900 Suite *s = suite_create ("queue");
901 TCase *tc_chain = tcase_create ("general");
903 suite_add_tcase (s, tc_chain);
904 tcase_add_checked_fixture (tc_chain, setup, cleanup);
905 tcase_add_test (tc_chain, test_non_leaky_underrun);
906 tcase_add_test (tc_chain, test_non_leaky_overrun);
907 tcase_add_test (tc_chain, test_leaky_upstream);
908 tcase_add_test (tc_chain, test_leaky_downstream);
909 tcase_add_test (tc_chain, test_time_level);
910 tcase_add_test (tc_chain, test_time_level_task_not_started);
911 tcase_add_test (tc_chain, test_queries_while_flushing);
913 tcase_add_test (tc_chain, test_newsegment);
915 tcase_add_test (tc_chain, test_sticky_not_linked);
920 GST_CHECK_MAIN (queue);