gstbin: Avoid pointless object lock forwarding messages.
[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.taymans@gmail.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., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, 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 #GstBin::element-added signal is fired whenever a new element is added to
55  * the bin. Likewise the #GstBin::element-removed signal is fired whenever an
56  * element is removed from the bin.
57  *
58  * <refsect2><title>Notes</title>
59  * <para>
60  * A #GstBin internally intercepts every #GstMessage posted by its children and
61  * implements the following default behaviour for each of them:
62  * <variablelist>
63  *   <varlistentry>
64  *     <term>GST_MESSAGE_EOS</term>
65  *     <listitem><para>This message is only posted by sinks in the PLAYING
66  *     state. If all sinks posted the EOS message, this bin will post and EOS
67  *     message upwards.</para></listitem>
68  *   </varlistentry>
69  *   <varlistentry>
70  *     <term>GST_MESSAGE_SEGMENT_START</term>
71  *     <listitem><para>just collected and never forwarded upwards.
72  *     The messages are used to decide when all elements have completed playback
73  *     of their segment.</para></listitem>
74  *   </varlistentry>
75  *   <varlistentry>
76  *     <term>GST_MESSAGE_SEGMENT_DONE</term>
77  *     <listitem><para> Is posted by #GstBin when all elements that posted
78  *     a SEGMENT_START have posted a SEGMENT_DONE.</para></listitem>
79  *   </varlistentry>
80  *   <varlistentry>
81  *     <term>GST_MESSAGE_DURATION_CHANGED</term>
82  *     <listitem><para> Is posted by an element that detected a change
83  *     in the stream duration. The default bin behaviour is to clear any
84  *     cached duration values so that the next duration query will perform
85  *     a full duration recalculation. The duration change is posted to the
86  *     application so that it can refetch the new duration with a duration
87  *     query. Note that these messages can be posted before the bin is
88  *     prerolled, in which case the duration query might fail.
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 2012-03-28 (0.11.3)
158  */
159
160 #include "gst_private.h"
161
162 #include "gstevent.h"
163 #include "gstbin.h"
164 #include "gstinfo.h"
165 #include "gsterror.h"
166
167 #include "gstutils.h"
168 #include "gstchildproxy.h"
169
170 GST_DEBUG_CATEGORY_STATIC (bin_debug);
171 #define GST_CAT_DEFAULT bin_debug
172
173 /* a bin is toplevel if it has no parent or when it is configured to behave like
174  * a toplevel bin */
175 #define BIN_IS_TOPLEVEL(bin) ((GST_OBJECT_PARENT (bin) == NULL) || bin->priv->asynchandling)
176
177 #define GST_BIN_GET_PRIVATE(obj)  \
178    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BIN, GstBinPrivate))
179
180 struct _GstBinPrivate
181 {
182   gboolean asynchandling;
183   /* if we get an ASYNC_DONE message from ourselves, this means that the
184    * subclass will simulate ASYNC behaviour without having ASYNC children. When
185    * such an ASYNC_DONE message is posted while we are doing a state change, we
186    * have to process the message after finishing the state change even when no
187    * child returned GST_STATE_CHANGE_ASYNC. */
188   gboolean pending_async_done;
189
190   guint32 structure_cookie;
191
192 #if 0
193   /* cached index */
194   GstIndex *index;
195 #endif
196
197   /* forward messages from our children */
198   gboolean message_forward;
199
200   gboolean posted_eos;
201
202   GList *contexts;
203 };
204
205 typedef struct
206 {
207   GstBin *bin;
208   guint32 cookie;
209   GstState pending;
210 } BinContinueData;
211
212 static void gst_bin_dispose (GObject * object);
213
214 static void gst_bin_set_property (GObject * object, guint prop_id,
215     const GValue * value, GParamSpec * pspec);
216 static void gst_bin_get_property (GObject * object, guint prop_id,
217     GValue * value, GParamSpec * pspec);
218
219 static GstStateChangeReturn gst_bin_change_state_func (GstElement * element,
220     GstStateChange transition);
221 static void gst_bin_state_changed (GstElement * element, GstState oldstate,
222     GstState newstate, GstState pending);
223 static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
224     GstState * state, GstState * pending, GstClockTime timeout);
225 static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
226     gboolean flag_pending, GstClockTime running_time);
227 static void bin_handle_async_start (GstBin * bin);
228 static void bin_push_state_continue (BinContinueData * data);
229 static void bin_do_eos (GstBin * bin);
230
231 static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
232 static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
233
234 #if 0
235 static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
236 static GstIndex *gst_bin_get_index_func (GstElement * element);
237 #endif
238
239 static GstClock *gst_bin_provide_clock_func (GstElement * element);
240 static gboolean gst_bin_set_clock_func (GstElement * element, GstClock * clock);
241
242 static void gst_bin_handle_message_func (GstBin * bin, GstMessage * message);
243 static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
244 static GstBusSyncReply bin_bus_handler (GstBus * bus,
245     GstMessage * message, GstBin * bin);
246 static gboolean gst_bin_query (GstElement * element, GstQuery * query);
247 static void gst_bin_set_context (GstElement * element, GstContext * context);
248
249 static gboolean gst_bin_do_latency_func (GstBin * bin);
250
251 static void bin_remove_messages (GstBin * bin, GstObject * src,
252     GstMessageType types);
253 static void gst_bin_continue_func (BinContinueData * data);
254 static gint bin_element_is_sink (GstElement * child, GstBin * bin);
255 static gint bin_element_is_src (GstElement * child, GstBin * bin);
256
257 static GstIterator *gst_bin_sort_iterator_new (GstBin * bin);
258
259 /* Bin signals and properties */
260 enum
261 {
262   ELEMENT_ADDED,
263   ELEMENT_REMOVED,
264   DO_LATENCY,
265   LAST_SIGNAL
266 };
267
268 #define DEFAULT_ASYNC_HANDLING  FALSE
269 #define DEFAULT_MESSAGE_FORWARD FALSE
270
271 enum
272 {
273   PROP_0,
274   PROP_ASYNC_HANDLING,
275   PROP_MESSAGE_FORWARD,
276   PROP_LAST
277 };
278
279 static void gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data);
280
281 static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
282
283 #define _do_init \
284 { \
285   static const GInterfaceInfo iface_info = { \
286     gst_bin_child_proxy_init, \
287     NULL, \
288     NULL}; \
289   \
290   g_type_add_interface_static (g_define_type_id, GST_TYPE_CHILD_PROXY, &iface_info); \
291   \
292   GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, \
293       "debugging info for the 'bin' container element"); \
294   \
295 }
296
297 #define gst_bin_parent_class parent_class
298 G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT, _do_init);
299
300 static GObject *
301 gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
302     guint index)
303 {
304   GstObject *res;
305   GstBin *bin;
306
307   bin = GST_BIN_CAST (child_proxy);
308
309   GST_OBJECT_LOCK (bin);
310   if ((res = g_list_nth_data (bin->children, index)))
311     gst_object_ref (res);
312   GST_OBJECT_UNLOCK (bin);
313
314   return (GObject *) res;
315 }
316
317 static guint
318 gst_bin_child_proxy_get_children_count (GstChildProxy * child_proxy)
319 {
320   guint num;
321   GstBin *bin;
322
323   bin = GST_BIN_CAST (child_proxy);
324
325   GST_OBJECT_LOCK (bin);
326   num = bin->numchildren;
327   GST_OBJECT_UNLOCK (bin);
328
329   return num;
330 }
331
332 static void
333 gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data)
334 {
335   GstChildProxyInterface *iface = g_iface;
336
337   iface->get_children_count = gst_bin_child_proxy_get_children_count;
338   iface->get_child_by_index = gst_bin_child_proxy_get_child_by_index;
339 }
340
341 static gboolean
342 _gst_boolean_accumulator (GSignalInvocationHint * ihint,
343     GValue * return_accu, const GValue * handler_return, gpointer dummy)
344 {
345   gboolean myboolean;
346
347   myboolean = g_value_get_boolean (handler_return);
348   if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
349     g_value_set_boolean (return_accu, myboolean);
350
351   GST_DEBUG ("invocation %d, %d", ihint->run_type, myboolean);
352
353   /* stop emission */
354   return FALSE;
355 }
356
357 static void
358 gst_bin_class_init (GstBinClass * klass)
359 {
360   GObjectClass *gobject_class;
361   GstElementClass *gstelement_class;
362   GError *err;
363
364   gobject_class = (GObjectClass *) klass;
365   gstelement_class = (GstElementClass *) klass;
366
367   g_type_class_add_private (klass, sizeof (GstBinPrivate));
368
369   gobject_class->set_property = gst_bin_set_property;
370   gobject_class->get_property = gst_bin_get_property;
371
372   /**
373    * GstBin:async-handling:
374    *
375    * If set to #TRUE, the bin will handle asynchronous state changes.
376    * This should be used only if the bin subclass is modifying the state
377    * of its children on its own.
378    */
379   g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
380       g_param_spec_boolean ("async-handling", "Async Handling",
381           "The bin will handle Asynchronous state changes",
382           DEFAULT_ASYNC_HANDLING, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
383
384   /**
385    * GstBin::element-added:
386    * @bin: the #GstBin
387    * @element: the #GstElement that was added to the bin
388    *
389    * Will be emitted after the element was added to the bin.
390    */
391   gst_bin_signals[ELEMENT_ADDED] =
392       g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
393       G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
394       NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
395   /**
396    * GstBin::element-removed:
397    * @bin: the #GstBin
398    * @element: the #GstElement that was removed from the bin
399    *
400    * Will be emitted after the element was removed from the bin.
401    */
402   gst_bin_signals[ELEMENT_REMOVED] =
403       g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
404       G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
405       NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
406   /**
407    * GstBin::do-latency:
408    * @bin: the #GstBin
409    *
410    * Will be emitted when the bin needs to perform latency calculations. This
411    * signal is only emitted for toplevel bins or when async-handling is
412    * enabled.
413    *
414    * Only one signal handler is invoked. If no signals are connected, the
415    * default handler is invoked, which will query and distribute the lowest
416    * possible latency to all sinks.
417    *
418    * Connect to this signal if the default latency calculations are not
419    * sufficient, like when you need different latencies for different sinks in
420    * the same pipeline.
421    */
422   gst_bin_signals[DO_LATENCY] =
423       g_signal_new ("do-latency", G_TYPE_FROM_CLASS (klass),
424       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstBinClass, do_latency),
425       _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
426       G_TYPE_BOOLEAN, 0, G_TYPE_NONE);
427
428   /**
429    * GstBin:message-forward:
430    *
431    * Forward all children messages, even those that would normally be filtered by
432    * the bin. This can be interesting when one wants to be notified of the EOS
433    * state of individual elements, for example.
434    *
435    * The messages are converted to an ELEMENT message with the bin as the
436    * source. The structure of the message is named 'GstBinForwarded' and contains
437    * a field named 'message' of type GST_TYPE_MESSAGE that contains the original
438    * forwarded message.
439    */
440   g_object_class_install_property (gobject_class, PROP_MESSAGE_FORWARD,
441       g_param_spec_boolean ("message-forward", "Message Forward",
442           "Forwards all children messages",
443           DEFAULT_MESSAGE_FORWARD, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
444
445   gobject_class->dispose = gst_bin_dispose;
446
447   gst_element_class_set_static_metadata (gstelement_class, "Generic bin",
448       "Generic/Bin",
449       "Simple container object",
450       "Erik Walthinsen <omega@cse.ogi.edu>,"
451       "Wim Taymans <wim.taymans@gmail.com>");
452
453   gstelement_class->change_state =
454       GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
455   gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
456   gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
457 #if 0
458   gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
459   gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
460 #endif
461   gstelement_class->provide_clock =
462       GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
463   gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
464
465   gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
466   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_bin_query);
467   gstelement_class->set_context = GST_DEBUG_FUNCPTR (gst_bin_set_context);
468
469   klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
470   klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
471   klass->handle_message = GST_DEBUG_FUNCPTR (gst_bin_handle_message_func);
472
473   klass->do_latency = GST_DEBUG_FUNCPTR (gst_bin_do_latency_func);
474
475   GST_DEBUG ("creating bin thread pool");
476   err = NULL;
477   klass->pool =
478       g_thread_pool_new ((GFunc) gst_bin_continue_func, NULL, -1, FALSE, &err);
479   if (err != NULL) {
480     g_critical ("could alloc threadpool %s", err->message);
481   }
482 }
483
484 static void
485 gst_bin_init (GstBin * bin)
486 {
487   GstBus *bus;
488
489   bin->numchildren = 0;
490   bin->children = NULL;
491   bin->children_cookie = 0;
492   bin->messages = NULL;
493   bin->provided_clock = NULL;
494   bin->clock_dirty = FALSE;
495
496   /* Set up a bus for listening to child elements */
497   bus = g_object_new (GST_TYPE_BUS, "enable-async", FALSE, NULL);
498   bin->child_bus = bus;
499   GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
500       bus);
501   gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin,
502       NULL);
503
504   bin->priv = GST_BIN_GET_PRIVATE (bin);
505   bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
506   bin->priv->structure_cookie = 0;
507   bin->priv->message_forward = DEFAULT_MESSAGE_FORWARD;
508 }
509
510 static void
511 gst_bin_dispose (GObject * object)
512 {
513   GstBin *bin = GST_BIN_CAST (object);
514   GstBus **child_bus_p = &bin->child_bus;
515   GstClock **provided_clock_p = &bin->provided_clock;
516   GstElement **clock_provider_p = &bin->clock_provider;
517
518   GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
519
520   GST_OBJECT_LOCK (object);
521   gst_object_replace ((GstObject **) child_bus_p, NULL);
522   gst_object_replace ((GstObject **) provided_clock_p, NULL);
523   gst_object_replace ((GstObject **) clock_provider_p, NULL);
524   bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
525   GST_OBJECT_UNLOCK (object);
526
527   while (bin->children) {
528     gst_bin_remove (bin, GST_ELEMENT_CAST (bin->children->data));
529   }
530   if (G_UNLIKELY (bin->children != NULL)) {
531     g_critical ("could not remove elements from bin '%s'",
532         GST_STR_NULL (GST_OBJECT_NAME (object)));
533   }
534
535   g_list_free_full (bin->priv->contexts, (GDestroyNotify) gst_context_unref);
536
537   G_OBJECT_CLASS (parent_class)->dispose (object);
538 }
539
540 /**
541  * gst_bin_new:
542  * @name: the name of the new bin
543  *
544  * Creates a new bin with the given name.
545  *
546  * Returns: (transfer floating): a new #GstBin
547  */
548 GstElement *
549 gst_bin_new (const gchar * name)
550 {
551   return gst_element_factory_make ("bin", name);
552 }
553
554 static void
555 gst_bin_set_property (GObject * object, guint prop_id,
556     const GValue * value, GParamSpec * pspec)
557 {
558   GstBin *gstbin;
559
560   gstbin = GST_BIN_CAST (object);
561
562   switch (prop_id) {
563     case PROP_ASYNC_HANDLING:
564       GST_OBJECT_LOCK (gstbin);
565       gstbin->priv->asynchandling = g_value_get_boolean (value);
566       GST_OBJECT_UNLOCK (gstbin);
567       break;
568     case PROP_MESSAGE_FORWARD:
569       GST_OBJECT_LOCK (gstbin);
570       gstbin->priv->message_forward = g_value_get_boolean (value);
571       GST_OBJECT_UNLOCK (gstbin);
572       break;
573     default:
574       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
575       break;
576   }
577 }
578
579 static void
580 gst_bin_get_property (GObject * object, guint prop_id,
581     GValue * value, GParamSpec * pspec)
582 {
583   GstBin *gstbin;
584
585   gstbin = GST_BIN_CAST (object);
586
587   switch (prop_id) {
588     case PROP_ASYNC_HANDLING:
589       GST_OBJECT_LOCK (gstbin);
590       g_value_set_boolean (value, gstbin->priv->asynchandling);
591       GST_OBJECT_UNLOCK (gstbin);
592       break;
593     case PROP_MESSAGE_FORWARD:
594       GST_OBJECT_LOCK (gstbin);
595       g_value_set_boolean (value, gstbin->priv->message_forward);
596       GST_OBJECT_UNLOCK (gstbin);
597       break;
598     default:
599       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
600       break;
601   }
602 }
603
604 #if 0
605 /* return the cached index */
606 static GstIndex *
607 gst_bin_get_index_func (GstElement * element)
608 {
609   GstBin *bin;
610   GstIndex *result;
611
612   bin = GST_BIN_CAST (element);
613
614   GST_OBJECT_LOCK (bin);
615   if ((result = bin->priv->index))
616     gst_object_ref (result);
617   GST_OBJECT_UNLOCK (bin);
618
619   return result;
620 }
621
622 /* set the index on all elements in this bin
623  *
624  * MT safe
625  */
626 static void
627 gst_bin_set_index_func (GstElement * element, GstIndex * index)
628 {
629   GstBin *bin;
630   gboolean done;
631   GstIterator *it;
632   GstIndex *old;
633   GValue data = { 0, };
634
635   bin = GST_BIN_CAST (element);
636
637   GST_OBJECT_LOCK (bin);
638   old = bin->priv->index;
639   if (G_UNLIKELY (old == index))
640     goto was_set;
641   if (index)
642     gst_object_ref (index);
643   bin->priv->index = index;
644   GST_OBJECT_UNLOCK (bin);
645
646   if (old)
647     gst_object_unref (old);
648
649   it = gst_bin_iterate_elements (bin);
650
651   /* set the index on all elements in the bin */
652   done = FALSE;
653   while (!done) {
654     switch (gst_iterator_next (it, &data)) {
655       case GST_ITERATOR_OK:
656       {
657         GstElement *child = g_value_get_object (&data);
658
659         GST_DEBUG_OBJECT (bin, "setting index on '%s'",
660             GST_ELEMENT_NAME (child));
661         gst_element_set_index (child, index);
662
663         g_value_reset (&data);
664         break;
665       }
666       case GST_ITERATOR_RESYNC:
667         GST_DEBUG_OBJECT (bin, "iterator doing resync");
668         gst_iterator_resync (it);
669         break;
670       default:
671       case GST_ITERATOR_DONE:
672         GST_DEBUG_OBJECT (bin, "iterator done");
673         done = TRUE;
674         break;
675     }
676   }
677   g_value_unset (&data);
678   gst_iterator_free (it);
679   return;
680
681 was_set:
682   {
683     GST_DEBUG_OBJECT (bin, "index was already set");
684     GST_OBJECT_UNLOCK (bin);
685     return;
686   }
687 }
688 #endif
689
690 /* set the clock on all elements in this bin
691  *
692  * MT safe
693  */
694 static gboolean
695 gst_bin_set_clock_func (GstElement * element, GstClock * clock)
696 {
697   GstBin *bin;
698   gboolean done;
699   GstIterator *it;
700   gboolean res = TRUE;
701   GValue data = { 0, };
702
703   bin = GST_BIN_CAST (element);
704
705   it = gst_bin_iterate_elements (bin);
706
707   done = FALSE;
708   while (!done) {
709     switch (gst_iterator_next (it, &data)) {
710       case GST_ITERATOR_OK:
711       {
712         GstElement *child = g_value_get_object (&data);
713
714         res &= gst_element_set_clock (child, clock);
715
716         g_value_reset (&data);
717         break;
718       }
719       case GST_ITERATOR_RESYNC:
720         GST_DEBUG_OBJECT (bin, "iterator doing resync");
721         gst_iterator_resync (it);
722         res = TRUE;
723         break;
724       default:
725       case GST_ITERATOR_DONE:
726         GST_DEBUG_OBJECT (bin, "iterator done");
727         done = TRUE;
728         break;
729     }
730   }
731   g_value_unset (&data);
732   gst_iterator_free (it);
733
734   if (res)
735     res = GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock);
736
737   return res;
738 }
739
740 /* get the clock for this bin by asking all of the children in this bin
741  *
742  * The ref of the returned clock in increased so unref after usage.
743  *
744  * We loop the elements in state order and pick the last clock we can
745  * get. This makes sure we get a clock from the source.
746  *
747  * MT safe
748  */
749 static GstClock *
750 gst_bin_provide_clock_func (GstElement * element)
751 {
752   GstClock *result = NULL;
753   GstElement *provider = NULL;
754   GstBin *bin;
755   GstIterator *it;
756   gboolean done;
757   GValue val = { 0, };
758   GstClock **provided_clock_p;
759   GstElement **clock_provider_p;
760
761   bin = GST_BIN_CAST (element);
762
763   GST_OBJECT_LOCK (bin);
764   if (!bin->clock_dirty)
765     goto not_dirty;
766
767   GST_DEBUG_OBJECT (bin, "finding new clock");
768
769   it = gst_bin_sort_iterator_new (bin);
770   GST_OBJECT_UNLOCK (bin);
771
772   done = FALSE;
773   while (!done) {
774     switch (gst_iterator_next (it, &val)) {
775       case GST_ITERATOR_OK:
776       {
777         GstElement *child = g_value_get_object (&val);
778         GstClock *clock;
779
780         clock = gst_element_provide_clock (child);
781         if (clock) {
782           GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
783               clock, GST_ELEMENT_NAME (child));
784           if (result) {
785             gst_object_unref (result);
786             gst_object_unref (provider);
787           }
788           result = clock;
789           provider = gst_object_ref (child);
790         }
791
792         g_value_reset (&val);
793         break;
794       }
795       case GST_ITERATOR_RESYNC:
796         gst_iterator_resync (it);
797         break;
798       default:
799       case GST_ITERATOR_DONE:
800         done = TRUE;
801         break;
802     }
803   }
804   g_value_unset (&val);
805   gst_iterator_free (it);
806
807   GST_OBJECT_LOCK (bin);
808   if (!bin->clock_dirty) {
809     if (provider)
810       gst_object_unref (provider);
811     if (result)
812       gst_object_unref (result);
813     result = NULL;
814
815     goto not_dirty;
816   }
817
818   provided_clock_p = &bin->provided_clock;
819   clock_provider_p = &bin->clock_provider;
820   gst_object_replace ((GstObject **) provided_clock_p, (GstObject *) result);
821   gst_object_replace ((GstObject **) clock_provider_p, (GstObject *) provider);
822   bin->clock_dirty = FALSE;
823   GST_DEBUG_OBJECT (bin,
824       "provided new clock %" GST_PTR_FORMAT " by provider %" GST_PTR_FORMAT,
825       result, provider);
826   /* Provider is not being returned to caller, just the result */
827   if (provider)
828     gst_object_unref (provider);
829   GST_OBJECT_UNLOCK (bin);
830
831   return result;
832
833 not_dirty:
834   {
835     if ((result = bin->provided_clock))
836       gst_object_ref (result);
837     GST_DEBUG_OBJECT (bin, "returning old clock %p", result);
838     GST_OBJECT_UNLOCK (bin);
839
840     return result;
841   }
842 }
843
844 /*
845  * functions for manipulating cached messages
846  */
847 typedef struct
848 {
849   GstObject *src;
850   GstMessageType types;
851 } MessageFind;
852
853 /* check if a message is of given src and type */
854 static gint
855 message_check (GstMessage * message, MessageFind * target)
856 {
857   gboolean eq = TRUE;
858
859   if (target->src)
860     eq &= GST_MESSAGE_SRC (message) == target->src;
861   if (target->types)
862     eq &= (GST_MESSAGE_TYPE (message) & target->types) != 0;
863   GST_LOG ("looking at message %p: %d", message, eq);
864
865   return (eq ? 0 : 1);
866 }
867
868 static GList *
869 find_message (GstBin * bin, GstObject * src, GstMessageType types)
870 {
871   GList *result;
872   MessageFind find;
873
874   find.src = src;
875   find.types = types;
876
877   result = g_list_find_custom (bin->messages, &find,
878       (GCompareFunc) message_check);
879
880   if (result) {
881     GST_DEBUG_OBJECT (bin, "we found a message %p from %s matching types %08x",
882         result->data, GST_OBJECT_NAME (GST_MESSAGE_CAST (result->data)->src),
883         types);
884   } else {
885     GST_DEBUG_OBJECT (bin, "no message found matching types %08x", types);
886 #ifndef GST_DISABLE_GST_DEBUG
887     {
888       guint i;
889
890       for (i = 0; i < 32; i++)
891         if (types & (1 << i))
892           GST_DEBUG_OBJECT (bin, "  %s", gst_message_type_get_name (1 << i));
893     }
894 #endif
895   }
896
897   return result;
898 }
899
900 /* with LOCK, returns TRUE if message had a valid SRC, takes ownership of
901  * the message.
902  *
903  * A message that is cached and has the same SRC and type is replaced
904  * by the given message.
905  */
906 static gboolean
907 bin_replace_message (GstBin * bin, GstMessage * message, GstMessageType types)
908 {
909   GList *previous;
910   GstObject *src;
911   gboolean res = TRUE;
912
913   if ((src = GST_MESSAGE_SRC (message))) {
914     /* first find the previous message posted by this element */
915     if ((previous = find_message (bin, src, types))) {
916       GstMessage *previous_msg;
917
918       /* if we found a previous message, replace it */
919       previous_msg = previous->data;
920       previous->data = message;
921
922       GST_DEBUG_OBJECT (bin, "replace old message %s from %s with %s message",
923           GST_MESSAGE_TYPE_NAME (previous_msg), GST_ELEMENT_NAME (src),
924           GST_MESSAGE_TYPE_NAME (message));
925
926       gst_message_unref (previous_msg);
927     } else {
928       /* keep new message */
929       bin->messages = g_list_prepend (bin->messages, message);
930
931       GST_DEBUG_OBJECT (bin, "got new message %p, %s from %s",
932           message, GST_MESSAGE_TYPE_NAME (message), GST_ELEMENT_NAME (src));
933     }
934   } else {
935     GST_DEBUG_OBJECT (bin, "got message %s from (NULL), not processing",
936         GST_MESSAGE_TYPE_NAME (message));
937     res = FALSE;
938     gst_message_unref (message);
939   }
940   return res;
941 }
942
943 /* with LOCK. Remove all messages of given types */
944 static void
945 bin_remove_messages (GstBin * bin, GstObject * src, GstMessageType types)
946 {
947   MessageFind find;
948   GList *walk, *next;
949
950   find.src = src;
951   find.types = types;
952
953   for (walk = bin->messages; walk; walk = next) {
954     GstMessage *message = (GstMessage *) walk->data;
955
956     next = g_list_next (walk);
957
958     if (message_check (message, &find) == 0) {
959       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
960           "deleting message %p of types 0x%08x", message, types);
961       bin->messages = g_list_delete_link (bin->messages, walk);
962       gst_message_unref (message);
963     } else {
964       GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message),
965           "not deleting message %p of type 0x%08x", message,
966           GST_MESSAGE_TYPE (message));
967     }
968   }
969 }
970
971
972 /* Check if the bin is EOS. We do this by scanning all sinks and
973  * checking if they posted an EOS message.
974  *
975  * call with bin LOCK */
976 static gboolean
977 is_eos (GstBin * bin, guint32 * seqnum)
978 {
979   gboolean result;
980   gint n_eos = 0;
981   GList *walk, *msgs;
982
983   result = TRUE;
984   for (walk = bin->children; walk; walk = g_list_next (walk)) {
985     GstElement *element;
986
987     element = GST_ELEMENT_CAST (walk->data);
988     if (bin_element_is_sink (element, bin) == 0) {
989       /* check if element posted EOS */
990       if ((msgs =
991               find_message (bin, GST_OBJECT_CAST (element), GST_MESSAGE_EOS))) {
992         GST_DEBUG ("sink '%s' posted EOS", GST_ELEMENT_NAME (element));
993         *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
994         n_eos++;
995       } else {
996         GST_DEBUG ("sink '%s' did not post EOS yet",
997             GST_ELEMENT_NAME (element));
998         result = FALSE;
999         break;
1000       }
1001     }
1002   }
1003   /* FIXME: Some tests (e.g. elements/capsfilter) use
1004    * pipelines with a dangling sinkpad but no sink element.
1005    * These tests assume that no EOS message is ever
1006    * posted on the bus so let's keep that behaviour.
1007    * In valid pipelines this doesn't make a difference.
1008    */
1009   return result && n_eos > 0;
1010 }
1011
1012
1013 /* Check if the bin is STREAM_START. We do this by scanning all sinks and
1014  * checking if they posted an STREAM_START message.
1015  *
1016  * call with bin LOCK */
1017 static gboolean
1018 is_stream_start (GstBin * bin, guint32 * seqnum, gboolean * have_group_id,
1019     guint * group_id)
1020 {
1021   gboolean result;
1022   GList *walk, *msgs;
1023   guint tmp_group_id;
1024   gboolean first = TRUE, same_group_id = TRUE;
1025
1026   *have_group_id = TRUE;
1027   *group_id = 0;
1028   result = TRUE;
1029   for (walk = bin->children; walk; walk = g_list_next (walk)) {
1030     GstElement *element;
1031
1032     element = GST_ELEMENT_CAST (walk->data);
1033     if (bin_element_is_sink (element, bin) == 0) {
1034       /* check if element posted STREAM_START */
1035       if ((msgs =
1036               find_message (bin, GST_OBJECT_CAST (element),
1037                   GST_MESSAGE_STREAM_START))) {
1038         GST_DEBUG ("sink '%s' posted STREAM_START", GST_ELEMENT_NAME (element));
1039         *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
1040         if (gst_message_parse_group_id (GST_MESSAGE_CAST (msgs->data),
1041                 &tmp_group_id)) {
1042           if (first) {
1043             first = FALSE;
1044             *group_id = tmp_group_id;
1045           } else {
1046             if (tmp_group_id != *group_id)
1047               same_group_id = FALSE;
1048           }
1049         } else {
1050           *have_group_id = FALSE;
1051         }
1052       } else {
1053         GST_DEBUG ("sink '%s' did not post STREAM_START yet",
1054             GST_ELEMENT_NAME (element));
1055         result = FALSE;
1056         break;
1057       }
1058     }
1059   }
1060
1061   /* If all have a group_id we only consider this stream started
1062    * if all group ids were the same and all sinks posted a stream-start
1063    * message */
1064   if (*have_group_id)
1065     return same_group_id && result;
1066   /* otherwise consider this stream started after all sinks
1067    * have reported stream-start for backward compatibility.
1068    * FIXME 2.0: This should go away! */
1069   return result;
1070 }
1071
1072 static void
1073 unlink_pads (const GValue * item, gpointer user_data)
1074 {
1075   GstPad *pad;
1076   GstPad *peer;
1077
1078   pad = g_value_get_object (item);
1079
1080   if ((peer = gst_pad_get_peer (pad))) {
1081     if (gst_pad_get_direction (pad) == GST_PAD_SRC)
1082       gst_pad_unlink (pad, peer);
1083     else
1084       gst_pad_unlink (peer, pad);
1085     gst_object_unref (peer);
1086   }
1087 }
1088
1089 /* vmethod that adds an element to a bin
1090  *
1091  * MT safe
1092  */
1093 static gboolean
1094 gst_bin_add_func (GstBin * bin, GstElement * element)
1095 {
1096   gchar *elem_name;
1097   GstIterator *it;
1098   gboolean is_sink, is_source, provides_clock, requires_clock;
1099   GstMessage *clock_message = NULL, *async_message = NULL;
1100   GstStateChangeReturn ret;
1101   GList *l;
1102
1103   GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
1104
1105   /* we obviously can't add ourself to ourself */
1106   if (G_UNLIKELY (element == GST_ELEMENT_CAST (bin)))
1107     goto adding_itself;
1108
1109   /* get the element name to make sure it is unique in this bin. */
1110   GST_OBJECT_LOCK (element);
1111   elem_name = g_strdup (GST_ELEMENT_NAME (element));
1112   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
1113   is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE);
1114   provides_clock =
1115       GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
1116   requires_clock =
1117       GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
1118   GST_OBJECT_UNLOCK (element);
1119
1120   GST_OBJECT_LOCK (bin);
1121
1122   /* then check to see if the element's name is already taken in the bin,
1123    * we can safely take the lock here. This check is probably bogus because
1124    * you can safely change the element name after this check and before setting
1125    * the object parent. The window is very small though... */
1126   if (G_UNLIKELY (!gst_object_check_uniqueness (bin->children, elem_name)))
1127     goto duplicate_name;
1128
1129   /* set the element's parent and add the element to the bin's list of children */
1130   if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (element),
1131               GST_OBJECT_CAST (bin))))
1132     goto had_parent;
1133
1134   /* if we add a sink we become a sink */
1135   if (is_sink) {
1136     GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was sink",
1137         elem_name);
1138     GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SINK);
1139   }
1140   if (is_source) {
1141     GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was source",
1142         elem_name);
1143     GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
1144   }
1145   if (provides_clock) {
1146     GST_DEBUG_OBJECT (bin, "element \"%s\" can provide a clock", elem_name);
1147     clock_message =
1148         gst_message_new_clock_provide (GST_OBJECT_CAST (element), NULL, TRUE);
1149     GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
1150   }
1151   if (requires_clock) {
1152     GST_DEBUG_OBJECT (bin, "element \"%s\" requires a clock", elem_name);
1153     GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
1154   }
1155
1156   bin->children = g_list_prepend (bin->children, element);
1157   bin->numchildren++;
1158   bin->children_cookie++;
1159   if (!GST_BIN_IS_NO_RESYNC (bin))
1160     bin->priv->structure_cookie++;
1161
1162   /* distribute the bus */
1163   gst_element_set_bus (element, bin->child_bus);
1164
1165   /* propagate the current base_time, start_time and clock */
1166   gst_element_set_base_time (element, GST_ELEMENT_CAST (bin)->base_time);
1167   gst_element_set_start_time (element, GST_ELEMENT_START_TIME (bin));
1168   /* it's possible that the element did not accept the clock but
1169    * that is not important right now. When the pipeline goes to PLAYING,
1170    * a new clock will be selected */
1171   gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
1172
1173   for (l = bin->priv->contexts; l; l = l->next)
1174     gst_element_set_context (element, l->data);
1175
1176 #if 0
1177   /* set the cached index on the children */
1178   if (bin->priv->index)
1179     gst_element_set_index (element, bin->priv->index);
1180 #endif
1181
1182   ret = GST_STATE_RETURN (bin);
1183   /* no need to update the state if we are in error */
1184   if (ret == GST_STATE_CHANGE_FAILURE)
1185     goto no_state_recalc;
1186
1187   /* update the bin state, the new element could have been an ASYNC or
1188    * NO_PREROLL element */
1189   ret = GST_STATE_RETURN (element);
1190   GST_DEBUG_OBJECT (bin, "added %s element",
1191       gst_element_state_change_return_get_name (ret));
1192
1193   switch (ret) {
1194     case GST_STATE_CHANGE_ASYNC:
1195     {
1196       /* create message to track this aync element when it posts an async-done
1197        * message */
1198       async_message = gst_message_new_async_start (GST_OBJECT_CAST (element));
1199       break;
1200     }
1201     case GST_STATE_CHANGE_NO_PREROLL:
1202       /* ignore all async elements we might have and commit our state */
1203       bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
1204       break;
1205     case GST_STATE_CHANGE_FAILURE:
1206       break;
1207     default:
1208       break;
1209   }
1210
1211 no_state_recalc:
1212   GST_OBJECT_UNLOCK (bin);
1213
1214   /* post the messages on the bus of the element so that the bin can handle
1215    * them */
1216   if (clock_message)
1217     gst_element_post_message (element, clock_message);
1218
1219   if (async_message)
1220     gst_element_post_message (element, async_message);
1221
1222   /* unlink all linked pads */
1223   it = gst_element_iterate_pads (element);
1224   gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
1225   gst_iterator_free (it);
1226
1227   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
1228       elem_name);
1229
1230   g_signal_emit (bin, gst_bin_signals[ELEMENT_ADDED], 0, element);
1231   gst_child_proxy_child_added ((GstChildProxy *) bin, (GObject *) element,
1232       elem_name);
1233
1234   g_free (elem_name);
1235
1236   return TRUE;
1237
1238   /* ERROR handling here */
1239 adding_itself:
1240   {
1241     GST_OBJECT_LOCK (bin);
1242     g_warning ("Cannot add bin '%s' to itself", GST_ELEMENT_NAME (bin));
1243     GST_OBJECT_UNLOCK (bin);
1244     return FALSE;
1245   }
1246 duplicate_name:
1247   {
1248     g_warning ("Name '%s' is not unique in bin '%s', not adding",
1249         elem_name, GST_ELEMENT_NAME (bin));
1250     GST_OBJECT_UNLOCK (bin);
1251     g_free (elem_name);
1252     return FALSE;
1253   }
1254 had_parent:
1255   {
1256     g_warning ("Element '%s' already has parent", elem_name);
1257     GST_OBJECT_UNLOCK (bin);
1258     g_free (elem_name);
1259     return FALSE;
1260   }
1261 }
1262
1263 /**
1264  * gst_bin_add:
1265  * @bin: a #GstBin
1266  * @element: (transfer full): the #GstElement to add
1267  *
1268  * Adds the given element to the bin.  Sets the element's parent, and thus
1269  * takes ownership of the element. An element can only be added to one bin.
1270  *
1271  * If the element's pads are linked to other pads, the pads will be unlinked
1272  * before the element is added to the bin.
1273  *
1274  * <note>
1275  * When you add an element to an already-running pipeline, you will have to
1276  * take care to set the state of the newly-added element to the desired
1277  * state (usually PLAYING or PAUSED, same you set the pipeline to originally)
1278  * with gst_element_set_state(), or use gst_element_sync_state_with_parent().
1279  * The bin or pipeline will not take care of this for you.
1280  * </note>
1281  *
1282  * MT safe.
1283  *
1284  * Returns: TRUE if the element could be added, FALSE if
1285  * the bin does not want to accept the element.
1286  */
1287 gboolean
1288 gst_bin_add (GstBin * bin, GstElement * element)
1289 {
1290   GstBinClass *bclass;
1291   gboolean result;
1292
1293   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
1294   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1295
1296   bclass = GST_BIN_GET_CLASS (bin);
1297
1298   if (G_UNLIKELY (bclass->add_element == NULL))
1299     goto no_function;
1300
1301   GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
1302       GST_STR_NULL (GST_ELEMENT_NAME (element)),
1303       GST_STR_NULL (GST_ELEMENT_NAME (bin)));
1304
1305   result = bclass->add_element (bin, element);
1306
1307   return result;
1308
1309   /* ERROR handling */
1310 no_function:
1311   {
1312     g_warning ("adding elements to bin '%s' is not supported",
1313         GST_ELEMENT_NAME (bin));
1314     return FALSE;
1315   }
1316 }
1317
1318 /* remove an element from the bin
1319  *
1320  * MT safe
1321  */
1322 static gboolean
1323 gst_bin_remove_func (GstBin * bin, GstElement * element)
1324 {
1325   gchar *elem_name;
1326   GstIterator *it;
1327   gboolean is_sink, is_source, provides_clock, requires_clock;
1328   gboolean othersink, othersource, otherprovider, otherrequirer, found;
1329   GstMessage *clock_message = NULL;
1330   GstClock **provided_clock_p;
1331   GstElement **clock_provider_p;
1332   GList *walk, *next;
1333   gboolean other_async, this_async, have_no_preroll;
1334   GstStateChangeReturn ret;
1335
1336   GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
1337
1338   GST_OBJECT_LOCK (bin);
1339
1340   GST_OBJECT_LOCK (element);
1341   elem_name = g_strdup (GST_ELEMENT_NAME (element));
1342
1343   if (GST_OBJECT_PARENT (element) != GST_OBJECT_CAST (bin))
1344     goto not_in_bin;
1345
1346   /* remove the parent ref */
1347   GST_OBJECT_PARENT (element) = NULL;
1348
1349   /* grab element name so we can print it */
1350   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
1351   is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE);
1352   provides_clock =
1353       GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
1354   requires_clock =
1355       GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
1356   GST_OBJECT_UNLOCK (element);
1357
1358   found = FALSE;
1359   othersink = FALSE;
1360   othersource = FALSE;
1361   otherprovider = FALSE;
1362   otherrequirer = FALSE;
1363   have_no_preroll = FALSE;
1364   /* iterate the elements, we collect which ones are async and no_preroll. We
1365    * also remove the element when we find it. */
1366   for (walk = bin->children; walk; walk = next) {
1367     GstElement *child = GST_ELEMENT_CAST (walk->data);
1368
1369     next = g_list_next (walk);
1370
1371     if (child == element) {
1372       found = TRUE;
1373       /* remove the element */
1374       bin->children = g_list_delete_link (bin->children, walk);
1375     } else {
1376       gboolean child_sink, child_source, child_provider, child_requirer;
1377
1378       GST_OBJECT_LOCK (child);
1379       child_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);
1380       child_source = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);
1381       child_provider =
1382           GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
1383       child_requirer =
1384           GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
1385       /* when we remove a sink, check if there are other sinks. */
1386       if (is_sink && !othersink && child_sink)
1387         othersink = TRUE;
1388       if (is_source && !othersource && child_source)
1389         othersource = TRUE;
1390       if (provides_clock && !otherprovider && child_provider)
1391         otherprovider = TRUE;
1392       if (requires_clock && !otherrequirer && child_requirer)
1393         otherrequirer = TRUE;
1394       /* check if we have NO_PREROLL children */
1395       if (GST_STATE_RETURN (child) == GST_STATE_CHANGE_NO_PREROLL)
1396         have_no_preroll = TRUE;
1397       GST_OBJECT_UNLOCK (child);
1398     }
1399   }
1400
1401   /* the element must have been in the bin's list of children */
1402   if (G_UNLIKELY (!found))
1403     goto not_in_bin;
1404
1405   /* we now removed the element from the list of elements, increment the cookie
1406    * so that others can detect a change in the children list. */
1407   bin->numchildren--;
1408   bin->children_cookie++;
1409   if (!GST_BIN_IS_NO_RESYNC (bin))
1410     bin->priv->structure_cookie++;
1411
1412   if (is_sink && !othersink) {
1413     /* we're not a sink anymore */
1414     GST_DEBUG_OBJECT (bin, "we removed the last sink");
1415     GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SINK);
1416   }
1417   if (is_source && !othersource) {
1418     /* we're not a source anymore */
1419     GST_DEBUG_OBJECT (bin, "we removed the last source");
1420     GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SOURCE);
1421   }
1422   if (provides_clock && !otherprovider) {
1423     /* we're not a clock provider anymore */
1424     GST_DEBUG_OBJECT (bin, "we removed the last clock provider");
1425     GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
1426   }
1427   if (requires_clock && !otherrequirer) {
1428     /* we're not a clock requirer anymore */
1429     GST_DEBUG_OBJECT (bin, "we removed the last clock requirer");
1430     GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
1431   }
1432
1433   /* if the clock provider for this element is removed, we lost
1434    * the clock as well, we need to inform the parent of this
1435    * so that it can select a new clock */
1436   if (bin->clock_provider == element) {
1437     GST_DEBUG_OBJECT (bin, "element \"%s\" provided the clock", elem_name);
1438     bin->clock_dirty = TRUE;
1439     clock_message =
1440         gst_message_new_clock_lost (GST_OBJECT_CAST (bin), bin->provided_clock);
1441     provided_clock_p = &bin->provided_clock;
1442     clock_provider_p = &bin->clock_provider;
1443     gst_object_replace ((GstObject **) provided_clock_p, NULL);
1444     gst_object_replace ((GstObject **) clock_provider_p, NULL);
1445   }
1446
1447   /* remove messages for the element, if there was a pending ASYNC_START
1448    * message we must see if removing the element caused the bin to lose its
1449    * async state. */
1450   this_async = FALSE;
1451   other_async = FALSE;
1452   for (walk = bin->messages; walk; walk = next) {
1453     GstMessage *message = (GstMessage *) walk->data;
1454     GstElement *src = GST_ELEMENT_CAST (GST_MESSAGE_SRC (message));
1455     gboolean remove;
1456
1457     next = g_list_next (walk);
1458     remove = FALSE;
1459
1460     switch (GST_MESSAGE_TYPE (message)) {
1461       case GST_MESSAGE_ASYNC_START:
1462         if (src == element)
1463           this_async = TRUE;
1464         else
1465           other_async = TRUE;
1466
1467         GST_DEBUG_OBJECT (src, "looking at message %p", message);
1468         break;
1469       case GST_MESSAGE_STRUCTURE_CHANGE:
1470       {
1471         GstElement *owner;
1472
1473         GST_DEBUG_OBJECT (src, "looking at structure change message %p",
1474             message);
1475         /* it's unlikely that this message is still in the list of messages
1476          * because this would mean that a link/unlink is busy in another thread
1477          * while we remove the element. We still have to remove the message
1478          * because we might not receive the done message anymore when the element
1479          * is removed from the bin. */
1480         gst_message_parse_structure_change (message, NULL, &owner, NULL);
1481         if (owner == element)
1482           remove = TRUE;
1483         break;
1484       }
1485       default:
1486         break;
1487     }
1488     if (src == element)
1489       remove = TRUE;
1490
1491     if (remove) {
1492       /* delete all message types */
1493       GST_DEBUG_OBJECT (src, "deleting message %p of element \"%s\"",
1494           message, elem_name);
1495       bin->messages = g_list_delete_link (bin->messages, walk);
1496       gst_message_unref (message);
1497     }
1498   }
1499
1500   /* get last return */
1501   ret = GST_STATE_RETURN (bin);
1502
1503   /* no need to update the state if we are in error */
1504   if (ret == GST_STATE_CHANGE_FAILURE)
1505     goto no_state_recalc;
1506
1507   if (!other_async && this_async) {
1508     /* all other elements were not async and we removed the async one,
1509      * handle the async-done case because we are not async anymore now. */
1510     GST_DEBUG_OBJECT (bin,
1511         "we removed the last async element, have no_preroll %d",
1512         have_no_preroll);
1513
1514     /* the current state return of the bin depends on if there are no_preroll
1515      * elements in the pipeline or not */
1516     if (have_no_preroll)
1517       ret = GST_STATE_CHANGE_NO_PREROLL;
1518     else
1519       ret = GST_STATE_CHANGE_SUCCESS;
1520
1521     bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
1522   } else {
1523     GST_DEBUG_OBJECT (bin,
1524         "recalc state preroll: %d, other async: %d, this async %d",
1525         have_no_preroll, other_async, this_async);
1526
1527     if (have_no_preroll) {
1528       ret = GST_STATE_CHANGE_NO_PREROLL;
1529     } else if (other_async) {
1530       /* there are other async elements and we were not doing an async state
1531        * change, change our pending state and go async */
1532       if (GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
1533         GST_STATE_NEXT (bin) = GST_STATE (bin);
1534         GST_STATE_PENDING (bin) = GST_STATE (bin);
1535       }
1536       ret = GST_STATE_CHANGE_ASYNC;
1537     }
1538     GST_STATE_RETURN (bin) = ret;
1539   }
1540 no_state_recalc:
1541   /* clear bus */
1542   gst_element_set_bus (element, NULL);
1543   /* Clear the clock we provided to the element */
1544   gst_element_set_clock (element, NULL);
1545   GST_OBJECT_UNLOCK (bin);
1546
1547   if (clock_message)
1548     gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
1549
1550   /* unlink all linked pads */
1551   it = gst_element_iterate_pads (element);
1552   gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
1553   gst_iterator_free (it);
1554
1555   GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
1556       elem_name);
1557
1558   g_signal_emit (bin, gst_bin_signals[ELEMENT_REMOVED], 0, element);
1559   gst_child_proxy_child_removed ((GstChildProxy *) bin, (GObject *) element,
1560       elem_name);
1561
1562   g_free (elem_name);
1563   /* element is really out of our control now */
1564   gst_object_unref (element);
1565
1566   return TRUE;
1567
1568   /* ERROR handling */
1569 not_in_bin:
1570   {
1571     g_warning ("Element '%s' is not in bin '%s'", elem_name,
1572         GST_ELEMENT_NAME (bin));
1573     GST_OBJECT_UNLOCK (element);
1574     GST_OBJECT_UNLOCK (bin);
1575     g_free (elem_name);
1576     return FALSE;
1577   }
1578 }
1579
1580 /**
1581  * gst_bin_remove:
1582  * @bin: a #GstBin
1583  * @element: (transfer none): the #GstElement to remove
1584  *
1585  * Removes the element from the bin, unparenting it as well.
1586  * Unparenting the element means that the element will be dereferenced,
1587  * so if the bin holds the only reference to the element, the element
1588  * will be freed in the process of removing it from the bin.  If you
1589  * want the element to still exist after removing, you need to call
1590  * gst_object_ref() before removing it from the bin.
1591  *
1592  * If the element's pads are linked to other pads, the pads will be unlinked
1593  * before the element is removed from the bin.
1594  *
1595  * MT safe.
1596  *
1597  * Returns: TRUE if the element could be removed, FALSE if
1598  * the bin does not want to remove the element.
1599  */
1600 gboolean
1601 gst_bin_remove (GstBin * bin, GstElement * element)
1602 {
1603   GstBinClass *bclass;
1604   gboolean result;
1605
1606   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
1607   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1608
1609   bclass = GST_BIN_GET_CLASS (bin);
1610
1611   if (G_UNLIKELY (bclass->remove_element == NULL))
1612     goto no_function;
1613
1614   GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
1615       GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
1616
1617   result = bclass->remove_element (bin, element);
1618
1619   return result;
1620
1621   /* ERROR handling */
1622 no_function:
1623   {
1624     g_warning ("removing elements from bin '%s' is not supported",
1625         GST_ELEMENT_NAME (bin));
1626     return FALSE;
1627   }
1628 }
1629
1630 /**
1631  * gst_bin_iterate_elements:
1632  * @bin: a #GstBin
1633  *
1634  * Gets an iterator for the elements in this bin.
1635  *
1636  * MT safe.  Caller owns returned value.
1637  *
1638  * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
1639  */
1640 GstIterator *
1641 gst_bin_iterate_elements (GstBin * bin)
1642 {
1643   GstIterator *result;
1644
1645   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1646
1647   GST_OBJECT_LOCK (bin);
1648   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
1649       GST_OBJECT_GET_LOCK (bin),
1650       &bin->children_cookie, &bin->children, (GObject *) bin, NULL);
1651   GST_OBJECT_UNLOCK (bin);
1652
1653   return result;
1654 }
1655
1656 static GstIteratorItem
1657 iterate_child_recurse (GstIterator * it, const GValue * item)
1658 {
1659   GstElement *child = g_value_get_object (item);
1660
1661   if (GST_IS_BIN (child)) {
1662     GstIterator *other = gst_bin_iterate_recurse (GST_BIN_CAST (child));
1663
1664     gst_iterator_push (it, other);
1665   }
1666   return GST_ITERATOR_ITEM_PASS;
1667 }
1668
1669 /**
1670  * gst_bin_iterate_recurse:
1671  * @bin: a #GstBin
1672  *
1673  * Gets an iterator for the elements in this bin.
1674  * This iterator recurses into GstBin children.
1675  *
1676  * MT safe.  Caller owns returned value.
1677  *
1678  * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
1679  */
1680 GstIterator *
1681 gst_bin_iterate_recurse (GstBin * bin)
1682 {
1683   GstIterator *result;
1684
1685   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1686
1687   GST_OBJECT_LOCK (bin);
1688   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
1689       GST_OBJECT_GET_LOCK (bin),
1690       &bin->children_cookie,
1691       &bin->children,
1692       (GObject *) bin, (GstIteratorItemFunction) iterate_child_recurse);
1693   GST_OBJECT_UNLOCK (bin);
1694
1695   return result;
1696 }
1697
1698 /* returns 0 when TRUE because this is a GCompareFunc */
1699 /* MT safe */
1700 static gint
1701 bin_element_is_sink (GstElement * child, GstBin * bin)
1702 {
1703   gboolean is_sink;
1704
1705   /* we lock the child here for the remainder of the function to
1706    * get its name and flag safely. */
1707   GST_OBJECT_LOCK (child);
1708   is_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);
1709
1710   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
1711       "child %s %s sink", GST_OBJECT_NAME (child), is_sink ? "is" : "is not");
1712
1713   GST_OBJECT_UNLOCK (child);
1714   return is_sink ? 0 : 1;
1715 }
1716
1717 static gint
1718 sink_iterator_filter (const GValue * vchild, GValue * vbin)
1719 {
1720   GstBin *bin = g_value_get_object (vbin);
1721   GstElement *child = g_value_get_object (vchild);
1722
1723   return (bin_element_is_sink (child, bin));
1724 }
1725
1726 /**
1727  * gst_bin_iterate_sinks:
1728  * @bin: a #GstBin
1729  *
1730  * Gets an iterator for all elements in the bin that have the
1731  * #GST_ELEMENT_FLAG_SINK flag set.
1732  *
1733  * MT safe.  Caller owns returned value.
1734  *
1735  * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
1736  */
1737 GstIterator *
1738 gst_bin_iterate_sinks (GstBin * bin)
1739 {
1740   GstIterator *children;
1741   GstIterator *result;
1742   GValue vbin = { 0, };
1743
1744   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1745
1746   g_value_init (&vbin, GST_TYPE_BIN);
1747   g_value_set_object (&vbin, bin);
1748
1749   children = gst_bin_iterate_elements (bin);
1750   result = gst_iterator_filter (children,
1751       (GCompareFunc) sink_iterator_filter, &vbin);
1752
1753   g_value_unset (&vbin);
1754
1755   return result;
1756 }
1757
1758 /* returns 0 when TRUE because this is a GCompareFunc */
1759 /* MT safe */
1760 static gint
1761 bin_element_is_src (GstElement * child, GstBin * bin)
1762 {
1763   gboolean is_src;
1764
1765   /* we lock the child here for the remainder of the function to
1766    * get its name and other info safely. */
1767   GST_OBJECT_LOCK (child);
1768   is_src = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);
1769
1770   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
1771       "child %s %s src", GST_OBJECT_NAME (child), is_src ? "is" : "is not");
1772
1773   GST_OBJECT_UNLOCK (child);
1774   return is_src ? 0 : 1;
1775 }
1776
1777 static gint
1778 src_iterator_filter (const GValue * vchild, GValue * vbin)
1779 {
1780   GstBin *bin = g_value_get_object (vbin);
1781   GstElement *child = g_value_get_object (vchild);
1782
1783   return (bin_element_is_src (child, bin));
1784 }
1785
1786 /**
1787  * gst_bin_iterate_sources:
1788  * @bin: a #GstBin
1789  *
1790  * Gets an iterator for all elements in the bin that have the
1791  * #GST_ELEMENT_FLAG_SOURCE flag set.
1792  *
1793  * MT safe.  Caller owns returned value.
1794  *
1795  * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
1796  */
1797 GstIterator *
1798 gst_bin_iterate_sources (GstBin * bin)
1799 {
1800   GstIterator *children;
1801   GstIterator *result;
1802   GValue vbin = { 0, };
1803
1804   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1805
1806   g_value_init (&vbin, GST_TYPE_BIN);
1807   g_value_set_object (&vbin, bin);
1808
1809   children = gst_bin_iterate_elements (bin);
1810   result = gst_iterator_filter (children,
1811       (GCompareFunc) src_iterator_filter, &vbin);
1812
1813   g_value_unset (&vbin);
1814
1815   return result;
1816 }
1817
1818 /*
1819  * MT safe
1820  */
1821 static GstStateChangeReturn
1822 gst_bin_get_state_func (GstElement * element, GstState * state,
1823     GstState * pending, GstClockTime timeout)
1824 {
1825   GstStateChangeReturn ret;
1826
1827   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1828
1829   ret =
1830       GST_ELEMENT_CLASS (parent_class)->get_state (element, state, pending,
1831       timeout);
1832
1833   return ret;
1834 }
1835
1836 /***********************************************
1837  * Topologically sorted iterator
1838  * see http://en.wikipedia.org/wiki/Topological_sorting
1839  *
1840  * For each element in the graph, an entry is kept in a HashTable
1841  * with its number of srcpad connections (degree).
1842  * We then change state of all elements without dependencies
1843  * (degree 0) and decrement the degree of all elements connected
1844  * on the sinkpads. When an element reaches degree 0, its state is
1845  * changed next.
1846  * When all elements are handled the algorithm stops.
1847  */
1848 typedef struct _GstBinSortIterator
1849 {
1850   GstIterator it;
1851   GQueue queue;                 /* elements queued for state change */
1852   GstBin *bin;                  /* bin we iterate */
1853   gint mode;                    /* adding or removing dependency */
1854   GstElement *best;             /* next element with least dependencies */
1855   gint best_deg;                /* best degree */
1856   GHashTable *hash;             /* hashtable with element dependencies */
1857   gboolean dirty;               /* we detected structure change */
1858 } GstBinSortIterator;
1859
1860 static void
1861 gst_bin_sort_iterator_copy (const GstBinSortIterator * it,
1862     GstBinSortIterator * copy)
1863 {
1864   GHashTableIter iter;
1865   gpointer key, value;
1866
1867   copy->queue = it->queue;
1868   g_queue_foreach (&copy->queue, (GFunc) gst_object_ref, NULL);
1869
1870   copy->bin = gst_object_ref (it->bin);
1871   if (it->best)
1872     copy->best = gst_object_ref (it->best);
1873
1874   copy->hash = g_hash_table_new (NULL, NULL);
1875   g_hash_table_iter_init (&iter, it->hash);
1876   while (g_hash_table_iter_next (&iter, &key, &value))
1877     g_hash_table_insert (copy->hash, key, value);
1878 }
1879
1880 /* we add and subtract 1 to make sure we don't confuse NULL and 0 */
1881 #define HASH_SET_DEGREE(bit, elem, deg) \
1882     g_hash_table_replace (bit->hash, elem, GINT_TO_POINTER(deg+1))
1883 #define HASH_GET_DEGREE(bit, elem) \
1884     (GPOINTER_TO_INT(g_hash_table_lookup (bit->hash, elem))-1)
1885
1886 /* add element to queue of next elements in the iterator.
1887  * We push at the tail to give higher priority elements a
1888  * chance first */
1889 static void
1890 add_to_queue (GstBinSortIterator * bit, GstElement * element)
1891 {
1892   GST_DEBUG_OBJECT (bit->bin, "adding '%s' to queue",
1893       GST_ELEMENT_NAME (element));
1894   gst_object_ref (element);
1895   g_queue_push_tail (&bit->queue, element);
1896   HASH_SET_DEGREE (bit, element, -1);
1897 }
1898
1899 static void
1900 remove_from_queue (GstBinSortIterator * bit, GstElement * element)
1901 {
1902   GList *find;
1903
1904   if ((find = g_queue_find (&bit->queue, element))) {
1905     GST_DEBUG_OBJECT (bit->bin, "removing '%s' from queue",
1906         GST_ELEMENT_NAME (element));
1907
1908     g_queue_delete_link (&bit->queue, find);
1909     gst_object_unref (element);
1910   } else {
1911     GST_DEBUG_OBJECT (bit->bin, "unable to remove '%s' from queue",
1912         GST_ELEMENT_NAME (element));
1913   }
1914 }
1915
1916 /* clear the queue, unref all objects as we took a ref when
1917  * we added them to the queue */
1918 static void
1919 clear_queue (GQueue * queue)
1920 {
1921   gpointer p;
1922
1923   while ((p = g_queue_pop_head (queue)))
1924     gst_object_unref (p);
1925 }
1926
1927 /* set all degrees to 0. Elements marked as a sink are
1928  * added to the queue immediately. Since we only look at the SINK flag of the
1929  * element, it is possible that we add non-sinks to the queue. These will be
1930  * removed from the queue again when we can prove that it provides data for some
1931  * other element. */
1932 static void
1933 reset_degree (GstElement * element, GstBinSortIterator * bit)
1934 {
1935   gboolean is_sink;
1936
1937   /* sinks are added right away */
1938   GST_OBJECT_LOCK (element);
1939   is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
1940   GST_OBJECT_UNLOCK (element);
1941
1942   if (is_sink) {
1943     add_to_queue (bit, element);
1944   } else {
1945     /* others are marked with 0 and handled when sinks are done */
1946     HASH_SET_DEGREE (bit, element, 0);
1947   }
1948 }
1949
1950 /* adjust the degree of all elements connected to the given
1951  * element. If a degree of an element drops to 0, it is
1952  * added to the queue of elements to schedule next.
1953  *
1954  * We have to make sure not to cross the bin boundary this element
1955  * belongs to.
1956  */
1957 static void
1958 update_degree (GstElement * element, GstBinSortIterator * bit)
1959 {
1960   gboolean linked = FALSE;
1961
1962   GST_OBJECT_LOCK (element);
1963   /* don't touch degree if element has no sinkpads */
1964   if (element->numsinkpads != 0) {
1965     /* loop over all sinkpads, decrement degree for all connected
1966      * elements in this bin */
1967     GList *pads;
1968
1969     for (pads = element->sinkpads; pads; pads = g_list_next (pads)) {
1970       GstPad *pad, *peer;
1971
1972       pad = GST_PAD_CAST (pads->data);
1973
1974       /* we're iterating over the sinkpads, check if it's busy in a link/unlink */
1975       if (G_UNLIKELY (find_message (bit->bin, GST_OBJECT_CAST (pad),
1976                   GST_MESSAGE_STRUCTURE_CHANGE))) {
1977         /* mark the iterator as dirty because we won't be updating the degree
1978          * of the peer parent now. This would result in the 'loop detected'
1979          * later on because the peer parent element could become the best next
1980          * element with a degree > 0. We will simply continue our state
1981          * changes and we'll eventually resync when the unlink completed and
1982          * the iterator cookie is updated. */
1983         bit->dirty = TRUE;
1984         continue;
1985       }
1986
1987       if ((peer = gst_pad_get_peer (pad))) {
1988         GstElement *peer_element;
1989
1990         if ((peer_element = gst_pad_get_parent_element (peer))) {
1991           GST_OBJECT_LOCK (peer_element);
1992           /* check that we don't go outside of this bin */
1993           if (GST_OBJECT_CAST (peer_element)->parent ==
1994               GST_OBJECT_CAST (bit->bin)) {
1995             gint old_deg, new_deg;
1996
1997             old_deg = HASH_GET_DEGREE (bit, peer_element);
1998
1999             /* check to see if we added an element as sink that was not really a
2000              * sink because it was connected to some other element. */
2001             if (old_deg == -1) {
2002               remove_from_queue (bit, peer_element);
2003               old_deg = 0;
2004             }
2005             new_deg = old_deg + bit->mode;
2006
2007             GST_DEBUG_OBJECT (bit->bin,
2008                 "change element %s, degree %d->%d, linked to %s",
2009                 GST_ELEMENT_NAME (peer_element), old_deg, new_deg,
2010                 GST_ELEMENT_NAME (element));
2011
2012             /* update degree, it is possible that an element was in 0 and
2013              * reaches -1 here. This would mean that the element had no sinkpads
2014              * but became linked while the state change was happening. We will
2015              * resync on this with the structure change message. */
2016             if (new_deg == 0) {
2017               /* degree hit 0, add to queue */
2018               add_to_queue (bit, peer_element);
2019             } else {
2020               HASH_SET_DEGREE (bit, peer_element, new_deg);
2021             }
2022             linked = TRUE;
2023           }
2024           GST_OBJECT_UNLOCK (peer_element);
2025           gst_object_unref (peer_element);
2026         }
2027         gst_object_unref (peer);
2028       }
2029     }
2030   }
2031   if (!linked) {
2032     GST_DEBUG_OBJECT (bit->bin, "element %s not linked on any sinkpads",
2033         GST_ELEMENT_NAME (element));
2034   }
2035   GST_OBJECT_UNLOCK (element);
2036 }
2037
2038 /* find the next best element not handled yet. This is the one
2039  * with the lowest non-negative degree */
2040 static void
2041 find_element (GstElement * element, GstBinSortIterator * bit)
2042 {
2043   gint degree;
2044
2045   /* element is already handled */
2046   if ((degree = HASH_GET_DEGREE (bit, element)) < 0)
2047     return;
2048
2049   /* first element or element with smaller degree */
2050   if (bit->best == NULL || bit->best_deg > degree) {
2051     bit->best = element;
2052     bit->best_deg = degree;
2053   }
2054 }
2055
2056 /* get next element in iterator. */
2057 static GstIteratorResult
2058 gst_bin_sort_iterator_next (GstBinSortIterator * bit, GValue * result)
2059 {
2060   GstElement *best;
2061   GstBin *bin = bit->bin;
2062
2063   /* empty queue, we have to find a next best element */
2064   if (g_queue_is_empty (&bit->queue)) {
2065     bit->best = NULL;
2066     bit->best_deg = G_MAXINT;
2067     g_list_foreach (bin->children, (GFunc) find_element, bit);
2068     if ((best = bit->best)) {
2069       /* when we detected an unlink, don't warn because our degrees might be
2070        * screwed up. We will resync later */
2071       if (bit->best_deg != 0 && !bit->dirty) {
2072         /* we don't fail on this one yet */
2073         GST_WARNING_OBJECT (bin, "loop dected in graph");
2074         g_warning ("loop detected in the graph of bin '%s'!!",
2075             GST_ELEMENT_NAME (bin));
2076       }
2077       /* best unhandled element, schedule as next element */
2078       GST_DEBUG_OBJECT (bin, "queue empty, next best: %s",
2079           GST_ELEMENT_NAME (best));
2080       HASH_SET_DEGREE (bit, best, -1);
2081       g_value_set_object (result, best);
2082     } else {
2083       GST_DEBUG_OBJECT (bin, "queue empty, elements exhausted");
2084       /* no more unhandled elements, we are done */
2085       return GST_ITERATOR_DONE;
2086     }
2087   } else {
2088     /* everything added to the queue got reffed */
2089     best = g_queue_pop_head (&bit->queue);
2090     g_value_set_object (result, best);
2091     gst_object_unref (best);
2092   }
2093
2094   GST_DEBUG_OBJECT (bin, "queue head gives %s", GST_ELEMENT_NAME (best));
2095   /* update degrees of linked elements */
2096   update_degree (best, bit);
2097
2098   return GST_ITERATOR_OK;
2099 }
2100
2101 /* clear queues, recalculate the degrees and restart. */
2102 static void
2103 gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
2104 {
2105   GstBin *bin = bit->bin;
2106
2107   GST_DEBUG_OBJECT (bin, "resync");
2108   bit->dirty = FALSE;
2109   clear_queue (&bit->queue);
2110   /* reset degrees */
2111   g_list_foreach (bin->children, (GFunc) reset_degree, bit);
2112   /* calc degrees, incrementing */
2113   bit->mode = 1;
2114   g_list_foreach (bin->children, (GFunc) update_degree, bit);
2115   /* for the rest of the function we decrement the degrees */
2116   bit->mode = -1;
2117 }
2118
2119 /* clear queues, unref bin and free iterator. */
2120 static void
2121 gst_bin_sort_iterator_free (GstBinSortIterator * bit)
2122 {
2123   GstBin *bin = bit->bin;
2124
2125   GST_DEBUG_OBJECT (bin, "free");
2126   clear_queue (&bit->queue);
2127   g_hash_table_destroy (bit->hash);
2128   gst_object_unref (bin);
2129 }
2130
2131 /* should be called with the bin LOCK held */
2132 static GstIterator *
2133 gst_bin_sort_iterator_new (GstBin * bin)
2134 {
2135   GstBinSortIterator *result;
2136
2137   /* we don't need an ItemFunction because we ref the items in the _next
2138    * method already */
2139   result = (GstBinSortIterator *)
2140       gst_iterator_new (sizeof (GstBinSortIterator),
2141       GST_TYPE_ELEMENT,
2142       GST_OBJECT_GET_LOCK (bin),
2143       &bin->priv->structure_cookie,
2144       (GstIteratorCopyFunction) gst_bin_sort_iterator_copy,
2145       (GstIteratorNextFunction) gst_bin_sort_iterator_next,
2146       (GstIteratorItemFunction) NULL,
2147       (GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
2148       (GstIteratorFreeFunction) gst_bin_sort_iterator_free);
2149   g_queue_init (&result->queue);
2150   result->hash = g_hash_table_new (NULL, NULL);
2151   gst_object_ref (bin);
2152   result->bin = bin;
2153   gst_bin_sort_iterator_resync (result);
2154
2155   return (GstIterator *) result;
2156 }
2157
2158 /**
2159  * gst_bin_iterate_sorted:
2160  * @bin: a #GstBin
2161  *
2162  * Gets an iterator for the elements in this bin in topologically
2163  * sorted order. This means that the elements are returned from
2164  * the most downstream elements (sinks) to the sources.
2165  *
2166  * This function is used internally to perform the state changes
2167  * of the bin elements and for clock selection.
2168  *
2169  * MT safe.  Caller owns returned value.
2170  *
2171  * Returns: (transfer full): a #GstIterator of #GstElement, or NULL
2172  */
2173 GstIterator *
2174 gst_bin_iterate_sorted (GstBin * bin)
2175 {
2176   GstIterator *result;
2177
2178   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
2179
2180   GST_OBJECT_LOCK (bin);
2181   result = gst_bin_sort_iterator_new (bin);
2182   GST_OBJECT_UNLOCK (bin);
2183
2184   return result;
2185 }
2186
2187 static GstStateChangeReturn
2188 gst_bin_element_set_state (GstBin * bin, GstElement * element,
2189     GstClockTime base_time, GstClockTime start_time, GstState current,
2190     GstState next)
2191 {
2192   GstStateChangeReturn ret;
2193   GstState child_current, child_pending;
2194   gboolean locked;
2195   GList *found;
2196
2197   GST_STATE_LOCK (element);
2198
2199   GST_OBJECT_LOCK (element);
2200   /* set base_time and start time on child */
2201   GST_ELEMENT_START_TIME (element) = start_time;
2202   element->base_time = base_time;
2203   /* peel off the locked flag */
2204   locked = GST_ELEMENT_IS_LOCKED_STATE (element);
2205   /* Get the previous set_state result to preserve NO_PREROLL and ASYNC */
2206   ret = GST_STATE_RETURN (element);
2207   child_current = GST_STATE (element);
2208   child_pending = GST_STATE_PENDING (element);
2209   GST_OBJECT_UNLOCK (element);
2210
2211   /* skip locked elements */
2212   if (G_UNLIKELY (locked))
2213     goto locked;
2214
2215   /* if the element was no preroll, just start changing the state regardless
2216    * if it had async elements (in the case of a bin) because they won't preroll
2217    * anyway. */
2218   if (G_UNLIKELY (ret == GST_STATE_CHANGE_NO_PREROLL)) {
2219     GST_DEBUG_OBJECT (element, "element is NO_PREROLL, ignore async elements");
2220     goto no_preroll;
2221   }
2222
2223   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2224       "current %s pending %s, desired next %s",
2225       gst_element_state_get_name (child_current),
2226       gst_element_state_get_name (child_pending),
2227       gst_element_state_get_name (next));
2228
2229   /* always recurse into bins so that we can set the base time */
2230   if (GST_IS_BIN (element))
2231     goto do_state;
2232
2233   /* Try not to change the state of elements that are already in the state we're
2234    * going to */
2235   if (child_current == next && child_pending == GST_STATE_VOID_PENDING) {
2236     /* child is already at the requested state, return previous return. Note that
2237      * if the child has a pending state to next, we will still call the
2238      * set_state function */
2239     goto unneeded;
2240   } else if (next > current) {
2241     /* upward state change */
2242     if (child_pending == GST_STATE_VOID_PENDING) {
2243       /* .. and the child is not busy doing anything */
2244       if (child_current > next) {
2245         /* .. and is already past the requested state, assume it got there
2246          * without error */
2247         ret = GST_STATE_CHANGE_SUCCESS;
2248         goto unneeded;
2249       }
2250     } else if (child_pending > child_current) {
2251       /* .. and the child is busy going upwards */
2252       if (child_current >= next) {
2253         /* .. and is already past the requested state, assume it got there
2254          * without error */
2255         ret = GST_STATE_CHANGE_SUCCESS;
2256         goto unneeded;
2257       }
2258     } else {
2259       /* .. and the child is busy going downwards */
2260       if (child_current > next) {
2261         /* .. and is already past the requested state, assume it got there
2262          * without error */
2263         ret = GST_STATE_CHANGE_SUCCESS;
2264         goto unneeded;
2265       }
2266     }
2267   } else if (next < current) {
2268     /* downward state change */
2269     if (child_pending == GST_STATE_VOID_PENDING) {
2270       /* .. and the child is not busy doing anything */
2271       if (child_current < next) {
2272         /* .. and is already past the requested state, assume it got there
2273          * without error */
2274         ret = GST_STATE_CHANGE_SUCCESS;
2275         goto unneeded;
2276       }
2277     } else if (child_pending < child_current) {
2278       /* .. and the child is busy going downwards */
2279       if (child_current <= next) {
2280         /* .. and is already past the requested state, assume it got there
2281          * without error */
2282         ret = GST_STATE_CHANGE_SUCCESS;
2283         goto unneeded;
2284       }
2285     } else {
2286       /* .. and the child is busy going upwards */
2287       if (child_current < next) {
2288         /* .. and is already past the requested state, assume it got there
2289          * without error */
2290         ret = GST_STATE_CHANGE_SUCCESS;
2291         goto unneeded;
2292       }
2293     }
2294   }
2295
2296 do_state:
2297   GST_OBJECT_LOCK (bin);
2298   /* the element was busy with an upwards async state change, we must wait for
2299    * an ASYNC_DONE message before we attemp to change the state. */
2300   if ((found =
2301           find_message (bin, GST_OBJECT_CAST (element),
2302               GST_MESSAGE_ASYNC_START))) {
2303 #ifndef GST_DISABLE_GST_DEBUG
2304     GstMessage *message = GST_MESSAGE_CAST (found->data);
2305
2306     GST_DEBUG_OBJECT (element, "element message %p, %s async busy",
2307         message, GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)));
2308 #endif
2309     /* only wait for upward state changes */
2310     if (next > current) {
2311       /* We found an async element check if we can force its state to change or
2312        * if we have to wait for it to preroll. */
2313       goto was_busy;
2314     }
2315   }
2316   GST_OBJECT_UNLOCK (bin);
2317
2318 no_preroll:
2319   GST_DEBUG_OBJECT (bin,
2320       "setting element %s to %s, base_time %" GST_TIME_FORMAT,
2321       GST_ELEMENT_NAME (element), gst_element_state_get_name (next),
2322       GST_TIME_ARGS (base_time));
2323
2324   /* change state */
2325   ret = gst_element_set_state (element, next);
2326
2327   GST_STATE_UNLOCK (element);
2328
2329   return ret;
2330
2331 locked:
2332   {
2333     GST_DEBUG_OBJECT (element,
2334         "element is locked, return previous return %s",
2335         gst_element_state_change_return_get_name (ret));
2336     GST_STATE_UNLOCK (element);
2337     return ret;
2338   }
2339 unneeded:
2340   {
2341     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2342         "skipping transition from %s to  %s",
2343         gst_element_state_get_name (child_current),
2344         gst_element_state_get_name (next));
2345     GST_STATE_UNLOCK (element);
2346     return ret;
2347   }
2348 was_busy:
2349   {
2350     GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
2351     GST_OBJECT_UNLOCK (bin);
2352     GST_STATE_UNLOCK (element);
2353     return GST_STATE_CHANGE_ASYNC;
2354   }
2355 }
2356
2357 /* gst_iterator_fold functions for pads_activate
2358  * Stop the iterator if activating one pad failed. */
2359 static gboolean
2360 activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
2361 {
2362   GstPad *pad = g_value_get_object (vpad);
2363   gboolean cont = TRUE;
2364
2365   if (!(cont = gst_pad_set_active (pad, *active)))
2366     g_value_set_boolean (ret, FALSE);
2367
2368   return cont;
2369 }
2370
2371 /* returns false on error or early cutout of the fold, true if all
2372  * pads in @iter were (de)activated successfully. */
2373 static gboolean
2374 iterator_activate_fold_with_resync (GstIterator * iter, gpointer user_data)
2375 {
2376   GstIteratorResult ires;
2377   GValue ret = { 0 };
2378
2379   /* no need to unset this later, it's just a boolean */
2380   g_value_init (&ret, G_TYPE_BOOLEAN);
2381   g_value_set_boolean (&ret, TRUE);
2382
2383   while (1) {
2384     ires = gst_iterator_fold (iter, (GstIteratorFoldFunction) activate_pads,
2385         &ret, user_data);
2386     switch (ires) {
2387       case GST_ITERATOR_RESYNC:
2388         /* need to reset the result again */
2389         g_value_set_boolean (&ret, TRUE);
2390         gst_iterator_resync (iter);
2391         break;
2392       case GST_ITERATOR_DONE:
2393         /* all pads iterated, return collected value */
2394         goto done;
2395       default:
2396         /* iterator returned _ERROR or premature end with _OK,
2397          * mark an error and exit */
2398         g_value_set_boolean (&ret, FALSE);
2399         goto done;
2400     }
2401   }
2402 done:
2403   /* return collected value */
2404   return g_value_get_boolean (&ret);
2405 }
2406
2407 /* is called with STATE_LOCK
2408  */
2409 static gboolean
2410 gst_bin_src_pads_activate (GstBin * bin, gboolean active)
2411 {
2412   GstIterator *iter;
2413   gboolean fold_ok;
2414
2415   GST_DEBUG_OBJECT (bin, "%s pads", active ? "activate" : "deactivate");
2416
2417   iter = gst_element_iterate_src_pads ((GstElement *) bin);
2418   fold_ok = iterator_activate_fold_with_resync (iter, &active);
2419   gst_iterator_free (iter);
2420   if (G_UNLIKELY (!fold_ok))
2421     goto failed;
2422
2423   GST_DEBUG_OBJECT (bin, "pad %sactivation successful", active ? "" : "de");
2424
2425   return TRUE;
2426
2427   /* ERRORS */
2428 failed:
2429   {
2430     GST_DEBUG_OBJECT (bin, "pad %sactivation failed", active ? "" : "de");
2431     return FALSE;
2432   }
2433 }
2434
2435 /**
2436  * gst_bin_recalculate_latency:
2437  * @bin: a #GstBin
2438  *
2439  * Query @bin for the current latency using and reconfigures this latency to all the
2440  * elements with a LATENCY event.
2441  *
2442  * This method is typically called on the pipeline when a #GST_MESSAGE_LATENCY
2443  * is posted on the bus.
2444  *
2445  * This function simply emits the 'do-latency' signal so any custom latency
2446  * calculations will be performed.
2447  *
2448  * Returns: %TRUE if the latency could be queried and reconfigured.
2449  */
2450 gboolean
2451 gst_bin_recalculate_latency (GstBin * bin)
2452 {
2453   gboolean res;
2454
2455   g_signal_emit (bin, gst_bin_signals[DO_LATENCY], 0, &res);
2456   GST_DEBUG_OBJECT (bin, "latency returned %d", res);
2457
2458   return res;
2459 }
2460
2461 static gboolean
2462 gst_bin_do_latency_func (GstBin * bin)
2463 {
2464   GstQuery *query;
2465   GstElement *element;
2466   GstClockTime min_latency, max_latency;
2467   gboolean res;
2468
2469   g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
2470
2471   element = GST_ELEMENT_CAST (bin);
2472
2473   GST_DEBUG_OBJECT (element, "querying latency");
2474
2475   query = gst_query_new_latency ();
2476   if ((res = gst_element_query (element, query))) {
2477     gboolean live;
2478
2479     gst_query_parse_latency (query, &live, &min_latency, &max_latency);
2480
2481     GST_DEBUG_OBJECT (element,
2482         "got min latency %" GST_TIME_FORMAT ", max latency %"
2483         GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
2484         GST_TIME_ARGS (max_latency), live);
2485
2486     if (max_latency < min_latency) {
2487       /* this is an impossible situation, some parts of the pipeline might not
2488        * work correctly. We post a warning for now. */
2489       GST_ELEMENT_WARNING (element, CORE, CLOCK, (NULL),
2490           ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
2491               GST_TIME_FORMAT ". Add queues or other buffering elements.",
2492               GST_TIME_ARGS (max_latency), GST_TIME_ARGS (min_latency)));
2493     }
2494
2495     /* configure latency on elements */
2496     res = gst_element_send_event (element, gst_event_new_latency (min_latency));
2497     if (res) {
2498       GST_INFO_OBJECT (element, "configured latency of %" GST_TIME_FORMAT,
2499           GST_TIME_ARGS (min_latency));
2500     } else {
2501       GST_WARNING_OBJECT (element,
2502           "did not really configure latency of %" GST_TIME_FORMAT,
2503           GST_TIME_ARGS (min_latency));
2504     }
2505   } else {
2506     /* this is not a real problem, we just don't configure any latency. */
2507     GST_WARNING_OBJECT (element, "failed to query latency");
2508   }
2509   gst_query_unref (query);
2510
2511   return res;
2512 }
2513
2514 static void
2515 gst_bin_state_changed (GstElement * element, GstState oldstate,
2516     GstState newstate, GstState pending)
2517 {
2518   GstElementClass *pklass = (GstElementClass *) parent_class;
2519
2520   if (newstate == GST_STATE_PLAYING && pending == GST_STATE_VOID_PENDING)
2521     bin_do_eos (GST_BIN_CAST (element));
2522
2523   if (pklass->state_changed)
2524     pklass->state_changed (element, oldstate, newstate, pending);
2525 }
2526
2527 static GstStateChangeReturn
2528 gst_bin_change_state_func (GstElement * element, GstStateChange transition)
2529 {
2530   GstBin *bin;
2531   GstStateChangeReturn ret;
2532   GstState current, next;
2533   gboolean have_async;
2534   gboolean have_no_preroll;
2535   GstClockTime base_time, start_time;
2536   GstIterator *it;
2537   gboolean done;
2538   GValue data = { 0, };
2539
2540   /* we don't need to take the STATE_LOCK, it is already taken */
2541   current = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2542   next = (GstState) GST_STATE_TRANSITION_NEXT (transition);
2543
2544   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2545       "changing state of children from %s to %s",
2546       gst_element_state_get_name (current), gst_element_state_get_name (next));
2547
2548   bin = GST_BIN_CAST (element);
2549
2550   switch (next) {
2551     case GST_STATE_PLAYING:
2552     {
2553       gboolean toplevel;
2554
2555       GST_OBJECT_LOCK (bin);
2556       toplevel = BIN_IS_TOPLEVEL (bin);
2557       GST_OBJECT_UNLOCK (bin);
2558
2559       if (toplevel)
2560         gst_bin_recalculate_latency (bin);
2561       break;
2562     }
2563     case GST_STATE_PAUSED:
2564       /* Clear EOS list on next PAUSED */
2565       GST_OBJECT_LOCK (bin);
2566       GST_DEBUG_OBJECT (element, "clearing EOS elements");
2567       bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
2568       bin->priv->posted_eos = FALSE;
2569       if (current == GST_STATE_READY)
2570         bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
2571       GST_OBJECT_UNLOCK (bin);
2572       if (current == GST_STATE_READY)
2573         if (!(gst_bin_src_pads_activate (bin, TRUE)))
2574           goto activate_failure;
2575       break;
2576     case GST_STATE_READY:
2577       /* Clear message list on next READY */
2578       GST_OBJECT_LOCK (bin);
2579       GST_DEBUG_OBJECT (element, "clearing all cached messages");
2580       bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
2581       GST_OBJECT_UNLOCK (bin);
2582       if (current == GST_STATE_PAUSED)
2583         if (!(gst_bin_src_pads_activate (bin, FALSE)))
2584           goto activate_failure;
2585       break;
2586     case GST_STATE_NULL:
2587       if (current == GST_STATE_READY) {
2588         GList *l;
2589
2590         if (!(gst_bin_src_pads_activate (bin, FALSE)))
2591           goto activate_failure;
2592
2593         /* Remove all non-persistent contexts */
2594         GST_OBJECT_LOCK (bin);
2595         for (l = bin->priv->contexts; l;) {
2596           GstContext *context = l->data;
2597
2598           if (!gst_context_is_persistent (context)) {
2599             GList *next;
2600
2601             gst_context_unref (context);
2602             next = l->next;
2603             bin->priv->contexts = g_list_delete_link (bin->priv->contexts, l);
2604             l = next;
2605           } else {
2606             l = l->next;
2607           }
2608         }
2609         GST_OBJECT_UNLOCK (bin);
2610       }
2611       break;
2612     default:
2613       break;
2614   }
2615
2616   /* this flag is used to make the async state changes return immediately. We
2617    * don't want them to interfere with this state change */
2618   GST_OBJECT_LOCK (bin);
2619   bin->polling = TRUE;
2620   GST_OBJECT_UNLOCK (bin);
2621
2622   /* iterate in state change order */
2623   it = gst_bin_iterate_sorted (bin);
2624
2625   /* mark if we've seen an ASYNC element in the bin when we did a state change.
2626    * Note how we don't reset this value when a resync happens, the reason being
2627    * that the async element posted ASYNC_START and we want to post ASYNC_DONE
2628    * even after a resync when the async element is gone */
2629   have_async = FALSE;
2630
2631 restart:
2632   /* take base_time */
2633   base_time = gst_element_get_base_time (element);
2634   start_time = gst_element_get_start_time (element);
2635
2636   have_no_preroll = FALSE;
2637
2638   done = FALSE;
2639   while (!done) {
2640     switch (gst_iterator_next (it, &data)) {
2641       case GST_ITERATOR_OK:
2642       {
2643         GstElement *child;
2644
2645         child = g_value_get_object (&data);
2646
2647         /* set state and base_time now */
2648         ret = gst_bin_element_set_state (bin, child, base_time, start_time,
2649             current, next);
2650
2651         switch (ret) {
2652           case GST_STATE_CHANGE_SUCCESS:
2653             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2654                 "child '%s' changed state to %d(%s) successfully",
2655                 GST_ELEMENT_NAME (child), next,
2656                 gst_element_state_get_name (next));
2657             break;
2658           case GST_STATE_CHANGE_ASYNC:
2659           {
2660             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2661                 "child '%s' is changing state asynchronously to %s",
2662                 GST_ELEMENT_NAME (child), gst_element_state_get_name (next));
2663             have_async = TRUE;
2664             break;
2665           }
2666           case GST_STATE_CHANGE_FAILURE:{
2667             GstObject *parent;
2668
2669             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2670                 "child '%s' failed to go to state %d(%s)",
2671                 GST_ELEMENT_NAME (child),
2672                 next, gst_element_state_get_name (next));
2673
2674             /* Only fail if the child is still inside
2675              * this bin. It might've been removed already
2676              * because of the error by the bin subclass
2677              * to ignore the error.  */
2678             parent = gst_object_get_parent (GST_OBJECT_CAST (child));
2679             if (parent == GST_OBJECT_CAST (element)) {
2680               /* element is still in bin, really error now */
2681               gst_object_unref (parent);
2682               goto done;
2683             }
2684             /* child removed from bin, let the resync code redo the state
2685              * change */
2686             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2687                 "child '%s' was removed from the bin",
2688                 GST_ELEMENT_NAME (child));
2689
2690             if (parent)
2691               gst_object_unref (parent);
2692
2693             break;
2694           }
2695           case GST_STATE_CHANGE_NO_PREROLL:
2696             GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2697                 "child '%s' changed state to %d(%s) successfully without preroll",
2698                 GST_ELEMENT_NAME (child), next,
2699                 gst_element_state_get_name (next));
2700             have_no_preroll = TRUE;
2701             break;
2702           default:
2703             g_assert_not_reached ();
2704             break;
2705         }
2706         g_value_reset (&data);
2707         break;
2708       }
2709       case GST_ITERATOR_RESYNC:
2710         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator doing resync");
2711         gst_iterator_resync (it);
2712         goto restart;
2713       default:
2714       case GST_ITERATOR_DONE:
2715         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator done");
2716         done = TRUE;
2717         break;
2718     }
2719   }
2720
2721   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2722   if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
2723     goto done;
2724
2725   if (have_no_preroll) {
2726     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
2727         "we have NO_PREROLL elements %s -> NO_PREROLL",
2728         gst_element_state_change_return_get_name (ret));
2729     ret = GST_STATE_CHANGE_NO_PREROLL;
2730   } else if (have_async) {
2731     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
2732         "we have ASYNC elements %s -> ASYNC",
2733         gst_element_state_change_return_get_name (ret));
2734     ret = GST_STATE_CHANGE_ASYNC;
2735   }
2736
2737 done:
2738   g_value_unset (&data);
2739   gst_iterator_free (it);
2740
2741   GST_OBJECT_LOCK (bin);
2742   bin->polling = FALSE;
2743   /* it's possible that we did not get ASYNC from the children while the bin is
2744    * simulating ASYNC behaviour by posting an ASYNC_DONE message on the bus with
2745    * itself as the source. In that case we still want to check if the state
2746    * change completed. */
2747   if (ret != GST_STATE_CHANGE_ASYNC && !bin->priv->pending_async_done) {
2748     /* no element returned ASYNC and there are no pending async_done messages,
2749      * we can just complete. */
2750     GST_DEBUG_OBJECT (bin, "no async elements");
2751     goto state_end;
2752   }
2753   /* when we get here an ASYNC element was found */
2754   if (GST_STATE_TARGET (bin) <= GST_STATE_READY) {
2755     /* we ignore ASYNC state changes when we go to READY or NULL */
2756     GST_DEBUG_OBJECT (bin, "target state %s <= READY",
2757         gst_element_state_get_name (GST_STATE_TARGET (bin)));
2758     goto state_end;
2759   }
2760
2761   GST_DEBUG_OBJECT (bin, "check async elements");
2762   /* check if all elements managed to commit their state already */
2763   if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
2764     /* nothing found, remove all old ASYNC_DONE messages. This can happen when
2765      * all the elements commited their state while we were doing the state
2766      * change. We will still return ASYNC for consistency but we commit the
2767      * state already so that a _get_state() will return immediately. */
2768     bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
2769
2770     GST_DEBUG_OBJECT (bin, "async elements commited");
2771     bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE,
2772         GST_CLOCK_TIME_NONE);
2773   }
2774
2775 state_end:
2776   bin->priv->pending_async_done = FALSE;
2777   GST_OBJECT_UNLOCK (bin);
2778
2779   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2780       "done changing bin's state from %s to %s, now in %s, ret %s",
2781       gst_element_state_get_name (current),
2782       gst_element_state_get_name (next),
2783       gst_element_state_get_name (GST_STATE (element)),
2784       gst_element_state_change_return_get_name (ret));
2785
2786   return ret;
2787
2788   /* ERRORS */
2789 activate_failure:
2790   {
2791     GST_CAT_WARNING_OBJECT (GST_CAT_STATES, element,
2792         "failure (de)activating src pads");
2793     return GST_STATE_CHANGE_FAILURE;
2794   }
2795 }
2796
2797 /*
2798  * This function is a utility event handler for seek events.
2799  * It will send the event to all sinks or sources and appropriate
2800  * ghost pads depending on the event-direction.
2801  *
2802  * Applications are free to override this behaviour and
2803  * implement their own seek handler, but this will work for
2804  * pretty much all cases in practice.
2805  */
2806 static gboolean
2807 gst_bin_send_event (GstElement * element, GstEvent * event)
2808 {
2809   GstBin *bin = GST_BIN_CAST (element);
2810   GstIterator *iter;
2811   gboolean res = TRUE;
2812   gboolean done = FALSE;
2813   GValue data = { 0, };
2814
2815   if (GST_EVENT_IS_DOWNSTREAM (event)) {
2816     iter = gst_bin_iterate_sources (bin);
2817     GST_DEBUG_OBJECT (bin, "Sending %s event to src children",
2818         GST_EVENT_TYPE_NAME (event));
2819   } else {
2820     iter = gst_bin_iterate_sinks (bin);
2821     GST_DEBUG_OBJECT (bin, "Sending %s event to sink children",
2822         GST_EVENT_TYPE_NAME (event));
2823   }
2824
2825   while (!done) {
2826     switch (gst_iterator_next (iter, &data)) {
2827       case GST_ITERATOR_OK:
2828       {
2829         GstElement *child = g_value_get_object (&data);
2830
2831         gst_event_ref (event);
2832         res &= gst_element_send_event (child, event);
2833
2834         GST_LOG_OBJECT (child, "After handling %s event: %d",
2835             GST_EVENT_TYPE_NAME (event), res);
2836
2837         g_value_reset (&data);
2838         break;
2839       }
2840       case GST_ITERATOR_RESYNC:
2841         gst_iterator_resync (iter);
2842         res = TRUE;
2843         break;
2844       case GST_ITERATOR_DONE:
2845         done = TRUE;
2846         break;
2847       case GST_ITERATOR_ERROR:
2848         g_assert_not_reached ();
2849         break;
2850     }
2851   }
2852   g_value_unset (&data);
2853   gst_iterator_free (iter);
2854
2855   if (GST_EVENT_IS_DOWNSTREAM (event)) {
2856     iter = gst_element_iterate_sink_pads (GST_ELEMENT (bin));
2857     GST_DEBUG_OBJECT (bin, "Sending %s event to sink pads",
2858         GST_EVENT_TYPE_NAME (event));
2859   } else {
2860     iter = gst_element_iterate_src_pads (GST_ELEMENT (bin));
2861     GST_DEBUG_OBJECT (bin, "Sending %s event to src pads",
2862         GST_EVENT_TYPE_NAME (event));
2863   }
2864
2865   done = FALSE;
2866   while (!done) {
2867     switch (gst_iterator_next (iter, &data)) {
2868       case GST_ITERATOR_OK:
2869       {
2870         GstPad *pad = g_value_get_object (&data);
2871
2872         gst_event_ref (event);
2873         res &= gst_pad_send_event (pad, event);
2874         GST_LOG_OBJECT (pad, "After handling %s event: %d",
2875             GST_EVENT_TYPE_NAME (event), res);
2876         break;
2877       }
2878       case GST_ITERATOR_RESYNC:
2879         gst_iterator_resync (iter);
2880         res = TRUE;
2881         break;
2882       case GST_ITERATOR_DONE:
2883         done = TRUE;
2884         break;
2885       case GST_ITERATOR_ERROR:
2886         g_assert_not_reached ();
2887         break;
2888     }
2889   }
2890
2891   g_value_unset (&data);
2892   gst_iterator_free (iter);
2893   gst_event_unref (event);
2894
2895   return res;
2896 }
2897
2898 /* this is the function called by the threadpool. When async elements commit
2899  * their state, this function will attempt to bring the bin to the next state.
2900  */
2901 static void
2902 gst_bin_continue_func (BinContinueData * data)
2903 {
2904   GstBin *bin;
2905   GstState current, next, pending;
2906   GstStateChange transition;
2907
2908   bin = data->bin;
2909   pending = data->pending;
2910
2911   GST_DEBUG_OBJECT (bin, "waiting for state lock");
2912   GST_STATE_LOCK (bin);
2913
2914   GST_DEBUG_OBJECT (bin, "doing state continue");
2915   GST_OBJECT_LOCK (bin);
2916
2917   /* if a new state change happened after this thread was scheduled, we return
2918    * immediately. */
2919   if (data->cookie != GST_ELEMENT_CAST (bin)->state_cookie)
2920     goto interrupted;
2921
2922   current = GST_STATE (bin);
2923   next = GST_STATE_GET_NEXT (current, pending);
2924   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2925
2926   GST_STATE_NEXT (bin) = next;
2927   GST_STATE_PENDING (bin) = pending;
2928   /* mark busy */
2929   GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
2930   GST_OBJECT_UNLOCK (bin);
2931
2932   GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
2933       "continue state change %s to %s, final %s",
2934       gst_element_state_get_name (current),
2935       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2936
2937   gst_element_change_state (GST_ELEMENT_CAST (bin), transition);
2938
2939   GST_STATE_UNLOCK (bin);
2940   GST_DEBUG_OBJECT (bin, "state continue done");
2941
2942   gst_object_unref (bin);
2943   g_slice_free (BinContinueData, data);
2944   return;
2945
2946 interrupted:
2947   {
2948     GST_OBJECT_UNLOCK (bin);
2949     GST_STATE_UNLOCK (bin);
2950     GST_DEBUG_OBJECT (bin, "state continue aborted due to intervening change");
2951     gst_object_unref (bin);
2952     g_slice_free (BinContinueData, data);
2953     return;
2954   }
2955 }
2956
2957 static GstBusSyncReply
2958 bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
2959 {
2960   GstBinClass *bclass;
2961
2962   bclass = GST_BIN_GET_CLASS (bin);
2963   if (bclass->handle_message)
2964     bclass->handle_message (bin, message);
2965   else
2966     gst_message_unref (message);
2967
2968   return GST_BUS_DROP;
2969 }
2970
2971 static void
2972 bin_push_state_continue (BinContinueData * data)
2973 {
2974   GstBinClass *klass;
2975   GstBin *bin;
2976
2977   /* ref was taken */
2978   bin = data->bin;
2979   klass = GST_BIN_GET_CLASS (bin);
2980
2981   GST_DEBUG_OBJECT (bin, "pushing continue on thread pool");
2982   g_thread_pool_push (klass->pool, data, NULL);
2983 }
2984
2985 /* an element started an async state change, if we were not busy with a state
2986  * change, we perform a lost state.
2987  * This function is called with the OBJECT lock.
2988  */
2989 static void
2990 bin_handle_async_start (GstBin * bin)
2991 {
2992   GstState old_state, new_state;
2993   gboolean toplevel;
2994   GstMessage *amessage = NULL;
2995
2996   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
2997     goto had_error;
2998
2999   /* get our toplevel state */
3000   toplevel = BIN_IS_TOPLEVEL (bin);
3001
3002   /* prepare an ASYNC_START message, we always post the start message even if we
3003    * are busy with a state change or when we are NO_PREROLL. */
3004   if (!toplevel)
3005     /* non toplevel bin, prepare async-start for the parent */
3006     amessage = gst_message_new_async_start (GST_OBJECT_CAST (bin));
3007
3008   if (bin->polling || GST_STATE_PENDING (bin) != GST_STATE_VOID_PENDING)
3009     goto was_busy;
3010
3011   /* async starts are ignored when we are NO_PREROLL */
3012   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_NO_PREROLL)
3013     goto was_no_preroll;
3014
3015   old_state = GST_STATE (bin);
3016
3017   /* when we PLAYING we go back to PAUSED, when preroll happens, we go back to
3018    * PLAYING after optionally redistributing the base_time. */
3019   if (old_state > GST_STATE_PAUSED)
3020     new_state = GST_STATE_PAUSED;
3021   else
3022     new_state = old_state;
3023
3024   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
3025       "lost state of %s, new %s", gst_element_state_get_name (old_state),
3026       gst_element_state_get_name (new_state));
3027
3028   GST_STATE (bin) = new_state;
3029   GST_STATE_NEXT (bin) = new_state;
3030   GST_STATE_PENDING (bin) = new_state;
3031   GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
3032   GST_OBJECT_UNLOCK (bin);
3033
3034   /* post message */
3035   _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), new_state, new_state,
3036       new_state);
3037
3038 post_start:
3039   if (amessage) {
3040     /* post our ASYNC_START. */
3041     GST_DEBUG_OBJECT (bin, "posting ASYNC_START to parent");
3042     gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
3043   }
3044   GST_OBJECT_LOCK (bin);
3045
3046   return;
3047
3048 had_error:
3049   {
3050     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
3051     return;
3052   }
3053 was_busy:
3054   {
3055     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
3056     GST_OBJECT_UNLOCK (bin);
3057     goto post_start;
3058   }
3059 was_no_preroll:
3060   {
3061     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "ignoring, we are NO_PREROLL");
3062     GST_OBJECT_UNLOCK (bin);
3063     goto post_start;
3064   }
3065 }
3066
3067 /* this function is called when there are no more async elements in the bin. We
3068  * post a state changed message and an ASYNC_DONE message.
3069  * This function is called with the OBJECT lock.
3070  */
3071 static void
3072 bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
3073     gboolean flag_pending, GstClockTime running_time)
3074 {
3075   GstState current, pending, target;
3076   GstStateChangeReturn old_ret;
3077   GstState old_state, old_next;
3078   gboolean toplevel, state_changed = FALSE;
3079   GstMessage *amessage = NULL;
3080   BinContinueData *cont = NULL;
3081
3082   if (GST_STATE_RETURN (bin) == GST_STATE_CHANGE_FAILURE)
3083     goto had_error;
3084
3085   pending = GST_STATE_PENDING (bin);
3086
3087   if (bin->polling)
3088     goto was_busy;
3089
3090   /* check if there is something to commit */
3091   if (pending == GST_STATE_VOID_PENDING)
3092     goto nothing_pending;
3093
3094   old_ret = GST_STATE_RETURN (bin);
3095   GST_STATE_RETURN (bin) = ret;
3096
3097   /* move to the next target state */
3098   target = GST_STATE_TARGET (bin);
3099   pending = GST_STATE_PENDING (bin) = target;
3100
3101   amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin), running_time);
3102
3103   old_state = GST_STATE (bin);
3104   /* this is the state we should go to next */
3105   old_next = GST_STATE_NEXT (bin);
3106
3107   if (old_next != GST_STATE_PLAYING) {
3108     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
3109         "committing state from %s to %s, old pending %s",
3110         gst_element_state_get_name (old_state),
3111         gst_element_state_get_name (old_next),
3112         gst_element_state_get_name (pending));
3113
3114     /* update current state */
3115     current = GST_STATE (bin) = old_next;
3116   } else {
3117     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
3118         "setting state from %s to %s, pending %s",
3119         gst_element_state_get_name (old_state),
3120         gst_element_state_get_name (old_state),
3121         gst_element_state_get_name (pending));
3122     current = old_state;
3123   }
3124
3125   /* get our toplevel state */
3126   toplevel = BIN_IS_TOPLEVEL (bin);
3127
3128   /* see if we reached the final state. If we are not toplevel, we also have to
3129    * stop here, the parent will continue our state. */
3130   if ((pending == current) || !toplevel) {
3131     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
3132         "completed state change, pending VOID");
3133
3134     /* mark VOID pending */
3135     pending = GST_STATE_VOID_PENDING;
3136     GST_STATE_PENDING (bin) = pending;
3137     GST_STATE_NEXT (bin) = GST_STATE_VOID_PENDING;
3138   } else {
3139     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin,
3140         "continue state change, pending %s",
3141         gst_element_state_get_name (pending));
3142
3143     cont = g_slice_new (BinContinueData);
3144
3145     /* ref to the bin */
3146     cont->bin = gst_object_ref (bin);
3147     /* cookie to detect concurrent state change */
3148     cont->cookie = GST_ELEMENT_CAST (bin)->state_cookie;
3149     /* pending target state */
3150     cont->pending = pending;
3151     /* mark busy */
3152     GST_STATE_RETURN (bin) = GST_STATE_CHANGE_ASYNC;
3153     GST_STATE_NEXT (bin) = GST_STATE_GET_NEXT (old_state, pending);
3154   }
3155
3156   if (old_next != GST_STATE_PLAYING) {
3157     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC) {
3158       state_changed = TRUE;
3159     }
3160   }
3161   GST_OBJECT_UNLOCK (bin);
3162
3163   if (state_changed) {
3164     _priv_gst_element_state_changed (GST_ELEMENT_CAST (bin), old_state,
3165         old_next, pending);
3166   }
3167   if (amessage) {
3168     /* post our combined ASYNC_DONE when all is ASYNC_DONE. */
3169     GST_DEBUG_OBJECT (bin, "posting ASYNC_DONE to parent");
3170     gst_element_post_message (GST_ELEMENT_CAST (bin), amessage);
3171   }
3172
3173   GST_OBJECT_LOCK (bin);
3174   if (cont) {
3175     /* toplevel, start continue state */
3176     GST_DEBUG_OBJECT (bin, "all async-done, starting state continue");
3177     bin_push_state_continue (cont);
3178   } else {
3179     GST_DEBUG_OBJECT (bin, "state change complete");
3180     GST_STATE_BROADCAST (bin);
3181   }
3182   return;
3183
3184 had_error:
3185   {
3186     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "we had an error");
3187     return;
3188   }
3189 was_busy:
3190   {
3191     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin, "state change busy");
3192     /* if we were busy with a state change and we are requested to flag a
3193      * pending async done, we do so here */
3194     if (flag_pending)
3195       bin->priv->pending_async_done = TRUE;
3196     return;
3197   }
3198 nothing_pending:
3199   {
3200     GST_CAT_INFO_OBJECT (GST_CAT_STATES, bin, "nothing pending");
3201     return;
3202   }
3203 }
3204
3205 static void
3206 bin_do_eos (GstBin * bin)
3207 {
3208   guint32 seqnum = 0;
3209   gboolean eos;
3210
3211   GST_OBJECT_LOCK (bin);
3212   /* If all sinks are EOS, we're in PLAYING and no state change is pending
3213    * we forward the EOS message to the parent bin or application
3214    */
3215   eos = GST_STATE (bin) == GST_STATE_PLAYING
3216       && GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING
3217       && is_eos (bin, &seqnum);
3218   GST_OBJECT_UNLOCK (bin);
3219
3220   if (eos
3221       && g_atomic_int_compare_and_exchange (&bin->priv->posted_eos, FALSE,
3222           TRUE)) {
3223     GstMessage *tmessage;
3224
3225     /* Clear out any further messages, and reset posted_eos so we can
3226        detect any new EOS that happens (eg, after a seek). Since all
3227        sinks have now posted an EOS, there will be no further EOS events
3228        seen unless there is a new logical EOS */
3229     GST_OBJECT_LOCK (bin);
3230     bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
3231     bin->priv->posted_eos = FALSE;
3232     GST_OBJECT_UNLOCK (bin);
3233
3234     tmessage = gst_message_new_eos (GST_OBJECT_CAST (bin));
3235     gst_message_set_seqnum (tmessage, seqnum);
3236     GST_DEBUG_OBJECT (bin,
3237         "all sinks posted EOS, posting seqnum #%" G_GUINT32_FORMAT, seqnum);
3238     gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
3239   }
3240 }
3241
3242 static void
3243 bin_do_stream_start (GstBin * bin)
3244 {
3245   guint32 seqnum = 0;
3246   gboolean stream_start;
3247   gboolean have_group_id = FALSE;
3248   guint group_id = 0;
3249
3250   GST_OBJECT_LOCK (bin);
3251   /* If all sinks are STREAM_START we forward the STREAM_START message
3252    * to the parent bin or application
3253    */
3254   stream_start = is_stream_start (bin, &seqnum, &have_group_id, &group_id);
3255   GST_OBJECT_UNLOCK (bin);
3256
3257   if (stream_start) {
3258     GstMessage *tmessage;
3259
3260     GST_OBJECT_LOCK (bin);
3261     bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
3262     GST_OBJECT_UNLOCK (bin);
3263
3264     tmessage = gst_message_new_stream_start (GST_OBJECT_CAST (bin));
3265     gst_message_set_seqnum (tmessage, seqnum);
3266     if (have_group_id)
3267       gst_message_set_group_id (tmessage, group_id);
3268
3269     GST_DEBUG_OBJECT (bin,
3270         "all sinks posted STREAM_START, posting seqnum #%" G_GUINT32_FORMAT,
3271         seqnum);
3272     gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
3273   }
3274 }
3275
3276 /* must be called without the object lock as it posts messages */
3277 static void
3278 bin_do_message_forward (GstBin * bin, GstMessage * message)
3279 {
3280   if (bin->priv->message_forward) {
3281     GstMessage *forwarded;
3282
3283     GST_DEBUG_OBJECT (bin, "pass %s message upward",
3284         GST_MESSAGE_TYPE_NAME (message));
3285
3286     /* we need to convert these messages to element messages so that our parent
3287      * bin can easily ignore them and so that the application can easily
3288      * distinguish between the internally forwarded and the real messages. */
3289     forwarded = gst_message_new_element (GST_OBJECT_CAST (bin),
3290         gst_structure_new ("GstBinForwarded",
3291             "message", GST_TYPE_MESSAGE, message, NULL));
3292
3293     gst_element_post_message (GST_ELEMENT_CAST (bin), forwarded);
3294   }
3295 }
3296
3297 static void
3298 gst_bin_update_context (GstBin * bin, GstContext * context)
3299 {
3300   GList *l;
3301   const gchar *context_type;
3302
3303   GST_OBJECT_LOCK (bin);
3304   context_type = gst_context_get_context_type (context);
3305   for (l = bin->priv->contexts; l; l = l->next) {
3306     GstContext *tmp = l->data;
3307     const gchar *tmp_type = gst_context_get_context_type (tmp);
3308
3309     /* Always store newest context but never replace
3310      * a persistent one by a non-persistent one */
3311     if (strcmp (context_type, tmp_type) == 0 &&
3312         (gst_context_is_persistent (context) ||
3313             !gst_context_is_persistent (tmp))) {
3314       gst_context_replace ((GstContext **) & l->data, context);
3315       break;
3316     }
3317   }
3318   /* Not found? Add */
3319   if (l == NULL)
3320     bin->priv->contexts =
3321         g_list_prepend (bin->priv->contexts, gst_context_ref (context));
3322   GST_OBJECT_UNLOCK (bin);
3323 }
3324
3325 /* handle child messages:
3326  *
3327  * This method is called synchronously when a child posts a message on
3328  * the internal bus.
3329  *
3330  * GST_MESSAGE_EOS: This message is only posted by sinks
3331  *     in the PLAYING state. If all sinks posted the EOS message, post
3332  *     one upwards.
3333  *
3334  * GST_MESSAGE_STATE_DIRTY: Deprecated
3335  *
3336  * GST_MESSAGE_SEGMENT_START: just collect, never forward upwards. If an
3337  *     element posts segment_start twice, only the last message is kept.
3338  *
3339  * GST_MESSAGE_SEGMENT_DONE: replace SEGMENT_START message from same poster
3340  *     with the segment_done message. If there are no more segment_start
3341  *     messages, post segment_done message upwards.
3342  *
3343  * GST_MESSAGE_DURATION_CHANGED: clear any cached durations.
3344  *     Whenever someone performs a duration query on the bin, we store the
3345  *     result so we can answer it quicker the next time. Any element that
3346  *     changes its duration marks our cached values invalid.
3347  *     This message is also posted upwards. This is currently disabled
3348  *     because too many elements don't post DURATION_CHANGED messages when
3349  *     the duration changes.
3350  *
3351  * GST_MESSAGE_CLOCK_LOST: This message is posted by an element when it
3352  *     can no longer provide a clock. The default bin behaviour is to
3353  *     check if the lost clock was the one provided by the bin. If so and
3354  *     we are currently in the PLAYING state, we forward the message to
3355  *     our parent.
3356  *     This message is also generated when we remove a clock provider from
3357  *     a bin. If this message is received by the application, it should
3358  *     PAUSE the pipeline and set it back to PLAYING to force a new clock
3359  *     and a new base_time distribution.
3360  *
3361  * GST_MESSAGE_CLOCK_PROVIDE: This message is generated when an element
3362  *     can provide a clock. This mostly happens when we add a new clock
3363  *     provider to the bin. The default behaviour of the bin is to mark the
3364  *     currently selected clock as dirty, which will perform a clock
3365  *     recalculation the next time we are asked to provide a clock.
3366  *     This message is never sent to the application but is forwarded to
3367  *     the parent.
3368  *
3369  * GST_MESSAGE_ASYNC_START: Create an internal ELEMENT message that stores
3370  *     the state of the element and the fact that the element will need a
3371  *     new base_time. This message is not forwarded to the application.
3372  *
3373  * GST_MESSAGE_ASYNC_DONE: Find the internal ELEMENT message we kept for the
3374  *     element when it posted ASYNC_START. If all elements are done, post a
3375  *     ASYNC_DONE message to the parent.
3376  *
3377  * OTHER: post upwards.
3378  */
3379 static void
3380 gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
3381 {
3382   GstObject *src;
3383   GstMessageType type;
3384   GstMessage *tmessage;
3385   guint32 seqnum;
3386
3387   src = GST_MESSAGE_SRC (message);
3388   type = GST_MESSAGE_TYPE (message);
3389
3390   GST_DEBUG_OBJECT (bin, "[msg %p] handling child %s message of type %s",
3391       message, src ? GST_ELEMENT_NAME (src) : "(NULL)",
3392       GST_MESSAGE_TYPE_NAME (message));
3393
3394   switch (type) {
3395     case GST_MESSAGE_ERROR:
3396     {
3397       GST_OBJECT_LOCK (bin);
3398       /* flag error */
3399       GST_DEBUG_OBJECT (bin, "got ERROR message, unlocking state change");
3400       GST_STATE_RETURN (bin) = GST_STATE_CHANGE_FAILURE;
3401       GST_STATE_BROADCAST (bin);
3402       GST_OBJECT_UNLOCK (bin);
3403
3404       goto forward;
3405     }
3406     case GST_MESSAGE_EOS:
3407     {
3408
3409       /* collect all eos messages from the children */
3410       bin_do_message_forward (bin, message);
3411       GST_OBJECT_LOCK (bin);
3412       /* ref message for future use  */
3413       bin_replace_message (bin, message, GST_MESSAGE_EOS);
3414       GST_OBJECT_UNLOCK (bin);
3415
3416       bin_do_eos (bin);
3417       break;
3418     }
3419     case GST_MESSAGE_STREAM_START:
3420     {
3421
3422       /* collect all stream_start messages from the children */
3423       GST_OBJECT_LOCK (bin);
3424       /* ref message for future use  */
3425       bin_replace_message (bin, message, GST_MESSAGE_STREAM_START);
3426       GST_OBJECT_UNLOCK (bin);
3427
3428       bin_do_stream_start (bin);
3429       break;
3430     }
3431     case GST_MESSAGE_STATE_DIRTY:
3432     {
3433       GST_WARNING_OBJECT (bin, "received deprecated STATE_DIRTY message");
3434
3435       /* free message */
3436       gst_message_unref (message);
3437       break;
3438     }
3439     case GST_MESSAGE_SEGMENT_START:{
3440       gboolean post = FALSE;
3441       GstFormat format;
3442       gint64 position;
3443
3444       gst_message_parse_segment_start (message, &format, &position);
3445       seqnum = gst_message_get_seqnum (message);
3446
3447       bin_do_message_forward (bin, message);
3448
3449       GST_OBJECT_LOCK (bin);
3450       /* if this is the first segment-start, post to parent but not to the
3451        * application */
3452       if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START) &&
3453           (GST_OBJECT_PARENT (bin) != NULL)) {
3454         post = TRUE;
3455       }
3456       /* replace any previous segment_start message from this source
3457        * with the new segment start message */
3458       bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
3459       GST_OBJECT_UNLOCK (bin);
3460       if (post) {
3461         tmessage = gst_message_new_segment_start (GST_OBJECT_CAST (bin),
3462             format, position);
3463         gst_message_set_seqnum (tmessage, seqnum);
3464
3465         /* post segment start with initial format and position. */
3466         GST_DEBUG_OBJECT (bin, "posting SEGMENT_START (%u) bus message: %p",
3467             seqnum, message);
3468         gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
3469       }
3470       break;
3471     }
3472     case GST_MESSAGE_SEGMENT_DONE:
3473     {
3474       gboolean post = FALSE;
3475       GstFormat format;
3476       gint64 position;
3477
3478       gst_message_parse_segment_done (message, &format, &position);
3479       seqnum = gst_message_get_seqnum (message);
3480
3481       bin_do_message_forward (bin, message);
3482
3483       GST_OBJECT_LOCK (bin);
3484       bin_replace_message (bin, message, GST_MESSAGE_SEGMENT_START);
3485       /* if there are no more segment_start messages, everybody posted
3486        * a segment_done and we can post one on the bus. */
3487
3488       /* we don't care who still has a pending segment start */
3489       if (!find_message (bin, NULL, GST_MESSAGE_SEGMENT_START)) {
3490         /* nothing found */
3491         post = TRUE;
3492         /* remove all old segment_done messages */
3493         bin_remove_messages (bin, NULL, GST_MESSAGE_SEGMENT_DONE);
3494       }
3495       GST_OBJECT_UNLOCK (bin);
3496       if (post) {
3497         tmessage = gst_message_new_segment_done (GST_OBJECT_CAST (bin),
3498             format, position);
3499         gst_message_set_seqnum (tmessage, seqnum);
3500
3501         /* post segment done with latest format and position. */
3502         GST_DEBUG_OBJECT (bin, "posting SEGMENT_DONE (%u) bus message: %p",
3503             seqnum, message);
3504         gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
3505       }
3506       break;
3507     }
3508     case GST_MESSAGE_DURATION_CHANGED:
3509     {
3510       /* FIXME: remove all cached durations, next time somebody asks
3511        * for duration, we will recalculate. */
3512 #if 0
3513       GST_OBJECT_LOCK (bin);
3514       bin_remove_messages (bin, NULL, GST_MESSAGE_DURATION_CHANGED);
3515       GST_OBJECT_UNLOCK (bin);
3516 #endif
3517       goto forward;
3518     }
3519     case GST_MESSAGE_CLOCK_LOST:
3520     {
3521       GstClock **provided_clock_p;
3522       GstElement **clock_provider_p;
3523       gboolean playing, toplevel, provided, forward;
3524       GstClock *clock;
3525
3526       gst_message_parse_clock_lost (message, &clock);
3527
3528       GST_OBJECT_LOCK (bin);
3529       bin->clock_dirty = TRUE;
3530       /* if we lost the clock that we provided, post to parent but
3531        * only if we are not a top-level bin or PLAYING.
3532        * The reason for this is that applications should be able
3533        * to PAUSE/PLAY if they receive this message without worrying
3534        * about the state of the pipeline. */
3535       provided = (clock == bin->provided_clock);
3536       playing = (GST_STATE (bin) == GST_STATE_PLAYING);
3537       toplevel = GST_OBJECT_PARENT (bin) == NULL;
3538       forward = provided && (playing || !toplevel);
3539       if (provided) {
3540         GST_DEBUG_OBJECT (bin,
3541             "Lost clock %" GST_PTR_FORMAT " provided by %" GST_PTR_FORMAT,
3542             bin->provided_clock, bin->clock_provider);
3543         provided_clock_p = &bin->provided_clock;
3544         clock_provider_p = &bin->clock_provider;
3545         gst_object_replace ((GstObject **) provided_clock_p, NULL);
3546         gst_object_replace ((GstObject **) clock_provider_p, NULL);
3547       }
3548       GST_DEBUG_OBJECT (bin, "provided %d, playing %d, forward %d",
3549           provided, playing, forward);
3550       GST_OBJECT_UNLOCK (bin);
3551
3552       if (forward)
3553         goto forward;
3554
3555       /* free message */
3556       gst_message_unref (message);
3557       break;
3558     }
3559     case GST_MESSAGE_CLOCK_PROVIDE:
3560     {
3561       gboolean forward;
3562
3563       GST_OBJECT_LOCK (bin);
3564       bin->clock_dirty = TRUE;
3565       /* a new clock is available, post to parent but not
3566        * to the application */
3567       forward = GST_OBJECT_PARENT (bin) != NULL;
3568       GST_OBJECT_UNLOCK (bin);
3569
3570       if (forward)
3571         goto forward;
3572
3573       /* free message */
3574       gst_message_unref (message);
3575       break;
3576     }
3577     case GST_MESSAGE_ASYNC_START:
3578     {
3579       GstState target;
3580
3581       GST_DEBUG_OBJECT (bin, "ASYNC_START message %p, %s", message,
3582           src ? GST_OBJECT_NAME (src) : "(NULL)");
3583
3584       bin_do_message_forward (bin, message);
3585
3586       GST_OBJECT_LOCK (bin);
3587       /* we ignore the message if we are going to <= READY */
3588       if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
3589         goto ignore_start_message;
3590
3591       /* takes ownership of the message */
3592       bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
3593
3594       bin_handle_async_start (bin);
3595       GST_OBJECT_UNLOCK (bin);
3596       break;
3597
3598     ignore_start_message:
3599       {
3600         GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
3601             gst_element_state_get_name (target));
3602         GST_OBJECT_UNLOCK (bin);
3603         gst_message_unref (message);
3604         break;
3605       }
3606     }
3607     case GST_MESSAGE_ASYNC_DONE:
3608     {
3609       GstClockTime running_time;
3610       GstState target;
3611
3612       GST_DEBUG_OBJECT (bin, "ASYNC_DONE message %p, %s", message,
3613           src ? GST_OBJECT_NAME (src) : "(NULL)");
3614
3615       gst_message_parse_async_done (message, &running_time);
3616
3617       bin_do_message_forward (bin, message);
3618
3619       GST_OBJECT_LOCK (bin);
3620       /* ignore messages if we are shutting down */
3621       if ((target = GST_STATE_TARGET (bin)) <= GST_STATE_READY)
3622         goto ignore_done_message;
3623
3624       bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
3625       /* if there are no more ASYNC_START messages, everybody posted
3626        * a ASYNC_DONE and we can post one on the bus. When checking, we
3627        * don't care who still has a pending ASYNC_START */
3628       if (!find_message (bin, NULL, GST_MESSAGE_ASYNC_START)) {
3629         /* nothing found, remove all old ASYNC_DONE messages */
3630         bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
3631
3632         GST_DEBUG_OBJECT (bin, "async elements commited");
3633         /* when we get an async done message when a state change was busy, we
3634          * need to set the pending_done flag so that at the end of the state
3635          * change we can see if we need to verify pending async elements, hence
3636          * the TRUE argument here. */
3637         bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE,
3638             running_time);
3639       } else {
3640         GST_DEBUG_OBJECT (bin, "there are more async elements pending");
3641       }
3642       GST_OBJECT_UNLOCK (bin);
3643       break;
3644
3645     ignore_done_message:
3646       {
3647         GST_DEBUG_OBJECT (bin, "ignoring message, target %s",
3648             gst_element_state_get_name (target));
3649         GST_OBJECT_UNLOCK (bin);
3650         gst_message_unref (message);
3651         break;
3652       }
3653     }
3654     case GST_MESSAGE_STRUCTURE_CHANGE:
3655     {
3656       gboolean busy;
3657
3658       gst_message_parse_structure_change (message, NULL, NULL, &busy);
3659
3660       GST_OBJECT_LOCK (bin);
3661       if (busy) {
3662         /* while the pad is busy, avoid following it when doing state changes.
3663          * Don't update the cookie yet, we will do that after the structure
3664          * change finished and we are ready to inspect the new updated
3665          * structure. */
3666         bin_replace_message (bin, message, GST_MESSAGE_STRUCTURE_CHANGE);
3667         message = NULL;
3668       } else {
3669         /* a pad link/unlink ended, signal the state change iterator that we
3670          * need to resync by updating the structure_cookie. */
3671         bin_remove_messages (bin, GST_MESSAGE_SRC (message),
3672             GST_MESSAGE_STRUCTURE_CHANGE);
3673         if (!GST_BIN_IS_NO_RESYNC (bin))
3674           bin->priv->structure_cookie++;
3675       }
3676       GST_OBJECT_UNLOCK (bin);
3677
3678       if (message)
3679         gst_message_unref (message);
3680
3681       break;
3682     }
3683     case GST_MESSAGE_NEED_CONTEXT:{
3684       const gchar *context_type;
3685       GList *l;
3686
3687       gst_message_parse_context_type (message, &context_type);
3688       GST_OBJECT_LOCK (bin);
3689       for (l = bin->priv->contexts; l; l = l->next) {
3690         GstContext *tmp = l->data;
3691         const gchar *tmp_type = gst_context_get_context_type (tmp);
3692
3693         if (strcmp (context_type, tmp_type) == 0) {
3694           gst_element_set_context (GST_ELEMENT (src), l->data);
3695           break;
3696         }
3697       }
3698       GST_OBJECT_UNLOCK (bin);
3699
3700       /* Forward if we couldn't answer the message */
3701       if (l == NULL) {
3702         goto forward;
3703       } else {
3704         gst_message_unref (message);
3705       }
3706
3707       break;
3708     }
3709     case GST_MESSAGE_HAVE_CONTEXT:{
3710       GstContext *context;
3711
3712       gst_message_parse_have_context (message, &context);
3713       gst_bin_update_context (bin, context);
3714       gst_context_unref (context);
3715
3716       goto forward;
3717       break;
3718     }
3719     default:
3720       goto forward;
3721   }
3722   return;
3723
3724 forward:
3725   {
3726     /* Send all other messages upward */
3727     GST_DEBUG_OBJECT (bin, "posting message upward");
3728     gst_element_post_message (GST_ELEMENT_CAST (bin), message);
3729     return;
3730   }
3731 }
3732
3733 /* generic struct passed to all query fold methods */
3734 typedef struct
3735 {
3736   GstQuery *query;
3737   gint64 min;
3738   gint64 max;
3739   gboolean live;
3740 } QueryFold;
3741
3742 typedef void (*QueryInitFunction) (GstBin * bin, QueryFold * fold);
3743 typedef void (*QueryDoneFunction) (GstBin * bin, QueryFold * fold);
3744
3745 /* for duration/position we collect all durations/positions and take
3746  * the MAX of all valid results */
3747 static void
3748 bin_query_min_max_init (GstBin * bin, QueryFold * fold)
3749 {
3750   fold->min = 0;
3751   fold->max = -1;
3752   fold->live = FALSE;
3753 }
3754
3755 static gboolean
3756 bin_query_duration_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
3757 {
3758   gboolean res = FALSE;
3759   GstObject *item = g_value_get_object (vitem);
3760   if (GST_IS_PAD (item))
3761     res = gst_pad_query (GST_PAD (item), fold->query);
3762   else
3763     res = gst_element_query (GST_ELEMENT (item), fold->query);
3764
3765   if (res) {
3766     gint64 duration;
3767
3768     g_value_set_boolean (ret, TRUE);
3769
3770     gst_query_parse_duration (fold->query, NULL, &duration);
3771
3772     GST_DEBUG_OBJECT (item, "got duration %" G_GINT64_FORMAT, duration);
3773
3774     if (duration == -1) {
3775       /* duration query succeeded, but duration is unknown */
3776       fold->max = -1;
3777       return FALSE;
3778     }
3779
3780     if (duration > fold->max)
3781       fold->max = duration;
3782   }
3783
3784   return TRUE;
3785 }
3786
3787 static void
3788 bin_query_duration_done (GstBin * bin, QueryFold * fold)
3789 {
3790   GstFormat format;
3791
3792   gst_query_parse_duration (fold->query, &format, NULL);
3793   /* store max in query result */
3794   gst_query_set_duration (fold->query, format, fold->max);
3795
3796   GST_DEBUG_OBJECT (bin, "max duration %" G_GINT64_FORMAT, fold->max);
3797
3798   /* FIXME: re-implement duration caching */
3799 #if 0
3800   /* and cache now */
3801   GST_OBJECT_LOCK (bin);
3802   bin->messages = g_list_prepend (bin->messages,
3803       gst_message_new_duration (GST_OBJECT_CAST (bin), format, fold->max));
3804   GST_OBJECT_UNLOCK (bin);
3805 #endif
3806 }
3807
3808 static gboolean
3809 bin_query_position_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
3810 {
3811   gboolean res = FALSE;
3812   GstObject *item = g_value_get_object (vitem);
3813   if (GST_IS_PAD (item))
3814     res = gst_pad_query (GST_PAD (item), fold->query);
3815   else
3816     res = gst_element_query (GST_ELEMENT (item), fold->query);
3817
3818   if (res) {
3819     gint64 position;
3820
3821     g_value_set_boolean (ret, TRUE);
3822
3823     gst_query_parse_position (fold->query, NULL, &position);
3824
3825     GST_DEBUG_OBJECT (item, "got position %" G_GINT64_FORMAT, position);
3826
3827     if (position > fold->max)
3828       fold->max = position;
3829   }
3830
3831   return TRUE;
3832 }
3833
3834 static void
3835 bin_query_position_done (GstBin * bin, QueryFold * fold)
3836 {
3837   GstFormat format;
3838
3839   gst_query_parse_position (fold->query, &format, NULL);
3840   /* store max in query result */
3841   gst_query_set_position (fold->query, format, fold->max);
3842
3843   GST_DEBUG_OBJECT (bin, "max position %" G_GINT64_FORMAT, fold->max);
3844 }
3845
3846 static gboolean
3847 bin_query_latency_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
3848 {
3849   gboolean res = FALSE;
3850   GstObject *item = g_value_get_object (vitem);
3851   if (GST_IS_PAD (item))
3852     res = gst_pad_query (GST_PAD (item), fold->query);
3853   else
3854     res = gst_element_query (GST_ELEMENT (item), fold->query);
3855   if (res) {
3856     GstClockTime min, max;
3857     gboolean live;
3858
3859     gst_query_parse_latency (fold->query, &live, &min, &max);
3860
3861     GST_DEBUG_OBJECT (item,
3862         "got latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
3863         ", live %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max), live);
3864
3865     /* for the combined latency we collect the MAX of all min latencies and
3866      * the MIN of all max latencies */
3867     if (live) {
3868       if (min > fold->min)
3869         fold->min = min;
3870       if (fold->max == -1)
3871         fold->max = max;
3872       else if (max < fold->max)
3873         fold->max = max;
3874       if (fold->live == FALSE)
3875         fold->live = live;
3876     }
3877   } else {
3878     g_value_set_boolean (ret, FALSE);
3879     GST_DEBUG_OBJECT (item, "failed query");
3880   }
3881
3882   return TRUE;
3883 }
3884
3885 static void
3886 bin_query_latency_done (GstBin * bin, QueryFold * fold)
3887 {
3888   /* store max in query result */
3889   gst_query_set_latency (fold->query, fold->live, fold->min, fold->max);
3890
3891   GST_DEBUG_OBJECT (bin,
3892       "latency min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT
3893       ", live %d", GST_TIME_ARGS (fold->min), GST_TIME_ARGS (fold->max),
3894       fold->live);
3895 }
3896
3897 /* generic fold, return first valid result */
3898 static gboolean
3899 bin_query_generic_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
3900 {
3901   gboolean res = FALSE;
3902   GstObject *item = g_value_get_object (vitem);
3903   if (GST_IS_PAD (item))
3904     res = gst_pad_query (GST_PAD (item), fold->query);
3905   else
3906     res = gst_element_query (GST_ELEMENT (item), fold->query);
3907   if (res) {
3908     g_value_set_boolean (ret, TRUE);
3909     GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
3910   }
3911
3912   /* and stop as soon as we have a valid result */
3913   return !res;
3914 }
3915
3916 /* Perform a query iteration for the given bin. The query is stored in
3917  * QueryFold and iter should be either a GstPad iterator or a
3918  * GstElement iterator. */
3919 static gboolean
3920 bin_iterate_fold (GstBin * bin, GstIterator * iter, QueryInitFunction fold_init,
3921     QueryDoneFunction fold_done, GstIteratorFoldFunction fold_func,
3922     QueryFold fold_data, gboolean default_return)
3923 {
3924   gboolean res = default_return;
3925   GValue ret = { 0 };
3926   /* set the result of the query to FALSE initially */
3927   g_value_init (&ret, G_TYPE_BOOLEAN);
3928   g_value_set_boolean (&ret, res);
3929
3930   while (TRUE) {
3931     GstIteratorResult ires;
3932
3933     ires = gst_iterator_fold (iter, fold_func, &ret, &fold_data);
3934
3935     switch (ires) {
3936       case GST_ITERATOR_RESYNC:
3937         gst_iterator_resync (iter);
3938         if (fold_init)
3939           fold_init (bin, &fold_data);
3940         g_value_set_boolean (&ret, res);
3941         break;
3942       case GST_ITERATOR_OK:
3943       case GST_ITERATOR_DONE:
3944         res = g_value_get_boolean (&ret);
3945         if (fold_done != NULL && res)
3946           fold_done (bin, &fold_data);
3947         goto done;
3948       default:
3949         res = FALSE;
3950         goto done;
3951     }
3952   }
3953 done:
3954   return res;
3955 }
3956
3957 static gboolean
3958 gst_bin_query (GstElement * element, GstQuery * query)
3959 {
3960   GstBin *bin = GST_BIN_CAST (element);
3961   GstIterator *iter;
3962   gboolean default_return = FALSE;
3963   gboolean res = FALSE;
3964   gboolean src_pads_query_result = FALSE;
3965   GstIteratorFoldFunction fold_func;
3966   QueryInitFunction fold_init = NULL;
3967   QueryDoneFunction fold_done = NULL;
3968   QueryFold fold_data;
3969
3970   switch (GST_QUERY_TYPE (query)) {
3971     case GST_QUERY_DURATION:
3972     {
3973       /* FIXME: implement duration caching in GstBin again */
3974 #if 0
3975       GList *cached;
3976       GstFormat qformat;
3977
3978       gst_query_parse_duration (query, &qformat, NULL);
3979
3980       /* find cached duration query */
3981       GST_OBJECT_LOCK (bin);
3982       for (cached = bin->messages; cached; cached = g_list_next (cached)) {
3983         GstMessage *message = (GstMessage *) cached->data;
3984
3985         if (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION_CHANGED &&
3986             GST_MESSAGE_SRC (message) == GST_OBJECT_CAST (bin)) {
3987           GstFormat format;
3988           gint64 duration;
3989
3990           gst_message_parse_duration (message, &format, &duration);
3991
3992           /* if cached same format, copy duration in query result */
3993           if (format == qformat) {
3994             GST_DEBUG_OBJECT (bin, "return cached duration %" G_GINT64_FORMAT,
3995                 duration);
3996             GST_OBJECT_UNLOCK (bin);
3997
3998             gst_query_set_duration (query, qformat, duration);
3999             res = TRUE;
4000             goto exit;
4001           }
4002         }
4003       }
4004       GST_OBJECT_UNLOCK (bin);
4005 #else
4006       GST_FIXME ("implement duration caching in GstBin again");
4007 #endif
4008       /* no cached value found, iterate and collect durations */
4009       fold_func = (GstIteratorFoldFunction) bin_query_duration_fold;
4010       fold_init = bin_query_min_max_init;
4011       fold_done = bin_query_duration_done;
4012       break;
4013     }
4014     case GST_QUERY_POSITION:
4015     {
4016       fold_func = (GstIteratorFoldFunction) bin_query_position_fold;
4017       fold_init = bin_query_min_max_init;
4018       fold_done = bin_query_position_done;
4019       break;
4020     }
4021     case GST_QUERY_LATENCY:
4022     {
4023       fold_func = (GstIteratorFoldFunction) bin_query_latency_fold;
4024       fold_init = bin_query_min_max_init;
4025       fold_done = bin_query_latency_done;
4026       default_return = TRUE;
4027       break;
4028     }
4029     default:
4030       fold_func = (GstIteratorFoldFunction) bin_query_generic_fold;
4031       break;
4032   }
4033
4034   fold_data.query = query;
4035
4036   iter = gst_bin_iterate_sinks (bin);
4037   GST_DEBUG_OBJECT (bin, "Sending query %p (type %s) to sink children",
4038       query, GST_QUERY_TYPE_NAME (query));
4039
4040   if (fold_init)
4041     fold_init (bin, &fold_data);
4042
4043   res =
4044       bin_iterate_fold (bin, iter, fold_init, fold_done, fold_func, fold_data,
4045       default_return);
4046   gst_iterator_free (iter);
4047
4048   if (!res) {
4049     /* Query the source pads of the element */
4050     iter = gst_element_iterate_src_pads (element);
4051     src_pads_query_result =
4052         bin_iterate_fold (bin, iter, fold_init, fold_done, fold_func,
4053         fold_data, default_return);
4054     gst_iterator_free (iter);
4055
4056     if (src_pads_query_result)
4057       res = TRUE;
4058   }
4059
4060   GST_DEBUG_OBJECT (bin, "query %p result %d", query, res);
4061
4062   return res;
4063 }
4064
4065 static void
4066 set_context (const GValue * item, gpointer user_data)
4067 {
4068   GstElement *element = g_value_get_object (item);
4069
4070   gst_element_set_context (element, user_data);
4071 }
4072
4073 static void
4074 gst_bin_set_context (GstElement * element, GstContext * context)
4075 {
4076   GstBin *bin;
4077   GstIterator *children;
4078
4079   g_return_if_fail (GST_IS_BIN (element));
4080
4081   bin = GST_BIN (element);
4082
4083   gst_bin_update_context (bin, context);
4084
4085   children = gst_bin_iterate_elements (bin);
4086   while (gst_iterator_foreach (children, set_context,
4087           context) == GST_ITERATOR_RESYNC)
4088     gst_iterator_resync (children);
4089   gst_iterator_free (children);
4090 }
4091
4092 static gint
4093 compare_name (const GValue * velement, const gchar * name)
4094 {
4095   gint eq;
4096   GstElement *element = g_value_get_object (velement);
4097
4098   GST_OBJECT_LOCK (element);
4099   eq = strcmp (GST_ELEMENT_NAME (element), name);
4100   GST_OBJECT_UNLOCK (element);
4101
4102   return eq;
4103 }
4104
4105 /**
4106  * gst_bin_get_by_name:
4107  * @bin: a #GstBin
4108  * @name: the element name to search for
4109  *
4110  * Gets the element with the given name from a bin. This
4111  * function recurses into child bins.
4112  *
4113  * Returns NULL if no element with the given name is found in the bin.
4114  *
4115  * MT safe.  Caller owns returned reference.
4116  *
4117  * Returns: (transfer full): the #GstElement with the given name, or NULL
4118  */
4119 GstElement *
4120 gst_bin_get_by_name (GstBin * bin, const gchar * name)
4121 {
4122   GstIterator *children;
4123   GValue result = { 0, };
4124   GstElement *element;
4125   gboolean found;
4126
4127   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
4128
4129   GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
4130       GST_ELEMENT_NAME (bin), name);
4131
4132   children = gst_bin_iterate_recurse (bin);
4133   found = gst_iterator_find_custom (children,
4134       (GCompareFunc) compare_name, &result, (gpointer) name);
4135   gst_iterator_free (children);
4136
4137   if (found) {
4138     element = g_value_dup_object (&result);
4139     g_value_unset (&result);
4140   } else {
4141     element = NULL;
4142   }
4143
4144   return element;
4145 }
4146
4147 /**
4148  * gst_bin_get_by_name_recurse_up:
4149  * @bin: a #GstBin
4150  * @name: the element name to search for
4151  *
4152  * Gets the element with the given name from this bin. If the
4153  * element is not found, a recursion is performed on the parent bin.
4154  *
4155  * Returns NULL if:
4156  * - no element with the given name is found in the bin
4157  *
4158  * MT safe.  Caller owns returned reference.
4159  *
4160  * Returns: (transfer full): the #GstElement with the given name, or NULL
4161  */
4162 GstElement *
4163 gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
4164 {
4165   GstElement *result;
4166
4167   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
4168   g_return_val_if_fail (name != NULL, NULL);
4169
4170   result = gst_bin_get_by_name (bin, name);
4171
4172   if (!result) {
4173     GstObject *parent;
4174
4175     parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
4176     if (parent) {
4177       if (GST_IS_BIN (parent)) {
4178         result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
4179       }
4180       gst_object_unref (parent);
4181     }
4182   }
4183
4184   return result;
4185 }
4186
4187 static gint
4188 compare_interface (const GValue * velement, GValue * interface)
4189 {
4190   GstElement *element = g_value_get_object (velement);
4191   GType interface_type = (GType) g_value_get_pointer (interface);
4192   gint ret;
4193
4194   if (G_TYPE_CHECK_INSTANCE_TYPE (element, interface_type)) {
4195     ret = 0;
4196   } else {
4197     ret = 1;
4198   }
4199   return ret;
4200 }
4201
4202 /**
4203  * gst_bin_get_by_interface:
4204  * @bin: a #GstBin
4205  * @iface: the #GType of an interface
4206  *
4207  * Looks for an element inside the bin that implements the given
4208  * interface. If such an element is found, it returns the element.
4209  * You can cast this element to the given interface afterwards.  If you want
4210  * all elements that implement the interface, use
4211  * gst_bin_iterate_all_by_interface(). This function recurses into child bins.
4212  *
4213  * MT safe.  Caller owns returned reference.
4214  *
4215  * Returns: (transfer full): A #GstElement inside the bin implementing the interface
4216  */
4217 GstElement *
4218 gst_bin_get_by_interface (GstBin * bin, GType iface)
4219 {
4220   GstIterator *children;
4221   GValue result = { 0, };
4222   GstElement *element;
4223   gboolean found;
4224   GValue viface = { 0, };
4225
4226   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
4227   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
4228
4229   g_value_init (&viface, G_TYPE_POINTER);
4230   g_value_set_pointer (&viface, (gpointer) iface);
4231
4232   children = gst_bin_iterate_recurse (bin);
4233   found = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
4234       &result, &viface);
4235   gst_iterator_free (children);
4236
4237   if (found) {
4238     element = g_value_dup_object (&result);
4239     g_value_unset (&result);
4240   } else {
4241     element = NULL;
4242   }
4243   g_value_unset (&viface);
4244
4245   return element;
4246 }
4247
4248 /**
4249  * gst_bin_iterate_all_by_interface:
4250  * @bin: a #GstBin
4251  * @iface: the #GType of an interface
4252  *
4253  * Looks for all elements inside the bin that implements the given
4254  * interface. You can safely cast all returned elements to the given interface.
4255  * The function recurses inside child bins. The iterator will yield a series
4256  * of #GstElement that should be unreffed after use.
4257  *
4258  * MT safe.  Caller owns returned value.
4259  *
4260  * Returns: (transfer full): a #GstIterator of #GstElement for all elements
4261  *          in the bin implementing the given interface, or NULL
4262  */
4263 GstIterator *
4264 gst_bin_iterate_all_by_interface (GstBin * bin, GType iface)
4265 {
4266   GstIterator *children;
4267   GstIterator *result;
4268   GValue viface = { 0, };
4269
4270   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
4271   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
4272
4273   g_value_init (&viface, G_TYPE_POINTER);
4274   g_value_set_pointer (&viface, (gpointer) iface);
4275
4276   children = gst_bin_iterate_recurse (bin);
4277   result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
4278       &viface);
4279
4280   g_value_unset (&viface);
4281
4282   return result;
4283 }