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