3 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
4 * 2004 Wim Taymans <wim@fluendo.com>
6 * gstbin.c: GstBin container object and support code
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.
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.
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.
26 #include "gst_private.h"
30 #include "gstmarshal.h"
38 GST_DEBUG_CATEGORY_STATIC (bin_debug);
39 #define GST_CAT_DEFAULT bin_debug
40 #define GST_LOG_BIN_CONTENTS(bin, text) GST_LOG_OBJECT ((bin), \
41 text ": %d elements: %u PLAYING, %u PAUSED, %u READY, %u NULL, own state: %s", \
42 (bin)->numchildren, (guint) (bin)->child_states[3], \
43 (guint) (bin)->child_states[2], (bin)->child_states[1], \
44 (bin)->child_states[0], gst_element_state_get_name (GST_STATE (bin)))
47 static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin",
49 "Simple container object",
50 "Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
52 GType _gst_bin_type = 0;
54 static void gst_bin_dispose (GObject * object);
56 static GstElementStateReturn gst_bin_change_state (GstElement * element);
57 static GstElementStateReturn gst_bin_get_state (GstElement * element,
58 GstElementState * state, GstElementState * pending, GTimeVal * timeout);
60 static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
61 static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
63 #ifndef GST_DISABLE_INDEX
64 static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
66 static GstClock *gst_bin_get_clock_func (GstElement * element);
67 static void gst_bin_set_clock_func (GstElement * element, GstClock * clock);
69 static gboolean gst_bin_send_event (GstElement * element, GstEvent * event);
70 static GstBusSyncReply bin_bus_handler (GstBus * bus,
71 GstMessage * message, GstBin * bin);
72 static gboolean gst_bin_query (GstElement * element, GstQuery * query);
74 #ifndef GST_DISABLE_LOADSAVE
75 static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
76 static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
79 static gint bin_element_is_sink (GstElement * child, GstBin * bin);
81 /* Bin signals and args */
95 static void gst_bin_base_init (gpointer g_class);
96 static void gst_bin_class_init (GstBinClass * klass);
97 static void gst_bin_init (GstBin * bin);
99 static GstElementClass *parent_class = NULL;
100 static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
105 * Returns: the type of #GstBin
108 gst_bin_get_type (void)
110 if (!_gst_bin_type) {
111 static const GTypeInfo bin_info = {
112 sizeof (GstBinClass),
115 (GClassInitFunc) gst_bin_class_init,
120 (GInstanceInitFunc) gst_bin_init,
125 g_type_register_static (GST_TYPE_ELEMENT, "GstBin", &bin_info, 0);
127 GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD,
128 "debugging info for the 'bin' container element");
130 return _gst_bin_type;
134 gst_bin_base_init (gpointer g_class)
136 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
138 gst_element_class_set_details (gstelement_class, &gst_bin_details);
142 gst_bin_class_init (GstBinClass * klass)
144 GObjectClass *gobject_class;
145 GstObjectClass *gstobject_class;
146 GstElementClass *gstelement_class;
148 gobject_class = (GObjectClass *) klass;
149 gstobject_class = (GstObjectClass *) klass;
150 gstelement_class = (GstElementClass *) klass;
152 parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
154 gst_bin_signals[ELEMENT_ADDED] =
155 g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
156 G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
157 NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
158 gst_bin_signals[ELEMENT_REMOVED] =
159 g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
160 G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
161 NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
163 gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose);
165 #ifndef GST_DISABLE_LOADSAVE
166 gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
167 gstobject_class->restore_thyself =
168 GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
171 gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_bin_change_state);
172 gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state);
173 #ifndef GST_DISABLE_INDEX
174 gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
176 gstelement_class->get_clock = GST_DEBUG_FUNCPTR (gst_bin_get_clock_func);
177 gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
179 gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_bin_send_event);
180 gstelement_class->query = GST_DEBUG_FUNCPTR (gst_bin_query);
182 klass->add_element = GST_DEBUG_FUNCPTR (gst_bin_add_func);
183 klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func);
187 gst_bin_init (GstBin * bin)
191 bin->numchildren = 0;
192 bin->children = NULL;
193 bin->children_cookie = 0;
196 /* Set up a bus for listening to child elements,
197 * and one for sending messages up the hierarchy */
198 bus = g_object_new (gst_bus_get_type (), NULL);
199 bin->child_bus = bus;
200 gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
202 bus = g_object_new (gst_bus_get_type (), NULL);
203 gst_element_set_bus (GST_ELEMENT (bin), bus);
204 /* set_bus refs the bus via gst_object_replace, we drop our ref */
205 gst_object_unref (bus);
210 * @name: name of new bin
212 * Create a new bin with given name.
217 gst_bin_new (const gchar * name)
219 return gst_element_factory_make ("bin", name);
222 /* set the index on all elements in this bin
226 #ifndef GST_DISABLE_INDEX
228 gst_bin_set_index_func (GstElement * element, GstIndex * index)
233 bin = GST_BIN (element);
236 for (children = bin->children; children; children = g_list_next (children)) {
237 GstElement *child = GST_ELEMENT (children->data);
239 gst_element_set_index (child, index);
245 /* set the clock on all elements in this bin
250 gst_bin_set_clock_func (GstElement * element, GstClock * clock)
255 bin = GST_BIN (element);
258 for (children = bin->children; children; children = g_list_next (children)) {
259 GstElement *child = GST_ELEMENT (children->data);
261 gst_element_set_clock (child, clock);
266 /* get the clock for this bin by asking all of the children in this bin
271 gst_bin_get_clock_func (GstElement * element)
273 GstClock *result = NULL;
277 bin = GST_BIN (element);
280 for (children = bin->children; children; children = g_list_next (children)) {
281 GstElement *child = GST_ELEMENT (children->data);
283 result = gst_element_get_clock (child);
293 is_eos (GstBin * bin)
296 gboolean result = TRUE;
297 gboolean done = FALSE;
299 sinks = gst_bin_iterate_sinks (bin);
303 switch (gst_iterator_next (sinks, &data)) {
304 case GST_ITERATOR_OK:
306 GstElement *element = GST_ELEMENT (data);
310 name = gst_element_get_name (element);
311 eosed = g_list_find (bin->eosed, element);
313 GST_DEBUG ("element %s did not post EOS yet", name);
317 GST_DEBUG ("element %s posted EOS", name);
320 gst_object_unref (element);
323 case GST_ITERATOR_RESYNC:
325 gst_iterator_resync (sinks);
327 case GST_ITERATOR_DONE:
331 g_assert_not_reached ();
335 gst_iterator_free (sinks);
340 unlink_pads (GstPad * pad)
344 if ((peer = gst_pad_get_peer (pad))) {
345 if (gst_pad_get_direction (pad) == GST_PAD_SRC)
346 gst_pad_unlink (pad, peer);
348 gst_pad_unlink (peer, pad);
349 gst_object_unref (peer);
351 gst_object_unref (pad);
354 /* add an element to this bin
359 gst_bin_add_func (GstBin * bin, GstElement * element)
364 /* we obviously can't add ourself to ourself */
365 if (G_UNLIKELY (GST_ELEMENT_CAST (element) == GST_ELEMENT_CAST (bin)))
368 /* get the element name to make sure it is unique in this bin. */
370 elem_name = g_strdup (GST_ELEMENT_NAME (element));
371 GST_UNLOCK (element);
375 /* then check to see if the element's name is already taken in the bin,
376 * we can safely take the lock here. This check is probably bogus because
377 * you can safely change the element name after this check and before setting
378 * the object parent. The window is very small though... */
379 if (G_UNLIKELY (!gst_object_check_uniqueness (bin->children, elem_name)))
382 /* set the element's parent and add the element to the bin's list of children */
383 if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (element),
384 GST_OBJECT_CAST (bin))))
387 /* if we add a sink we become a sink */
388 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK))
389 GST_FLAG_SET (bin, GST_ELEMENT_IS_SINK);
391 bin->children = g_list_prepend (bin->children, element);
393 bin->children_cookie++;
395 /* distribute the bus */
396 gst_element_set_bus (element, bin->child_bus);
398 /* propagate the current base time and clock */
399 gst_element_set_base_time (element, GST_ELEMENT (bin)->base_time);
400 gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
404 /* unlink all linked pads */
405 it = gst_element_iterate_pads (element);
406 gst_iterator_foreach (it, (GFunc) unlink_pads, element);
407 gst_iterator_free (it);
409 GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
413 g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_ADDED], 0, element);
417 /* ERROR handling here */
421 g_warning ("Cannot add bin %s to itself", GST_ELEMENT_NAME (bin));
427 g_warning ("Name %s is not unique in bin %s, not adding",
428 elem_name, GST_ELEMENT_NAME (bin));
435 g_warning ("Element %s already has parent", elem_name);
445 * @bin: #GstBin to add element to
446 * @element: #GstElement to add to bin
448 * Adds the given element to the bin. Sets the element's parent, and thus
449 * takes ownership of the element. An element can only be added to one bin.
451 * If the element's pads are linked to other pads, the pads will be unlinked
452 * before the element is added to the bin.
456 * Returns: TRUE if the element could be added, FALSE on wrong parameters or
457 * the bin does not want to accept the element.
460 gst_bin_add (GstBin * bin, GstElement * element)
465 g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
466 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
468 bclass = GST_BIN_GET_CLASS (bin);
470 if (G_UNLIKELY (bclass->add_element == NULL))
473 GST_CAT_DEBUG (GST_CAT_PARENTAGE, "adding element %s to bin %s",
474 GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
476 result = bclass->add_element (bin, element);
483 g_warning ("adding elements to bin %s is not supported",
484 GST_ELEMENT_NAME (bin));
489 /* remove an element from the bin
494 gst_bin_remove_func (GstBin * bin, GstElement * element)
499 /* grab element name so we can print it */
501 elem_name = g_strdup (GST_ELEMENT_NAME (element));
502 GST_UNLOCK (element);
505 /* the element must be in the bin's list of children */
506 if (G_UNLIKELY (g_list_find (bin->children, element) == NULL))
509 /* now remove the element from the list of elements */
510 bin->children = g_list_remove (bin->children, element);
512 bin->children_cookie++;
514 /* check if we removed a sink */
515 if (GST_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK)) {
518 /* check if we removed the last sink */
519 other_sink = g_list_find_custom (bin->children,
520 bin, (GCompareFunc) bin_element_is_sink);
522 /* yups, we're not a sink anymore */
523 GST_FLAG_UNSET (bin, GST_ELEMENT_IS_SINK);
528 GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
532 /* unlink all linked pads */
533 it = gst_element_iterate_pads (element);
534 gst_iterator_foreach (it, (GFunc) unlink_pads, element);
535 gst_iterator_free (it);
537 gst_element_set_bus (element, NULL);
539 /* unlock any waiters for the state change. It is possible that
540 * we are waiting for an ASYNC state change on this element. The
541 * element cannot be added to another bin yet as it is not yet
543 GST_STATE_LOCK (element);
544 GST_STATE_BROADCAST (element);
545 GST_STATE_UNLOCK (element);
547 /* we ref here because after the _unparent() the element can be disposed
548 * and we still need it to fire a signal. */
549 gst_object_ref (element);
550 gst_object_unparent (GST_OBJECT_CAST (element));
552 g_signal_emit (G_OBJECT (bin), gst_bin_signals[ELEMENT_REMOVED], 0, element);
553 /* element is really out of our control now */
554 gst_object_unref (element);
561 g_warning ("Element %s is not in bin %s", elem_name,
562 GST_ELEMENT_NAME (bin));
571 * @bin: #GstBin to remove element from
572 * @element: #GstElement to remove
574 * Remove the element from its associated bin, unparenting it as well.
575 * Unparenting the element means that the element will be dereferenced,
576 * so if the bin holds the only reference to the element, the element
577 * will be freed in the process of removing it from the bin. If you
578 * want the element to still exist after removing, you need to call
579 * #gst_object_ref before removing it from the bin.
581 * If the element's pads are linked to other pads, the pads will be unlinked
582 * before the element is removed from the bin.
586 * Returns: TRUE if the element could be removed, FALSE on wrong parameters or
587 * the bin does not want to remove the element.
590 gst_bin_remove (GstBin * bin, GstElement * element)
595 g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
596 g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
598 bclass = GST_BIN_GET_CLASS (bin);
600 if (G_UNLIKELY (bclass->remove_element == NULL))
603 GST_CAT_DEBUG (GST_CAT_PARENTAGE, "removing element %s from bin %s",
604 GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
606 result = bclass->remove_element (bin, element);
613 g_warning ("removing elements from bin %s is not supported",
614 GST_ELEMENT_NAME (bin));
619 static GstIteratorItem
620 iterate_child (GstIterator * it, GstElement * child)
622 gst_object_ref (child);
623 return GST_ITERATOR_ITEM_PASS;
627 * gst_bin_iterate_elements:
628 * @bin: #Gstbin to iterate the elements of
630 * Get an iterator for the elements in this bin.
631 * Each element will have its refcount increased, so unref
636 * Returns: a #GstIterator of #GstElements. gst_iterator_free after
637 * use. returns NULL when passing bad parameters.
640 gst_bin_iterate_elements (GstBin * bin)
644 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
647 /* add ref because the iterator refs the bin. When the iterator
648 * is freed it will unref the bin again using the provided dispose
650 gst_object_ref (bin);
651 result = gst_iterator_new_list (GST_GET_LOCK (bin),
652 &bin->children_cookie,
655 (GstIteratorItemFunction) iterate_child,
656 (GstIteratorDisposeFunction) gst_object_unref);
662 static GstIteratorItem
663 iterate_child_recurse (GstIterator * it, GstElement * child)
665 gst_object_ref (child);
666 if (GST_IS_BIN (child)) {
667 GstIterator *other = gst_bin_iterate_recurse (GST_BIN (child));
669 gst_iterator_push (it, other);
671 return GST_ITERATOR_ITEM_PASS;
675 * gst_bin_iterate_recurse:
676 * @bin: #Gstbin to iterate the elements of
678 * Get an iterator for the elements in this bin.
679 * Each element will have its refcount increased, so unref
680 * after use. This iterator recurses into GstBin children.
684 * Returns: a #GstIterator of #GstElements. gst_iterator_free after
685 * use. returns NULL when passing bad parameters.
688 gst_bin_iterate_recurse (GstBin * bin)
692 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
695 /* add ref because the iterator refs the bin. When the iterator
696 * is freed it will unref the bin again using the provided dispose
698 gst_object_ref (bin);
699 result = gst_iterator_new_list (GST_GET_LOCK (bin),
700 &bin->children_cookie,
703 (GstIteratorItemFunction) iterate_child_recurse,
704 (GstIteratorDisposeFunction) gst_object_unref);
710 /* returns 0 when TRUE because this is a GCompareFunc */
713 bin_element_is_sink (GstElement * child, GstBin * bin)
717 /* we lock the child here for the remainder of the function to
718 * get its name safely. */
720 is_sink = GST_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK);
722 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
723 "child %s %s sink", GST_OBJECT_NAME (child), is_sink ? "is" : "is not");
726 return is_sink ? 0 : 1;
729 /* check if object has the given ancestor somewhere up in
733 has_ancestor (GstObject * object, GstObject * ancestor)
736 gboolean result = FALSE;
741 if (object == ancestor)
744 parent = gst_object_get_parent (object);
745 result = has_ancestor (parent, ancestor);
747 gst_object_unref (parent);
752 /* returns 0 when TRUE because this is a GCompareFunc.
753 * This function returns elements that have no connected srcpads and
754 * are therefore not reachable from a real sink. */
757 bin_element_is_semi_sink (GstElement * child, GstBin * bin)
761 /* we lock the child here for the remainder of the function to
762 * get its pads and name safely. */
765 /* check if this is a sink element, these are the elements
766 * without (linked) source pads. */
767 if (child->numsrcpads == 0) {
769 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
770 "adding child %s as sink", GST_OBJECT_NAME (child));
773 /* loop over all pads, try to figure out if this element
774 * is a semi sink because it has no linked source pads */
776 gboolean connected_src = FALSE;
778 for (pads = child->srcpads; pads; pads = g_list_next (pads)) {
781 GST_DEBUG ("looking at pad %p", pads->data);
782 if ((peer = gst_pad_get_peer (GST_PAD_CAST (pads->data)))) {
784 has_ancestor (GST_OBJECT_CAST (peer), GST_OBJECT_CAST (bin));
785 gst_object_unref (peer);
792 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
793 "not adding child %s as sink: linked source pads",
794 GST_OBJECT_NAME (child));
796 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
797 "adding child %s as sink since it has unlinked source pads in this bin",
798 GST_OBJECT_NAME (child));
808 sink_iterator_filter (GstElement * child, GstBin * bin)
810 if (bin_element_is_sink (child, bin) == 0) {
811 /* returns 0 because this is a GCompareFunc */
814 /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
816 gst_object_unref ((GstObject *) child);
822 * gst_bin_iterate_sinks:
823 * @bin: #Gstbin to iterate on
825 * Get an iterator for the sink elements in this bin.
826 * Each element will have its refcount increased, so unref
829 * The sink elements are those without any linked srcpads.
833 * Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
836 gst_bin_iterate_sinks (GstBin * bin)
838 GstIterator *children;
841 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
843 children = gst_bin_iterate_elements (bin);
844 result = gst_iterator_filter (children,
845 (GCompareFunc) sink_iterator_filter, bin);
851 * 1) check state of all children with 0 timeout to find ERROR and
852 * NO_PREROLL elements. return if found.
853 * 2) perform full blocking wait with requested timeout.
855 * 2) cannot be performed when 1) returns results as the sinks might
856 * not be able to complete the state change making 2) block forever.
860 static GstElementStateReturn
861 gst_bin_get_state (GstElement * element, GstElementState * state,
862 GstElementState * pending, GTimeVal * timeout)
864 GstBin *bin = GST_BIN (element);
865 GstElementStateReturn ret = GST_STATE_SUCCESS;
867 guint32 children_cookie;
868 gboolean have_no_preroll;
870 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
872 /* lock bin, no element can be added or removed between going into
873 * the quick scan and the blocking wait. */
877 have_no_preroll = FALSE;
879 /* first we need to poll with a non zero timeout to make sure we don't block
880 * on the sinks when we have NO_PREROLL elements. This is why we do
881 * a quick check if there are still NO_PREROLL elements. We also
882 * catch the error elements this way. */
885 gboolean have_async = FALSE;
887 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "checking for NO_PREROLL");
888 /* use 0 timeout so we don't block on the sinks */
889 GST_TIME_TO_TIMEVAL (0, tv);
890 children = bin->children;
891 children_cookie = bin->children_cookie;
893 GstElement *child = GST_ELEMENT_CAST (children->data);
895 gst_object_ref (child);
896 /* now we release the lock to enter a non blocking wait. We
897 * release the lock anyway since we can. */
900 ret = gst_element_get_state (child, NULL, NULL, &tv);
902 gst_object_unref (child);
904 /* now grab the lock to iterate to the next child */
906 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
907 /* child added/removed during state change, restart. We need
908 * to restart with the quick check as a no-preroll element could
909 * have been added here and we don't want to block on sinks then.*/
914 /* report FAILURE immediatly */
915 case GST_STATE_FAILURE:
917 case GST_STATE_NO_PREROLL:
918 /* we have to continue scanning as there might be
920 have_no_preroll = TRUE;
922 case GST_STATE_ASYNC:
928 children = g_list_next (children);
930 /* if we get here, we have no FAILURES, check for any NO_PREROLL
932 if (have_no_preroll) {
933 ret = GST_STATE_NO_PREROLL;
937 /* if we get here, no NO_PREROLL elements are in the pipeline */
938 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "no NO_PREROLL elements");
940 /* if no ASYNC elements exist we don't even have to poll with a
943 ret = GST_STATE_SUCCESS;
948 /* next we poll all children for their state to see if one of them
949 * is still busy with its state change. We did not release the bin lock
950 * yet so the elements are the same as the ones from the quick scan. */
951 children = bin->children;
952 children_cookie = bin->children_cookie;
954 GstElement *child = GST_ELEMENT_CAST (children->data);
956 gst_object_ref (child);
957 /* now we release the lock to enter the potentialy blocking wait */
960 /* ret is ASYNC if some child is still performing the state change
961 * ater the timeout. */
962 ret = gst_element_get_state (child, NULL, NULL, timeout);
964 gst_object_unref (child);
966 /* now grab the lock to iterate to the next child */
968 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
969 /* child added/removed during state change, restart. We need
970 * to restart with the quick check as a no-preroll element could
971 * have been added here and we don't want to block on sinks then.*/
976 case GST_STATE_SUCCESS:
978 case GST_STATE_FAILURE:
979 case GST_STATE_NO_PREROLL:
980 /* report FAILURE and NO_PREROLL immediatly */
982 case GST_STATE_ASYNC:
985 g_assert_not_reached ();
987 children = g_list_next (children);
989 /* if we got here, all elements can do preroll */
990 have_no_preroll = FALSE;
995 /* now we can take the state lock, it is possible that new elements
996 * are added now and we still report the old state. No problem though as
997 * the return is still consistent, the effect is as if the element was
998 * added after this function completed. */
999 GST_STATE_LOCK (bin);
1001 case GST_STATE_SUCCESS:
1002 /* we can commit the state */
1003 gst_element_commit_state (element);
1005 case GST_STATE_FAILURE:
1006 /* some element failed, abort the state change */
1007 gst_element_abort_state (element);
1010 /* other cases are just passed along */
1014 /* and report the state if needed */
1016 *state = GST_STATE (element);
1018 *pending = GST_STATE_PENDING (element);
1020 GST_STATE_NO_PREROLL (element) = have_no_preroll;
1022 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1023 "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1024 gst_element_state_get_name (GST_STATE (element)),
1025 gst_element_state_get_name (GST_STATE_PENDING (element)),
1026 GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1028 GST_STATE_UNLOCK (bin);
1034 append_child (gpointer child, GQueue * queue)
1036 g_queue_push_tail (queue, child);
1040 * gst_bin_iterate_state_order:
1041 * @bin: #Gstbin to iterate on
1043 * Get an iterator for the elements in this bin in the order
1044 * in which a state change should be performed on them. This
1045 * means that first the sinks and then the other elements will
1047 * Each element will have its refcount increased, so unref
1050 * Not implemented yet.
1054 * Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
1057 gst_bin_iterate_state_order (GstBin * bin)
1059 GstIterator *result;
1061 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1069 clear_queue (GQueue * queue, gboolean unref)
1073 while ((p = g_queue_pop_head (queue)))
1075 gst_object_unref (p);
1079 remove_all_from_queue (GQueue * queue, gpointer elem, gboolean unref)
1083 while ((p = g_queue_find (queue, elem))) {
1085 gst_object_unref (elem);
1086 g_queue_delete_link (queue, p);
1090 /* this function is called with the STATE_LOCK held. It works
1093 * 1) put all sink elements on the queue.
1094 * 2) put all semisink elements on the queue.
1095 * 3) change state of elements in queue, put linked elements to queue.
1096 * 4) while queue not empty goto 3)
1098 * This will effectively change the state of all elements in the bin
1099 * from the sinks to the sources. We have to change the states this
1100 * way so that when a source element pushes data, the downstream element
1101 * is in the right state to receive the data.
1105 /* FIXME, make me more elegant, want to use a topological sort algorithm
1106 * based on indegrees (or outdegrees in our case) */
1107 static GstElementStateReturn
1108 gst_bin_change_state (GstElement * element)
1111 GstElementStateReturn ret;
1112 GstElementState old_state, pending;
1113 gboolean have_async = FALSE;
1114 gboolean have_no_preroll = FALSE;
1116 guint32 children_cookie;
1117 GQueue *elem_queue; /* list of elements waiting for a state change */
1118 GQueue *semi_queue; /* list of elements with no connected srcpads */
1119 GQueue *temp; /* queue of leftovers */
1120 GstClockTime base_time;
1122 bin = GST_BIN (element);
1124 /* we don't need to take the STATE_LOCK, it is already taken */
1125 old_state = GST_STATE (element);
1126 pending = GST_STATE_PENDING (element);
1128 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1129 "changing state of children from %s to %s",
1130 gst_element_state_get_name (old_state),
1131 gst_element_state_get_name (pending));
1133 if (pending == GST_STATE_VOID_PENDING)
1134 return GST_STATE_SUCCESS;
1136 /* Clear eosed element list on READY-> PAUSED */
1137 if (GST_STATE_TRANSITION (element) == GST_STATE_READY_TO_PAUSED) {
1138 g_list_free (bin->eosed);
1142 /* all elements added to these queues should have their refcount
1144 elem_queue = g_queue_new ();
1145 semi_queue = g_queue_new ();
1146 temp = g_queue_new ();
1148 /* first step, find all sink elements, these are the elements
1149 * without (linked) source pads. */
1153 /* take base time */
1154 base_time = element->base_time;
1156 /* make sure queues are empty, they could be filled when
1158 clear_queue (elem_queue, TRUE);
1159 clear_queue (semi_queue, TRUE);
1160 clear_queue (temp, TRUE);
1162 children = bin->children;
1163 children_cookie = bin->children_cookie;
1164 GST_DEBUG_OBJECT (bin, "reffing and examining children");
1166 GstElement *child = GST_ELEMENT_CAST (children->data);
1168 gst_object_ref (child);
1171 if (bin_element_is_sink (child, bin) == 0) {
1172 g_queue_push_tail (elem_queue, child);
1173 } else if (bin_element_is_semi_sink (child, bin) == 0) {
1174 g_queue_push_tail (semi_queue, child);
1176 g_queue_push_tail (temp, child);
1180 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
1181 GST_INFO_OBJECT (bin, "bin->children_cookie changed, restarting");
1182 /* restart will unref the children in the queues so that we don't
1183 * leak refcounts. */
1186 children = g_list_next (children);
1188 GST_DEBUG_OBJECT (bin, "reffed and examined children");
1191 /* after this point new elements can be added/removed from the
1192 * bin. We operate on the snapshot taken above. Applications
1193 * should serialize their add/remove and set_state. */
1195 /* now change state for semi sink elements first so add them in
1196 * front of the other elements */
1197 g_queue_foreach (temp, (GFunc) append_child, semi_queue);
1198 clear_queue (temp, FALSE);
1200 /* if we don't have real sinks, we continue with the other elements */
1201 if (g_queue_is_empty (elem_queue) && !g_queue_is_empty (semi_queue)) {
1202 GQueue *q = elem_queue;
1204 /* we swap the queues as oposed to copy them over */
1205 elem_queue = semi_queue;
1209 /* second step, change state of elements in the queue */
1210 GST_DEBUG_OBJECT (bin, "change state of elements in the queue");
1211 while (!g_queue_is_empty (elem_queue)) {
1212 GstElement *qelement;
1217 qelement = g_queue_pop_head (elem_queue);
1218 /* we don't need any duplicates in the other queue anymore */
1219 remove_all_from_queue (semi_queue, qelement, TRUE);
1221 /* queue all elements connected to the sinkpads of this element */
1222 GST_LOCK (qelement);
1223 pads = qelement->sinkpads;
1225 GstPad *pad = GST_PAD_CAST (pads->data);
1228 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1229 "found sinkpad %s:%s", GST_DEBUG_PAD_NAME (pad));
1231 peer = gst_pad_get_peer (pad);
1233 GstObject *peer_parent;
1236 peer_parent = gst_object_get_parent (GST_OBJECT (peer));
1238 /* if we have an element parent, follow it */
1239 if (peer_parent && GST_IS_ELEMENT (peer_parent)) {
1242 /* see if this element is in the bin we are currently handling */
1243 parent = gst_object_get_parent (peer_parent);
1245 if (parent == GST_OBJECT_CAST (bin)) {
1246 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1247 "adding element %s to queue", GST_ELEMENT_NAME (peer_parent));
1249 /* make sure we don't have duplicates */
1250 remove_all_from_queue (semi_queue, peer_parent, TRUE);
1251 remove_all_from_queue (elem_queue, peer_parent, TRUE);
1253 /* was reffed before pushing on the queue by the
1254 * gst_object_get_parent() call we used to get the element. */
1255 g_queue_push_tail (elem_queue, peer_parent);
1256 /* so that we don't unref it */
1259 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1260 "not adding element %s to queue, it is in another bin",
1261 GST_ELEMENT_NAME (peer_parent));
1263 gst_object_unref (parent);
1267 gst_object_unref (peer_parent);
1269 gst_object_unref (peer);
1271 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1272 "pad %s:%s does not have a peer", GST_DEBUG_PAD_NAME (pad));
1274 pads = g_list_next (pads);
1276 /* peel off the locked flag and release the element lock */
1277 locked = GST_FLAG_IS_SET (qelement, GST_ELEMENT_LOCKED_STATE);
1278 GST_UNLOCK (qelement);
1280 /* skip locked elements */
1281 if (G_UNLIKELY (locked))
1284 /* set base time on element */
1285 gst_element_set_base_time (qelement, base_time);
1287 /* then change state */
1288 ret = gst_element_set_state (qelement, pending);
1290 /* the set state could have cause elements to be added/removed,
1291 * we support that. */
1293 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
1294 gst_object_unref (qelement);
1300 case GST_STATE_SUCCESS:
1301 GST_CAT_DEBUG (GST_CAT_STATES,
1302 "child '%s' changed state to %d(%s) successfully",
1303 GST_ELEMENT_NAME (qelement), pending,
1304 gst_element_state_get_name (pending));
1306 case GST_STATE_ASYNC:
1307 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1308 "child '%s' is changing state asynchronously",
1309 GST_ELEMENT_NAME (qelement));
1312 case GST_STATE_FAILURE:
1313 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1314 "child '%s' failed to go to state %d(%s)",
1315 GST_ELEMENT_NAME (qelement),
1316 pending, gst_element_state_get_name (pending));
1317 ret = GST_STATE_FAILURE;
1318 /* release refcount of element we popped off the queue */
1319 gst_object_unref (qelement);
1321 case GST_STATE_NO_PREROLL:
1322 GST_CAT_DEBUG (GST_CAT_STATES,
1323 "child '%s' changed state to %d(%s) successfully without preroll",
1324 GST_ELEMENT_NAME (qelement), pending,
1325 gst_element_state_get_name (pending));
1326 have_no_preroll = TRUE;
1329 g_assert_not_reached ();
1333 gst_object_unref (qelement);
1335 /* if queue is empty now, continue with a non-sink */
1336 if (g_queue_is_empty (elem_queue)) {
1337 GstElement *non_sink;
1339 GST_DEBUG ("sinks and upstream elements exhausted");
1340 non_sink = g_queue_pop_head (semi_queue);
1342 GST_DEBUG ("found lefover non-sink %s", GST_OBJECT_NAME (non_sink));
1343 g_queue_push_tail (elem_queue, non_sink);
1348 if (have_no_preroll) {
1349 ret = GST_STATE_NO_PREROLL;
1350 } else if (have_async) {
1351 ret = GST_STATE_ASYNC;
1353 ret = parent_class->change_state (element);
1356 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1357 "done changing bin's state from %s to %s, now in %s, ret %d",
1358 gst_element_state_get_name (old_state),
1359 gst_element_state_get_name (pending),
1360 gst_element_state_get_name (GST_STATE (element)), ret);
1363 /* release refcounts in queue, should normally be empty unless we
1365 clear_queue (elem_queue, TRUE);
1366 clear_queue (semi_queue, TRUE);
1367 g_queue_free (elem_queue);
1368 g_queue_free (semi_queue);
1369 g_queue_free (temp);
1375 gst_bin_dispose (GObject * object)
1377 GstBin *bin = GST_BIN (object);
1379 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
1381 /* ref to not hit 0 again */
1382 gst_object_ref (object);
1384 g_list_free (bin->eosed);
1386 gst_object_unref (bin->child_bus);
1387 bin->child_bus = NULL;
1388 gst_element_set_bus (GST_ELEMENT (bin), NULL);
1390 while (bin->children) {
1391 gst_bin_remove (bin, GST_ELEMENT (bin->children->data));
1393 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose no children");
1394 g_assert (bin->children == NULL);
1395 g_assert (bin->numchildren == 0);
1397 G_OBJECT_CLASS (parent_class)->dispose (object);
1401 * This function is a utility event handler for seek events.
1402 * It will send the event to all sinks.
1403 * Applications are free to override this behaviour and
1404 * implement their own seek handler, but this will work for
1405 * pretty much all cases in practice.
1408 gst_bin_send_event (GstElement * element, GstEvent * event)
1410 GstBin *bin = GST_BIN (element);
1412 gboolean res = TRUE;
1413 gboolean done = FALSE;
1415 iter = gst_bin_iterate_sinks (bin);
1416 GST_DEBUG_OBJECT (bin, "Sending event to sink children");
1421 switch (gst_iterator_next (iter, &data)) {
1422 case GST_ITERATOR_OK:
1426 gst_event_ref (event);
1427 sink = GST_ELEMENT_CAST (data);
1428 res &= gst_element_send_event (sink, event);
1429 gst_object_unref (sink);
1432 case GST_ITERATOR_RESYNC:
1433 gst_iterator_resync (iter);
1437 case GST_ITERATOR_DONE:
1442 gst_iterator_free (iter);
1443 gst_event_unref (event);
1448 static GstBusSyncReply
1449 bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
1451 GST_DEBUG_OBJECT (bin, "[msg %p] handling child message of type %d",
1452 message, GST_MESSAGE_TYPE (message));
1454 switch (GST_MESSAGE_TYPE (message)) {
1455 case GST_MESSAGE_EOS:{
1456 gchar *name = gst_object_get_name (GST_MESSAGE_SRC (message));
1458 GST_DEBUG_OBJECT (bin, "got EOS message from %s", name);
1461 /* collect all eos messages from the children */
1462 GST_LOCK (bin->child_bus);
1463 bin->eosed = g_list_prepend (bin->eosed, GST_MESSAGE_SRC (message));
1464 GST_UNLOCK (bin->child_bus);
1466 /* if we are completely EOS, we forward an EOS message */
1468 GST_DEBUG_OBJECT (bin, "all sinks posted EOS");
1469 gst_element_post_message (GST_ELEMENT (bin),
1470 gst_message_new_eos (GST_OBJECT (bin)));
1473 /* we drop all EOS messages */
1474 gst_message_unref (message);
1478 /* Send all other messages upward */
1479 GST_DEBUG_OBJECT (bin, "posting message upward");
1480 gst_element_post_message (GST_ELEMENT (bin), message);
1484 return GST_BUS_DROP;
1488 gst_bin_query (GstElement * element, GstQuery * query)
1490 GstBin *bin = GST_BIN (element);
1492 gboolean res = FALSE, done = FALSE;
1494 iter = gst_bin_iterate_sinks (bin);
1495 GST_DEBUG_OBJECT (bin, "Sending event to sink children");
1497 while (!(res || done)) {
1500 switch (gst_iterator_next (iter, &data)) {
1501 case GST_ITERATOR_OK:
1505 sink = GST_ELEMENT_CAST (data);
1506 res = gst_element_query (sink, query);
1507 gst_object_unref (sink);
1510 case GST_ITERATOR_RESYNC:
1511 gst_iterator_resync (iter);
1514 case GST_ITERATOR_DONE:
1519 gst_iterator_free (iter);
1525 compare_name (GstElement * element, const gchar * name)
1530 eq = strcmp (GST_ELEMENT_NAME (element), name);
1531 GST_UNLOCK (element);
1534 gst_object_unref (element);
1540 * gst_bin_get_by_name:
1541 * @bin: #Gstbin to search
1542 * @name: the element name to search for
1544 * Get the element with the given name from this bin. This
1545 * function recurses into subbins.
1549 * Returns: the element with the given name. Returns NULL if the
1550 * element is not found or when bad parameters were given. Unref after
1554 gst_bin_get_by_name (GstBin * bin, const gchar * name)
1556 GstIterator *children;
1557 GstIterator *result;
1559 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1561 GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
1562 GST_ELEMENT_NAME (bin), name);
1564 children = gst_bin_iterate_recurse (bin);
1565 result = gst_iterator_find_custom (children,
1566 (GCompareFunc) compare_name, (gpointer) name);
1567 gst_iterator_free (children);
1569 return GST_ELEMENT_CAST (result);
1573 * gst_bin_get_by_name_recurse_up:
1574 * @bin: #Gstbin to search
1575 * @name: the element name to search for
1579 * Get the element with the given name from this bin. If the
1580 * element is not found, a recursion is performed on the parent bin.
1582 * Returns: the element with the given name or NULL when the element
1583 * was not found or bad parameters were given. Unref after use.
1586 gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
1590 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1591 g_return_val_if_fail (name != NULL, NULL);
1593 result = gst_bin_get_by_name (bin, name);
1598 parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
1600 if (GST_IS_BIN (parent)) {
1601 result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
1603 gst_object_unref (parent);
1611 compare_interface (GstElement * element, gpointer interface)
1615 if (G_TYPE_CHECK_INSTANCE_TYPE (element, GPOINTER_TO_INT (interface))) {
1618 /* we did not find the element, need to release the ref
1619 * added by the iterator */
1620 gst_object_unref (element);
1627 * gst_bin_get_by_interface:
1628 * @bin: bin to find element in
1629 * @interface: interface to be implemented by interface
1631 * Looks for the first element inside the bin that implements the given
1632 * interface. If such an element is found, it returns the element. You can
1633 * cast this element to the given interface afterwards.
1634 * If you want all elements that implement the interface, use
1635 * gst_bin_iterate_all_by_interface(). The function recurses inside bins.
1639 * Returns: An #GstElement inside the bin implementing the interface.
1643 gst_bin_get_by_interface (GstBin * bin, GType interface)
1645 GstIterator *children;
1646 GstIterator *result;
1648 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1650 children = gst_bin_iterate_recurse (bin);
1651 result = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
1652 GINT_TO_POINTER (interface));
1653 gst_iterator_free (children);
1655 return GST_ELEMENT_CAST (result);
1659 * gst_bin_get_all_by_interface:
1660 * @bin: bin to find elements in
1661 * @interface: interface to be implemented by interface
1663 * Looks for all elements inside the bin that implements the given
1664 * interface. You can safely cast all returned elements to the given interface.
1665 * The function recurses bins inside bins. The iterator will return a series
1666 * of #GstElement that should be unreffed after use.
1670 * Returns: A #GstIterator for the elements inside the bin implementing the
1674 gst_bin_iterate_all_by_interface (GstBin * bin, GType interface)
1676 GstIterator *children;
1677 GstIterator *result;
1679 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1681 children = gst_bin_iterate_recurse (bin);
1682 result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
1683 GINT_TO_POINTER (interface));
1688 #ifndef GST_DISABLE_LOADSAVE
1690 gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
1692 GstBin *bin = GST_BIN (object);
1693 xmlNodePtr childlist, elementnode;
1697 if (GST_OBJECT_CLASS (parent_class)->save_thyself)
1698 GST_OBJECT_CLASS (parent_class)->save_thyself (GST_OBJECT (bin), parent);
1700 childlist = xmlNewChild (parent, NULL, (xmlChar *) "children", NULL);
1702 GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
1703 GST_ELEMENT_NAME (bin), bin->numchildren);
1705 children = bin->children;
1707 child = GST_ELEMENT (children->data);
1708 elementnode = xmlNewChild (childlist, NULL, (xmlChar *) "element", NULL);
1709 gst_object_save_thyself (GST_OBJECT (child), elementnode);
1710 children = g_list_next (children);
1716 gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
1718 GstBin *bin = GST_BIN (object);
1719 xmlNodePtr field = self->xmlChildrenNode;
1720 xmlNodePtr childlist;
1723 if (!strcmp ((char *) field->name, "children")) {
1724 GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
1725 GST_ELEMENT_NAME (object));
1726 childlist = field->xmlChildrenNode;
1728 if (!strcmp ((char *) childlist->name, "element")) {
1729 GstElement *element =
1730 gst_xml_make_element (childlist, GST_OBJECT (bin));
1732 /* it had to be parented to find the pads, now we ref and unparent so
1733 * we can add it to the bin */
1734 gst_object_ref (element);
1735 gst_object_unparent (GST_OBJECT (element));
1737 gst_bin_add (bin, element);
1739 childlist = childlist->next;
1743 field = field->next;
1745 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
1746 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
1748 #endif /* GST_DISABLE_LOADSAVE */