gst/gstbin.c: Move ASYNC_START message posting to where it belongs, similar to async_...
[platform/upstream/gstreamer.git] / gst / gstbin.c
1 /* GStreamer
2  *
3  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
4  *                    2004 Wim Taymans <wim@fluendo.com>
5  *
6  * gstbin.c: GstBin container object and support code
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  *
23  * MT safe.
24  */
25
26 /**
27  * SECTION:gstbin
28  * @short_description: Base class and element that can contain other elements
29  *
30  * #GstBin is an element that can contain other #GstElement, allowing them to be
31  * managed as a group.
32  * Pads from the child elements can be ghosted to the bin, see #GstGhostPad.
33  * This makes the bin look like any other elements and enables creation of
34  * higher-level abstraction elements.
35  *
36  * A new #GstBin is created with gst_bin_new(). Use a #GstPipeline instead if you
37  * want to create a toplevel bin because a normal bin doesn't have a bus or
38  * handle clock distribution of its own.
39  *
40  * After the bin has been created you will typically add elements to it with
41  * gst_bin_add(). You can remove elements with gst_bin_remove().
42  *
43  * An element can be retrieved from a bin with gst_bin_get_by_name(), using the
44  * elements name. gst_bin_get_by_name_recurse_up() is mainly used for internal
45  * purposes and will query the parent bins when the element is not found in the
46  * current bin.
47  *
48  * An iterator of elements in a bin can be retrieved with
49  * gst_bin_iterate_elements(). Various other iterators exist to retrieve the
50  * elements in a bin.
51  *
52  * gst_object_unref() is used to drop your reference to the bin.
53  *
54  * The <link linkend="GstBin-element-added">element-added</link> signal is
55  * fired whenever a new element is added to the bin. Likewise the <link
56  * linkend="GstBin-element-removed">element-removed</link> signal is fired
57  * whenever an element is removed from the bin.
58  *
59  * <refsect2><title>Notes</title>
60  * <para>
61  * A #GstBin internally intercepts every #GstMessage posted by its children and
62  * implements the following default behaviour for each of them:
63  * <variablelist>
64  *   <varlistentry>
65  *     <term>GST_MESSAGE_EOS</term>
66  *     <listitem><para>This message is only posted by sinks in the PLAYING
67  *     state. If all sinks posted the EOS message, this bin will post and EOS
68  *     message upwards.</para></listitem>
69  *   </varlistentry>
70  *   <varlistentry>
71  *     <term>GST_MESSAGE_SEGMENT_START</term>
72  *     <listitem><para>just collected and never forwarded upwards.
73  *     The messages are used to decide when all elements have completed playback
74  *     of their segment.</para></listitem>
75  *   </varlistentry>
76  *   <varlistentry>
77  *     <term>GST_MESSAGE_SEGMENT_DONE</term>
78  *     <listitem><para> Is posted by #GstBin when all elements that posted
79  *     a SEGMENT_START have posted a SEGMENT_DONE.</para></listitem>
80  *   </varlistentry>
81  *   <varlistentry>
82  *     <term>GST_MESSAGE_DURATION</term>
83  *     <listitem><para> Is posted by an element that detected a change
84  *     in the stream duration. The default bin behaviour is to clear any
85  *     cached duration values so that the next duration query will perform
86  *     a full duration recalculation. The duration change is posted to the
87  *     application so that it can refetch the new duration with a duration
88  *     query.
89  *     </para></listitem>
90  *   </varlistentry>
91  *   <varlistentry>
92  *     <term>GST_MESSAGE_CLOCK_LOST</term>
93  *     <listitem><para> This message is posted by an element when it
94  *     can no longer provide a clock. The default bin behaviour is to
95  *     check if the lost clock was the one provided by the bin. If so and
96  *     the bin is currently in the PLAYING state, the message is forwarded to
97  *     the bin parent.
98  *     This message is also generated when a clock provider is removed from
99  *     the bin. If this message is received by the application, it should
100  *     PAUSE the pipeline and set it back to PLAYING to force a new clock
101  *     distribution.
102  *     </para></listitem>
103  *   </varlistentry>
104  *   <varlistentry>
105  *     <term>GST_MESSAGE_CLOCK_PROVIDE</term>
106  *     <listitem><para> This message is generated when an element
107  *     can provide a clock. This mostly happens when a new clock
108  *     provider is added to the bin. The default behaviour of the bin is to
109  *     mark the currently selected clock as dirty, which will perform a clock
110  *     recalculation the next time the bin is asked to provide a clock.
111  *     This message is never sent tot the application but is forwarded to
112  *     the parent of the bin.
113  *     </para></listitem>
114  *   </varlistentry>
115  *   <varlistentry>
116  *     <term>OTHERS</term>
117  *     <listitem><para> posted upwards.</para></listitem>
118  *   </varlistentry>
119  * </variablelist>
120  *
121  *
122  * A #GstBin implements the following default behaviour for answering to a
123  * #GstQuery:
124  * <variablelist>
125  *   <varlistentry>
126  *     <term>GST_QUERY_DURATION</term>
127  *     <listitem><para>If the query has been asked before with the same format
128  *     and the bin is a toplevel bin (ie. has no parent),
129  *     use the cached previous value. If no previous value was cached, the
130  *     query is sent to all sink elements in the bin and the MAXIMUM of all
131  *     values is returned. If the bin is a toplevel bin the value is cached.
132  *     If no sinks are available in the bin, the query fails.
133  *     </para></listitem>
134  *   </varlistentry>
135  *   <varlistentry>
136  *     <term>GST_QUERY_POSITION</term>
137  *     <listitem><para>The query is sent to all sink elements in the bin and the
138  *     MAXIMUM of all values is returned. If no sinks are available in the bin,
139  *     the query fails.
140  *     </para></listitem>
141  *   </varlistentry>
142  *   <varlistentry>
143  *     <term>OTHERS</term>
144  *     <listitem><para>the query is forwarded to all sink elements, the result
145  *     of the first sink that answers the query successfully is returned. If no
146  *     sink is in the bin, the query fails.</para></listitem>
147  *   </varlistentry>
148  * </variablelist>
149  *
150  * A #GstBin will by default forward any event sent to it to all sink elements.
151  * If all the sinks return TRUE, the bin will also return TRUE, else FALSE is
152  * returned. If no sinks are in the bin, the event handler will return TRUE.
153  *
154  * </para>
155  * </refsect2>
156  *
157  * Last reviewed on 2006-04-28 (0.10.6)
158  */
159
160 #include "gst_private.h"
161
162 #include "gstevent.h"
163 #include "gstbin.h"
164 #include "gstmarshal.h"
165 #include "gstxml.h"
166 #include "gstinfo.h"
167 #include "gsterror.h"
168
169 #include "gstindex.h"
170 #include "gstindexfactory.h"
171 #include "gstutils.h"
172 #include "gstchildproxy.h"
173
174 /* enable for DURATION caching.
175  * FIXME currently too many elements don't update
176  * their duration when it changes so we return inaccurate values. */
177 #undef DURATION_CACHING
178
179 /* latency is by default enabled now.
180  * live-preroll and no-live-preroll in the environment var GST_COMPAT
181  * to enables or disable it respectively.
182  */
183 static gboolean enable_latency = TRUE;
184
185 GST_DEBUG_CATEGORY_STATIC (bin_debug);
186 #define GST_CAT_DEFAULT bin_debug
187
188 static const GstElementDetails gst_bin_details =
189 GST_ELEMENT_DETAILS ("Generic bin",
190     "Generic/Bin",
191     "Simple container object",
192     "Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
193
194 /* a bin is toplevel if it has no parent or when it is configured to behave like
195  * a toplevel bin */
196 #define BIN_IS_TOPLEVEL(bin) ((GST_OBJECT_PARENT (bin) == NULL) || bin->priv->asynchandling)
197
198 struct _GstBinPrivate
199 {
200   gboolean asynchandling;
201 };
202
203 typedef struct
204 {
205   GstBin *bin;
206   guint32 cookie;
207   GstState pending;
208 } BinContinueData;
209
210 static void gst_bin_dispose (GObject * object);
211
212 static void gst_bin_set_property (GObject * object, guint prop_id,
213     const GValue * value, GParamSpec * pspec);
214 static void gst_bin_get_property (GObject * object, guint prop_id,
215     GValue * value, GParamSpec * pspec);
216
217 static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
218     GstStateChange transition);
219 static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
220     GstState * state, GstState * pending, GstClockTime timeout);
221 static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret);
222 static void bin_handle_async_start (GstBin * bin, gboolean new_base_time);
223 static void bin_push_state_continue (BinContinueData * data);
224
225 static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
226 static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
227
228 #ifndef GST_DISABLE_INDEX
229 static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
230 #endif
231 static GstClock *gst_bin_provide_clock_func (GstElement * element);
232 static gboolean gst_bin_set_clock_func (GstElement * element, GstClock * clock);
233
234 static void gst_bin_handle_message_func (GstBin * bin, GstMessage * message);
235 static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
236 static GstBusSyncReply bin_bus_handler (GstBus * bus,
237     GstMessage * message, GstBin * bin);
238 static gboolean gst_bin_query (GstElement * element, GstQuery * query);
239
240 #ifndef GST_DISABLE_LOADSAVE
241 static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
242 static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
243 #endif
244
245 static void bin_remove_messages (GstBin * bin, GstObject * src,
246     GstMessageType types);
247 static void gst_bin_continue_func (BinContinueData * data);
248 static gint bin_element_is_sink (GstElement * child, GstBin * bin);
249 static gint bin_element_is_src (GstElement * child, GstBin * bin);
250
251 static GstIterator *gst_bin_sort_iterator_new (GstBin * bin);
252
253 /* Bin signals and properties */
254 enum
255 {
256   ELEMENT_ADDED,
257   ELEMENT_REMOVED,
258   LAST_SIGNAL
259 };
260
261 enum
262 {
263   PROP_0,
264   PROP_ASYNC_HANDLING
265       /* FILL ME */
266 };
267
268 static void gst_bin_base_init (gpointer g_class);
269 static void gst_bin_class_init (GstBinClass * klass);
270 static void gst_bin_init (GstBin * bin);
271 static void gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data);
272
273 static GstElementClass *parent_class = NULL;
274 static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
275
276 /**
277  * gst_bin_get_type:
278  *
279  * Returns: the type of #GstBin
280  */
281 GType
282 gst_bin_get_type (void)
283 {
284   static GType gst_bin_type = 0;
285   const gchar *compat;
286
287   if (G_UNLIKELY (gst_bin_type == 0)) {
288     static const GTypeInfo bin_info = {
289       sizeof (GstBinClass),
290       gst_bin_base_init,
291       NULL,
292       (GClassInitFunc) gst_bin_class_init,
293       NULL,
294       NULL,
295       sizeof (GstBin),
296       0,
297       (GInstanceInitFunc) gst_bin_init,
298       NULL
299     };
300     static const GInterfaceInfo child_proxy_info = {
301       gst_bin_child_proxy_init,
302       NULL,
303       NULL
304     };
305
306     gst_bin_type =
307         g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
308
309     g_type_add_interface_static (gst_bin_type, GST_TYPE_CHILD_PROXY,
310         &child_proxy_info);
311
312     GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD,
313         "debugging info for the 'bin' container element");
314
315     /* compatibility stuff */
316     compat = g_getenv ("GST_COMPAT");
317     if (compat != NULL) {
318       if (strstr (compat, "no-live-preroll"))
319         enable_latency = FALSE;
320       else if (strstr (compat, "live-preroll"))
321         enable_latency = TRUE;
322     }
323   }
324   return gst_bin_type;
325 }
326
327 static void
328 gst_bin_base_init (gpointer g_class)
329 {
330   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
331
332   gst_element_class_set_details (gstelement_class, &gst_bin_details);
333 }
334
335 static GstObject *
336 gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
337     guint index)
338 {
339   GstObject *res;
340   GstBin *bin;
341
342   bin = GST_BIN_CAST (child_proxy);
343
344   GST_OBJECT_LOCK (bin);
345   if ((res = g_list_nth_data (bin->children, index)))
346     gst_object_ref (res);
347   GST_OBJECT_UNLOCK (bin);
348
349   return res;
350 }
351
352 guint
353 gst_bin_child_proxy_get_children_count (GstChildProxy * child_proxy)
354 {
355   guint num;
356   GstBin *bin;
357
358   bin = GST_BIN_CAST (child_proxy);
359
360   GST_OBJECT_LOCK (bin);
361   num = bin->numchildren;
362   GST_OBJECT_UNLOCK (bin);
363
364   return num;
365 }
366
367 static void
368 gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data)
369 {
370   GstChildProxyInterface *iface = g_iface;
371
372   iface->get_children_count = gst_bin_child_proxy_get_children_count;
373   iface->get_child_by_index = gst_bin_child_proxy_get_child_by_index;
374 }
375
376 static void
377 gst_bin_class_init (GstBinClass * klass)
378 {
379   GObjectClass *gobject_class;
380   GstObjectClass *gstobject_class;
381   GstElementClass *gstelement_class;
382   GError *err;
383
384   gobject_class = (GObjectClass *) klass;
385   gstobject_class = (GstObjectClass *) klass;
386   gstelement_class = (GstElementClass *) klass;
387
388   parent_class = g_type_class_peek_parent (klass);
389
390   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bin_set_property);
391   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bin_get_property);
392
393   /**
394    * GstBin:async-handling
395    *
396    * If set to #TRUE, the bin will handle asynchronous state changes.
397    * This should be used only if the bin subclass is modifying the state
398    * of its childs on its own.
399    *
400    * Since: 0.10.13
401    */
402   g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
403       g_param_spec_boolean ("async-handling", "Async Handling",
404           "The bin will handle Asynchronous state changes",
405           FALSE, G_PARAM_READWRITE));
406
407   /**
408    * GstBin::element-added:
409    * @bin: the #GstBin
410    * @element: the #GstElement that was added to the bin
411    *
412    * Will be emitted after the element was added to the bin.
413    */
414   gst_bin_signals[ELEMENT_ADDED] =
415       g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
416       G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
417       NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
418   /**
419    * GstBin::element-removed:
420    * @bin: the #GstBin
421    * @element: the #GstElement that was removed from the bin
422    *
423    * Will be emitted after the element was removed from the bin.
424    */
425   gst_bin_signals[ELEMENT_REMOVED] =
426       g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
427       G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
428       NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
429
430   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
431
432 #ifndef GST_DISABLE_LOADSAVE
433   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
434   gstobject_class->restore_thyself =
435       GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
436 #endif
437
438   gstelement_class->change_state =
439       GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
440   gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
441 #ifndef GST_DISABLE_INDEX
442   gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
443 #endif
444   gstelement_class->provide_clock =
445       GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
446   gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
447
448   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
449   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_bin_query);
450
451   klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
452   klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
453   klass->handle_message = GST_DEBUG_FUNCPTR (gst_bin_handle_message_func);
454
455   GST_DEBUG ("creating bin thread pool");
456   err = NULL;
457   klass->pool =
458       g_thread_pool_new ((GFunc) gst_bin_continue_func, NULL, -1, FALSE, &err);
459   if (err != NULL) {
460     g_critical ("could alloc threadpool %s", err->message);
461   }
462 }
463
464 static void
465 gst_bin_init (GstBin * bin)
466 {
467   GstBus *bus;
468
469   bin->numchildren = 0;
470   bin->children = NULL;
471   bin->children_cookie = 0;
472   bin->messages = NULL;
473   bin->provided_clock = NULL;
474   bin->clock_dirty = FALSE;
475
476   /* Set up a bus for listening to child elements */
477   bus = gst_bus_new ();
478   bin->child_bus = bus;
479   GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
480       bus);
481   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
482
483   bin->priv = g_new0 (GstBinPrivate, 1);
484   bin->priv->asynchandling = FALSE;
485 }
486
487 static void
488 gst_bin_dispose (GObject * object)
489 {
490   GstBin *bin = GST_BIN (object);
491   GstBus **child_bus_p = &bin->child_bus;
492   GstClock **provided_clock_p = &bin->provided_clock;
493   GstElement **clock_provider_p = &bin->clock_provider;
494
495   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
496
497   bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
498
499   gst_object_replace ((GstObject **) child_bus_p, NULL);
500   gst_object_replace ((GstObject **) provided_clock_p, NULL);
501   gst_object_replace ((GstObject **) clock_provider_p, NULL);
502
503   while (bin->children) {
504     gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
505   }
506   if (G_UNLIKELY (bin->children != NULL)) {
507     g_critical ("could not remove elements from bin %s",
508         GST_STR_NULL (GST_OBJECT_NAME (object)));
509   }
510
511   if (bin->priv) {
512     g_free (bin->priv);
513     bin->priv = NULL;
514   }
515
516   G_OBJECT_CLASS (parent_class)->dispose (object);
517 }
518
519 /**
520  * gst_bin_new:
521  * @name: the name of the new bin
522  *
523  * Creates a new bin with the given name.
524  *
525  * Returns: a new #GstBin
526  */
527 GstElement *
528 gst_bin_new (const gchar * name)
529 {
530   return gst_element_factory_make ("bin", name);
531 }
532
533 static void
534 gst_bin_set_property (GObject * object, guint prop_id,
535     const GValue * value, GParamSpec * pspec)
536 {
537   GstBin *gstbin;
538
539   gstbin = GST_BIN (object);
540
541   switch (prop_id) {
542     case PROP_ASYNC_HANDLING:
543       GST_OBJECT_LOCK (gstbin);
544       gstbin->priv->asynchandling = g_value_get_boolean (value);
545       GST_OBJECT_UNLOCK (gstbin);
546       break;
547     default:
548       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
549       break;
550   }
551 }
552
553 static void
554 gst_bin_get_property (GObject * object, guint prop_id,
555     GValue * value, GParamSpec * pspec)
556 {
557   GstBin *gstbin;
558
559   gstbin = GST_BIN (object);
560
561   switch (prop_id) {
562     case PROP_ASYNC_HANDLING:
563       GST_OBJECT_LOCK (gstbin);
564       g_value_set_boolean (value, gstbin->priv->asynchandling);
565       GST_OBJECT_UNLOCK (gstbin);
566       break;
567     default:
568       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
569       break;
570   }
571 }
572
573 /* set the index on all elements in this bin
574  *
575  * MT safe
576  */
577 #ifndef GST_DISABLE_INDEX
578 static void
579 gst_bin_set_index_func (GstElement * element, GstIndex * index)
580 {
581   GstBin *bin;
582   GList *children;
583
584   bin = GST_BIN (element);
585
586   GST_OBJECT_LOCK (bin);
587   for (children = bin->children; children; children = g_list_next (children)) {
588     GstElement *child = GST_ELEMENT (children->data);
589
590     gst_element_set_index (child, index);
591   }
592   GST_OBJECT_UNLOCK (bin);
593 }
594 #endif
595
596 /* set the clock on all elements in this bin
597  *
598  * MT safe
599  */
600 static gboolean
601 gst_bin_set_clock_func (GstElement * element, GstClock * clock)
602 {
603   GList *children;
604   GstBin *bin;
605   gboolean res = TRUE;
606
607   bin = GST_BIN (element);
608
609   GST_OBJECT_LOCK (bin);
610   if (element->clock != clock) {
611     for (children = bin->children; children; children = g_list_next (children)) {
612       GstElement *child = GST_ELEMENT (children->data);
613
614       res &= gst_element_set_clock (child, clock);
615     }
616   }
617   GST_OBJECT_UNLOCK (bin);
618
619   return res;
620 }
621
622 /* get the clock for this bin by asking all of the children in this bin
623  *
624  * The ref of the returned clock in increased so unref after usage.
625  *
626  * We loop the elements in state order and pick the last clock we can
627  * get. This makes sure we get a clock from the source.
628  *
629  * MT safe
630  */
631 static GstClock *
632 gst_bin_provide_clock_func (GstElement * element)
633 {
634   GstClock *result = NULL;
635   GstElement *provider = NULL;
636   GstBin *bin;
637   GstIterator *it;
638   gpointer val;
639   GstClock **provided_clock_p;
640   GstElement **clock_provider_p;
641
642   bin = GST_BIN (element);
643
644   GST_OBJECT_LOCK (bin);
645   if (!bin->clock_dirty)
646     goto not_dirty;
647
648   GST_DEBUG_OBJECT (bin, "finding new clock");
649
650   it = gst_bin_sort_iterator_new (bin);
651
652   while (it->next (it, &val) == GST_ITERATOR_OK) {
653     GstElement *child = GST_ELEMENT_CAST (val);
654     GstClock *clock;
655
656     clock = gst_element_provide_clock (child);
657     if (clock) {
658       GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
659           clock, GST_ELEMENT_NAME (child));
660       if (result) {
661         gst_object_unref (result);
662         gst_object_unref (provider);
663       }
664       result = clock;
665       provider = child;
666     } else {
667       gst_object_unref (child);
668     }
669   }
670
671   provided_clock_p = &bin->provided_clock;
672   clock_provider_p = &bin->clock_provider;
673   gst_object_replace ((GstObject **) provided_clock_p, (GstObject *) result);
674   gst_object_replace ((GstObject **) clock_provider_p, (GstObject *) provider);
675   bin->clock_dirty = FALSE;
676   GST_DEBUG_OBJECT (bin,
677       "provided new clock %" GST_PTR_FORMAT " by provider %" GST_PTR_FORMAT,
678       result, provider);
679   /* Provider is not being returned to caller, just the result */
680   if (provider)
681     gst_object_unref (provider);
682   GST_OBJECT_UNLOCK (bin);
683
684   gst_iterator_free (it);
685
686   return result;
687
688 not_dirty:
689   {
690     if ((result = bin->provided_clock))
691       gst_object_ref (result);
692     GST_DEBUG_OBJECT (bin, "returning old clock %p", result);
693     GST_OBJECT_UNLOCK (bin);
694
695     return result;
696   }
697 }
698
699 /*
700  * functions for manipulating cached messages
701  */
702 typedef struct
703 {
704   GstObject *src;
705   GstMessageType types;
706 } MessageFind;
707
708 /* check if a message is of given src and type */
709 static gint
710 message_check (GstMessage * message, MessageFind * target)
711 {
712   gboolean eq = TRUE;
713
714   if (target->src)
715     eq &= GST_MESSAGE_SRC (message) == target->src;
716   if (target->types)
717     eq &= (GST_MESSAGE_TYPE (message) & target->types) != 0;
718
719   return (eq ? 0 : 1);
720 }
721
722 static GList *
723 find_message (GstBin * bin, GstObject * src, GstMessageType types)
724 {
725   GList *result;
726   MessageFind find;
727
728   find.src = src;
729   find.types = types;
730
731   result = g_list_find_custom (bin->messages, &find,
732       (GCompareFunc) message_check);
733
734   if (result) {
735     GST_DEBUG_OBJECT (bin, "we found a message %p from %s mathing types %08x",
736         result->data, GST_OBJECT_NAME (GST_MESSAGE_CAST (result->data)->src),
737         types);
738   } else {
739     GST_DEBUG_OBJECT (bin, "no message found matching types %08x", types);
740   }
741
742   return result;
743 }
744
745 /* with LOCK, returns TRUE if message had a valid SRC, takes ref on
746  * the message.
747  *
748  * A message that is cached and has the same SRC and type is replaced
749  * by the given message.
750  */
751 static gboolean
752 bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
753 {
754   GList *previous;
755   GstObject *src;
756   gboolean res = TRUE;
757   const gchar *name;
758
759   name = GST_MESSAGE_TYPE_NAME (message);
760
761   if ((src = GST_MESSAGE_SRC (message))) {
762     /* first find the previous message posted by this element */
763     if ((previous = find_message (bin, src, types))) {
764       /* if we found a previous message, replace it */
765       gst_message_unref (previous->data);
766       previous->data = message;
767
768       GST_DEBUG_OBJECT (bin, "replace old message %s from %s",
769           name, GST_ELEMENT_NAME (src));
770     } else {
771       /* keep new message */
772       bin->messages = g_list_prepend (bin->messages, message);
773
774       GST_DEBUG_OBJECT (bin, "got new message %p, %s from %s",
775           message, name, GST_ELEMENT_NAME (src));
776     }
777   } else {
778     GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing", name);
779     res = FALSE;
780     gst_message_unref (message);
781   }
782   return res;
783 }
784
785 /* with LOCK. Remove all messages of given types */
786 static void
787 bin_remove_messages (GstBin * bin, GstObject * src, GstMessageType types)
788 {
789   MessageFind find;
790   GList *walk, *next;
791
792   find.src = src;
793   find.types = types;
794
795   for (walk = bin->messages; walk; walk = next) {
796     GstMessage *message = (GstMessage *) walk->data;
797
798     next = g_list_next (walk);
799
800     if (message_check (message, &find) == 0) {
801       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
802           "deleting message %p of types 0x%08x", message, types);
803       bin->messages = g_list_delete_link (bin->messages, walk);
804       gst_message_unref (message);
805     } else {
806       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
807           "not deleting message %p of type 0x%08x", message,
808           GST_MESSAGE_TYPE (message));
809     }
810   }
811 }
812
813
814 /* Check if the bin is EOS. We do this by scanning all sinks and
815  * checking if they posted an EOS message.
816  *
817  * call with bin LOCK */
818 static gboolean
819 is_eos (GstBin * bin)
820 {
821   gboolean result;
822   GList *walk;
823
824   result = TRUE;
825   for (walk = bin->children; walk; walk = g_list_next (walk)) {
826     GstElement *element;
827
828     element = GST_ELEMENT_CAST (walk->data);
829     if (bin_element_is_sink (element, bin) == 0) {
830       /* check if element posted EOS */
831       if (find_message (bin, GST_OBJECT_CAST (element), GST_MESSAGE_EOS)) {
832         GST_DEBUG ("element posted EOS");
833       } else {
834         GST_DEBUG ("element did not post EOS yet");
835         result = FALSE;
836         break;
837       }
838     }
839   }
840   return result;
841 }
842
843 static void
844 unlink_pads (GstPad * pad)
845 {
846   GstPad *peer;
847
848   if ((peer = gst_pad_get_peer (pad))) {
849     if (gst_pad_get_direction (pad) == GST_PAD_SRC)
850       gst_pad_unlink (pad, peer);
851     else
852       gst_pad_unlink (peer, pad);
853     gst_object_unref (peer);
854   }
855   gst_object_unref (pad);
856 }
857
858 /* vmethod that adds an element to a bin
859  *
860  * MT safe
861  */
862 static gboolean
863 gst_bin_add_func (GstBin * bin, GstElement * element)
864 {
865   gchar *elem_name;
866   GstIterator *it;
867   gboolean is_sink;
868   GstMessage *clock_message = NULL;
869   GstStateChangeReturn ret;
870
871   GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
872
873   /* we obviously can't add ourself to ourself */
874   if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
875     goto adding_itself;
876
877   /* get the element name to make sure it is unique in this bin. */
878   GST_OBJECT_LOCK (element);
879   elem_name = g_strdup (GST_ELEMENT_NAME (element));
880   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
881   GST_OBJECT_UNLOCK (element);
882
883   GST_OBJECT_LOCK (bin);
884
885   /* then check to see if the element's name is already taken in the bin,
886    * we can safely take the lock here. This check is probably bogus because
887    * you can safely change the element name after this check and before setting
888    * the object parent. The window is very small though... */
889   if (G_UNLIKELY (!gst_object_check_uniqueness (bin->children, elem_name)))
890     goto duplicate_name;
891
892   /* set the element's parent and add the element to the bin's list of children */
893   if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (element),
894               GST_OBJECT_CAST (bin))))
895     goto had_parent;
896
897   /* if we add a sink we become a sink */
898   if (is_sink) {
899     GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was sink",
900         elem_name);
901     GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SINK);
902   }
903   if (gst_element_provides_clock (element)) {
904     GST_DEBUG_OBJECT (bin, "element \"%s\" can provide a clock", elem_name);
905     bin->clock_dirty = TRUE;
906     clock_message =
907         gst_message_new_clock_provide (GST_OBJECT_CAST (bin), NULL, TRUE);
908   }
909
910   bin->children = g_list_prepend (bin->children, element);
911   bin->numchildren++;
912   bin->children_cookie++;
913
914   ret = GST_STATE_RETURN (bin);
915
916   /* no need to update the state if we are in error */
917   if (ret == GST_STATE_CHANGE_FAILURE)
918     goto no_state_recalc;
919
920   /* update the bin state, the new element could have been an ASYNC or
921    * NO_PREROLL element */
922   ret = GST_STATE_RETURN (element);
923   GST_DEBUG_OBJECT (bin, "added %s element",
924       gst_element_state_change_return_get_name (ret));
925
926   switch (ret) {
927     case GST_STATE_CHANGE_ASYNC:
928       bin_handle_async_start (bin, FALSE);
929       break;
930     case GST_STATE_CHANGE_NO_PREROLL:
931       bin_handle_async_done (bin, ret);
932       break;
933     case GST_STATE_CHANGE_FAILURE:
934       break;
935     default:
936       break;
937   }
938
939 no_state_recalc:
940   /* distribute the bus */
941   gst_element_set_bus (element, bin->child_bus);
942
943   /* propagate the current base_time and clock */
944   gst_element_set_base_time (element, GST_ELEMENT (bin)->base_time);
945   /* it's possible that the element did not accept the clock but
946    * that is not important right now. When the pipeline goes to PLAYING,
947    * a new clock will be selected */
948   gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
949   GST_OBJECT_UNLOCK (bin);
950
951   if (clock_message)
952     gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
953
954   /* unlink all linked pads */
955   it = gst_element_iterate_pads (element);
956   gst_iterator_foreach (it, (GFunc) unlink_pads, element);
957   gst_iterator_free (it);
958
959   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
960       elem_name);
961   g_free (elem_name);
962
963   g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
964
965   return TRUE;
966
967   /* ERROR handling here */
968 adding_itself:
969   {
970     GST_OBJECT_LOCK (bin);
971     g_warning ("Cannot add bin %s to itself", GST_ELEMENT_NAME (bin));
972     GST_OBJECT_UNLOCK (bin);
973     return FALSE;
974   }
975 duplicate_name:
976   {
977     g_warning ("Name %s is not unique in bin %s, not adding",
978         elem_name, GST_ELEMENT_NAME (bin));
979     GST_OBJECT_UNLOCK (bin);
980     g_free (elem_name);
981     return FALSE;
982   }
983 had_parent:
984   {
985     g_warning ("Element %s already has parent", elem_name);
986     GST_OBJECT_UNLOCK (bin);
987     g_free (elem_name);
988     return FALSE;
989   }
990 }
991
992 /**
993  * gst_bin_add:
994  * @bin: a #GstBin
995  * @element: the #GstElement to add
996  *
997  * Adds the given element to the bin.  Sets the element's parent, and thus
998  * takes ownership of the element. An element can only be added to one bin.
999  *
1000  * If the element's pads are linked to other pads, the pads will be unlinked
1001  * before the element is added to the bin.
1002  *
1003  * MT safe.
1004  *
1005  * Returns: TRUE if the element could be added, FALSE if
1006  * the bin does not want to accept the element.
1007  */
1008 gboolean
1009 gst_bin_add (GstBin * bin, GstElement * element)
1010 {
1011   GstBinClass *bclass;
1012   gboolean result;
1013
1014   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
1015   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1016
1017   bclass = GST_BIN_GET_CLASS (bin);
1018
1019   if (G_UNLIKELY (bclass->add_element == NULL))
1020     goto no_function;
1021
1022   GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
1023       GST_STR_NULL (GST_ELEMENT_NAME (element)),
1024       GST_STR_NULL (GST_ELEMENT_NAME (bin)));
1025
1026   result = bclass->add_element (bin, element);
1027
1028   return result;
1029
1030   /* ERROR handling */
1031 no_function:
1032   {
1033     g_warning ("adding elements to bin %s is not supported",
1034         GST_ELEMENT_NAME (bin));
1035     return FALSE;
1036   }
1037 }
1038
1039 /* remove an element from the bin
1040  *
1041  * MT safe
1042  */
1043 static gboolean
1044 gst_bin_remove_func (GstBin * bin, GstElement * element)
1045 {
1046   gchar *elem_name;
1047   GstIterator *it;
1048   gboolean is_sink, othersink, found;
1049   GstMessage *clock_message = NULL;
1050   GList *walk, *next;
1051   gboolean other_async, this_async, have_no_preroll;
1052   GstStateChangeReturn ret;
1053
1054   GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
1055
1056   GST_OBJECT_LOCK (element);
1057   /* Check if the element is already being removed and immediately
1058    * return */
1059   if (G_UNLIKELY (GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_UNPARENTING)))
1060     goto already_removing;
1061
1062   GST_OBJECT_FLAG_SET (element, GST_ELEMENT_UNPARENTING);
1063   /* grab element name so we can print it */
1064   elem_name = g_strdup (GST_ELEMENT_NAME (element));
1065   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
1066   GST_OBJECT_UNLOCK (element);
1067
1068   /* unlink all linked pads */
1069   it = gst_element_iterate_pads (element);
1070   gst_iterator_foreach (it, (GFunc) unlink_pads, element);
1071   gst_iterator_free (it);
1072
1073   GST_OBJECT_LOCK (bin);
1074   found = FALSE;
1075   othersink = FALSE;
1076   have_no_preroll = FALSE;
1077   /* iterate the elements, we collect which ones are async and no_preroll. We
1078    * also remove the element when we find it. */
1079   for (walk = bin->children; walk; walk = next) {
1080     GstElement *child = GST_ELEMENT_CAST (walk->data);
1081
1082     next = g_list_next (walk);
1083
1084     if (child == element) {
1085       found = TRUE;
1086       /* remove the element */
1087       bin->children = g_list_delete_link (bin->children, walk);
1088     } else {
1089       gboolean child_sink;
1090
1091       GST_OBJECT_LOCK (child);
1092       child_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK);
1093       /* when we remove a sink, check if there are other sinks. */
1094       if (is_sink && !othersink && child_sink)
1095         othersink = TRUE;
1096       /* check if we have NO_PREROLL children */
1097       if (GST_STATE_RETURN (child) == GST_STATE_CHANGE_NO_PREROLL)
1098         have_no_preroll = TRUE;
1099       GST_OBJECT_UNLOCK (child);
1100     }
1101   }
1102
1103   /* the element must have been in the bin's list of children */
1104   if (G_UNLIKELY (!found))
1105     goto not_in_bin;
1106
1107   /* we now removed the element from the list of elements, increment the cookie
1108    * so that others can detect a change in the children list. */
1109   bin->numchildren--;
1110   bin->children_cookie++;
1111
1112   if (is_sink && !othersink) {
1113     /* we're not a sink anymore */
1114     GST_DEBUG_OBJECT (bin, "we removed the last sink");
1115     GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_IS_SINK);
1116   }
1117
1118   /* if the clock provider for this element is removed, we lost
1119    * the clock as well, we need to inform the parent of this
1120    * so that it can select a new clock */
1121   if (bin->clock_provider == element) {
1122     GST_DEBUG_OBJECT (bin, "element \"%s\" provided the clock", elem_name);
1123     bin->clock_dirty = TRUE;
1124     clock_message =
1125         gst_message_new_clock_lost (GST_OBJECT_CAST (bin), bin->provided_clock);
1126   }
1127
1128   /* remove messages for the element, if there was a pending ASYNC_START
1129    * message we must see if removing the element caused the bin to lose its
1130    * async state. */
1131   this_async = FALSE;
1132   other_async = FALSE;
1133   for (walk = bin->messages; walk; walk = next) {
1134     GstMessage *message = (GstMessage *) walk->data;
1135     GstElement *src = GST_ELEMENT_CAST (GST_MESSAGE_SRC (message));
1136
1137     next = g_list_next (walk);
1138
1139     if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_START) {
1140       if (src == element)
1141         this_async = TRUE;
1142       else
1143         other_async = TRUE;
1144
1145       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
1146           "looking at message %p", message);
1147     }
1148     if (src == element) {
1149       /* delete all message types */
1150       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
1151           "deleting message %p of element \"%s\"", message, elem_name);
1152       bin->messages = g_list_delete_link (bin->messages, walk);
1153       gst_message_unref (message);
1154     }
1155   }
1156
1157   /* get last return */
1158   ret = GST_STATE_RETURN (bin);
1159
1160   /* no need to update the state if we are in error */
1161   if (ret == GST_STATE_CHANGE_FAILURE)
1162     goto no_state_recalc;
1163
1164   if (!other_async && this_async) {
1165     GstStateChangeReturn ret;
1166
1167     /* all other elements were not async and we removed the async one,
1168      * handle the async-done case because we are not async anymore now. */
1169     GST_DEBUG_OBJECT (bin,
1170         "we removed the last async element, have no_preroll %d",
1171         have_no_preroll);
1172
1173     /* the current state return of the bin depends on if there are no_preroll
1174      * elements in the pipeline or not */
1175     if (have_no_preroll)
1176       ret = GST_STATE_CHANGE_NO_PREROLL;
1177     else
1178       ret = GST_STATE_CHANGE_SUCCESS;
1179
1180     bin_handle_async_done (bin, ret);
1181   } else {
1182     GST_DEBUG_OBJECT (bin,
1183         "recalc state preroll: %d, other async: %d, this async %d",
1184         have_no_preroll, other_async, this_async);
1185
1186     if (have_no_preroll) {
1187       ret = GST_STATE_CHANGE_NO_PREROLL;
1188     } else if (other_async) {
1189       /* there are other async elements and we were not doing an async state
1190        * change, change our pending state and go async */
1191       if (GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
1192         GST_STATE_NEXT (bin) = GST_STATE (bin);
1193         GST_STATE_PENDING (bin) = GST_STATE (bin);
1194       }
1195       ret = GST_STATE_CHANGE_ASYNC;
1196     }
1197     GST_STATE_RETURN (bin) = ret;
1198   }
1199 no_state_recalc:
1200   GST_OBJECT_UNLOCK (bin);
1201
1202   if (clock_message)
1203     gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
1204
1205   GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
1206       elem_name);
1207   g_free (elem_name);
1208
1209   gst_element_set_bus (element, NULL);
1210
1211   /* Clear the clock we provided to the element */
1212   gst_element_set_clock (element, NULL);
1213
1214   /* we ref here because after the _unparent() the element can be disposed
1215    * and we still need it to reset the UNPARENTING flag and fire a signal. */
1216   gst_object_ref (element);
1217   gst_object_unparent (GST_OBJECT_CAST (element));
1218
1219   GST_OBJECT_LOCK (element);
1220   GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_UNPARENTING);
1221   GST_OBJECT_UNLOCK (element);
1222
1223   g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
1224
1225   /* element is really out of our control now */
1226   gst_object_unref (element);
1227
1228   return TRUE;
1229
1230   /* ERROR handling */
1231 not_in_bin:
1232   {
1233     g_warning ("Element %s is not in bin %s", elem_name,
1234         GST_ELEMENT_NAME (bin));
1235     GST_OBJECT_UNLOCK (bin);
1236     g_free (elem_name);
1237     return FALSE;
1238   }
1239 already_removing:
1240   {
1241     GST_OBJECT_UNLOCK (element);
1242     return FALSE;
1243   }
1244 }
1245
1246 /**
1247  * gst_bin_remove:
1248  * @bin: a #GstBin
1249  * @element: the #GstElement to remove
1250  *
1251  * Removes the element from the bin, unparenting it as well.
1252  * Unparenting the element means that the element will be dereferenced,
1253  * so if the bin holds the only reference to the element, the element
1254  * will be freed in the process of removing it from the bin.  If you
1255  * want the element to still exist after removing, you need to call
1256  * gst_object_ref() before removing it from the bin.
1257  *
1258  * If the element's pads are linked to other pads, the pads will be unlinked
1259  * before the element is removed from the bin.
1260  *
1261  * MT safe.
1262  *
1263  * Returns: TRUE if the element could be removed, FALSE if
1264  * the bin does not want to remove the element.
1265  */
1266 gboolean
1267 gst_bin_remove (GstBin * bin, GstElement * element)
1268 {
1269   GstBinClass *bclass;
1270   gboolean result;
1271
1272   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
1273   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1274
1275   bclass = GST_BIN_GET_CLASS (bin);
1276
1277   if (G_UNLIKELY (bclass->remove_element == NULL))
1278     goto no_function;
1279
1280   GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
1281       GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
1282
1283   result = bclass->remove_element (bin, element);
1284
1285   return result;
1286
1287   /* ERROR handling */
1288 no_function:
1289   {
1290     g_warning ("removing elements from bin %s is not supported",
1291         GST_ELEMENT_NAME (bin));
1292     return FALSE;
1293   }
1294 }
1295
1296 static GstIteratorItem
1297 iterate_child (GstIterator * it, GstElement * child)
1298 {
1299   gst_object_ref (child);
1300   return GST_ITERATOR_ITEM_PASS;
1301 }
1302
1303 /**
1304  * gst_bin_iterate_elements:
1305  * @bin: a #GstBin
1306  *
1307  * Gets an iterator for the elements in this bin.
1308  *
1309  * Each element yielded by the iterator will have its refcount increased, so
1310  * unref after use.
1311  *
1312  * MT safe.  Caller owns returned value.
1313  *
1314  * Returns: a #GstIterator of #GstElement, or NULL
1315  */
1316 GstIterator *
1317 gst_bin_iterate_elements (GstBin * bin)
1318 {
1319   GstIterator *result;
1320
1321   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1322
1323   GST_OBJECT_LOCK (bin);
1324   /* add ref because the iterator refs the bin. When the iterator
1325    * is freed it will unref the bin again using the provided dispose
1326    * function. */
1327   gst_object_ref (bin);
1328   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
1329       GST_OBJECT_GET_LOCK (bin),
1330       &bin->children_cookie,
1331       &bin->children,
1332       bin,
1333       (GstIteratorItemFunction) iterate_child,
1334       (GstIteratorDisposeFunction) gst_object_unref);
1335   GST_OBJECT_UNLOCK (bin);
1336
1337   return result;
1338 }
1339
1340 static GstIteratorItem
1341 iterate_child_recurse (GstIterator * it, GstElement * child)
1342 {
1343   gst_object_ref (child);
1344   if (GST_IS_BIN (child)) {
1345     GstIterator *other = gst_bin_iterate_recurse (GST_BIN (child));
1346
1347     gst_iterator_push (it, other);
1348   }
1349   return GST_ITERATOR_ITEM_PASS;
1350 }
1351
1352 /**
1353  * gst_bin_iterate_recurse:
1354  * @bin: a #GstBin
1355  *
1356  * Gets an iterator for the elements in this bin.
1357  * This iterator recurses into GstBin children.
1358  *
1359  * Each element yielded by the iterator will have its refcount increased, so
1360  * unref after use.
1361  *
1362  * MT safe.  Caller owns returned value.
1363  *
1364  * Returns: a #GstIterator of #GstElement, or NULL
1365  */
1366 GstIterator *
1367 gst_bin_iterate_recurse (GstBin * bin)
1368 {
1369   GstIterator *result;
1370
1371   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1372
1373   GST_OBJECT_LOCK (bin);
1374   /* add ref because the iterator refs the bin. When the iterator
1375    * is freed it will unref the bin again using the provided dispose
1376    * function. */
1377   gst_object_ref (bin);
1378   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
1379       GST_OBJECT_GET_LOCK (bin),
1380       &bin->children_cookie,
1381       &bin->children,
1382       bin,
1383       (GstIteratorItemFunction) iterate_child_recurse,
1384       (GstIteratorDisposeFunction) gst_object_unref);
1385   GST_OBJECT_UNLOCK (bin);
1386
1387   return result;
1388 }
1389
1390 /* returns 0 when TRUE because this is a GCompareFunc */
1391 /* MT safe */
1392 static gint
1393 bin_element_is_sink (GstElement * child, GstBin * bin)
1394 {
1395   gboolean is_sink;
1396
1397   /* we lock the child here for the remainder of the function to
1398    * get its name and flag safely. */
1399   GST_OBJECT_LOCK (child);
1400   is_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK);
1401
1402   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
1403       "child %s %s sink", GST_OBJECT_NAME (child), is_sink ? "is" : "is not");
1404
1405   GST_OBJECT_UNLOCK (child);
1406   return is_sink ? 0 : 1;
1407 }
1408
1409 static gint
1410 sink_iterator_filter (GstElement * child, GstBin * bin)
1411 {
1412   if (bin_element_is_sink (child, bin) == 0) {
1413     /* returns 0 because this is a GCompareFunc */
1414     return 0;
1415   } else {
1416     /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
1417        through */
1418     gst_object_unref (child);
1419     return 1;
1420   }
1421 }
1422
1423 /**
1424  * gst_bin_iterate_sinks:
1425  * @bin: a #GstBin
1426  *
1427  * Gets an iterator for all elements in the bin that have the
1428  * #GST_ELEMENT_IS_SINK flag set.
1429  *
1430  * Each element yielded by the iterator will have its refcount increased, so
1431  * unref after use.
1432  *
1433  * MT safe.  Caller owns returned value.
1434  *
1435  * Returns: a #GstIterator of #GstElement, or NULL
1436  */
1437 GstIterator *
1438 gst_bin_iterate_sinks (GstBin * bin)
1439 {
1440   GstIterator *children;
1441   GstIterator *result;
1442
1443   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1444
1445   children = gst_bin_iterate_elements (bin);
1446   result = gst_iterator_filter (children,
1447       (GCompareFunc) sink_iterator_filter, bin);
1448
1449   return result;
1450 }
1451
1452 /* returns 0 when TRUE because this is a GCompareFunc */
1453 /* MT safe */
1454 static gint
1455 bin_element_is_src (GstElement * child, GstBin * bin)
1456 {
1457   gboolean is_src = FALSE;
1458
1459   /* we lock the child here for the remainder of the function to
1460    * get its name and flag safely. */
1461   GST_OBJECT_LOCK (child);
1462   if (!GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK) &&
1463       !child->numsinkpads) {
1464     is_src = TRUE;
1465   }
1466
1467   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
1468       "child %s %s src", GST_OBJECT_NAME (child), is_src ? "is" : "is not");
1469
1470   GST_OBJECT_UNLOCK (child);
1471   return is_src ? 0 : 1;
1472 }
1473
1474 static gint
1475 src_iterator_filter (GstElement * child, GstBin * bin)
1476 {
1477   if (bin_element_is_src (child, bin) == 0) {
1478     /* returns 0 because this is a GCompareFunc */
1479     return 0;
1480   } else {
1481     /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
1482        through */
1483     gst_object_unref (child);
1484     return 1;
1485   }
1486 }
1487
1488 /**
1489  * gst_bin_iterate_sources:
1490  * @bin: a #GstBin
1491  *
1492  * Gets an iterator for all elements in the bin that have no sinkpads and have
1493  * the #GST_ELEMENT_IS_SINK flag unset.
1494  *
1495  * Each element yielded by the iterator will have its refcount increased, so
1496  * unref after use.
1497  *
1498  * MT safe.  Caller owns returned value.
1499  *
1500  * Returns: a #GstIterator of #GstElement, or NULL
1501  */
1502 GstIterator *
1503 gst_bin_iterate_sources (GstBin * bin)
1504 {
1505   GstIterator *children;
1506   GstIterator *result;
1507
1508   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1509
1510   children = gst_bin_iterate_elements (bin);
1511   result = gst_iterator_filter (children,
1512       (GCompareFunc) src_iterator_filter, bin);
1513
1514   return result;
1515 }
1516
1517 /*
1518  * MT safe
1519  */
1520 static GstStateChangeReturn
1521 gst_bin_get_state_func (GstElement * element, GstState * state,
1522     GstState * pending, GstClockTime timeout)
1523 {
1524   GstBin *bin = GST_BIN (element);
1525   GstStateChangeReturn ret;
1526
1527   GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "getting state");
1528
1529   ret = parent_class->get_state (element, state, pending, timeout);
1530
1531   return ret;
1532 }
1533
1534 /***********************************************
1535  * Topologically sorted iterator
1536  * see http://en.wikipedia.org/wiki/Topological_sorting
1537  *
1538  * For each element in the graph, an entry is kept in a HashTable
1539  * with its number of srcpad connections (degree).
1540  * We then change state of all elements without dependencies
1541  * (degree 0) and decrement the degree of all elements connected
1542  * on the sinkpads. When an element reaches degree 0, its state is
1543  * changed next.
1544  * When all elements are handled the algorithm stops.
1545  */
1546 typedef struct _GstBinSortIterator
1547 {
1548   GstIterator it;
1549   GQueue *queue;                /* elements queued for state change */
1550   GstBin *bin;                  /* bin we iterate */
1551   gint mode;                    /* adding or removing dependency */
1552   GstElement *best;             /* next element with least dependencies */
1553   gint best_deg;                /* best degree */
1554   GHashTable *hash;             /* hashtable with element dependencies */
1555 } GstBinSortIterator;
1556
1557 /* we add and subtract 1 to make sure we don't confuse NULL and 0 */
1558 #define HASH_SET_DEGREE(bit, elem, deg) \
1559     g_hash_table_replace (bit->hash, elem, GINT_TO_POINTER(deg+1))
1560 #define HASH_GET_DEGREE(bit, elem) \
1561     (GPOINTER_TO_INT(g_hash_table_lookup (bit->hash, elem))-1)
1562
1563 /* add element to queue of next elements in the iterator.
1564  * We push at the tail to give higher priority elements a
1565  * chance first */
1566 static void
1567 add_to_queue (GstBinSortIterator * bit, GstElement * element)
1568 {
1569   GST_DEBUG_OBJECT (bit->bin, "%s add to queue", GST_ELEMENT_NAME (element));
1570   gst_object_ref (element);
1571   g_queue_push_tail (bit->queue, element);
1572   HASH_SET_DEGREE (bit, element, -1);
1573 }
1574
1575 /* clear the queue, unref all objects as we took a ref when
1576  * we added them to the queue */
1577 static void
1578 clear_queue (GQueue * queue)
1579 {
1580   gpointer p;
1581
1582   while ((p = g_queue_pop_head (queue)))
1583     gst_object_unref (p);
1584 }
1585
1586 /* set all degrees to 0. Elements marked as a sink are
1587  * added to the queue immediatly. */
1588 static void
1589 reset_degree (GstElement * element, GstBinSortIterator * bit)
1590 {
1591   gboolean is_sink;
1592
1593   /* sinks are added right away */
1594   GST_OBJECT_LOCK (element);
1595   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
1596   GST_OBJECT_UNLOCK (element);
1597
1598   if (is_sink) {
1599     add_to_queue (bit, element);
1600   } else {
1601     /* others are marked with 0 and handled when sinks are done */
1602     HASH_SET_DEGREE (bit, element, 0);
1603   }
1604 }
1605
1606 /* adjust the degree of all elements connected to the given
1607  * element. If a degree of an element drops to 0, it is
1608  * added to the queue of elements to schedule next.
1609  *
1610  * We have to make sure not to cross the bin boundary this element
1611  * belongs to.
1612  */
1613 static void
1614 update_degree (GstElement * element, GstBinSortIterator * bit)
1615 {
1616   gboolean linked = FALSE;
1617
1618   GST_OBJECT_LOCK (element);
1619   /* don't touch degree if element has no sourcepads */
1620   if (element->numsinkpads != 0) {
1621     /* loop over all sinkpads, decrement degree for all connected
1622      * elements in this bin */
1623     GList *pads;
1624
1625     for (pads = element->sinkpads; pads; pads = g_list_next (pads)) {
1626       GstPad *peer;
1627
1628       if ((peer = gst_pad_get_peer (GST_PAD_CAST (pads->data)))) {
1629         GstElement *peer_element;
1630
1631         if ((peer_element = gst_pad_get_parent_element (peer))) {
1632           GST_OBJECT_LOCK (peer_element);
1633           /* check that we don't go outside of this bin */
1634           if (GST_OBJECT_CAST (peer_element)->parent ==
1635               GST_OBJECT_CAST (bit->bin)) {
1636             gint old_deg, new_deg;
1637
1638             old_deg = HASH_GET_DEGREE (bit, peer_element);
1639             new_deg = old_deg + bit->mode;
1640
1641             GST_DEBUG_OBJECT (bit->bin,
1642                 "change element %s, degree %d->%d, linked to %s",
1643                 GST_ELEMENT_NAME (peer_element), old_deg, new_deg,
1644                 GST_ELEMENT_NAME (element));
1645
1646             /* update degree */
1647             if (new_deg == 0) {
1648               /* degree hit 0, add to queue */
1649               add_to_queue (bit, peer_element);
1650             } else {
1651               HASH_SET_DEGREE (bit, peer_element, new_deg);
1652             }
1653             linked = TRUE;
1654           }
1655           GST_OBJECT_UNLOCK (peer_element);
1656           gst_object_unref (peer_element);
1657         }
1658         gst_object_unref (peer);
1659       }
1660     }
1661   }
1662   if (!linked) {
1663     GST_DEBUG_OBJECT (bit->bin, "element %s not linked on any sinkpads",
1664         GST_ELEMENT_NAME (element));
1665   }
1666   GST_OBJECT_UNLOCK (element);
1667 }
1668
1669 /* find the next best element not handled yet. This is the one
1670  * with the lowest non-negative degree */
1671 static void
1672 find_element (GstElement * element, GstBinSortIterator * bit)
1673 {
1674   gint degree;
1675
1676   /* element is already handled */
1677   if ((degree = HASH_GET_DEGREE (bit, element)) < 0)
1678     return;
1679
1680   /* first element or element with smaller degree */
1681   if (bit->best == NULL || bit->best_deg > degree) {
1682     bit->best = element;
1683     bit->best_deg = degree;
1684   }
1685 }
1686
1687 /* get next element in iterator. the returned element has the
1688  * refcount increased */
1689 static GstIteratorResult
1690 gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
1691 {
1692   GstBin *bin = bit->bin;
1693
1694   /* empty queue, we have to find a next best element */
1695   if (g_queue_is_empty (bit->queue)) {
1696     GstElement *best;
1697
1698     bit->best = NULL;
1699     bit->best_deg = G_MAXINT;
1700     g_list_foreach (bin->children, (GFunc) find_element, bit);
1701     if ((best = bit->best)) {
1702       if (bit->best_deg != 0) {
1703         /* we don't fail on this one yet */
1704         g_warning ("loop detected in the graph !!");
1705       }
1706       /* best unhandled element, schedule as next element */
1707       GST_DEBUG_OBJECT (bin, "queue empty, next best: %s",
1708           GST_ELEMENT_NAME (best));
1709       gst_object_ref (best);
1710       HASH_SET_DEGREE (bit, best, -1);
1711       *result = best;
1712     } else {
1713       GST_DEBUG_OBJECT (bin, "queue empty, elements exhausted");
1714       /* no more unhandled elements, we are done */
1715       return GST_ITERATOR_DONE;
1716     }
1717   } else {
1718     /* everything added to the queue got reffed */
1719     *result = g_queue_pop_head (bit->queue);
1720   }
1721
1722   GST_DEBUG_OBJECT (bin, "queue head gives %s", GST_ELEMENT_NAME (*result));
1723   /* update degrees of linked elements */
1724   update_degree (GST_ELEMENT_CAST (*result), bit);
1725
1726   return GST_ITERATOR_OK;
1727 }
1728
1729 /* clear queues, recalculate the degrees and restart. */
1730 static void
1731 gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
1732 {
1733   GstBin *bin = bit->bin;
1734
1735   GST_DEBUG_OBJECT (bin, "resync");
1736   clear_queue (bit->queue);
1737   /* reset degrees */
1738   g_list_foreach (bin->children, (GFunc) reset_degree, bit);
1739   /* calc degrees, incrementing */
1740   bit->mode = 1;
1741   g_list_foreach (bin->children, (GFunc) update_degree, bit);
1742   /* for the rest of the function we decrement the degrees */
1743   bit->mode = -1;
1744 }
1745
1746 /* clear queues, unref bin and free iterator. */
1747 static void
1748 gst_bin_sort_iterator_free (GstBinSortIterator * bit)
1749 {
1750   GstBin *bin = bit->bin;
1751
1752   GST_DEBUG_OBJECT (bin, "free");
1753   clear_queue (bit->queue);
1754   g_queue_free (bit->queue);
1755   g_hash_table_destroy (bit->hash);
1756   gst_object_unref (bin);
1757   g_free (bit);
1758 }
1759
1760 /* should be called with the bin LOCK held */
1761 static GstIterator *
1762 gst_bin_sort_iterator_new (GstBin * bin)
1763 {
1764   GstBinSortIterator *result;
1765
1766   /* we don't need an ItemFunction because we ref the items in the _next
1767    * method already */
1768   result = (GstBinSortIterator *)
1769       gst_iterator_new (sizeof (GstBinSortIterator),
1770       GST_TYPE_ELEMENT,
1771       GST_OBJECT_GET_LOCK (bin),
1772       &bin->children_cookie,
1773       (GstIteratorNextFunction) gst_bin_sort_iterator_next,
1774       (GstIteratorItemFunction) NULL,
1775       (GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
1776       (GstIteratorFreeFunction) gst_bin_sort_iterator_free);
1777   result->queue = g_queue_new ();
1778   result->hash = g_hash_table_new (NULL, NULL);
1779   gst_object_ref (bin);
1780   result->bin = bin;
1781   gst_bin_sort_iterator_resync (result);
1782
1783   return (GstIterator *) result;
1784 }
1785
1786 /**
1787  * gst_bin_iterate_sorted:
1788  * @bin: a #GstBin
1789  *
1790  * Gets an iterator for the elements in this bin in topologically
1791  * sorted order. This means that the elements are returned from
1792  * the most downstream elements (sinks) to the sources.
1793  *
1794  * This function is used internally to perform the state changes
1795  * of the bin elements.
1796  *
1797  * Each element yielded by the iterator will have its refcount increased, so
1798  * unref after use.
1799  *
1800  * MT safe.  Caller owns returned value.
1801  *
1802  * Returns: a #GstIterator of #GstElement, or NULL
1803  */
1804 GstIterator *
1805 gst_bin_iterate_sorted (GstBin * bin)
1806 {
1807   GstIterator *result;
1808
1809   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1810
1811   GST_OBJECT_LOCK (bin);
1812   result = gst_bin_sort_iterator_new (bin);
1813   GST_OBJECT_UNLOCK (bin);
1814
1815   return result;
1816 }
1817
1818 static GstStateChangeReturn
1819 gst_bin_element_set_state (GstBin * bin, GstElement * element,
1820     GstClockTime base_time, GstState current, GstState next)
1821 {
1822   GstStateChangeReturn ret;
1823   gboolean locked;
1824   GList *found;
1825
1826   /* peel off the locked flag */
1827   GST_OBJECT_LOCK (element);
1828   locked = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1829   /* get previous state return */
1830   ret = GST_STATE_RETURN (element);
1831   GST_OBJECT_UNLOCK (element);
1832
1833   /* skip locked elements */
1834   if (G_UNLIKELY (locked))
1835     goto locked;
1836
1837   /* if the element was no preroll, just start changing the state regardless
1838    * if it had async elements (in the case of a bin) because they won't preroll
1839    * anyway. */
1840   if (G_UNLIKELY (ret == GST_STATE_CHANGE_NO_PREROLL)) {
1841     GST_DEBUG_OBJECT (element, "element is NO_PREROLL, ignore async elements");
1842     goto no_preroll;
1843   }
1844
1845   GST_OBJECT_LOCK (bin);
1846   /* the element was busy with an upwards async state change, we must wait for
1847    * an ASYNC_DONE message before we attemp to change the state. */
1848   if ((found =
1849           find_message (bin, GST_OBJECT_CAST (element),
1850               GST_MESSAGE_ASYNC_START))) {
1851 #ifndef GST_DISABLE_GST_DEBUG
1852     GstMessage *message = GST_MESSAGE_CAST (found->data);
1853
1854     GST_DEBUG_OBJECT (element, "element message %p, %s async busy",
1855         message, GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)));
1856 #endif
1857     /* only wait for upward state changes */
1858     if (next > current) {
1859       /* We found an async element check if we can force its state to change or
1860        * if we have to wait for it to preroll. */
1861       if (G_UNLIKELY (!enable_latency)) {
1862         g_warning ("Future versions of GStreamer will wait for element \"%s\"\n"
1863             "\tto preroll in order to perform correct latency calculations.\n"
1864             "\tPlease verify that the application continues to work correctly by\n"
1865             "\tsetting the environment variable GST_COMPAT to a value containing\n"
1866             "\tthe string 'live-preroll'.", GST_ELEMENT_NAME (element));
1867         goto no_latency;
1868       }
1869       goto was_busy;
1870     }
1871   }
1872 no_latency:
1873   GST_OBJECT_UNLOCK (bin);
1874
1875 no_preroll:
1876   GST_DEBUG_OBJECT (bin,
1877       "setting element %s to %s, base_time %" GST_TIME_FORMAT,
1878       GST_ELEMENT_NAME (element), gst_element_state_get_name (next),
1879       GST_TIME_ARGS (base_time));
1880
1881   /* set base_time on child */
1882   gst_element_set_base_time (element, base_time);
1883
1884   /* change state */
1885   ret = gst_element_set_state (element, next);
1886
1887   return ret;
1888
1889 locked:
1890   {
1891     GST_DEBUG_OBJECT (element,
1892         "element is locked, return previous return %s",
1893         gst_element_state_change_return_get_name (ret));
1894     return ret;
1895   }
1896 was_busy:
1897   {
1898     GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
1899     GST_OBJECT_UNLOCK (bin);
1900     return GST_STATE_CHANGE_ASYNC;
1901   }
1902 }
1903
1904 /* gst_iterator_fold functions for pads_activate
1905  * Note how we don't stop the iterator when we fail an activation. This is
1906  * probably a FIXME since when one pad activation fails, we don't want to
1907  * continue our state change. */
1908 static gboolean
1909 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
1910 {
1911   if (!gst_pad_set_active (pad, *active))
1912     g_value_set_boolean (ret, FALSE);
1913   else if (!*active)
1914     gst_pad_set_caps (pad, NULL);
1915
1916   /* unref the object that was reffed for us by _fold */
1917   gst_object_unref (pad);
1918   return TRUE;
1919 }
1920
1921 /* returns false on error or early cutout (will never happen because the fold
1922  * function always returns TRUE, see FIXME above) of the fold, true if all
1923  * pads in @iter were (de)activated successfully. */
1924 static gboolean
1925 iterator_activate_fold_with_resync (GstIterator * iter, gpointer user_data)
1926 {
1927   GstIteratorResult ires;
1928   GValue ret = { 0 };
1929
1930   /* no need to unset this later, it's just a boolean */
1931   g_value_init (&ret, G_TYPE_BOOLEAN);
1932   g_value_set_boolean (&ret, TRUE);
1933
1934   while (1) {
1935     ires = gst_iterator_fold (iter, (GstIteratorFoldFunction) activate_pads,
1936         &ret, user_data);
1937     switch (ires) {
1938       case GST_ITERATOR_RESYNC:
1939         /* need to reset the result again */
1940         g_value_set_boolean (&ret, TRUE);
1941         gst_iterator_resync (iter);
1942         break;
1943       case GST_ITERATOR_DONE:
1944         /* all pads iterated, return collected value */
1945         goto done;
1946       default:
1947         /* iterator returned _ERROR or premature end with _OK,
1948          * mark an error and exit */
1949         g_value_set_boolean (&ret, FALSE);
1950         goto done;
1951     }
1952   }
1953 done:
1954   /* return collected value */
1955   return g_value_get_boolean (&ret);
1956 }
1957
1958 /* is called with STATE_LOCK
1959  */
1960 static gboolean
1961 gst_bin_src_pads_activate (GstBin * bin, gboolean active)
1962 {
1963   GstIterator *iter;
1964   gboolean fold_ok;
1965
1966   GST_DEBUG_OBJECT (bin, "src_pads_activate with active %d", active);
1967
1968   iter = gst_element_iterate_src_pads ((GstElement *) bin);
1969   fold_ok = iterator_activate_fold_with_resync (iter, &active);
1970   gst_iterator_free (iter);
1971   if (G_UNLIKELY (!fold_ok))
1972     goto failed;
1973
1974   GST_DEBUG_OBJECT (bin, "pads_activate successful");
1975
1976   return TRUE;
1977
1978   /* ERRORS */
1979 failed:
1980   {
1981     GST_DEBUG_OBJECT (bin, "source pads_activate failed");
1982     return FALSE;
1983   }
1984 }
1985 static GstStateChangeReturn
1986 gst_bin_change_state_func (GstElement * element, GstStateChange transition)
1987 {
1988   GstBin *bin;
1989   GstStateChangeReturn ret;
1990   GstState current, next;
1991   gboolean have_async;
1992   gboolean have_no_preroll;
1993   GstClockTime base_time;
1994   GstIterator *it;
1995   gboolean done;
1996
1997   /* we don't need to take the STATE_LOCK, it is already taken */
1998   current = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
1999   next = (GstState) GST_STATE_TRANSITION_NEXT (transition);
2000
2001   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2002       "changing state of children from %s to %s",
2003       gst_element_state_get_name (current), gst_element_state_get_name (next));
2004
2005   bin = GST_BIN_CAST (element);
2006
2007   switch (next) {
2008     case GST_STATE_PAUSED:
2009       /* Clear EOS list on next PAUSED */
2010       GST_OBJECT_LOCK (bin);
2011       GST_DEBUG_OBJECT (element, "clearing EOS elements");
2012       bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
2013       GST_OBJECT_UNLOCK (bin);
2014       if (current == GST_STATE_READY)
2015         if (!(gst_bin_src_pads_activate (bin, TRUE)))
2016           goto activate_failure;
2017       break;
2018     case GST_STATE_READY:
2019       /* Clear message list on next READY */
2020       GST_OBJECT_LOCK (bin);
2021       GST_DEBUG_OBJECT (element, "clearing all cached messages");
2022       bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
2023       GST_OBJECT_UNLOCK (bin);
2024       if (current == GST_STATE_PAUSED)
2025         if (!(gst_bin_src_pads_activate (bin, FALSE)))
2026           goto activate_failure;
2027       break;
2028     case GST_STATE_NULL:
2029       if (current == GST_STATE_READY)
2030         if (!(gst_bin_src_pads_activate (bin, FALSE)))
2031           goto activate_failure;
2032       break;
2033     default:
2034       break;
2035   }
2036
2037   GST_OBJECT_LOCK (bin);
2038   bin->polling = TRUE;
2039   GST_OBJECT_UNLOCK (bin);
2040
2041   /* iterate in state change order */
2042   it = gst_bin_iterate_sorted (bin);
2043
2044   /* mark if we've seen an ASYNC element in the bin when we did a state change.
2045    * Note how we don't reset this value when a resync happens, the reason being
2046    * that the async element posted ASYNC_START and we want to post ASYNC_DONE
2047    * even after a resync when the async element is gone */
2048   have_async = FALSE;
2049
2050 restart:
2051   /* take base_time */
2052   base_time = gst_element_get_base_time (element);
2053
2054   have_no_preroll = FALSE;
2055
2056   done = FALSE;
2057   while (!done) {
2058     gpointer data;
2059
2060     switch (gst_iterator_next (it, &data)) {
2061       case GST_ITERATOR_OK:
2062       {
2063         GstElement *child;
2064
2065         child = GST_ELEMENT_CAST (data);
2066
2067         /* set state and base_time now */
2068         ret = gst_bin_element_set_state (bin, child, base_time, current, next);
2069
2070         switch (ret) {
2071           case GST_STATE_CHANGE_SUCCESS:
2072             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2073                 "child '%s' changed state to %d(%s) successfully",
2074                 GST_ELEMENT_NAME (child), next,
2075                 gst_element_state_get_name (next));
2076             break;
2077           case GST_STATE_CHANGE_ASYNC:
2078           {
2079             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2080                 "child '%s' is changing state asynchronously to %s",
2081                 GST_ELEMENT_NAME (child), gst_element_state_get_name (next));
2082             have_async = TRUE;
2083             break;
2084           }
2085           case GST_STATE_CHANGE_FAILURE:
2086             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2087                 "child '%s' failed to go to state %d(%s)",
2088                 GST_ELEMENT_NAME (child),
2089                 next, gst_element_state_get_name (next));
2090             gst_object_unref (child);
2091             goto done;
2092           case GST_STATE_CHANGE_NO_PREROLL:
2093             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2094                 "child '%s' changed state to %d(%s) successfully without preroll",
2095                 GST_ELEMENT_NAME (child), next,
2096                 gst_element_state_get_name (next));
2097             have_no_preroll = TRUE;
2098             break;
2099           default:
2100             g_assert_not_reached ();
2101             break;
2102         }
2103         gst_object_unref (child);
2104         break;
2105       }
2106       case GST_ITERATOR_RESYNC:
2107         GST_CAT_DEBUG (GST_CAT_STATES, "iterator doing resync");
2108         gst_iterator_resync (it);
2109         goto restart;
2110       default:
2111       case GST_ITERATOR_DONE:
2112         GST_CAT_DEBUG (GST_CAT_STATES, "iterator done");
2113         done = TRUE;
2114         break;
2115     }
2116   }
2117
2118   ret = parent_class->change_state (element, transition);
2119   if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
2120     goto done;
2121
2122   if (have_no_preroll) {
2123     ret = GST_STATE_CHANGE_NO_PREROLL;
2124   } else if (have_async) {
2125     ret = GST_STATE_CHANGE_ASYNC;
2126   }
2127
2128 done:
2129   gst_iterator_free (it);
2130
2131   GST_OBJECT_LOCK (bin);
2132   bin->polling = FALSE;
2133   if (ret != GST_STATE_CHANGE_ASYNC) {
2134     /* no element returned ASYNC, we can just complete. */
2135     GST_DEBUG_OBJECT (bin, "no async elements");
2136     goto state_end;
2137   }
2138   /* when we get here an ASYNC element was found */
2139   if (GST_STATE_TARGET (bin) <= GST_STATE_READY) {
2140     /* we ignore ASYNC state changes when we go to READY or NULL */
2141     GST_DEBUG_OBJECT (bin, "target state %s <= READY",
2142         gst_element_state_get_name (GST_STATE_TARGET (bin)));
2143     goto state_end;
2144   }
2145
2146   GST_DEBUG_OBJECT (bin, "check async elements");
2147   /* check if all elements managed to commit their state already */
2148   if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
2149     /* nothing found, remove all old ASYNC_DONE messages. This can happen when
2150      * all the elements commited their state while we were doing the state
2151      * change. We will still return ASYNC for consistency but we commit the
2152      * state already so that a _get_state() will return immediatly. */
2153     bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
2154
2155     GST_DEBUG_OBJECT (bin, "async elements commited");
2156     bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS);
2157   }
2158
2159 state_end:
2160   GST_OBJECT_UNLOCK (bin);
2161
2162   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2163       "done changing bin's state from %s to %s, now in %s, ret %s",
2164       gst_element_state_get_name (current),
2165       gst_element_state_get_name (next),
2166       gst_element_state_get_name (GST_STATE (element)),
2167       gst_element_state_change_return_get_name (ret));
2168
2169   return ret;
2170
2171   /* ERRORS */
2172 activate_failure:
2173   {
2174     GST_CAT_WARNING_OBJECT (GST_CAT_STATES, element,
2175         "failure (de)activating src pads");
2176     return GST_STATE_CHANGE_FAILURE;
2177   }
2178 }
2179
2180 /*
2181  * This function is a utility event handler for seek events.
2182  * It will send the event to all sinks or sources depending on the
2183  * event-direction.
2184  *
2185  * Applications are free to override this behaviour and
2186  * implement their own seek handler, but this will work for
2187  * pretty much all cases in practice.
2188  */
2189 static gboolean
2190 gst_bin_send_event (GstElement * element, GstEvent * event)
2191 {
2192   GstBin *bin = GST_BIN (element);
2193   GstIterator *iter;
2194   gboolean res = TRUE;
2195   gboolean done = FALSE;
2196
2197   if (GST_EVENT_IS_DOWNSTREAM (event)) {
2198     iter = gst_bin_iterate_sources (bin);
2199     GST_DEBUG_OBJECT (bin, "Sending %s event to src children",
2200         GST_EVENT_TYPE_NAME (event));
2201   } else {
2202     iter = gst_bin_iterate_sinks (bin);
2203     GST_DEBUG_OBJECT (bin, "Sending %s event to sink children",
2204         GST_EVENT_TYPE_NAME (event));
2205   }
2206
2207   while (!done) {
2208     gpointer data;
2209
2210     switch (gst_iterator_next (iter, &data)) {
2211       case GST_ITERATOR_OK:
2212       {
2213         GstElement *child;
2214
2215         gst_event_ref (event);
2216         child = GST_ELEMENT_CAST (data);
2217         res &= gst_element_send_event (child, event);
2218         gst_object_unref (child);
2219         break;
2220       }
2221       case GST_ITERATOR_RESYNC:
2222         gst_iterator_resync (iter);
2223         res = TRUE;
2224         break;
2225       case GST_ITERATOR_DONE:
2226         done = TRUE;
2227         break;
2228       case GST_ITERATOR_ERROR:
2229         g_assert_not_reached ();
2230         break;
2231     }
2232   }
2233   gst_iterator_free (iter);
2234   gst_event_unref (event);
2235
2236   return res;
2237 }
2238
2239 static void
2240 gst_bin_continue_func (BinContinueData * data)
2241 {
2242   GstBin *bin;
2243   GstState current, next, pending, transition;
2244   GstStateChangeReturn ret;
2245
2246   bin = data->bin;
2247   pending = data->pending;
2248
2249   GST_DEBUG_OBJECT (bin, "waiting for state lock");
2250   GST_STATE_LOCK (bin);
2251
2252   GST_DEBUG_OBJECT (bin, "doing state continue");
2253   GST_OBJECT_LOCK (bin);
2254
2255   if (data->cookie != GST_ELEMENT_CAST (bin)->state_cookie)
2256     goto interrupted;
2257
2258   current = GST_STATE (bin);
2259   next = GST_STATE_GET_NEXT (current, pending);
2260   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2261
2262   GST_STATE_NEXT (bin) = next;
2263   /* mark busy */
2264   GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
2265   GST_OBJECT_UNLOCK (bin);
2266
2267   GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
2268       "continue state change %s to %s, final %s",
2269       gst_element_state_get_name (current),
2270       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2271
2272   ret = gst_element_change_state (GST_ELEMENT_CAST (bin), transition);
2273
2274   GST_STATE_UNLOCK (bin);
2275   GST_DEBUG_OBJECT (bin, "state continue done");
2276   gst_object_unref (bin);
2277   g_free (data);
2278   return;
2279
2280 interrupted:
2281   GST_OBJECT_UNLOCK (bin);
2282   GST_STATE_UNLOCK (bin);
2283   GST_DEBUG_OBJECT (bin, "state continue aborted due to intervening change");
2284   gst_object_unref (bin);
2285   g_free (data);
2286 }
2287
2288 static GstBusSyncReply
2289 bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
2290 {
2291   GstBinClass *bclass;
2292
2293   bclass = GST_BIN_GET_CLASS (bin);
2294   if (bclass->handle_message)
2295     bclass->handle_message (bin, message);
2296   else
2297     gst_message_unref (message);
2298
2299   return GST_BUS_DROP;
2300 }
2301
2302 static void
2303 bin_push_state_continue (BinContinueData * data)
2304 {
2305   GstBinClass *klass;
2306   GstBin *bin;
2307
2308   /* ref was taken */
2309   bin = data->bin;
2310   klass = GST_BIN_GET_CLASS (bin);
2311
2312   GST_DEBUG_OBJECT (bin, "pushing continue on thread pool");
2313   g_thread_pool_push (klass->pool, data, NULL);
2314 }
2315
2316 /* an element started an async state change, if we were not busy with a state
2317  * change, we perform a lost state.
2318  */
2319 static void
2320 bin_handle_async_start (GstBin * bin, gboolean new_base_time)
2321 {
2322   GstState old_state, new_state;
2323   gboolean toplevel;
2324   GstMessage *amessage = NULL;
2325
2326   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
2327     goto had_error;
2328
2329   /* get our toplevel state */
2330   toplevel = BIN_IS_TOPLEVEL (bin);
2331
2332   /* prepare an ASYNC_START message, we always post the start message even if we
2333    * are busy with a state change or when we are NO_PREROLL. */
2334   if (!toplevel)
2335     /* non toplevel bin, prepare async-start for the parent */
2336     amessage =
2337         gst_message_new_async_start (GST_OBJECT_CAST (bin), new_base_time);
2338
2339   if (bin->polling || GST_STATE_PENDING (bin) != GST_STATE_VOID_PENDING)
2340     goto was_busy;
2341
2342   /* async starts are ignored when we are NO_PREROLL */
2343   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_NO_PREROLL)
2344     goto was_no_preroll;
2345
2346   old_state = GST_STATE (bin);
2347
2348   /* when we PLAYING we go back to PAUSED, when preroll happens, we go back to
2349    * PLAYING after optionally redistributing the base_time. */
2350   if (old_state > GST_STATE_PAUSED)
2351     new_state = GST_STATE_PAUSED;
2352   else
2353     new_state = old_state;
2354
2355   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
2356       "lost state of %s, new %s", gst_element_state_get_name (old_state),
2357       gst_element_state_get_name (new_state));
2358
2359   GST_STATE (bin) = new_state;
2360   GST_STATE_NEXT (bin) = new_state;
2361   GST_STATE_PENDING (bin) = new_state;
2362   GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
2363   GST_OBJECT_UNLOCK (bin);
2364
2365   /* post message */
2366   gst_element_post_message (GST_ELEMENT_CAST (bin),
2367       gst_message_new_state_changed (GST_OBJECT_CAST (bin),
2368           new_state, new_state, new_state));
2369
2370 post_start:
2371   if (amessage) {
2372     /* post our ASYNC_START. */
2373     GST_DEBUG_OBJECT (bin, "posting ASYNC_START to parent");
2374     gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
2375   }
2376   GST_OBJECT_LOCK (bin);
2377
2378   return;
2379
2380 had_error:
2381   {
2382     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
2383     return;
2384   }
2385 was_busy:
2386   {
2387     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
2388     GST_OBJECT_UNLOCK (bin);
2389     goto post_start;
2390   }
2391 was_no_preroll:
2392   {
2393     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "ignoring, we are NO_PREROLL");
2394     GST_OBJECT_UNLOCK (bin);
2395     goto post_start;
2396   }
2397 }
2398
2399 /* this function is called when there are no more async elements in the bin. We
2400  * post a state changed message and an ASYNC_DONE message. */
2401 static void
2402 bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret)
2403 {
2404   GstState current, pending, target;
2405   GstStateChangeReturn old_ret;
2406   GstState old_state, old_next;
2407   gboolean toplevel;
2408   GstMessage *smessage = NULL, *amessage = NULL;
2409   BinContinueData *cont = NULL;
2410
2411   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
2412     goto had_error;
2413
2414   pending = GST_STATE_PENDING (bin);
2415
2416   if (bin->polling)
2417     goto was_busy;
2418
2419   /* check if there is something to commit */
2420   if (pending == GST_STATE_VOID_PENDING)
2421     goto nothing_pending;
2422
2423   old_ret = GST_STATE_RETURN (bin);
2424   GST_STATE_RETURN (bin) = ret;
2425
2426   /* move to the next target state */
2427   target = GST_STATE_TARGET (bin);
2428   pending = GST_STATE_PENDING (bin) = target;
2429
2430   amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin));
2431
2432   old_state = GST_STATE (bin);
2433   /* this is the state we should go to next */
2434   old_next = GST_STATE_NEXT (bin);
2435
2436   if (old_next != GST_STATE_PLAYING) {
2437     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
2438         "committing state from %s to %s, old pending %s",
2439         gst_element_state_get_name (old_state),
2440         gst_element_state_get_name (old_next),
2441         gst_element_state_get_name (pending));
2442
2443     /* update current state */
2444     current = GST_STATE (bin) = old_next;
2445   } else {
2446     current = old_state;
2447   }
2448
2449   /* get our toplevel state */
2450   toplevel = BIN_IS_TOPLEVEL (bin);
2451
2452   /* see if we reached the final state. If we are not toplevel, we also have to
2453    * stop here, the parent will continue our state. */
2454   if ((pending == current) || !toplevel) {
2455     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
2456         "completed state change, pending VOID");
2457
2458     /* mark VOID pending */
2459     pending = GST_STATE_VOID_PENDING;
2460     GST_STATE_PENDING (bin) = pending;
2461     GST_STATE_NEXT (bin) = GST_STATE_VOID_PENDING;
2462   } else {
2463     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
2464         "continue state change, pending %s",
2465         gst_element_state_get_name (pending));
2466
2467     cont = g_new0 (BinContinueData, 1);
2468
2469     /* ref to the bin */
2470     cont->bin = gst_object_ref (bin);
2471     /* cookie to detect concurrent state change */
2472     cont->cookie = GST_ELEMENT_CAST (bin)->state_cookie;
2473     /* pending target state */
2474     cont->pending = pending;
2475     /* mark busy */
2476     GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
2477   }
2478
2479   if (old_next != GST_STATE_PLAYING) {
2480     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
2481       smessage = gst_message_new_state_changed (GST_OBJECT_CAST (bin),
2482           old_state, old_next, pending);
2483     }
2484   }
2485   GST_OBJECT_UNLOCK (bin);
2486
2487   if (smessage) {
2488     GST_DEBUG_OBJECT (bin, "posting state change message");
2489     gst_element_post_message (GST_ELEMENT_CAST (bin), smessage);
2490   }
2491   if (amessage) {
2492     /* post our combined ASYNC_DONE when all is ASYNC_DONE. */
2493     GST_DEBUG_OBJECT (bin, "posting ASYNC_DONE to parent");
2494     gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
2495   }
2496
2497   GST_OBJECT_LOCK (bin);
2498   if (cont) {
2499     /* toplevel, start continue state */
2500     GST_DEBUG_OBJECT (bin, "all async-done, starting state continue");
2501     bin_push_state_continue (cont);
2502   } else {
2503     GST_DEBUG_OBJECT (bin, "state change complete");
2504     GST_STATE_BROADCAST (bin);
2505   }
2506   return;
2507
2508 had_error:
2509   {
2510     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
2511     return;
2512   }
2513 was_busy:
2514   {
2515     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
2516     return;
2517   }
2518 nothing_pending:
2519   {
2520     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "nothing pending");
2521     return;
2522   }
2523 }
2524
2525 /* handle child messages:
2526  *
2527  * This method is called synchronously when a child posts a message on
2528  * the internal bus.
2529  *
2530  * GST_MESSAGE_EOS: This message is only posted by sinks
2531  *     in the PLAYING state. If all sinks posted the EOS message, post
2532  *     one upwards.
2533  *
2534  * GST_MESSAGE_STATE_DIRTY: if we are the toplevel bin we do a state
2535  *     recalc. If we are not toplevel (we have a parent) we just post
2536  *     the message upwards. This makes sure only the toplevel bin will
2537  *     run over all its children to check if a state change happened.
2538  *
2539  * GST_MESSAGE_SEGMENT_START: just collect, never forward upwards. If an
2540  *     element posts segment_start twice, only the last message is kept.
2541  *
2542  * GST_MESSAGE_SEGMENT_DONE: replace SEGMENT_START message from same poster
2543  *     with the segment_done message. If there are no more segment_start
2544  *     messages, post segment_done message upwards.
2545  *
2546  * GST_MESSAGE_DURATION: remove all previously cached duration messages.
2547  *     Whenever someone performs a duration query on the bin, we store the
2548  *     result so we can answer it quicker the next time. Any element that
2549  *     changes its duration marks our cached values invalid.
2550  *     This message is also posted upwards. This is currently disabled
2551  *     because too many elements don't post DURATION messages when the
2552  *     duration changes.
2553  *
2554  * GST_MESSAGE_CLOCK_LOST: This message is posted by an element when it
2555  *     can no longer provide a clock. The default bin behaviour is to
2556  *     check if the lost clock was the one provided by the bin. If so and
2557  *     we are currently in the PLAYING state, we forward the message to
2558  *     our parent.
2559  *     This message is also generated when we remove a clock provider from
2560  *     a bin. If this message is received by the application, it should
2561  *     PAUSE the pipeline and set it back to PLAYING to force a new clock
2562  *     and a new base_time distribution.
2563  *
2564  * GST_MESSAGE_CLOCK_PROVIDE: This message is generated when an element
2565  *     can provide a clock. This mostly happens when we add a new clock
2566  *     provider to the bin. The default behaviour of the bin is to mark the
2567  *     currently selected clock as dirty, which will perform a clock
2568  *     recalculation the next time we are asked to provide a clock.
2569  *     This message is never sent to the application but is forwarded to
2570  *     the parent.
2571  *
2572  * GST_MESSAGE_ASYNC_START: Create an internal ELEMENT message that stores
2573  *     the state of the element and the fact that the element will need a
2574  *     new base_time.
2575  *
2576  * GST_MESSAGE_ASYNC_DONE: Find the internal ELEMENT message we kept for the
2577  *     element when it posted ASYNC_START. If all elements are done, post a
2578  *     ASYNC_DONE message to the parent.
2579  *
2580  * OTHER: post upwards.
2581  */
2582 static void
2583 gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
2584 {
2585   GstObject *src;
2586   GstMessageType type;
2587
2588   src = GST_MESSAGE_SRC (message);
2589   type = GST_MESSAGE_TYPE (message);
2590
2591   GST_DEBUG_OBJECT (bin, "[msg %p] handling child %s message of type %s",
2592       message, GST_ELEMENT_NAME (src), GST_MESSAGE_TYPE_NAME (message));
2593
2594   switch (type) {
2595     case GST_MESSAGE_EOS:
2596     {
2597       gboolean eos;
2598
2599       /* collect all eos messages from the children */
2600       GST_OBJECT_LOCK (bin);
2601       bin_replace_message (bin, message, GST_MESSAGE_EOS);
2602       eos = is_eos (bin);
2603       GST_OBJECT_UNLOCK (bin);
2604
2605       /* if we are completely EOS, we forward an EOS message */
2606       if (eos) {
2607         GST_DEBUG_OBJECT (bin, "all sinks posted EOS");
2608         gst_element_post_message (GST_ELEMENT_CAST (bin),
2609             gst_message_new_eos (GST_OBJECT_CAST (bin)));
2610       }
2611       break;
2612     }
2613     case GST_MESSAGE_STATE_DIRTY:
2614     {
2615       GST_WARNING_OBJECT (bin, "received deprecated STATE_DIRTY message");
2616
2617       /* free message */
2618       gst_message_unref (message);
2619       break;
2620     }
2621     case GST_MESSAGE_SEGMENT_START:
2622       GST_OBJECT_LOCK (bin);
2623       /* replace any previous segment_start message from this source
2624        * with the new segment start message */
2625       bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
2626       GST_OBJECT_UNLOCK (bin);
2627       break;
2628     case GST_MESSAGE_SEGMENT_DONE:
2629     {
2630       gboolean post = FALSE;
2631       GstFormat format;
2632       gint64 position;
2633
2634       gst_message_parse_segment_done (message, &format, &position);
2635
2636       GST_OBJECT_LOCK (bin);
2637       bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
2638       /* if there are no more segment_start messages, everybody posted
2639        * a segment_done and we can post one on the bus. */
2640
2641       /* we don't care who still has a pending segment start */
2642       if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START)) {
2643         /* nothing found */
2644         post = TRUE;
2645         /* remove all old segment_done messages */
2646         bin_remove_messages (bin, NULL, GST_MESSAGE_SEGMENT_DONE);
2647       }
2648       GST_OBJECT_UNLOCK (bin);
2649       if (post) {
2650         /* post segment done with latest format and position. */
2651         gst_element_post_message (GST_ELEMENT_CAST (bin),
2652             gst_message_new_segment_done (GST_OBJECT_CAST (bin),
2653                 format, position));
2654       }
2655       break;
2656     }
2657     case GST_MESSAGE_DURATION:
2658     {
2659       /* remove all cached duration messages, next time somebody asks
2660        * for duration, we will recalculate. */
2661       GST_OBJECT_LOCK (bin);
2662       bin_remove_messages (bin, NULL, GST_MESSAGE_DURATION);
2663       GST_OBJECT_UNLOCK (bin);
2664       goto forward;
2665     }
2666     case GST_MESSAGE_CLOCK_LOST:
2667     {
2668       GstClock **provided_clock_p;
2669       GstElement **clock_provider_p;
2670       gboolean playing, provided, forward;
2671       GstClock *clock;
2672
2673       gst_message_parse_clock_lost (message, &clock);
2674
2675       GST_OBJECT_LOCK (bin);
2676       bin->clock_dirty = TRUE;
2677       /* if we lost the clock that we provided, post to parent but
2678        * only if we are PLAYING. */
2679       provided = (clock == bin->provided_clock);
2680       playing = (GST_STATE (bin) == GST_STATE_PLAYING);
2681       forward = playing & provided;
2682       if (provided) {
2683         GST_DEBUG_OBJECT (bin,
2684             "Lost clock %" GST_PTR_FORMAT " provided by %" GST_PTR_FORMAT,
2685             bin->provided_clock, bin->clock_provider);
2686         provided_clock_p = &bin->provided_clock;
2687         clock_provider_p = &bin->clock_provider;
2688         gst_object_replace ((GstObject **) provided_clock_p, NULL);
2689         gst_object_replace ((GstObject **) clock_provider_p, NULL);
2690       }
2691       GST_DEBUG_OBJECT (bin, "provided %d, playing %d, forward %d",
2692           provided, playing, forward);
2693       GST_OBJECT_UNLOCK (bin);
2694
2695       if (forward)
2696         goto forward;
2697
2698       /* free message */
2699       gst_message_unref (message);
2700       break;
2701     }
2702     case GST_MESSAGE_CLOCK_PROVIDE:
2703     {
2704       gboolean forward;
2705
2706       GST_OBJECT_LOCK (bin);
2707       bin->clock_dirty = TRUE;
2708       /* a new clock is available, post to parent but not
2709        * to the application */
2710       forward = GST_OBJECT_PARENT (bin) != NULL;
2711       GST_OBJECT_UNLOCK (bin);
2712
2713       if (forward)
2714         goto forward;
2715
2716       /* free message */
2717       gst_message_unref (message);
2718       break;
2719     }
2720     case GST_MESSAGE_ASYNC_START:
2721     {
2722       gboolean new_base_time;
2723       GstState target;
2724
2725       GST_DEBUG_OBJECT (bin, "ASYNC_START message %p, %s", message,
2726           GST_OBJECT_NAME (src));
2727
2728       gst_message_parse_async_start (message, &new_base_time);
2729
2730       GST_OBJECT_LOCK (bin);
2731       /* we ignore the message if we are going to <= READY */
2732       target = GST_STATE_TARGET (bin);
2733       if (target <= GST_STATE_READY)
2734         goto ignore_start_message;
2735
2736       /* takes ownership of the message */
2737       bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
2738
2739       bin_handle_async_start (bin, new_base_time);
2740       GST_OBJECT_UNLOCK (bin);
2741       break;
2742
2743     ignore_start_message:
2744       {
2745         GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
2746             gst_element_state_get_name (target));
2747         GST_OBJECT_UNLOCK (bin);
2748         gst_message_unref (message);
2749         break;
2750       }
2751     }
2752     case GST_MESSAGE_ASYNC_DONE:
2753     {
2754       GstState target;
2755
2756       GST_DEBUG_OBJECT (bin, "ASYNC_DONE message %p, %s", message,
2757           GST_OBJECT_NAME (src));
2758
2759       GST_OBJECT_LOCK (bin);
2760       target = GST_STATE_TARGET (bin);
2761       /* ignore messages if we are shutting down */
2762       if (target <= GST_STATE_READY)
2763         goto ignore_done_message;
2764
2765       bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
2766       /* if there are no more ASYNC_START messages, everybody posted
2767        * a ASYNC_DONE and we can post one on the bus. When checking, we
2768        * don't care who still has a pending ASYNC_START */
2769       if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
2770         /* nothing found, remove all old ASYNC_DONE messages */
2771         bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
2772
2773         bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS);
2774       }
2775       GST_OBJECT_UNLOCK (bin);
2776       break;
2777
2778     ignore_done_message:
2779       {
2780         GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
2781             gst_element_state_get_name (target));
2782         GST_OBJECT_UNLOCK (bin);
2783         gst_message_unref (message);
2784         break;
2785       }
2786     }
2787     default:
2788       goto forward;
2789   }
2790   return;
2791
2792 forward:
2793   {
2794     /* Send all other messages upward */
2795     GST_DEBUG_OBJECT (bin, "posting message upward");
2796     gst_element_post_message (GST_ELEMENT_CAST (bin), message);
2797     return;
2798   }
2799 }
2800
2801 /* generic struct passed to all query fold methods */
2802 typedef struct
2803 {
2804   GstQuery *query;
2805   gint64 min;
2806   gint64 max;
2807   gboolean live;
2808 } QueryFold;
2809
2810 typedef void (*QueryInitFunction) (GstBin * bin, QueryFold * fold);
2811 typedef void (*QueryDoneFunction) (GstBin * bin, QueryFold * fold);
2812
2813 /* for duration/position we collect all durations/positions and take
2814  * the MAX of all valid results */
2815 static void
2816 bin_query_min_max_init (GstBin * bin, QueryFold * fold)
2817 {
2818   fold->min = 0;
2819   fold->max = -1;
2820   fold->live = FALSE;
2821 }
2822
2823 static gboolean
2824 bin_query_duration_fold (GstElement * item, GValue * ret, QueryFold * fold)
2825 {
2826   if (gst_element_query (item, fold->query)) {
2827     gint64 duration;
2828
2829     g_value_set_boolean (ret, TRUE);
2830
2831     gst_query_parse_duration (fold->query, NULL, &duration);
2832
2833     GST_DEBUG_OBJECT (item, "got duration %" G_GINT64_FORMAT, duration);
2834
2835     if (duration > fold->max)
2836       fold->max = duration;
2837   }
2838
2839   gst_object_unref (item);
2840   return TRUE;
2841 }
2842 static void
2843 bin_query_duration_done (GstBin * bin, QueryFold * fold)
2844 {
2845   GstFormat format;
2846
2847   gst_query_parse_duration (fold->query, &format, NULL);
2848   /* store max in query result */
2849   gst_query_set_duration (fold->query, format, fold->max);
2850
2851   GST_DEBUG_OBJECT (bin, "max duration %" G_GINT64_FORMAT, fold->max);
2852
2853 #ifdef DURATION_CACHING
2854   /* and cache now */
2855   GST_OBJECT_LOCK (bin);
2856   bin->messages = g_list_prepend (bin->messages,
2857       gst_message_new_duration (GST_OBJECT_CAST (bin), format, fold->max));
2858   GST_OBJECT_UNLOCK (bin);
2859 #endif
2860 }
2861
2862 static gboolean
2863 bin_query_position_fold (GstElement * item, GValue * ret, QueryFold * fold)
2864 {
2865   if (gst_element_query (item, fold->query)) {
2866     gint64 position;
2867
2868     g_value_set_boolean (ret, TRUE);
2869
2870     gst_query_parse_position (fold->query, NULL, &position);
2871
2872     GST_DEBUG_OBJECT (item, "got position %" G_GINT64_FORMAT, position);
2873
2874     if (position > fold->max)
2875       fold->max = position;
2876   }
2877
2878   gst_object_unref (item);
2879   return TRUE;
2880 }
2881 static void
2882 bin_query_position_done (GstBin * bin, QueryFold * fold)
2883 {
2884   GstFormat format;
2885
2886   gst_query_parse_position (fold->query, &format, NULL);
2887   /* store max in query result */
2888   gst_query_set_position (fold->query, format, fold->max);
2889
2890   GST_DEBUG_OBJECT (bin, "max position %" G_GINT64_FORMAT, fold->max);
2891 }
2892
2893 static gboolean
2894 bin_query_latency_fold (GstElement * item, GValue * ret, QueryFold * fold)
2895 {
2896   if (gst_element_query (item, fold->query)) {
2897     GstClockTime min, max;
2898     gboolean live;
2899
2900     g_value_set_boolean (ret, TRUE);
2901
2902     gst_query_parse_latency (fold->query, &live, &min, &max);
2903
2904     GST_DEBUG_OBJECT (item,
2905         "got latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
2906         ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live);
2907
2908     /* for the combined latency we collect the MAX of all min latencies and
2909      * the MIN of all max latencies */
2910     if (min > fold->min)
2911       fold->min = min;
2912     if (fold->max == -1)
2913       fold->max = max;
2914     else if (max < fold->max)
2915       fold->max = max;
2916     if (fold->live == FALSE)
2917       fold->live = live;
2918   }
2919
2920   gst_object_unref (item);
2921   return TRUE;
2922 }
2923 static void
2924 bin_query_latency_done (GstBin * bin, QueryFold * fold)
2925 {
2926   /* store max in query result */
2927   gst_query_set_latency (fold->query, fold->live, fold->min, fold->max);
2928
2929   GST_DEBUG_OBJECT (bin,
2930       "latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
2931       ", live %d", GST_TIME_ARGS (fold->min), GST_TIME_ARGS (fold->max),
2932       fold->live);
2933 }
2934
2935
2936 /* generic fold, return first valid result */
2937 static gboolean
2938 bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)
2939 {
2940   gboolean res;
2941
2942   if ((res = gst_element_query (item, fold->query))) {
2943     g_value_set_boolean (ret, TRUE);
2944     GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
2945   }
2946
2947   gst_object_unref (item);
2948
2949   /* and stop as soon as we have a valid result */
2950   return !res;
2951 }
2952
2953 static gboolean
2954 gst_bin_query (GstElement * element, GstQuery * query)
2955 {
2956   GstBin *bin = GST_BIN (element);
2957   GstIterator *iter;
2958   gboolean res = FALSE;
2959   GstIteratorFoldFunction fold_func;
2960   QueryInitFunction fold_init = NULL;
2961   QueryDoneFunction fold_done = NULL;
2962   QueryFold fold_data;
2963   GValue ret = { 0 };
2964
2965   switch (GST_QUERY_TYPE (query)) {
2966     case GST_QUERY_DURATION:
2967     {
2968 #ifdef DURATION_CACHING
2969       GList *cached;
2970       GstFormat qformat;
2971
2972       gst_query_parse_duration (query, &qformat, NULL);
2973
2974       /* find cached duration query */
2975       GST_OBJECT_LOCK (bin);
2976       for (cached = bin->messages; cached; cached = g_list_next (cached)) {
2977         GstMessage *message = (GstMessage *) cached->data;
2978
2979         if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION &&
2980             GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (bin)) {
2981           GstFormat format;
2982           gint64 duration;
2983
2984           gst_message_parse_duration (message, &format, &duration);
2985
2986           /* if cached same format, copy duration in query result */
2987           if (format == qformat) {
2988             GST_DEBUG_OBJECT (bin, "return cached duration %" G_GINT64_FORMAT,
2989                 duration);
2990             GST_OBJECT_UNLOCK (bin);
2991
2992             gst_query_set_duration (query, qformat, duration);
2993             res = TRUE;
2994             goto exit;
2995           }
2996         }
2997       }
2998       GST_OBJECT_UNLOCK (bin);
2999 #endif
3000       /* no cached value found, iterate and collect durations */
3001       fold_func = (GstIteratorFoldFunction) bin_query_duration_fold;
3002       fold_init = bin_query_min_max_init;
3003       fold_done = bin_query_duration_done;
3004       break;
3005     }
3006     case GST_QUERY_POSITION:
3007     {
3008       fold_func = (GstIteratorFoldFunction) bin_query_position_fold;
3009       fold_init = bin_query_min_max_init;
3010       fold_done = bin_query_position_done;
3011       break;
3012     }
3013     case GST_QUERY_LATENCY:
3014     {
3015       fold_func = (GstIteratorFoldFunction) bin_query_latency_fold;
3016       fold_init = bin_query_min_max_init;
3017       fold_done = bin_query_latency_done;
3018       break;
3019     }
3020     default:
3021       fold_func = (GstIteratorFoldFunction) bin_query_generic_fold;
3022       break;
3023   }
3024
3025   fold_data.query = query;
3026
3027   g_value_init (&ret, G_TYPE_BOOLEAN);
3028   g_value_set_boolean (&ret, FALSE);
3029
3030   iter = gst_bin_iterate_sinks (bin);
3031   GST_DEBUG_OBJECT (bin, "Sending query %p (type %s) to sink children",
3032       query, GST_QUERY_TYPE_NAME (query));
3033
3034   if (fold_init)
3035     fold_init (bin, &fold_data);
3036
3037   while (TRUE) {
3038     GstIteratorResult ires;
3039
3040     ires = gst_iterator_fold (iter, fold_func, &ret, &fold_data);
3041
3042     switch (ires) {
3043       case GST_ITERATOR_RESYNC:
3044         gst_iterator_resync (iter);
3045         if (fold_init)
3046           fold_init (bin, &fold_data);
3047         g_value_set_boolean (&ret, FALSE);
3048         break;
3049       case GST_ITERATOR_OK:
3050       case GST_ITERATOR_DONE:
3051         res = g_value_get_boolean (&ret);
3052         if (fold_done != NULL && res)
3053           fold_done (bin, &fold_data);
3054         goto done;
3055       default:
3056         res = FALSE;
3057         goto done;
3058     }
3059   }
3060 done:
3061   gst_iterator_free (iter);
3062
3063 #ifdef DURATION_CACHING
3064 exit:
3065 #endif
3066   GST_DEBUG_OBJECT (bin, "query %p result %d", query, res);
3067
3068   return res;
3069 }
3070
3071 static gint
3072 compare_name (GstElement * element, const gchar * name)
3073 {
3074   gint eq;
3075
3076   GST_OBJECT_LOCK (element);
3077   eq = strcmp (GST_ELEMENT_NAME (element), name);
3078   GST_OBJECT_UNLOCK (element);
3079
3080   if (eq != 0) {
3081     gst_object_unref (element);
3082   }
3083   return eq;
3084 }
3085
3086 /**
3087  * gst_bin_get_by_name:
3088  * @bin: a #GstBin
3089  * @name: the element name to search for
3090  *
3091  * Gets the element with the given name from a bin. This
3092  * function recurses into child bins.
3093  *
3094  * Returns NULL if no element with the given name is found in the bin.
3095  *
3096  * MT safe.  Caller owns returned reference.
3097  *
3098  * Returns: the #GstElement with the given name, or NULL
3099  */
3100 GstElement *
3101 gst_bin_get_by_name (GstBin * bin, const gchar * name)
3102 {
3103   GstIterator *children;
3104   GstIterator *result;
3105
3106   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
3107
3108   GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
3109       GST_ELEMENT_NAME (bin), name);
3110
3111   children = gst_bin_iterate_recurse (bin);
3112   result = gst_iterator_find_custom (children,
3113       (GCompareFunc) compare_name, (gpointer) name);
3114   gst_iterator_free (children);
3115
3116   return GST_ELEMENT_CAST (result);
3117 }
3118
3119 /**
3120  * gst_bin_get_by_name_recurse_up:
3121  * @bin: a #GstBin
3122  * @name: the element name to search for
3123  *
3124  * Gets the element with the given name from this bin. If the
3125  * element is not found, a recursion is performed on the parent bin.
3126  *
3127  * Returns NULL if:
3128  * - no element with the given name is found in the bin
3129  *
3130  * MT safe.  Caller owns returned reference.
3131  *
3132  * Returns: the #GstElement with the given name, or NULL
3133  */
3134 GstElement *
3135 gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
3136 {
3137   GstElement *result;
3138
3139   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
3140   g_return_val_if_fail (name != NULL, NULL);
3141
3142   result = gst_bin_get_by_name (bin, name);
3143
3144   if (!result) {
3145     GstObject *parent;
3146
3147     parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
3148     if (parent) {
3149       if (GST_IS_BIN (parent)) {
3150         result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
3151       }
3152       gst_object_unref (parent);
3153     }
3154   }
3155
3156   return result;
3157 }
3158
3159 static gint
3160 compare_interface (GstElement * element, gpointer interface)
3161 {
3162   GType interface_type = (GType) interface;
3163   gint ret;
3164
3165   if (G_TYPE_CHECK_INSTANCE_TYPE (element, interface_type)) {
3166     ret = 0;
3167   } else {
3168     /* we did not find the element, need to release the ref
3169      * added by the iterator */
3170     gst_object_unref (element);
3171     ret = 1;
3172   }
3173   return ret;
3174 }
3175
3176 /**
3177  * gst_bin_get_by_interface:
3178  * @bin: a #GstBin
3179  * @iface: the #GType of an interface
3180  *
3181  * Looks for an element inside the bin that implements the given
3182  * interface. If such an element is found, it returns the element.
3183  * You can cast this element to the given interface afterwards.  If you want
3184  * all elements that implement the interface, use
3185  * gst_bin_iterate_all_by_interface(). This function recurses into child bins.
3186  *
3187  * MT safe.  Caller owns returned reference.
3188  *
3189  * Returns: A #GstElement inside the bin implementing the interface
3190  */
3191 GstElement *
3192 gst_bin_get_by_interface (GstBin * bin, GType iface)
3193 {
3194   GstIterator *children;
3195   gpointer result;
3196
3197   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
3198   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
3199
3200   children = gst_bin_iterate_recurse (bin);
3201   result = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
3202       (gpointer) iface);
3203   gst_iterator_free (children);
3204
3205   return GST_ELEMENT_CAST (result);
3206 }
3207
3208 /**
3209  * gst_bin_iterate_all_by_interface:
3210  * @bin: a #GstBin
3211  * @iface: the #GType of an interface
3212  *
3213  * Looks for all elements inside the bin that implements the given
3214  * interface. You can safely cast all returned elements to the given interface.
3215  * The function recurses inside child bins. The iterator will yield a series
3216  * of #GstElement that should be unreffed after use.
3217  *
3218  * Each element yielded by the iterator will have its refcount increased, so
3219  * unref after use.
3220  *
3221  * MT safe.  Caller owns returned value.
3222  *
3223  * Returns: a #GstIterator of #GstElement for all elements in the bin
3224  *          implementing the given interface, or NULL
3225  */
3226 GstIterator *
3227 gst_bin_iterate_all_by_interface (GstBin * bin, GType iface)
3228 {
3229   GstIterator *children;
3230   GstIterator *result;
3231
3232   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
3233   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
3234
3235   children = gst_bin_iterate_recurse (bin);
3236   result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
3237       (gpointer) iface);
3238
3239   return result;
3240 }
3241
3242 #ifndef GST_DISABLE_LOADSAVE
3243 static xmlNodePtr
3244 gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
3245 {
3246   GstBin *bin = GST_BIN (object);
3247   xmlNodePtr childlist, elementnode;
3248   GList *children;
3249   GstElement *child;
3250
3251   if (GST_OBJECT_CLASS (parent_class)->save_thyself)
3252     GST_OBJECT_CLASS (parent_class)->save_thyself (GST_OBJECT (bin), parent);
3253
3254   childlist = xmlNewChild (parent, NULL, (xmlChar *) "children", NULL);
3255
3256   GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
3257       GST_ELEMENT_NAME (bin), bin->numchildren);
3258
3259   children = bin->children;
3260   while (children) {
3261     child = GST_ELEMENT (children->data);
3262     elementnode = xmlNewChild (childlist, NULL, (xmlChar *) "element", NULL);
3263     gst_object_save_thyself (GST_OBJECT (child), elementnode);
3264     children = g_list_next (children);
3265   }
3266   return childlist;
3267 }
3268
3269 static void
3270 gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
3271 {
3272   GstBin *bin = GST_BIN (object);
3273   xmlNodePtr field = self->xmlChildrenNode;
3274   xmlNodePtr childlist;
3275
3276   while (field) {
3277     if (!strcmp ((char *) field->name, "children")) {
3278       GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
3279           GST_ELEMENT_NAME (object));
3280       childlist = field->xmlChildrenNode;
3281       while (childlist) {
3282         if (!strcmp ((char *) childlist->name, "element")) {
3283           /* gst_xml_make_element will gst_bin_add() the element to ourself */
3284           gst_xml_make_element (childlist, GST_OBJECT (bin));
3285         }
3286         childlist = childlist->next;
3287       }
3288     }
3289
3290     field = field->next;
3291   }
3292   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3293     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3294 }
3295 #endif /* GST_DISABLE_LOADSAVE */