check/gst/gstbin.c: Add bus to bin.
[platform/upstream/gstreamer.git] / gst / gstpipeline.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2004,2005 Wim Taymans <wim@fluendo.com>
4  *
5  * gstpipeline.c: Overall pipeline management element
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  * SECTION:gstpipeline
24  * @short_description: Top-level bin with scheduling and pipeline management functionality.
25  * @see_also: #GstBin
26  *
27  * In almost all cases, you'll want to use a GstPipeline when creating a filter
28  * graph.  The GstPipeline will manage all the scheduling issues, including
29  * threading, as well as provide simple interfaces to common functions, like
30  * 'Play'.
31  *
32  * gst_pipeline_new() is used to create a pipeline. when you are done with 
33  * the pipeline, use gst_object_unref() to free its resources including all
34  * added #GstElement objects (if not otherwiese referenced).
35  */
36
37 #include "gst_private.h"
38
39 #include "gstpipeline.h"
40 #include "gstinfo.h"
41 #include "gstsystemclock.h"
42
43 static GstElementDetails gst_pipeline_details =
44 GST_ELEMENT_DETAILS ("Pipeline object",
45     "Generic/Bin",
46     "Complete pipeline object",
47     "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
48
49 /* Pipeline signals and args */
50 enum
51 {
52   /* FILL ME */
53   LAST_SIGNAL
54 };
55
56 #define DEFAULT_DELAY 0
57 #define DEFAULT_PLAY_TIMEOUT  (2*GST_SECOND)
58 enum
59 {
60   ARG_0,
61   ARG_DELAY,
62   ARG_PLAY_TIMEOUT,
63   /* FILL ME */
64 };
65
66
67 static void gst_pipeline_base_init (gpointer g_class);
68 static void gst_pipeline_class_init (gpointer g_class, gpointer class_data);
69 static void gst_pipeline_init (GTypeInstance * instance, gpointer g_class);
70
71 static void gst_pipeline_dispose (GObject * object);
72 static void gst_pipeline_set_property (GObject * object, guint prop_id,
73     const GValue * value, GParamSpec * pspec);
74 static void gst_pipeline_get_property (GObject * object, guint prop_id,
75     GValue * value, GParamSpec * pspec);
76
77 static gboolean gst_pipeline_send_event (GstElement * element,
78     GstEvent * event);
79
80 static GstClock *gst_pipeline_provide_clock_func (GstElement * element);
81 static GstStateChangeReturn gst_pipeline_change_state (GstElement * element,
82     GstStateChange transition);
83
84 static GstBinClass *parent_class = NULL;
85
86 /* static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 }; */
87
88 GType
89 gst_pipeline_get_type (void)
90 {
91   static GType pipeline_type = 0;
92
93   if (!pipeline_type) {
94     static const GTypeInfo pipeline_info = {
95       sizeof (GstPipelineClass),
96       gst_pipeline_base_init,
97       NULL,
98       (GClassInitFunc) gst_pipeline_class_init,
99       NULL,
100       NULL,
101       sizeof (GstPipeline),
102       0,
103       gst_pipeline_init,
104       NULL
105     };
106
107     pipeline_type =
108         g_type_register_static (GST_TYPE_BIN, "GstPipeline", &pipeline_info, 0);
109   }
110   return pipeline_type;
111 }
112
113 static void
114 gst_pipeline_base_init (gpointer g_class)
115 {
116   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
117
118   gst_element_class_set_details (gstelement_class, &gst_pipeline_details);
119 }
120
121 static void
122 gst_pipeline_class_init (gpointer g_class, gpointer class_data)
123 {
124   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
125   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
126   GstPipelineClass *klass = GST_PIPELINE_CLASS (g_class);
127
128   parent_class = g_type_class_peek_parent (klass);
129
130   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pipeline_set_property);
131   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pipeline_get_property);
132
133   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DELAY,
134       g_param_spec_uint64 ("delay", "Delay",
135           "Expected delay needed for elements "
136           "to spin up to PLAYING in nanoseconds", 0, G_MAXUINT64, DEFAULT_DELAY,
137           G_PARAM_READWRITE));
138   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PLAY_TIMEOUT,
139       g_param_spec_uint64 ("play-timeout", "Play Timeout",
140           "Max timeout for going to PLAYING in nanoseconds", 0, G_MAXUINT64,
141           DEFAULT_PLAY_TIMEOUT, G_PARAM_READWRITE));
142
143   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose);
144
145   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_pipeline_send_event);
146   gstelement_class->change_state =
147       GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
148   gstelement_class->provide_clock =
149       GST_DEBUG_FUNCPTR (gst_pipeline_provide_clock_func);
150 }
151
152 static void
153 gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
154 {
155   GstPipeline *pipeline = GST_PIPELINE (instance);
156   GstBus *bus;
157
158   pipeline->delay = DEFAULT_DELAY;
159   pipeline->play_timeout = DEFAULT_PLAY_TIMEOUT;
160
161   bus = g_object_new (gst_bus_get_type (), NULL);
162   gst_element_set_bus (GST_ELEMENT_CAST (pipeline), bus);
163   gst_object_unref (bus);
164 }
165
166 static void
167 gst_pipeline_dispose (GObject * object)
168 {
169   GstPipeline *pipeline = GST_PIPELINE (object);
170
171   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pipeline, "dispose");
172
173   gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
174
175   G_OBJECT_CLASS (parent_class)->dispose (object);
176 }
177
178 static void
179 gst_pipeline_set_property (GObject * object, guint prop_id,
180     const GValue * value, GParamSpec * pspec)
181 {
182   GstPipeline *pipeline = GST_PIPELINE (object);
183
184   GST_LOCK (pipeline);
185   switch (prop_id) {
186     case ARG_DELAY:
187       pipeline->delay = g_value_get_uint64 (value);
188       break;
189     case ARG_PLAY_TIMEOUT:
190       pipeline->play_timeout = g_value_get_uint64 (value);
191       break;
192     default:
193       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
194       break;
195   }
196   GST_UNLOCK (pipeline);
197 }
198
199 static void
200 gst_pipeline_get_property (GObject * object, guint prop_id,
201     GValue * value, GParamSpec * pspec)
202 {
203   GstPipeline *pipeline = GST_PIPELINE (object);
204
205   GST_LOCK (pipeline);
206   switch (prop_id) {
207     case ARG_DELAY:
208       g_value_set_uint64 (value, pipeline->delay);
209       break;
210     case ARG_PLAY_TIMEOUT:
211       g_value_set_uint64 (value, pipeline->play_timeout);
212       break;
213     default:
214       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
215       break;
216   }
217   GST_UNLOCK (pipeline);
218 }
219
220 static gboolean
221 do_pipeline_seek (GstElement * element, GstEvent * event)
222 {
223   gdouble rate;
224   GstSeekFlags flags;
225   gboolean flush;
226   gboolean was_playing = FALSE;
227   gboolean res;
228
229   gst_event_parse_seek (event, &rate, NULL, &flags, NULL, NULL, NULL, NULL);
230
231   flush = flags & GST_SEEK_FLAG_FLUSH;
232
233   if (flush) {
234     GstState state;
235     GTimeVal timeout;
236
237     GST_TIME_TO_TIMEVAL (0, timeout);
238     /* need to call _get_state() since a bin state is only updated
239      * with this call. */
240     gst_element_get_state (element, &state, NULL, &timeout);
241     was_playing = state == GST_STATE_PLAYING;
242
243     if (was_playing)
244       gst_element_set_state (element, GST_STATE_PAUSED);
245   }
246
247   res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
248
249   if (flush && res) {
250     /* need to reset the stream time to 0 after a flushing seek */
251     gst_pipeline_set_new_stream_time (GST_PIPELINE (element), 0);
252     if (was_playing) {
253       /* and continue playing */
254       gst_element_set_state (element, GST_STATE_PLAYING);
255     }
256   }
257   return res;
258 }
259
260 /* sending a seek event on the pipeline pauses the pipeline if it
261  * was playing.
262  */
263 static gboolean
264 gst_pipeline_send_event (GstElement * element, GstEvent * event)
265 {
266   gboolean res;
267   GstEventType event_type = GST_EVENT_TYPE (event);
268
269   switch (event_type) {
270     case GST_EVENT_SEEK:
271       res = do_pipeline_seek (element, event);
272       break;
273     default:
274       res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
275       break;
276   }
277
278   return res;
279 }
280
281 /**
282  * gst_pipeline_new:
283  * @name: name of new pipeline
284  *
285  * Create a new pipeline with the given name.
286  *
287  * Returns: newly created GstPipeline
288  *
289  * MT safe.
290  */
291 GstElement *
292 gst_pipeline_new (const gchar * name)
293 {
294   return gst_element_factory_make ("pipeline", name);
295 }
296
297 /* MT safe */
298 static GstStateChangeReturn
299 gst_pipeline_change_state (GstElement * element, GstStateChange transition)
300 {
301   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
302   GstPipeline *pipeline = GST_PIPELINE (element);
303   GstClockTime play_timeout;
304   GstClock *clock;
305
306   switch (transition) {
307     case GST_STATE_CHANGE_NULL_TO_READY:
308       GST_LOCK (element);
309       if (element->bus)
310         gst_bus_set_flushing (element->bus, FALSE);
311       GST_UNLOCK (element);
312       break;
313     case GST_STATE_CHANGE_READY_TO_PAUSED:
314       break;
315     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
316       /* when going to playing, select a clock */
317       if ((clock = gst_element_provide_clock (element))) {
318         GstClockTime start_time;
319
320         /* distribute the clock */
321         gst_element_set_clock (element, clock);
322
323         /* get start time */
324         start_time = gst_clock_get_time (clock);
325         gst_object_unref (clock);
326
327         GST_LOCK (element);
328         element->base_time = start_time -
329             pipeline->stream_time + pipeline->delay;
330         GST_DEBUG ("stream_time=%" GST_TIME_FORMAT ", start_time=%"
331             GST_TIME_FORMAT ", base time %" GST_TIME_FORMAT,
332             GST_TIME_ARGS (pipeline->stream_time),
333             GST_TIME_ARGS (start_time), GST_TIME_ARGS (element->base_time));
334         GST_UNLOCK (element);
335       } else {
336         GST_DEBUG ("no clock, using base time of 0");
337         gst_element_set_base_time (element, 0);
338       }
339       break;
340     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
341     case GST_STATE_CHANGE_PAUSED_TO_READY:
342     case GST_STATE_CHANGE_READY_TO_NULL:
343       break;
344   }
345
346   result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
347
348   switch (transition) {
349     case GST_STATE_CHANGE_NULL_TO_READY:
350       break;
351     case GST_STATE_CHANGE_READY_TO_PAUSED:
352       gst_pipeline_set_new_stream_time (pipeline, 0);
353       break;
354     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
355       break;
356     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
357       GST_LOCK (element);
358       if ((clock = element->clock)) {
359         GstClockTime now;
360
361         gst_object_ref (clock);
362         GST_UNLOCK (element);
363
364         /* calculate the time when we stopped */
365         now = gst_clock_get_time (clock);
366         gst_object_unref (clock);
367
368         GST_LOCK (element);
369         /* store the current stream time */
370         pipeline->stream_time = now - element->base_time;
371         GST_DEBUG ("stream_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT
372             ", base time %" GST_TIME_FORMAT,
373             GST_TIME_ARGS (pipeline->stream_time),
374             GST_TIME_ARGS (now), GST_TIME_ARGS (element->base_time));
375       }
376       GST_UNLOCK (element);
377       break;
378     case GST_STATE_CHANGE_PAUSED_TO_READY:
379       break;
380     case GST_STATE_CHANGE_READY_TO_NULL:
381       GST_LOCK (element);
382       if (element->bus) {
383         gst_bus_set_flushing (element->bus, TRUE);
384       }
385       GST_UNLOCK (element);
386       break;
387   }
388
389   if (result == GST_STATE_CHANGE_ASYNC) {
390     GST_LOCK (pipeline);
391     play_timeout = pipeline->play_timeout;
392     GST_UNLOCK (pipeline);
393   } else {
394     play_timeout = 0;
395   }
396
397   /* we wait for async state changes ourselves when we are in an
398    * intermediate state. */
399   if (play_timeout > 0) {
400     GTimeVal *timeval, timeout;
401
402     GST_STATE_UNLOCK (pipeline);
403
404     if (play_timeout == G_MAXUINT64) {
405       timeval = NULL;
406     } else {
407       GST_TIME_TO_TIMEVAL (play_timeout, timeout);
408       timeval = &timeout;
409     }
410
411     result = gst_element_get_state (element, NULL, NULL, timeval);
412     if (result == GST_STATE_CHANGE_ASYNC) {
413       GST_WARNING_OBJECT (pipeline,
414           "timeout in PREROLL, forcing next state change");
415       g_warning ("timeout in PREROLL, forcing next state change");
416       result = GST_STATE_CHANGE_SUCCESS;
417     }
418
419     GST_STATE_LOCK (pipeline);
420   }
421
422   return result;
423 }
424
425 /**
426  * gst_pipeline_get_bus:
427  * @pipeline: the pipeline
428  *
429  * Gets the #GstBus of this pipeline.
430  *
431  * Returns: a GstBus
432  *
433  * MT safe.
434  */
435 GstBus *
436 gst_pipeline_get_bus (GstPipeline * pipeline)
437 {
438   return gst_element_get_bus (GST_ELEMENT (pipeline));
439 }
440
441 /**
442  * gst_pipeline_set_new_stream_time:
443  * @pipeline: the pipeline
444  * @time: the new stream time to set
445  *
446  * Set the new stream time of the pipeline. The stream time is used to
447  * set the base time on the elements (see @gst_element_set_base_time())
448  * in the PAUSED->PLAYING state transition.
449  *
450  * MT safe.
451  */
452 void
453 gst_pipeline_set_new_stream_time (GstPipeline * pipeline, GstClockTime time)
454 {
455   g_return_if_fail (GST_IS_PIPELINE (pipeline));
456
457   GST_LOCK (pipeline);
458   pipeline->stream_time = time;
459   GST_DEBUG ("%s: set new stream_time to %" GST_TIME_FORMAT,
460       GST_ELEMENT_NAME (pipeline), GST_TIME_ARGS (time));
461   GST_UNLOCK (pipeline);
462 }
463
464 /**
465  * gst_pipeline_get_last_stream_time:
466  * @pipeline: the pipeline
467  *
468  * Gets the last stream time of the pipeline. If the pipeline is PLAYING,
469  * the returned time is the stream time used to configure the elements
470  * in the PAUSED->PLAYING state. If the pipeline is PAUSED, the returned
471  * time is the stream time when the pipeline was paused.
472  *
473  * Returns: a GstClockTime
474  *
475  * MT safe.
476  */
477 GstClockTime
478 gst_pipeline_get_last_stream_time (GstPipeline * pipeline)
479 {
480   GstClockTime result;
481
482   g_return_val_if_fail (GST_IS_PIPELINE (pipeline), GST_CLOCK_TIME_NONE);
483
484   GST_LOCK (pipeline);
485   result = pipeline->stream_time;
486   GST_UNLOCK (pipeline);
487
488   return result;
489 }
490
491 static GstClock *
492 gst_pipeline_provide_clock_func (GstElement * element)
493 {
494   GstClock *clock = NULL;
495   GstPipeline *pipeline = GST_PIPELINE (element);
496
497   /* if we have a fixed clock, use that one */
498   GST_LOCK (pipeline);
499   if (GST_FLAG_IS_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK)) {
500     clock = pipeline->fixed_clock;
501     gst_object_ref (clock);
502     GST_UNLOCK (pipeline);
503
504     GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)",
505         clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
506   } else {
507     GST_UNLOCK (pipeline);
508     clock =
509         GST_ELEMENT_CLASS (parent_class)->
510         provide_clock (GST_ELEMENT (pipeline));
511     /* no clock, use a system clock */
512     if (!clock) {
513       clock = gst_system_clock_obtain ();
514
515       GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained system clock: %p (%s)",
516           clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
517     } else {
518       GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained clock: %p (%s)",
519           clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
520     }
521   }
522   return clock;
523 }
524
525 /**
526  * gst_pipeline_get_clock:
527  * @pipeline: the pipeline
528  *
529  * Gets the current clock used by the pipeline.
530  *
531  * Returns: a GstClock
532  */
533 GstClock *
534 gst_pipeline_get_clock (GstPipeline * pipeline)
535 {
536   g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
537
538   return gst_pipeline_provide_clock_func (GST_ELEMENT (pipeline));
539 }
540
541
542 /**
543  * gst_pipeline_use_clock:
544  * @pipeline: the pipeline
545  * @clock: the clock to use
546  *
547  * Force the pipeline to use the given clock. The pipeline will
548  * always use the given clock even if new clock providers are added
549  * to this pipeline.
550  *
551  * MT safe.
552  */
553 void
554 gst_pipeline_use_clock (GstPipeline * pipeline, GstClock * clock)
555 {
556   g_return_if_fail (GST_IS_PIPELINE (pipeline));
557
558   GST_LOCK (pipeline);
559   GST_FLAG_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
560
561   gst_object_replace ((GstObject **) & pipeline->fixed_clock,
562       (GstObject *) clock);
563   GST_UNLOCK (pipeline);
564
565   GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)", clock,
566       (clock ? GST_OBJECT_NAME (clock) : "nil"));
567 }
568
569 /**
570  * gst_pipeline_set_clock:
571  * @pipeline: the pipeline
572  * @clock: the clock to set
573  *
574  * Set the clock for the pipeline. The clock will be distributed
575  * to all the elements managed by the pipeline.
576  *
577  * MT safe.
578  */
579 void
580 gst_pipeline_set_clock (GstPipeline * pipeline, GstClock * clock)
581 {
582   g_return_if_fail (pipeline != NULL);
583   g_return_if_fail (GST_IS_PIPELINE (pipeline));
584
585   GST_ELEMENT_CLASS (parent_class)->set_clock (GST_ELEMENT (pipeline), clock);
586 }
587
588 /**
589  * gst_pipeline_auto_clock:
590  * @pipeline: the pipeline
591  *
592  * Let the pipeline select a clock automatically.
593  *
594  * MT safe.
595  */
596 void
597 gst_pipeline_auto_clock (GstPipeline * pipeline)
598 {
599   g_return_if_fail (pipeline != NULL);
600   g_return_if_fail (GST_IS_PIPELINE (pipeline));
601
602   GST_LOCK (pipeline);
603   GST_FLAG_UNSET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
604
605   gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
606   GST_UNLOCK (pipeline);
607
608   GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
609 }