*.c: Don't cast to GST_OBJECT when reffing or unreffing. Large source-munging commit!!!
[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 "gstscheduler.h"
28 #include "gstsystemclock.h"
29
30 static GstElementDetails gst_pipeline_details =
31 GST_ELEMENT_DETAILS ("Pipeline object",
32     "Generic/Bin",
33     "Complete pipeline object",
34     "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
35
36 /* Pipeline signals and args */
37 enum
38 {
39   /* FILL ME */
40   LAST_SIGNAL
41 };
42
43 #define DEFAULT_DELAY 0
44 #define DEFAULT_PLAY_TIMEOUT  (2*GST_SECOND)
45 enum
46 {
47   ARG_0,
48   ARG_DELAY,
49   ARG_PLAY_TIMEOUT,
50   /* FILL ME */
51 };
52
53
54 static void gst_pipeline_base_init (gpointer g_class);
55 static void gst_pipeline_class_init (gpointer g_class, gpointer class_data);
56 static void gst_pipeline_init (GTypeInstance * instance, gpointer g_class);
57
58 static void gst_pipeline_dispose (GObject * object);
59 static void gst_pipeline_set_property (GObject * object, guint prop_id,
60     const GValue * value, GParamSpec * pspec);
61 static void gst_pipeline_get_property (GObject * object, guint prop_id,
62     GValue * value, GParamSpec * pspec);
63
64 static gboolean gst_pipeline_send_event (GstElement * element,
65     GstEvent * event);
66 static GstBusSyncReply pipeline_bus_handler (GstBus * bus, GstMessage * message,
67     GstPipeline * pipeline);
68
69 static GstClock *gst_pipeline_get_clock_func (GstElement * element);
70 static GstElementStateReturn gst_pipeline_change_state (GstElement * element);
71
72 static GstBinClass *parent_class = NULL;
73
74 /* static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 }; */
75
76 GType
77 gst_pipeline_get_type (void)
78 {
79   static GType pipeline_type = 0;
80
81   if (!pipeline_type) {
82     static const GTypeInfo pipeline_info = {
83       sizeof (GstPipelineClass),
84       gst_pipeline_base_init,
85       NULL,
86       (GClassInitFunc) gst_pipeline_class_init,
87       NULL,
88       NULL,
89       sizeof (GstPipeline),
90       0,
91       gst_pipeline_init,
92       NULL
93     };
94
95     pipeline_type =
96         g_type_register_static (GST_TYPE_BIN, "GstPipeline", &pipeline_info, 0);
97   }
98   return pipeline_type;
99 }
100
101 static void
102 gst_pipeline_base_init (gpointer g_class)
103 {
104   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
105
106   gst_element_class_set_details (gstelement_class, &gst_pipeline_details);
107 }
108
109 static void
110 gst_pipeline_class_init (gpointer g_class, gpointer class_data)
111 {
112   GObjectClass *gobject_class = G_OBJECT_CLASS (g_class);
113   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
114   GstPipelineClass *klass = GST_PIPELINE_CLASS (g_class);
115
116   parent_class = g_type_class_peek_parent (klass);
117
118   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_pipeline_set_property);
119   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_pipeline_get_property);
120
121   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DELAY,
122       g_param_spec_uint64 ("delay", "Delay",
123           "Expected delay needed for elements "
124           "to spin up to PLAYING in nanoseconds", 0, G_MAXUINT64, DEFAULT_DELAY,
125           G_PARAM_READWRITE));
126   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PLAY_TIMEOUT,
127       g_param_spec_uint64 ("play-timeout", "Play Timeout",
128           "Max timeout for going to PLAYING in nanoseconds", 0, G_MAXUINT64,
129           DEFAULT_PLAY_TIMEOUT, G_PARAM_READWRITE));
130
131   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose);
132
133   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_pipeline_send_event);
134   gstelement_class->change_state =
135       GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
136   gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_pipeline_get_clock_func);
137 }
138
139 static void
140 gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
141 {
142   GstScheduler *scheduler;
143   GstPipeline *pipeline = GST_PIPELINE (instance);
144   GstBus *bus;
145
146   /* get an instance of the default scheduler */
147   scheduler = gst_scheduler_factory_make (NULL, GST_ELEMENT (pipeline));
148
149   /* FIXME need better error handling */
150   if (scheduler == NULL) {
151     const gchar *name = gst_scheduler_factory_get_default_name ();
152
153     g_error ("Critical error: could not get scheduler \"%s\"\n"
154         "Are you sure you have a registry ?\n"
155         "Run gst-register as root if you haven't done so yet.", name);
156   } else {
157     gst_element_set_scheduler (GST_ELEMENT (pipeline), scheduler);
158     /* set_scheduler refs the bus via gst_object_replace, we drop our ref */
159     gst_object_unref ((GstObject *) scheduler);
160   }
161
162   pipeline->eosed = NULL;
163   pipeline->delay = DEFAULT_DELAY;
164   pipeline->play_timeout = DEFAULT_PLAY_TIMEOUT;
165   /* we are our own manager */
166   GST_ELEMENT_MANAGER (pipeline) = pipeline;
167
168   bus = g_object_new (gst_bus_get_type (), NULL);
169   gst_bus_set_sync_handler (bus,
170       (GstBusSyncHandler) pipeline_bus_handler, pipeline);
171   gst_element_set_bus (GST_ELEMENT (pipeline), bus);
172   /* set_bus refs the bus via gst_object_replace, we drop our ref */
173   gst_object_unref ((GstObject *) bus);
174 }
175
176 static void
177 gst_pipeline_dispose (GObject * object)
178 {
179   GstPipeline *pipeline = GST_PIPELINE (object);
180
181   gst_element_set_bus (GST_ELEMENT (pipeline), NULL);
182   gst_scheduler_reset (GST_ELEMENT_SCHEDULER (object));
183   gst_element_set_scheduler (GST_ELEMENT (pipeline), NULL);
184   gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
185
186   G_OBJECT_CLASS (parent_class)->dispose (object);
187 }
188
189 static void
190 gst_pipeline_set_property (GObject * object, guint prop_id,
191     const GValue * value, GParamSpec * pspec)
192 {
193   GstPipeline *pipeline = GST_PIPELINE (object);
194
195   GST_LOCK (pipeline);
196   switch (prop_id) {
197     case ARG_DELAY:
198       pipeline->delay = g_value_get_uint64 (value);
199       break;
200     case ARG_PLAY_TIMEOUT:
201       pipeline->play_timeout = g_value_get_uint64 (value);
202       break;
203     default:
204       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
205       break;
206   }
207   GST_UNLOCK (pipeline);
208 }
209
210 static void
211 gst_pipeline_get_property (GObject * object, guint prop_id,
212     GValue * value, GParamSpec * pspec)
213 {
214   GstPipeline *pipeline = GST_PIPELINE (object);
215
216   GST_LOCK (pipeline);
217   switch (prop_id) {
218     case ARG_DELAY:
219       g_value_set_uint64 (value, pipeline->delay);
220       break;
221     case ARG_PLAY_TIMEOUT:
222       g_value_set_uint64 (value, pipeline->play_timeout);
223       break;
224     default:
225       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
226       break;
227   }
228   GST_UNLOCK (pipeline);
229 }
230
231 static gboolean
232 is_eos (GstPipeline * pipeline)
233 {
234   GstIterator *sinks;
235   gboolean result = TRUE;
236   gboolean done = FALSE;
237
238   sinks = gst_bin_iterate_sinks (GST_BIN (pipeline));
239   while (!done) {
240     gpointer data;
241
242     switch (gst_iterator_next (sinks, &data)) {
243       case GST_ITERATOR_OK:
244       {
245         GstElement *element = GST_ELEMENT (data);
246         GList *eosed;
247         gchar *name;
248
249         name = gst_element_get_name (element);
250         eosed = g_list_find (pipeline->eosed, element);
251         if (!eosed) {
252           GST_DEBUG ("element %s did not post EOS yet", name);
253           result = FALSE;
254           done = TRUE;
255         } else {
256           GST_DEBUG ("element %s posted EOS", name);
257         }
258         g_free (name);
259         gst_object_unref (element);
260         break;
261       }
262       case GST_ITERATOR_RESYNC:
263         result = TRUE;
264         gst_iterator_resync (sinks);
265         break;
266       case GST_ITERATOR_DONE:
267         done = TRUE;
268         break;
269       default:
270         g_assert_not_reached ();
271         break;
272     }
273   }
274   gst_iterator_free (sinks);
275   return result;
276 }
277
278 /* sending an event on the pipeline pauses the pipeline if it
279  * was playing.
280  */
281 static gboolean
282 gst_pipeline_send_event (GstElement * element, GstEvent * event)
283 {
284   gboolean was_playing;
285   gboolean res;
286   GstElementState state;
287   GstEventType event_type = GST_EVENT_TYPE (event);
288   GTimeVal timeout;
289
290   /* need to call _get_state() since a bin state is only updated
291    * with this call. */
292   GST_TIME_TO_TIMEVAL (0, timeout);
293
294   gst_element_get_state (element, &state, NULL, &timeout);
295   was_playing = state == GST_STATE_PLAYING;
296
297   if (was_playing && event_type == GST_EVENT_SEEK)
298     gst_element_set_state (element, GST_STATE_PAUSED);
299
300   res = GST_ELEMENT_CLASS (parent_class)->send_event (element, event);
301
302   if (was_playing && event_type == GST_EVENT_SEEK)
303     gst_element_set_state (element, GST_STATE_PLAYING);
304
305   return res;
306 }
307
308 /* FIXME, make me threadsafe */
309 static GstBusSyncReply
310 pipeline_bus_handler (GstBus * bus, GstMessage * message,
311     GstPipeline * pipeline)
312 {
313   GstBusSyncReply result = GST_BUS_PASS;
314   gboolean posteos = FALSE;
315
316   /* we don't want messages from the streaming thread while we're doing the 
317    * state change. We do want them from the state change functions. */
318
319   switch (GST_MESSAGE_TYPE (message)) {
320     case GST_MESSAGE_EOS:
321       if (GST_MESSAGE_SRC (message) != GST_OBJECT (pipeline)) {
322         GST_DEBUG ("got EOS message");
323         GST_LOCK (bus);
324         pipeline->eosed =
325             g_list_prepend (pipeline->eosed, GST_MESSAGE_SRC (message));
326         GST_UNLOCK (bus);
327         if (is_eos (pipeline)) {
328           posteos = TRUE;
329           GST_DEBUG ("all sinks posted EOS");
330         }
331         /* we drop all EOS messages */
332         result = GST_BUS_DROP;
333         gst_message_unref (message);
334       }
335       break;
336     case GST_MESSAGE_ERROR:
337       break;
338     default:
339       break;
340   }
341
342   if (posteos) {
343     gst_bus_post (bus, gst_message_new_eos (GST_OBJECT (pipeline)));
344   }
345
346   return result;
347 }
348
349 /**
350  * gst_pipeline_new:
351  * @name: name of new pipeline
352  *
353  * Create a new pipeline with the given name.
354  *
355  * Returns: newly created GstPipeline
356  *
357  * MT safe.
358  */
359 GstElement *
360 gst_pipeline_new (const gchar * name)
361 {
362   return gst_element_factory_make ("pipeline", name);
363 }
364
365 /* MT safe */
366 static GstElementStateReturn
367 gst_pipeline_change_state (GstElement * element)
368 {
369   GstElementStateReturn result = GST_STATE_SUCCESS;
370   GstPipeline *pipeline = GST_PIPELINE (element);
371   gint transition = GST_STATE_TRANSITION (element);
372
373   switch (transition) {
374     case GST_STATE_NULL_TO_READY:
375       if (element->bus)
376         gst_bus_set_flushing (element->bus, FALSE);
377       gst_scheduler_setup (GST_ELEMENT_SCHEDULER (pipeline));
378       break;
379     case GST_STATE_READY_TO_PAUSED:
380     {
381       GstClock *clock;
382
383       clock = gst_element_get_clock (element);
384       gst_element_set_clock (element, clock);
385       pipeline->eosed = NULL;
386       break;
387     }
388     case GST_STATE_PAUSED_TO_PLAYING:
389       if (element->clock) {
390         GstClockTime start_time = gst_clock_get_time (element->clock);
391
392         element->base_time = start_time -
393             pipeline->stream_time + pipeline->delay;
394         GST_DEBUG ("stream_time=%" GST_TIME_FORMAT ", start_time=%"
395             GST_TIME_FORMAT ", base time %" GST_TIME_FORMAT,
396             GST_TIME_ARGS (pipeline->stream_time),
397             GST_TIME_ARGS (start_time), GST_TIME_ARGS (element->base_time));
398       } else {
399         element->base_time = 0;
400         GST_DEBUG ("no clock, using base time of 0");
401       }
402       break;
403     case GST_STATE_PLAYING_TO_PAUSED:
404     case GST_STATE_PAUSED_TO_READY:
405     case GST_STATE_READY_TO_NULL:
406       break;
407   }
408
409   result = GST_ELEMENT_CLASS (parent_class)->change_state (element);
410
411   switch (transition) {
412     case GST_STATE_READY_TO_PAUSED:
413       pipeline->stream_time = 0;
414       break;
415     case GST_STATE_PAUSED_TO_PLAYING:
416       break;
417     case GST_STATE_PLAYING_TO_PAUSED:
418       if (element->clock) {
419         GstClockTime now;
420
421         now = gst_clock_get_time (element->clock);
422         pipeline->stream_time = now - element->base_time;
423         GST_DEBUG ("stream_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT
424             ", base time %" GST_TIME_FORMAT,
425             GST_TIME_ARGS (pipeline->stream_time),
426             GST_TIME_ARGS (now), GST_TIME_ARGS (element->base_time));
427       }
428       break;
429     case GST_STATE_PAUSED_TO_READY:
430       break;
431     case GST_STATE_READY_TO_NULL:
432       if (element->bus) {
433         gst_bus_set_flushing (element->bus, TRUE);
434       }
435       break;
436   }
437
438   /* we wait for async state changes ourselves when we are in an
439    * intermediate state.
440    * FIXME this can block forever, better do this in a worker
441    * thread or use a timeout? */
442   if (result == GST_STATE_ASYNC &&
443       (GST_STATE_FINAL (pipeline) != GST_STATE_PENDING (pipeline))) {
444     GTimeVal *timeval, timeout;
445
446     GST_STATE_UNLOCK (pipeline);
447
448     GST_LOCK (pipeline);
449     if (pipeline->play_timeout > 0) {
450       GST_TIME_TO_TIMEVAL (pipeline->play_timeout, timeout);
451       timeval = &timeout;
452     } else {
453       timeval = NULL;
454     }
455     GST_UNLOCK (pipeline);
456
457     result = gst_element_get_state (element, NULL, NULL, timeval);
458     GST_STATE_LOCK (pipeline);
459   }
460
461   return result;
462 }
463
464 /**
465  * gst_pipeline_get_scheduler:
466  * @pipeline: the pipeline
467  *
468  * Gets the #GstScheduler of this pipeline.
469  *
470  * Returns: a GstScheduler.
471  *
472  * MT safe.
473  */
474 GstScheduler *
475 gst_pipeline_get_scheduler (GstPipeline * pipeline)
476 {
477   return gst_element_get_scheduler (GST_ELEMENT (pipeline));
478 }
479
480 /**
481  * gst_pipeline_get_bus:
482  * @pipeline: the pipeline
483  *
484  * Gets the #GstBus of this pipeline.
485  *
486  * Returns: a GstBus
487  *
488  * MT safe.
489  */
490 GstBus *
491 gst_pipeline_get_bus (GstPipeline * pipeline)
492 {
493   return gst_element_get_bus (GST_ELEMENT (pipeline));
494 }
495
496 static GstClock *
497 gst_pipeline_get_clock_func (GstElement * element)
498 {
499   GstClock *clock = NULL;
500   GstPipeline *pipeline = GST_PIPELINE (element);
501
502   /* if we have a fixed clock, use that one */
503   GST_LOCK (pipeline);
504   if (GST_FLAG_IS_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK)) {
505     clock = pipeline->fixed_clock;
506     gst_object_ref (clock);
507     GST_UNLOCK (pipeline);
508
509     GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)",
510         clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
511   } else {
512     GST_UNLOCK (pipeline);
513     clock =
514         GST_ELEMENT_CLASS (parent_class)->get_clock (GST_ELEMENT (pipeline));
515     /* no clock, use a system clock */
516     if (!clock) {
517       clock = gst_system_clock_obtain ();
518       /* we unref since this function is not supposed to increase refcount
519        * of clock object returned; this is ok since the systemclock always
520        * has a refcount of at least one in the current code. */
521       gst_object_unref (clock);
522       GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained system clock: %p (%s)",
523           clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
524     } else {
525       GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline obtained clock: %p (%s)",
526           clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-");
527     }
528   }
529   return clock;
530 }
531
532 /**
533  * gst_pipeline_get_clock:
534  * @pipeline: the pipeline
535  *
536  * Gets the current clock used by the pipeline.
537  *
538  * Returns: a GstClock
539  */
540 GstClock *
541 gst_pipeline_get_clock (GstPipeline * pipeline)
542 {
543   g_return_val_if_fail (GST_IS_PIPELINE (pipeline), NULL);
544
545   return gst_pipeline_get_clock_func (GST_ELEMENT (pipeline));
546 }
547
548
549 /**
550  * gst_pipeline_use_clock:
551  * @pipeline: the pipeline
552  * @clock: the clock to use
553  *
554  * Force the pipeline to use the given clock. The pipeline will
555  * always use the given clock even if new clock providers are added
556  * to this pipeline.
557  *
558  * MT safe.
559  */
560 void
561 gst_pipeline_use_clock (GstPipeline * pipeline, GstClock * clock)
562 {
563   g_return_if_fail (GST_IS_PIPELINE (pipeline));
564
565   GST_LOCK (pipeline);
566   GST_FLAG_SET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
567
568   gst_object_replace ((GstObject **) & pipeline->fixed_clock,
569       (GstObject *) clock);
570   GST_UNLOCK (pipeline);
571
572   GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using fixed clock %p (%s)", clock,
573       (clock ? GST_OBJECT_NAME (clock) : "nil"));
574 }
575
576 /**
577  * gst_pipeline_set_clock:
578  * @pipeline: the pipeline
579  * @clock: the clock to set
580  *
581  * Set the clock for the pipeline. The clock will be distributed
582  * to all the elements managed by the pipeline.
583  *
584  * MT safe.
585  */
586 void
587 gst_pipeline_set_clock (GstPipeline * pipeline, GstClock * clock)
588 {
589   g_return_if_fail (pipeline != NULL);
590   g_return_if_fail (GST_IS_PIPELINE (pipeline));
591
592   GST_ELEMENT_CLASS (parent_class)->set_clock (GST_ELEMENT (pipeline), clock);
593 }
594
595 /**
596  * gst_pipeline_auto_clock:
597  * @pipeline: the pipeline
598  *
599  * Let the pipeline select a clock automatically.
600  *
601  * MT safe.
602  */
603 void
604 gst_pipeline_auto_clock (GstPipeline * pipeline)
605 {
606   g_return_if_fail (pipeline != NULL);
607   g_return_if_fail (GST_IS_PIPELINE (pipeline));
608
609   GST_LOCK (pipeline);
610   GST_FLAG_UNSET (pipeline, GST_PIPELINE_FLAG_FIXED_CLOCK);
611
612   gst_object_replace ((GstObject **) & pipeline->fixed_clock, NULL);
613   GST_UNLOCK (pipeline);
614
615   GST_CAT_DEBUG (GST_CAT_CLOCK, "pipeline using automatic clock");
616 }