2 * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
4 * gstpipeline.c: Unit test for GstPipeline
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., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
25 #include <gst/check/gstcheck.h>
28 #define WAIT_TIME (300 * GST_MSECOND)
30 /* an empty pipeline can go to PLAYING in one go */
31 GST_START_TEST (test_async_state_change_empty)
33 GstPipeline *pipeline;
35 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
36 fail_unless (pipeline != NULL, "Could not create pipeline");
38 fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
39 GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS);
41 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
42 gst_object_unref (pipeline);
47 GST_START_TEST (test_async_state_change_fake_ready)
49 GstPipeline *pipeline;
50 GstElement *src, *sink;
52 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
53 fail_unless (pipeline != NULL, "Could not create pipeline");
55 src = gst_element_factory_make ("fakesrc", NULL);
56 sink = gst_element_factory_make ("fakesink", NULL);
58 gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
59 gst_element_link (src, sink);
61 fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
62 GST_STATE_READY), GST_STATE_CHANGE_SUCCESS);
64 gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
65 gst_object_unref (pipeline);
70 GST_START_TEST (test_async_state_change_fake)
72 GstPipeline *pipeline;
73 GstElement *src, *sink;
75 gboolean done = FALSE;
77 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
78 fail_unless (pipeline != NULL, "Could not create pipeline");
80 src = gst_element_factory_make ("fakesrc", NULL);
81 sink = gst_element_factory_make ("fakesink", NULL);
83 gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
84 gst_element_link (src, sink);
86 bus = gst_pipeline_get_bus (pipeline);
88 fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
89 GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC);
93 GstState old, new, pending;
95 message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
97 gst_message_parse_state_changed (message, &old, &new, &pending);
98 GST_DEBUG_OBJECT (message->src, "state change from %d to %d", old, new);
99 if (message->src == GST_OBJECT (pipeline) && new == GST_STATE_PLAYING)
101 gst_message_unref (message);
105 fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
106 GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS);
108 /* here we don't get the state change messages, because of auto-flush in
111 gst_object_unref (bus);
112 gst_object_unref (pipeline);
117 GST_START_TEST (test_get_bus)
119 GstPipeline *pipeline;
122 pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
123 fail_unless (pipeline != NULL, "Could not create pipeline");
124 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
126 bus = gst_pipeline_get_bus (pipeline);
127 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after get_bus", 1);
128 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
130 /* bindings don't like the floating flag to be set here */
131 fail_if (g_object_is_floating (bus));
133 gst_object_unref (pipeline);
135 ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1);
136 gst_object_unref (bus);
141 static GMainLoop *loop = NULL;
144 message_received (GstBus * bus, GstMessage * message, gpointer data)
146 GstElement *pipeline = GST_ELEMENT (data);
147 GstMessageType type = message->type;
149 GST_DEBUG ("message received");
151 case GST_MESSAGE_STATE_CHANGED:
153 GstState old, new, pending;
155 GST_DEBUG ("state change message received");
156 gst_message_parse_state_changed (message, &old, &new, &pending);
157 GST_DEBUG ("new state %d", new);
158 if (message->src == GST_OBJECT (pipeline) && new == GST_STATE_PLAYING) {
159 GST_DEBUG ("quitting main loop");
160 g_main_loop_quit (loop);
164 case GST_MESSAGE_ERROR:
176 GST_START_TEST (test_bus)
178 GstElement *pipeline;
179 GstElement *src, *sink;
183 GstStateChangeReturn ret;
185 pipeline = gst_pipeline_new (NULL);
186 fail_unless (pipeline != NULL, "Could not create pipeline");
187 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
189 src = gst_element_factory_make ("fakesrc", NULL);
190 fail_unless (src != NULL);
191 sink = gst_element_factory_make ("fakesink", NULL);
192 fail_unless (sink != NULL);
194 gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
195 fail_unless (gst_element_link (src, sink));
197 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
198 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after get_bus", 1);
199 ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
201 id = gst_bus_add_watch (bus, message_received, pipeline);
202 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after add_watch", 1);
203 ASSERT_OBJECT_REFCOUNT (bus, "bus after add_watch", 3);
205 ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
206 fail_unless (ret == GST_STATE_CHANGE_ASYNC);
208 loop = g_main_loop_new (NULL, FALSE);
209 GST_DEBUG ("going into main loop");
210 g_main_loop_run (loop);
211 GST_DEBUG ("left main loop");
215 ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline after gone to playing", 1,
219 GST_DEBUG ("cleanup");
221 ret = gst_element_set_state (pipeline, GST_STATE_NULL);
222 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
223 ret = gst_element_get_state (pipeline, ¤t, NULL, GST_CLOCK_TIME_NONE);
224 fail_unless (ret == GST_STATE_CHANGE_SUCCESS);
225 fail_unless (current == GST_STATE_NULL, "state is not NULL but %d", current);
227 ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline at start of cleanup", 1);
228 ASSERT_OBJECT_REFCOUNT (bus, "bus at start of cleanup", 3);
230 fail_unless (g_source_remove (id));
231 ASSERT_OBJECT_REFCOUNT (bus, "bus after removing source", 2);
233 GST_DEBUG ("unreffing pipeline");
234 gst_object_unref (pipeline);
236 ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1);
237 gst_object_unref (bus);
242 static GMutex probe_lock;
243 static GCond probe_cond;
245 static GstPadProbeReturn
246 sink_pad_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
248 GstClockTime *first_timestamp = user_data;
251 fail_unless ((GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER));
253 buffer = GST_BUFFER (info->data);
255 GST_LOG_OBJECT (pad, "buffer with timestamp %" GST_TIME_FORMAT,
256 GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
258 fail_if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE,
259 "testing if buffer timestamps are right, but got CLOCK_TIME_NONE");
261 if (*first_timestamp == GST_CLOCK_TIME_NONE) {
262 *first_timestamp = GST_BUFFER_TIMESTAMP (buffer);
265 g_mutex_lock (&probe_lock);
266 g_cond_signal (&probe_cond);
267 g_mutex_unlock (&probe_lock);
269 return GST_PAD_PROBE_OK;
272 GST_START_TEST (test_base_time)
274 GstElement *pipeline, *fakesrc, *fakesink;
276 GstClockTime observed, lower, upper, base, stream;
279 pipeline = gst_element_factory_make ("pipeline", "pipeline");
280 fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
281 fakesink = gst_element_factory_make ("fakesink", "fakesink");
283 fail_unless (pipeline && fakesrc && fakesink, "couldn't make elements");
285 g_object_set (fakesrc, "is-live", (gboolean) TRUE, NULL);
287 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
288 gst_element_link (fakesrc, fakesink);
290 sink = gst_element_get_static_pad (fakesink, "sink");
291 gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_BUFFER, sink_pad_probe,
294 fail_unless (gst_element_set_state (pipeline, GST_STATE_PAUSED)
295 == GST_STATE_CHANGE_NO_PREROLL, "expected no-preroll from live pipeline");
297 clock = gst_system_clock_obtain ();
298 fail_unless (clock && GST_IS_CLOCK (clock), "i want a clock dammit");
299 gst_pipeline_use_clock (GST_PIPELINE (pipeline), clock);
301 fail_unless (gst_element_get_start_time (pipeline) == 0,
302 "stream time doesn't start off at 0");
304 /* test the first: that base time is being distributed correctly, timestamps
305 are correct relative to the running clock and base time */
307 lower = gst_clock_get_time (clock);
309 observed = GST_CLOCK_TIME_NONE;
311 gst_element_set_state (pipeline, GST_STATE_PLAYING);
312 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
314 == GST_STATE_CHANGE_SUCCESS, "failed state change");
316 g_mutex_lock (&probe_lock);
317 while (observed == GST_CLOCK_TIME_NONE)
318 g_cond_wait (&probe_cond, &probe_lock);
319 g_mutex_unlock (&probe_lock);
321 /* now something a little more than lower was distributed as the base time,
322 * and the buffer was timestamped between 0 and upper-base
325 base = gst_element_get_base_time (pipeline);
326 fail_if (base == GST_CLOCK_TIME_NONE);
328 /* set stream time */
329 gst_element_set_state (pipeline, GST_STATE_PAUSED);
331 /* pulling upper here makes sure that the pipeline's new stream time has
332 already been computed */
333 upper = gst_clock_get_time (clock);
335 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
337 == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
339 fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
341 fail_unless (base >= lower, "early base time: %" GST_TIME_FORMAT " < %"
342 GST_TIME_FORMAT, GST_TIME_ARGS (base), GST_TIME_ARGS (lower));
343 fail_unless (upper >= base, "bogus base time: %" GST_TIME_FORMAT " > %"
344 GST_TIME_FORMAT, GST_TIME_ARGS (base), GST_TIME_ARGS (upper));
346 stream = gst_element_get_start_time (pipeline);
348 fail_unless (stream > 0, "bogus new stream time: %" GST_TIME_FORMAT " > %"
349 GST_TIME_FORMAT, GST_TIME_ARGS (stream), GST_TIME_ARGS (0));
350 fail_unless (stream <= upper,
351 "bogus new stream time: %" GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
352 GST_TIME_ARGS (stream), GST_TIME_ARGS (upper));
354 fail_unless (observed <= stream, "timestamps outrun stream time: %"
355 GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
356 GST_TIME_ARGS (observed), GST_TIME_ARGS (stream));
357 fail_unless (observed != GST_CLOCK_TIME_NONE, "early timestamp: %"
358 GST_TIME_FORMAT " < %" GST_TIME_FORMAT, GST_TIME_ARGS (observed),
359 GST_TIME_ARGS (lower - base));
360 fail_unless (observed <= upper - base,
361 "late timestamp: %" GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
362 GST_TIME_ARGS (observed), GST_TIME_ARGS (upper - base));
365 /* test the second: that the base time is redistributed when we go to PLAYING
369 GstClockTime oldbase = base, oldstream = stream;
371 /* let some time pass */
372 clock_id = gst_clock_new_single_shot_id (clock, upper + WAIT_TIME);
373 fail_unless (gst_clock_id_wait (clock_id, NULL) == GST_CLOCK_OK,
374 "unexpected clock_id_wait return");
375 gst_clock_id_unref (clock_id);
377 lower = gst_clock_get_time (clock);
378 fail_if (lower == GST_CLOCK_TIME_NONE);
380 observed = GST_CLOCK_TIME_NONE;
382 fail_unless (lower >= upper + WAIT_TIME, "clock did not advance?");
384 gst_element_set_state (pipeline, GST_STATE_PLAYING);
385 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
387 == GST_STATE_CHANGE_SUCCESS, "failed state change");
389 g_mutex_lock (&probe_lock);
390 while (observed == GST_CLOCK_TIME_NONE)
391 g_cond_wait (&probe_cond, &probe_lock);
392 g_mutex_unlock (&probe_lock);
394 /* now the base time should have advanced by more than WAIT_TIME compared
395 * to what it was. The buffer will be timestamped between the last stream
396 * time and upper minus base.
399 base = gst_element_get_base_time (pipeline);
400 fail_if (base == GST_CLOCK_TIME_NONE);
402 /* set stream time */
403 gst_element_set_state (pipeline, GST_STATE_PAUSED);
405 /* new stream time already set */
406 upper = gst_clock_get_time (clock);
408 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
410 == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
412 fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
414 stream = gst_element_get_start_time (pipeline);
416 fail_unless (base >= oldbase + WAIT_TIME, "base time not reset");
417 fail_unless (upper >= base + stream, "bogus base time: %"
418 GST_TIME_FORMAT " > %" GST_TIME_FORMAT, GST_TIME_ARGS (base),
419 GST_TIME_ARGS (upper));
421 fail_unless (lower >= base);
422 fail_unless (observed >= lower - base, "early timestamp: %"
423 GST_TIME_FORMAT " < %" GST_TIME_FORMAT,
424 GST_TIME_ARGS (observed), GST_TIME_ARGS (lower - base));
425 fail_unless (observed <= upper - base, "late timestamp: %"
426 GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
427 GST_TIME_ARGS (observed), GST_TIME_ARGS (upper - base));
428 fail_unless (stream - oldstream <= upper - lower,
429 "insufficient stream time: %" GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
430 GST_TIME_ARGS (observed), GST_TIME_ARGS (upper));
433 /* test the third: that if I set CLOCK_TIME_NONE as the stream time, that the
434 base time is not changed */
437 GstClockTime oldbase = base, oldobserved = observed;
440 /* let some time pass */
441 clock_id = gst_clock_new_single_shot_id (clock, upper + WAIT_TIME);
442 ret = gst_clock_id_wait (clock_id, NULL);
443 fail_unless (ret == GST_CLOCK_OK,
444 "unexpected clock_id_wait return %d", ret);
445 gst_clock_id_unref (clock_id);
447 lower = gst_clock_get_time (clock);
449 observed = GST_CLOCK_TIME_NONE;
451 fail_unless (lower >= upper + WAIT_TIME, "clock did not advance?");
454 gst_element_set_start_time (pipeline, GST_CLOCK_TIME_NONE);
456 gst_element_set_state (pipeline, GST_STATE_PLAYING);
457 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
459 == GST_STATE_CHANGE_SUCCESS, "failed state change");
461 g_mutex_lock (&probe_lock);
462 while (observed == GST_CLOCK_TIME_NONE)
463 g_cond_wait (&probe_cond, &probe_lock);
464 g_mutex_unlock (&probe_lock);
466 /* now the base time should be the same as it was, and the timestamp should
467 * be more than WAIT_TIME past what it was.
470 base = gst_element_get_base_time (pipeline);
472 /* set stream time */
473 gst_element_set_state (pipeline, GST_STATE_PAUSED);
475 /* new stream time already set */
476 upper = gst_clock_get_time (clock);
478 fail_unless (gst_element_get_state (pipeline, NULL, NULL,
480 == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
482 fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
484 fail_unless (gst_element_get_start_time (pipeline)
485 == GST_CLOCK_TIME_NONE, "stream time was reset");
487 fail_unless (base == oldbase, "base time was reset");
489 fail_unless (observed >= lower - base, "early timestamp: %"
490 GST_TIME_FORMAT " < %" GST_TIME_FORMAT,
491 GST_TIME_ARGS (observed), GST_TIME_ARGS (lower - base));
492 fail_unless (observed <= upper - base, "late timestamp: %"
493 GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
494 GST_TIME_ARGS (observed), GST_TIME_ARGS (upper - base));
495 fail_unless (observed - oldobserved >= WAIT_TIME,
496 "insufficient tstamp delta: %" GST_TIME_FORMAT " > %" GST_TIME_FORMAT,
497 GST_TIME_ARGS (observed), GST_TIME_ARGS (oldobserved));
500 gst_element_set_state (pipeline, GST_STATE_NULL);
502 gst_object_unref (sink);
503 gst_object_unref (clock);
504 gst_object_unref (pipeline);
510 pipeline_thread (gpointer data)
512 GstElement *pipeline, *src, *sink;
514 src = gst_element_factory_make ("fakesrc", NULL);
515 g_object_set (src, "num-buffers", 20, NULL);
516 sink = gst_element_factory_make ("fakesink", NULL);
517 g_object_set (sink, "sync", TRUE, NULL);
518 pipeline = gst_pipeline_new (NULL);
519 gst_bin_add (GST_BIN (pipeline), src);
520 gst_bin_add (GST_BIN (pipeline), sink);
521 gst_element_link (src, sink);
522 gst_element_set_state (pipeline, GST_STATE_PLAYING);
523 g_usleep (G_USEC_PER_SEC / 10);
524 gst_element_set_state (pipeline, GST_STATE_NULL);
525 gst_object_unref (pipeline);
529 GST_START_TEST (test_concurrent_create)
531 GThread *threads[30];
534 for (i = 0; i < G_N_ELEMENTS (threads); ++i) {
535 threads[i] = g_thread_try_new ("gst-check", pipeline_thread, NULL, NULL);
537 for (i = 0; i < G_N_ELEMENTS (threads); ++i) {
539 g_thread_join (threads[i]);
545 GST_START_TEST (test_pipeline_in_pipeline)
547 GstElement *pipeline, *bin, *fakesrc, *fakesink;
550 pipeline = gst_element_factory_make ("pipeline", "pipeline");
551 bin = gst_element_factory_make ("pipeline", "pipeline-as-bin");
552 fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
553 fakesink = gst_element_factory_make ("fakesink", "fakesink");
555 fail_unless (pipeline && bin && fakesrc && fakesink);
557 g_object_set (fakesrc, "num-buffers", 100, NULL);
559 gst_bin_add (GST_BIN (pipeline), bin);
560 gst_bin_add_many (GST_BIN (bin), fakesrc, fakesink, NULL);
561 gst_element_link (fakesrc, fakesink);
563 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
564 GST_STATE_CHANGE_ASYNC);
566 msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
568 gst_message_unref (msg);
570 gst_element_set_state (pipeline, GST_STATE_NULL);
572 gst_object_unref (pipeline);
577 GST_START_TEST (test_pipeline_reset_start_time)
579 GstElement *pipeline, *fakesrc, *fakesink;
585 pipeline = gst_element_factory_make ("pipeline", "pipeline");
586 fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
587 fakesink = gst_element_factory_make ("fakesink", "fakesink");
589 /* no more than 100 buffers per second */
590 g_object_set (fakesrc, "do-timestamp", TRUE, "format", GST_FORMAT_TIME,
591 "sizetype", 2, "sizemax", 4096, "datarate", 4096 * 100, NULL);
593 g_object_set (fakesink, "sync", TRUE, NULL);
595 fail_unless (pipeline && fakesrc && fakesink);
597 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
598 gst_element_link (fakesrc, fakesink);
600 fail_unless (gst_element_get_start_time (fakesink) == 0);
602 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
603 GST_STATE_CHANGE_ASYNC);
604 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
605 GST_STATE_CHANGE_SUCCESS);
606 fail_unless_equals_int (state, GST_STATE_PLAYING);
608 /* We just started and never paused, start time must be 0 */
609 fail_unless (gst_element_get_start_time (fakesink) == 0);
611 clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
612 fail_unless (clock != NULL);
613 id = gst_clock_new_single_shot_id (clock,
614 gst_element_get_base_time (pipeline) + 55 * GST_MSECOND);
615 gst_clock_id_wait (id, NULL);
616 gst_clock_id_unref (id);
617 gst_object_unref (clock);
619 /* We waited 50ms, so the position should be now >= 50ms */
620 fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
622 fail_unless (position >= 50 * GST_MSECOND,
623 "Pipeline position is not at least 50millisecond (reported %"
624 G_GUINT64_FORMAT " nanoseconds)", position);
626 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
627 GST_STATE_CHANGE_ASYNC);
628 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
629 GST_STATE_CHANGE_SUCCESS);
630 fail_unless_equals_int (state, GST_STATE_PAUSED);
632 /* And now after pausing the start time should be bigger than the last
634 fail_unless (gst_element_get_start_time (fakesink) >= 50 * GST_MSECOND);
635 fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
637 fail_unless (position >= 50 * GST_MSECOND);
639 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_READY),
640 GST_STATE_CHANGE_SUCCESS);
642 /* When going back to ready the start time should be reset everywhere */
643 fail_unless (gst_element_get_start_time (fakesink) == 0);
645 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
646 GST_STATE_CHANGE_ASYNC);
647 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
648 GST_STATE_CHANGE_SUCCESS);
649 fail_unless_equals_int (state, GST_STATE_PAUSED);
651 /* And the start time should still be set to 0 when we go to paused for the
652 * first time. Same goes for the position */
653 fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
655 fail_unless (position < 50 * GST_MSECOND);
657 fail_unless (gst_element_get_start_time (fakesink) == 0);
659 gst_element_set_state (pipeline, GST_STATE_NULL);
661 gst_object_unref (pipeline);
666 GST_START_TEST (test_pipeline_processing_deadline)
668 GstElement *pipeline, *fakesrc, *queue, *fakesink;
675 GstClockTime min, max;
679 pipeline = gst_element_factory_make ("pipeline", "pipeline");
680 fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
681 queue = gst_element_factory_make ("queue", "queue");
682 fakesink = gst_element_factory_make ("fakesink", "fakesink");
684 /* no more than 100 buffers per second */
685 g_object_set (fakesrc, "do-timestamp", TRUE, "format", GST_FORMAT_TIME,
686 "sizetype", 2, "sizemax", 4096, "datarate", 4096 * 100, "is-live", TRUE,
689 g_object_set (fakesink, "sync", TRUE, NULL);
691 fail_unless (pipeline && fakesrc && queue && fakesink);
693 gst_bin_add_many (GST_BIN (pipeline), fakesrc, queue, fakesink, NULL);
694 gst_element_link_many (fakesrc, queue, fakesink, NULL);
696 gst_element_set_state (pipeline, GST_STATE_PLAYING);
697 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
698 GST_STATE_CHANGE_SUCCESS);
699 fail_unless_equals_int (state, GST_STATE_PLAYING);
701 q = gst_query_new_latency ();
702 fail_unless (gst_element_query (pipeline, q));
703 gst_query_parse_latency (q, &live, &min, &max);
704 fail_unless (live == TRUE);
705 fail_unless (min == 20 * GST_MSECOND);
706 fail_unless (max >= min);
709 /* Wait for 50 msecs */
710 clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
711 fail_unless (clock != NULL);
712 id = gst_clock_new_single_shot_id (clock,
713 gst_element_get_base_time (pipeline) + 50 * GST_MSECOND);
714 gst_clock_id_wait (id, NULL);
715 gst_clock_id_unref (id);
716 gst_object_unref (clock);
718 /* We waited 50ms, but the position should be now < 40ms */
719 fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
721 fail_unless (position < 40 * GST_MSECOND,
722 "Pipeline position is not at least 50millisecond (reported %"
723 G_GUINT64_FORMAT " nanoseconds)", position);
725 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
726 GST_STATE_CHANGE_NO_PREROLL);
727 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
728 GST_STATE_CHANGE_NO_PREROLL);
729 fail_unless_equals_int (state, GST_STATE_PAUSED);
731 /* And now after pausing the start time should be bigger than the last
733 fail_unless (gst_element_get_start_time (fakesink) >= 50 * GST_MSECOND);
734 fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
736 fail_unless (position < 50 * GST_MSECOND);
738 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_READY),
739 GST_STATE_CHANGE_SUCCESS);
741 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
742 GST_STATE_CHANGE_NO_PREROLL);
743 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
744 GST_STATE_CHANGE_NO_PREROLL);
745 fail_unless_equals_int (state, GST_STATE_PAUSED);
747 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
748 msg = gst_bus_pop_filtered (bus, GST_MESSAGE_WARNING);
749 fail_unless (msg == NULL);
750 gst_object_unref (bus);
752 gst_element_set_state (pipeline, GST_STATE_NULL);
754 gst_object_unref (pipeline);
760 GST_START_TEST (test_pipeline_processing_deadline_no_queue)
762 GstElement *pipeline, *fakesrc, *fakesink;
766 GError *gerror = NULL;
768 pipeline = gst_element_factory_make ("pipeline", "pipeline");
769 fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
770 fakesink = gst_element_factory_make ("fakesink", "fakesink");
772 /* no more than 100 buffers per second */
773 g_object_set (fakesrc, "do-timestamp", TRUE, "format", GST_FORMAT_TIME,
774 "sizetype", 2, "sizemax", 4096, "datarate", 4096 * 100, "is-live", TRUE,
777 g_object_set (fakesink, "sync", TRUE, "processing-deadline", 60 * GST_MSECOND,
780 fail_unless (pipeline && fakesrc && fakesink);
782 gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
783 gst_element_link (fakesrc, fakesink);
785 fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
786 GST_STATE_CHANGE_ASYNC);
787 fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
788 GST_STATE_CHANGE_SUCCESS);
790 bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
791 msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
792 GST_MESSAGE_WARNING);
793 fail_unless (msg != NULL);
794 gst_message_parse_warning (msg, &gerror, NULL);
795 fail_unless (g_error_matches (gerror, GST_CORE_ERROR, GST_CORE_ERROR_CLOCK));
796 gst_message_unref (msg);
797 gst_object_unref (bus);
798 g_clear_error (&gerror);
800 gst_element_set_state (pipeline, GST_STATE_NULL);
802 gst_object_unref (pipeline);
809 gst_pipeline_suite (void)
811 Suite *s = suite_create ("GstPipeline");
812 TCase *tc_chain = tcase_create ("pipeline tests");
814 tcase_set_timeout (tc_chain, 0);
816 suite_add_tcase (s, tc_chain);
817 tcase_add_test (tc_chain, test_async_state_change_empty);
818 tcase_add_test (tc_chain, test_async_state_change_fake_ready);
819 tcase_add_test (tc_chain, test_async_state_change_fake);
820 tcase_add_test (tc_chain, test_get_bus);
821 tcase_add_test (tc_chain, test_bus);
822 tcase_add_test (tc_chain, test_base_time);
823 tcase_add_test (tc_chain, test_concurrent_create);
824 tcase_add_test (tc_chain, test_pipeline_in_pipeline);
825 tcase_add_test (tc_chain, test_pipeline_reset_start_time);
826 tcase_add_test (tc_chain, test_pipeline_processing_deadline);
827 tcase_add_test (tc_chain, test_pipeline_processing_deadline_no_queue);
832 GST_CHECK_MAIN (gst_pipeline);