0745d57818353918b88953c70b7836c55956667c
[platform/upstream/gstreamer.git] / tests / check / gst / gstpipeline.c
1 /* GStreamer
2  * Copyright (C) 2005 Thomas Vander Stichele <thomas at apestaart dot org>
3  *
4  * gstpipeline.c: Unit test for GstPipeline
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., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <gst/check/gstcheck.h>
26 #include <gst/gst.h>
27
28 #define WAIT_TIME (300 * GST_MSECOND)
29
30 /* an empty pipeline can go to PLAYING in one go */
31 GST_START_TEST (test_async_state_change_empty)
32 {
33   GstPipeline *pipeline;
34
35   pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
36   fail_unless (pipeline != NULL, "Could not create pipeline");
37
38   fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
39           GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS);
40
41   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
42   gst_object_unref (pipeline);
43 }
44
45 GST_END_TEST;
46
47 GST_START_TEST (test_async_state_change_fake_ready)
48 {
49   GstPipeline *pipeline;
50   GstElement *src, *sink;
51
52   pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
53   fail_unless (pipeline != NULL, "Could not create pipeline");
54
55   src = gst_element_factory_make ("fakesrc", NULL);
56   sink = gst_element_factory_make ("fakesink", NULL);
57
58   gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
59   gst_element_link (src, sink);
60
61   fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
62           GST_STATE_READY), GST_STATE_CHANGE_SUCCESS);
63
64   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
65   gst_object_unref (pipeline);
66 }
67
68 GST_END_TEST;
69
70 GST_START_TEST (test_async_state_change_fake)
71 {
72   GstPipeline *pipeline;
73   GstElement *src, *sink;
74   GstBus *bus;
75   gboolean done = FALSE;
76
77   pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
78   fail_unless (pipeline != NULL, "Could not create pipeline");
79
80   src = gst_element_factory_make ("fakesrc", NULL);
81   sink = gst_element_factory_make ("fakesink", NULL);
82
83   gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
84   gst_element_link (src, sink);
85
86   bus = gst_pipeline_get_bus (pipeline);
87
88   fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
89           GST_STATE_PLAYING), GST_STATE_CHANGE_ASYNC);
90
91   while (!done) {
92     GstMessage *message;
93     GstState old, new, pending;
94
95     message = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, -1);
96     if (message) {
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)
100         done = TRUE;
101       gst_message_unref (message);
102     }
103   }
104
105   fail_unless_equals_int (gst_element_set_state (GST_ELEMENT (pipeline),
106           GST_STATE_NULL), GST_STATE_CHANGE_SUCCESS);
107
108   /* here we don't get the state change messages, because of auto-flush in 
109    * the bus */
110
111   gst_object_unref (bus);
112   gst_object_unref (pipeline);
113 }
114
115 GST_END_TEST;
116
117 GST_START_TEST (test_get_bus)
118 {
119   GstPipeline *pipeline;
120   GstBus *bus;
121
122   pipeline = GST_PIPELINE (gst_pipeline_new (NULL));
123   fail_unless (pipeline != NULL, "Could not create pipeline");
124   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
125
126   bus = gst_pipeline_get_bus (pipeline);
127   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline after get_bus", 1);
128   ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
129
130   /* bindings don't like the floating flag to be set here */
131   fail_if (g_object_is_floating (bus));
132
133   gst_object_unref (pipeline);
134
135   ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1);
136   gst_object_unref (bus);
137 }
138
139 GST_END_TEST;
140
141 static GMainLoop *loop = NULL;
142
143 static gboolean
144 message_received (GstBus * bus, GstMessage * message, gpointer data)
145 {
146   GstElement *pipeline = GST_ELEMENT (data);
147   GstMessageType type = message->type;
148
149   GST_DEBUG ("message received");
150   switch (type) {
151     case GST_MESSAGE_STATE_CHANGED:
152     {
153       GstState old, new, pending;
154
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);
161       }
162     }
163       break;
164     case GST_MESSAGE_ERROR:
165     {
166       g_print ("error\n");
167     }
168       break;
169     default:
170       break;
171   }
172
173   return TRUE;
174 }
175
176 GST_START_TEST (test_bus)
177 {
178   GstElement *pipeline;
179   GstElement *src, *sink;
180   GstBus *bus;
181   guint id;
182   GstState current;
183   GstStateChangeReturn ret;
184
185   pipeline = gst_pipeline_new (NULL);
186   fail_unless (pipeline != NULL, "Could not create pipeline");
187   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
188
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);
193
194   gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL);
195   fail_unless (gst_element_link (src, sink));
196
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);
200
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);
204
205   ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
206   fail_unless (ret == GST_STATE_CHANGE_ASYNC);
207
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");
212
213   /* PLAYING now */
214
215   ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline after gone to playing", 1,
216       3);
217
218   /* cleanup */
219   GST_DEBUG ("cleanup");
220
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, &current, 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);
226
227   ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline at start of cleanup", 1);
228   ASSERT_OBJECT_REFCOUNT (bus, "bus at start of cleanup", 3);
229
230   fail_unless (g_source_remove (id));
231   ASSERT_OBJECT_REFCOUNT (bus, "bus after removing source", 2);
232
233   GST_DEBUG ("unreffing pipeline");
234   gst_object_unref (pipeline);
235
236   ASSERT_OBJECT_REFCOUNT (bus, "bus after unref pipeline", 1);
237   gst_object_unref (bus);
238 }
239
240 GST_END_TEST;
241
242 static GMutex probe_lock;
243 static GCond probe_cond;
244
245 static GstPadProbeReturn
246 sink_pad_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
247 {
248   GstClockTime *first_timestamp = user_data;
249   GstBuffer *buffer;
250
251   fail_unless ((GST_PAD_PROBE_INFO_TYPE (info) & GST_PAD_PROBE_TYPE_BUFFER));
252
253   buffer = GST_BUFFER (info->data);
254
255   GST_LOG_OBJECT (pad, "buffer with timestamp %" GST_TIME_FORMAT,
256       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
257
258   fail_if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE,
259       "testing if buffer timestamps are right, but got CLOCK_TIME_NONE");
260
261   if (*first_timestamp == GST_CLOCK_TIME_NONE) {
262     *first_timestamp = GST_BUFFER_TIMESTAMP (buffer);
263   }
264
265   g_mutex_lock (&probe_lock);
266   g_cond_signal (&probe_cond);
267   g_mutex_unlock (&probe_lock);
268
269   return GST_PAD_PROBE_OK;
270 }
271
272 GST_START_TEST (test_base_time)
273 {
274   GstElement *pipeline, *fakesrc, *fakesink;
275   GstPad *sink;
276   GstClockTime observed, lower, upper, base, stream;
277   GstClock *clock;
278
279   pipeline = gst_element_factory_make ("pipeline", "pipeline");
280   fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
281   fakesink = gst_element_factory_make ("fakesink", "fakesink");
282
283   fail_unless (pipeline && fakesrc && fakesink, "couldn't make elements");
284
285   g_object_set (fakesrc, "is-live", (gboolean) TRUE, NULL);
286
287   gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
288   gst_element_link (fakesrc, fakesink);
289
290   sink = gst_element_get_static_pad (fakesink, "sink");
291   gst_pad_add_probe (sink, GST_PAD_PROBE_TYPE_BUFFER, sink_pad_probe,
292       &observed, NULL);
293
294   fail_unless (gst_element_set_state (pipeline, GST_STATE_PAUSED)
295       == GST_STATE_CHANGE_NO_PREROLL, "expected no-preroll from live pipeline");
296
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);
300
301   fail_unless (gst_element_get_start_time (pipeline) == 0,
302       "stream time doesn't start off at 0");
303
304   /* test the first: that base time is being distributed correctly, timestamps
305      are correct relative to the running clock and base time */
306   {
307     lower = gst_clock_get_time (clock);
308
309     observed = GST_CLOCK_TIME_NONE;
310
311     gst_element_set_state (pipeline, GST_STATE_PLAYING);
312     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
313             GST_CLOCK_TIME_NONE)
314         == GST_STATE_CHANGE_SUCCESS, "failed state change");
315
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);
320
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
323      */
324
325     base = gst_element_get_base_time (pipeline);
326     fail_if (base == GST_CLOCK_TIME_NONE);
327
328     /* set stream time */
329     gst_element_set_state (pipeline, GST_STATE_PAUSED);
330
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);
334
335     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
336             GST_CLOCK_TIME_NONE)
337         == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
338
339     fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
340
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));
345
346     stream = gst_element_get_start_time (pipeline);
347
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));
353
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));
363   }
364
365   /* test the second: that the base time is redistributed when we go to PLAYING
366      again */
367   {
368     GstClockID clock_id;
369     GstClockTime oldbase = base, oldstream = stream;
370
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);
376
377     lower = gst_clock_get_time (clock);
378     fail_if (lower == GST_CLOCK_TIME_NONE);
379
380     observed = GST_CLOCK_TIME_NONE;
381
382     fail_unless (lower >= upper + WAIT_TIME, "clock did not advance?");
383
384     gst_element_set_state (pipeline, GST_STATE_PLAYING);
385     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
386             GST_CLOCK_TIME_NONE)
387         == GST_STATE_CHANGE_SUCCESS, "failed state change");
388
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);
393
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.
397      */
398
399     base = gst_element_get_base_time (pipeline);
400     fail_if (base == GST_CLOCK_TIME_NONE);
401
402     /* set stream time */
403     gst_element_set_state (pipeline, GST_STATE_PAUSED);
404
405     /* new stream time already set */
406     upper = gst_clock_get_time (clock);
407
408     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
409             GST_CLOCK_TIME_NONE)
410         == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
411
412     fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
413
414     stream = gst_element_get_start_time (pipeline);
415
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));
420
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));
431   }
432
433   /* test the third: that if I set CLOCK_TIME_NONE as the stream time, that the
434      base time is not changed */
435   {
436     GstClockID clock_id;
437     GstClockTime oldbase = base, oldobserved = observed;
438     GstClockReturn ret;
439
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);
446
447     lower = gst_clock_get_time (clock);
448
449     observed = GST_CLOCK_TIME_NONE;
450
451     fail_unless (lower >= upper + WAIT_TIME, "clock did not advance?");
452
453     /* bling */
454     gst_element_set_start_time (pipeline, GST_CLOCK_TIME_NONE);
455
456     gst_element_set_state (pipeline, GST_STATE_PLAYING);
457     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
458             GST_CLOCK_TIME_NONE)
459         == GST_STATE_CHANGE_SUCCESS, "failed state change");
460
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);
465
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.
468      */
469
470     base = gst_element_get_base_time (pipeline);
471
472     /* set stream time */
473     gst_element_set_state (pipeline, GST_STATE_PAUSED);
474
475     /* new stream time already set */
476     upper = gst_clock_get_time (clock);
477
478     fail_unless (gst_element_get_state (pipeline, NULL, NULL,
479             GST_CLOCK_TIME_NONE)
480         == GST_STATE_CHANGE_NO_PREROLL, "failed state change");
481
482     fail_if (observed == GST_CLOCK_TIME_NONE, "no timestamp recorded");
483
484     fail_unless (gst_element_get_start_time (pipeline)
485         == GST_CLOCK_TIME_NONE, "stream time was reset");
486
487     fail_unless (base == oldbase, "base time was reset");
488
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));
498   }
499
500   gst_element_set_state (pipeline, GST_STATE_NULL);
501
502   gst_object_unref (sink);
503   gst_object_unref (clock);
504   gst_object_unref (pipeline);
505 }
506
507 GST_END_TEST;
508
509 static gpointer
510 pipeline_thread (gpointer data)
511 {
512   GstElement *pipeline, *src, *sink;
513
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);
526   return NULL;
527 }
528
529 GST_START_TEST (test_concurrent_create)
530 {
531   GThread *threads[30];
532   int i;
533
534   for (i = 0; i < G_N_ELEMENTS (threads); ++i) {
535     threads[i] = g_thread_try_new ("gst-check", pipeline_thread, NULL, NULL);
536   }
537   for (i = 0; i < G_N_ELEMENTS (threads); ++i) {
538     if (threads[i])
539       g_thread_join (threads[i]);
540   }
541 }
542
543 GST_END_TEST;
544
545 GST_START_TEST (test_pipeline_in_pipeline)
546 {
547   GstElement *pipeline, *bin, *fakesrc, *fakesink;
548   GstMessage *msg;
549
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");
554
555   fail_unless (pipeline && bin && fakesrc && fakesink);
556
557   g_object_set (fakesrc, "num-buffers", 100, NULL);
558
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);
562
563   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
564       GST_STATE_CHANGE_ASYNC);
565
566   msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipeline), -1,
567       GST_MESSAGE_EOS);
568   gst_message_unref (msg);
569
570   gst_element_set_state (pipeline, GST_STATE_NULL);
571
572   gst_object_unref (pipeline);
573 }
574
575 GST_END_TEST;
576
577 GST_START_TEST (test_pipeline_reset_start_time)
578 {
579   GstElement *pipeline, *fakesrc, *fakesink;
580   GstState state;
581   GstClock *clock;
582   GstClockID id;
583   gint64 position;
584
585   pipeline = gst_element_factory_make ("pipeline", "pipeline");
586   fakesrc = gst_element_factory_make ("fakesrc", "fakesrc");
587   fakesink = gst_element_factory_make ("fakesink", "fakesink");
588
589   g_object_set (fakesrc, "do-timestamp", TRUE, "format", GST_FORMAT_TIME, NULL);
590
591   fail_unless (pipeline && fakesrc && fakesink);
592
593   gst_bin_add_many (GST_BIN (pipeline), fakesrc, fakesink, NULL);
594   gst_element_link (fakesrc, fakesink);
595
596   fail_unless (gst_element_get_start_time (fakesink) == 0);
597
598   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PLAYING),
599       GST_STATE_CHANGE_ASYNC);
600   fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
601       GST_STATE_CHANGE_SUCCESS);
602   fail_unless_equals_int (state, GST_STATE_PLAYING);
603
604   /* We just started and never paused, start time must be 0 */
605   fail_unless (gst_element_get_start_time (fakesink) == 0);
606
607   clock = gst_pipeline_get_clock (GST_PIPELINE (pipeline));
608   fail_unless (clock != NULL);
609   id = gst_clock_new_single_shot_id (clock,
610       gst_element_get_base_time (pipeline) + 55 * GST_MSECOND);
611   gst_clock_id_wait (id, NULL);
612   gst_clock_id_unref (id);
613   gst_object_unref (clock);
614
615   /* We waited 50ms, so the position should be now >= 50ms */
616   fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
617           &position));
618   fail_unless (position >= 50 * GST_MSECOND,
619       "Pipeline position is not at least 50millisecond (reported %"
620       G_GUINT64_FORMAT " nanoseconds)", position);
621
622   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
623       GST_STATE_CHANGE_ASYNC);
624   fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
625       GST_STATE_CHANGE_SUCCESS);
626   fail_unless_equals_int (state, GST_STATE_PAUSED);
627
628   /* And now after pausing the start time should be bigger than the last
629    * position */
630   fail_unless (gst_element_get_start_time (fakesink) >= 50 * GST_MSECOND);
631   fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
632           &position));
633   fail_unless (position >= 50 * GST_MSECOND);
634
635   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_READY),
636       GST_STATE_CHANGE_SUCCESS);
637
638   /* When going back to ready the start time should be reset everywhere */
639   fail_unless (gst_element_get_start_time (fakesink) == 0);
640
641   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_PAUSED),
642       GST_STATE_CHANGE_ASYNC);
643   fail_unless_equals_int (gst_element_get_state (pipeline, &state, NULL, -1),
644       GST_STATE_CHANGE_SUCCESS);
645   fail_unless_equals_int (state, GST_STATE_PAUSED);
646
647   /* And the start time should still be set to 0 when we go to paused for the
648    * first time. Same goes for the position */
649   fail_unless (gst_element_query_position (fakesink, GST_FORMAT_TIME,
650           &position));
651   fail_unless (position < 50 * GST_MSECOND);
652
653   fail_unless (gst_element_get_start_time (fakesink) == 0);
654
655   gst_element_set_state (pipeline, GST_STATE_NULL);
656
657   gst_object_unref (pipeline);
658 }
659
660 GST_END_TEST;
661
662 static Suite *
663 gst_pipeline_suite (void)
664 {
665   Suite *s = suite_create ("GstPipeline");
666   TCase *tc_chain = tcase_create ("pipeline tests");
667
668   tcase_set_timeout (tc_chain, 0);
669
670   suite_add_tcase (s, tc_chain);
671   tcase_add_test (tc_chain, test_async_state_change_empty);
672   tcase_add_test (tc_chain, test_async_state_change_fake_ready);
673   tcase_add_test (tc_chain, test_async_state_change_fake);
674   tcase_add_test (tc_chain, test_get_bus);
675   tcase_add_test (tc_chain, test_bus);
676   tcase_add_test (tc_chain, test_base_time);
677   tcase_add_test (tc_chain, test_concurrent_create);
678   tcase_add_test (tc_chain, test_pipeline_in_pipeline);
679   tcase_add_test (tc_chain, test_pipeline_reset_start_time);
680
681   return s;
682 }
683
684 GST_CHECK_MAIN (gst_pipeline);