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