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 if ((peer = gst_pad_get_peer (GST_PAD_CAST (pads->data)))) {
783 has_ancestor (GST_OBJECT_CAST (peer), GST_OBJECT_CAST (bin));
784 gst_object_unref (peer);
791 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
792 "not adding child %s as sink: linked source pads",
793 GST_OBJECT_NAME (child));
795 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
796 "adding child %s as sink since it has unlinked source pads in this bin",
797 GST_OBJECT_NAME (child));
807 sink_iterator_filter (GstElement * child, GstBin * bin)
809 if (bin_element_is_sink (child, bin) == 0) {
810 /* returns 0 because this is a GCompareFunc */
813 /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
815 gst_object_unref ((GstObject *) child);
821 * gst_bin_iterate_sinks:
822 * @bin: #Gstbin to iterate on
824 * Get an iterator for the sink elements in this bin.
825 * Each element will have its refcount increased, so unref
828 * The sink elements are those without any linked srcpads.
832 * Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
835 gst_bin_iterate_sinks (GstBin * bin)
837 GstIterator *children;
840 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
842 children = gst_bin_iterate_elements (bin);
843 result = gst_iterator_filter (children,
844 (GCompareFunc) sink_iterator_filter, bin);
850 * 1) check state of all children with 0 timeout to find ERROR and
851 * NO_PREROLL elements. return if found.
852 * 2) perform full blocking wait with requested timeout.
854 * 2) cannot be performed when 1) returns results as the sinks might
855 * not be able to complete the state change making 2) block forever.
859 static GstElementStateReturn
860 gst_bin_get_state (GstElement * element, GstElementState * state,
861 GstElementState * pending, GTimeVal * timeout)
863 GstBin *bin = GST_BIN (element);
864 GstElementStateReturn ret = GST_STATE_SUCCESS;
866 guint32 children_cookie;
867 gboolean have_no_preroll;
869 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
871 /* lock bin, no element can be added or removed between going into
872 * the quick scan and the blocking wait. */
876 have_no_preroll = FALSE;
878 /* first we need to poll with a non zero timeout to make sure we don't block
879 * on the sinks when we have NO_PREROLL elements. This is why we do
880 * a quick check if there are still NO_PREROLL elements. We also
881 * catch the error elements this way. */
884 gboolean have_async = FALSE;
886 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "checking for NO_PREROLL");
887 /* use 0 timeout so we don't block on the sinks */
888 GST_TIME_TO_TIMEVAL (0, tv);
889 children = bin->children;
890 children_cookie = bin->children_cookie;
892 GstElement *child = GST_ELEMENT_CAST (children->data);
894 gst_object_ref (child);
895 /* now we release the lock to enter a non blocking wait. We
896 * release the lock anyway since we can. */
899 ret = gst_element_get_state (child, NULL, NULL, &tv);
901 gst_object_unref (child);
903 /* now grab the lock to iterate to the next child */
905 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
906 /* child added/removed during state change, restart. We need
907 * to restart with the quick check as a no-preroll element could
908 * have been added here and we don't want to block on sinks then.*/
913 /* report FAILURE immediatly */
914 case GST_STATE_FAILURE:
916 case GST_STATE_NO_PREROLL:
917 /* we have to continue scanning as there might be
919 have_no_preroll = TRUE;
921 case GST_STATE_ASYNC:
927 children = g_list_next (children);
929 /* if we get here, we have no FAILURES, check for any NO_PREROLL
931 if (have_no_preroll) {
932 ret = GST_STATE_NO_PREROLL;
936 /* if we get here, no NO_PREROLL elements are in the pipeline */
937 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "no NO_PREROLL elements");
939 /* if no ASYNC elements exist we don't even have to poll with a
942 ret = GST_STATE_SUCCESS;
947 /* next we poll all children for their state to see if one of them
948 * is still busy with its state change. We did not release the bin lock
949 * yet so the elements are the same as the ones from the quick scan. */
950 children = bin->children;
951 children_cookie = bin->children_cookie;
953 GstElement *child = GST_ELEMENT_CAST (children->data);
955 gst_object_ref (child);
956 /* now we release the lock to enter the potentialy blocking wait */
959 /* ret is ASYNC if some child is still performing the state change
960 * ater the timeout. */
961 ret = gst_element_get_state (child, NULL, NULL, timeout);
963 gst_object_unref (child);
965 /* now grab the lock to iterate to the next child */
967 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
968 /* child added/removed during state change, restart. We need
969 * to restart with the quick check as a no-preroll element could
970 * have been added here and we don't want to block on sinks then.*/
975 case GST_STATE_SUCCESS:
977 case GST_STATE_FAILURE:
978 case GST_STATE_NO_PREROLL:
979 /* report FAILURE and NO_PREROLL immediatly */
981 case GST_STATE_ASYNC:
984 g_assert_not_reached ();
986 children = g_list_next (children);
988 /* if we got here, all elements can do preroll */
989 have_no_preroll = FALSE;
994 /* now we can take the state lock, it is possible that new elements
995 * are added now and we still report the old state. No problem though as
996 * the return is still consistent, the effect is as if the element was
997 * added after this function completed. */
998 GST_STATE_LOCK (bin);
1000 case GST_STATE_SUCCESS:
1001 /* we can commit the state */
1002 gst_element_commit_state (element);
1004 case GST_STATE_FAILURE:
1005 /* some element failed, abort the state change */
1006 gst_element_abort_state (element);
1009 /* other cases are just passed along */
1013 /* and report the state if needed */
1015 *state = GST_STATE (element);
1017 *pending = GST_STATE_PENDING (element);
1019 GST_STATE_NO_PREROLL (element) = have_no_preroll;
1021 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1022 "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1023 gst_element_state_get_name (GST_STATE (element)),
1024 gst_element_state_get_name (GST_STATE_PENDING (element)),
1025 GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1027 GST_STATE_UNLOCK (bin);
1033 append_child (gpointer child, GQueue * queue)
1035 g_queue_push_tail (queue, child);
1039 * gst_bin_iterate_state_order:
1040 * @bin: #Gstbin to iterate on
1042 * Get an iterator for the elements in this bin in the order
1043 * in which a state change should be performed on them. This
1044 * means that first the sinks and then the other elements will
1046 * Each element will have its refcount increased, so unref
1049 * Not implemented yet.
1053 * Returns: a #GstIterator of #GstElements. gst_iterator_free after use.
1056 gst_bin_iterate_state_order (GstBin * bin)
1058 GstIterator *result;
1060 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1068 clear_queue (GQueue * queue, gboolean unref)
1072 while ((p = g_queue_pop_head (queue)))
1074 gst_object_unref (p);
1077 remove_all_from_queue (GQueue * queue, gpointer elem, gboolean unref)
1081 while ((p = g_queue_find (queue, elem))) {
1083 gst_object_unref (elem);
1084 g_queue_delete_link (queue, p);
1088 /* this function is called with the STATE_LOCK held. It works
1091 * 1) put all sink elements on the queue.
1092 * 2) put all semisink elements on the queue.
1093 * 3) change state of elements in queue, put linked elements to queue.
1094 * 4) while queue not empty goto 3)
1096 * This will effectively change the state of all elements in the bin
1097 * from the sinks to the sources. We have to change the states this
1098 * way so that when a source element pushes data, the downstream element
1099 * is in the right state to receive the data.
1103 /* FIXME, make me more elegant, want to use a topological sort algorithm
1104 * based on indegrees (or outdegrees in our case) */
1105 static GstElementStateReturn
1106 gst_bin_change_state (GstElement * element)
1109 GstElementStateReturn ret;
1110 GstElementState old_state, pending;
1111 gboolean have_async = FALSE;
1112 gboolean have_no_preroll = FALSE;
1114 guint32 children_cookie;
1115 GQueue *elem_queue; /* list of elements waiting for a state change */
1116 GQueue *semi_queue; /* list of elements with no connected srcpads */
1117 GQueue *temp; /* queue of leftovers */
1118 GstClockTime base_time;
1120 bin = GST_BIN (element);
1122 /* we don't need to take the STATE_LOCK, it is already taken */
1123 old_state = GST_STATE (element);
1124 pending = GST_STATE_PENDING (element);
1126 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1127 "changing state of children from %s to %s",
1128 gst_element_state_get_name (old_state),
1129 gst_element_state_get_name (pending));
1131 if (pending == GST_STATE_VOID_PENDING)
1132 return GST_STATE_SUCCESS;
1134 /* Clear eosed element list on READY-> PAUSED */
1135 if (GST_STATE_TRANSITION (element) == GST_STATE_READY_TO_PAUSED) {
1136 g_list_free (bin->eosed);
1140 /* all elements added to these queues should have their refcount
1142 elem_queue = g_queue_new ();
1143 semi_queue = g_queue_new ();
1144 temp = g_queue_new ();
1146 /* first step, find all sink elements, these are the elements
1147 * without (linked) source pads. */
1151 /* take base time */
1152 base_time = element->base_time;
1154 /* make sure queues are empty, they could be filled when
1156 clear_queue (elem_queue, TRUE);
1157 clear_queue (semi_queue, TRUE);
1158 clear_queue (temp, TRUE);
1160 children = bin->children;
1161 children_cookie = bin->children_cookie;
1163 GstElement *child = GST_ELEMENT_CAST (children->data);
1165 gst_object_ref (child);
1168 if (bin_element_is_sink (child, bin) == 0) {
1169 g_queue_push_tail (elem_queue, child);
1170 } else if (bin_element_is_semi_sink (child, bin) == 0) {
1171 g_queue_push_tail (semi_queue, child);
1173 g_queue_push_tail (temp, child);
1177 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
1178 /* FIXME: we reffed some children already, are we leaking refcounts
1180 GST_INFO_OBJECT (bin, "bin->children_cookie changed, restarting");
1183 children = g_list_next (children);
1186 /* after this point new elements can be added/removed from the
1187 * bin. We operate on the snapshot taken above. Applications
1188 * should serialize their add/remove and set_state. */
1190 /* now change state for semi sink elements first so add them in
1191 * front of the other elements */
1192 g_queue_foreach (temp, (GFunc) append_child, semi_queue);
1193 clear_queue (temp, FALSE);
1195 /* if we don't have real sinks, we continue with the other elements */
1196 if (g_queue_is_empty (elem_queue) && !g_queue_is_empty (semi_queue)) {
1197 GQueue *q = elem_queue;
1199 /* we swap the queues as oposed to copy them over */
1200 elem_queue = semi_queue;
1204 /* second step, change state of elements in the queue */
1205 while (!g_queue_is_empty (elem_queue)) {
1206 GstElement *qelement;
1211 qelement = g_queue_pop_head (elem_queue);
1212 /* we don't need any duplicates in the other queue anymore */
1213 remove_all_from_queue (semi_queue, qelement, TRUE);
1215 /* queue all elements connected to the sinkpads of this element */
1216 GST_LOCK (qelement);
1217 pads = qelement->sinkpads;
1219 GstPad *pad = GST_PAD_CAST (pads->data);
1222 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1223 "found sinkpad %s:%s", GST_DEBUG_PAD_NAME (pad));
1225 peer = gst_pad_get_peer (pad);
1227 GstObject *peer_parent;
1230 peer_parent = gst_object_get_parent (GST_OBJECT (peer));
1232 /* if we have an element parent, follow it */
1233 if (peer_parent && GST_IS_ELEMENT (peer_parent)) {
1236 /* see if this element is in the bin we are currently handling */
1237 parent = gst_object_get_parent (peer_parent);
1239 if (parent == GST_OBJECT_CAST (bin)) {
1240 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1241 "adding element %s to queue", GST_ELEMENT_NAME (peer_parent));
1243 /* make sure we don't have duplicates */
1244 remove_all_from_queue (semi_queue, peer_parent, TRUE);
1245 remove_all_from_queue (elem_queue, peer_parent, TRUE);
1247 /* was reffed before pushing on the queue by the
1248 * gst_object_get_parent() call we used to get the element. */
1249 g_queue_push_tail (elem_queue, peer_parent);
1250 /* so that we don't unref it */
1253 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1254 "not adding element %s to queue, it is in another bin",
1255 GST_ELEMENT_NAME (peer_parent));
1257 gst_object_unref (parent);
1261 gst_object_unref (peer_parent);
1263 gst_object_unref (peer);
1265 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1266 "pad %s:%s does not have a peer", GST_DEBUG_PAD_NAME (pad));
1268 pads = g_list_next (pads);
1270 /* peel off the locked flag and release the element lock */
1271 locked = GST_FLAG_IS_SET (qelement, GST_ELEMENT_LOCKED_STATE);
1272 GST_UNLOCK (qelement);
1274 /* skip locked elements */
1275 if (G_UNLIKELY (locked))
1278 /* set base time on element */
1279 gst_element_set_base_time (qelement, base_time);
1281 /* then change state */
1282 ret = gst_element_set_state (qelement, pending);
1284 /* the set state could have cause elements to be added/removed,
1285 * we support that. */
1287 if (G_UNLIKELY (children_cookie != bin->children_cookie)) {
1288 gst_object_unref (qelement);
1294 case GST_STATE_SUCCESS:
1295 GST_CAT_DEBUG (GST_CAT_STATES,
1296 "child '%s' changed state to %d(%s) successfully",
1297 GST_ELEMENT_NAME (qelement), pending,
1298 gst_element_state_get_name (pending));
1300 case GST_STATE_ASYNC:
1301 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1302 "child '%s' is changing state asynchronously",
1303 GST_ELEMENT_NAME (qelement));
1306 case GST_STATE_FAILURE:
1307 GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1308 "child '%s' failed to go to state %d(%s)",
1309 GST_ELEMENT_NAME (qelement),
1310 pending, gst_element_state_get_name (pending));
1311 ret = GST_STATE_FAILURE;
1312 /* release refcount of element we popped off the queue */
1313 gst_object_unref (qelement);
1315 case GST_STATE_NO_PREROLL:
1316 GST_CAT_DEBUG (GST_CAT_STATES,
1317 "child '%s' changed state to %d(%s) successfully without preroll",
1318 GST_ELEMENT_NAME (qelement), pending,
1319 gst_element_state_get_name (pending));
1320 have_no_preroll = TRUE;
1323 g_assert_not_reached ();
1327 gst_object_unref (qelement);
1329 /* if queue is empty now, continue with a non-sink */
1330 if (g_queue_is_empty (elem_queue)) {
1331 GstElement *non_sink;
1333 GST_DEBUG ("sinks and upstream elements exhausted");
1334 non_sink = g_queue_pop_head (semi_queue);
1336 GST_DEBUG ("found lefover non-sink %s", GST_OBJECT_NAME (non_sink));
1337 g_queue_push_tail (elem_queue, non_sink);
1342 if (have_no_preroll) {
1343 ret = GST_STATE_NO_PREROLL;
1344 } else if (have_async) {
1345 ret = GST_STATE_ASYNC;
1347 ret = parent_class->change_state (element);
1350 GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1351 "done changing bin's state from %s to %s, now in %s, ret %d",
1352 gst_element_state_get_name (old_state),
1353 gst_element_state_get_name (pending),
1354 gst_element_state_get_name (GST_STATE (element)), ret);
1357 /* release refcounts in queue, should normally be empty unless we
1359 clear_queue (elem_queue, TRUE);
1360 clear_queue (semi_queue, TRUE);
1361 g_queue_free (elem_queue);
1362 g_queue_free (semi_queue);
1363 g_queue_free (temp);
1369 gst_bin_dispose (GObject * object)
1371 GstBin *bin = GST_BIN (object);
1373 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
1375 /* ref to not hit 0 again */
1376 gst_object_ref (object);
1378 g_list_free (bin->eosed);
1380 gst_object_unref (bin->child_bus);
1381 bin->child_bus = NULL;
1382 gst_element_set_bus (GST_ELEMENT (bin), NULL);
1384 while (bin->children) {
1385 gst_bin_remove (bin, GST_ELEMENT (bin->children->data));
1387 GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose no children");
1388 g_assert (bin->children == NULL);
1389 g_assert (bin->numchildren == 0);
1391 G_OBJECT_CLASS (parent_class)->dispose (object);
1395 * This function is a utility event handler for seek events.
1396 * It will send the event to all sinks.
1397 * Applications are free to override this behaviour and
1398 * implement their own seek handler, but this will work for
1399 * pretty much all cases in practice.
1402 gst_bin_send_event (GstElement * element, GstEvent * event)
1404 GstBin *bin = GST_BIN (element);
1406 gboolean res = TRUE;
1407 gboolean done = FALSE;
1409 iter = gst_bin_iterate_sinks (bin);
1410 GST_DEBUG_OBJECT (bin, "Sending event to sink children");
1415 switch (gst_iterator_next (iter, &data)) {
1416 case GST_ITERATOR_OK:
1420 gst_event_ref (event);
1421 sink = GST_ELEMENT_CAST (data);
1422 res &= gst_element_send_event (sink, event);
1423 gst_object_unref (sink);
1426 case GST_ITERATOR_RESYNC:
1427 gst_iterator_resync (iter);
1431 case GST_ITERATOR_DONE:
1436 gst_iterator_free (iter);
1437 gst_event_unref (event);
1442 /* FIXME, make me threadsafe */
1443 static GstBusSyncReply
1444 bin_bus_handler (GstBus * bus, GstMessage * message, GstBin * bin)
1446 GST_DEBUG_OBJECT (bin, "[msg %p] handling child message of type %d",
1447 message, GST_MESSAGE_TYPE (message));
1448 /* we don't want messages from the streaming thread while we're doing the
1449 * state change. We do want them from the state change functions. */
1450 switch (GST_MESSAGE_TYPE (message)) {
1451 case GST_MESSAGE_EOS:{
1452 gchar *name = gst_object_get_name (GST_MESSAGE_SRC (message));
1454 GST_DEBUG_OBJECT (bin, "got EOS message from %s", name);
1457 GST_LOCK (bin->child_bus);
1458 bin->eosed = g_list_prepend (bin->eosed, GST_MESSAGE_SRC (message));
1459 GST_UNLOCK (bin->child_bus);
1462 GST_DEBUG_OBJECT (bin, "all sinks posted EOS");
1463 gst_bus_post (GST_ELEMENT (bin)->bus,
1464 gst_message_new_eos (GST_OBJECT (bin)));
1467 /* we drop all EOS messages */
1468 gst_message_unref (message);
1474 /* Send all other messages upward */
1476 if (!(bus = GST_ELEMENT (bin)->bus)) {
1477 GST_DEBUG_OBJECT (bin, "dropping message because no parent bus");
1480 gst_object_ref (bus);
1483 GST_DEBUG_OBJECT (bin, "posting message upward");
1484 gst_bus_post (GST_ELEMENT (bin)->bus, message);
1485 gst_object_unref (bus);
1491 return GST_BUS_DROP;
1495 gst_bin_query (GstElement * element, GstQuery * query)
1497 GstBin *bin = GST_BIN (element);
1499 gboolean res = FALSE, done = FALSE;
1501 iter = gst_bin_iterate_sinks (bin);
1502 GST_DEBUG_OBJECT (bin, "Sending event to sink children");
1504 while (!(res || done)) {
1507 switch (gst_iterator_next (iter, &data)) {
1508 case GST_ITERATOR_OK:
1512 sink = GST_ELEMENT_CAST (data);
1513 res = gst_element_query (sink, query);
1514 gst_object_unref (sink);
1517 case GST_ITERATOR_RESYNC:
1518 gst_iterator_resync (iter);
1521 case GST_ITERATOR_DONE:
1526 gst_iterator_free (iter);
1532 compare_name (GstElement * element, const gchar * name)
1537 eq = strcmp (GST_ELEMENT_NAME (element), name);
1538 GST_UNLOCK (element);
1541 gst_object_unref (element);
1547 * gst_bin_get_by_name:
1548 * @bin: #Gstbin to search
1549 * @name: the element name to search for
1551 * Get the element with the given name from this bin. This
1552 * function recurses into subbins.
1556 * Returns: the element with the given name. Returns NULL if the
1557 * element is not found or when bad parameters were given. Unref after
1561 gst_bin_get_by_name (GstBin * bin, const gchar * name)
1563 GstIterator *children;
1564 GstIterator *result;
1566 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1568 GST_CAT_INFO (GST_CAT_PARENTAGE, "[%s]: looking up child element %s",
1569 GST_ELEMENT_NAME (bin), name);
1571 children = gst_bin_iterate_recurse (bin);
1572 result = gst_iterator_find_custom (children,
1573 (GCompareFunc) compare_name, (gpointer) name);
1574 gst_iterator_free (children);
1576 return GST_ELEMENT_CAST (result);
1580 * gst_bin_get_by_name_recurse_up:
1581 * @bin: #Gstbin to search
1582 * @name: the element name to search for
1586 * Get the element with the given name from this bin. If the
1587 * element is not found, a recursion is performed on the parent bin.
1589 * Returns: the element with the given name or NULL when the element
1590 * was not found or bad parameters were given. Unref after use.
1593 gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
1597 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1598 g_return_val_if_fail (name != NULL, NULL);
1600 result = gst_bin_get_by_name (bin, name);
1605 parent = gst_object_get_parent (GST_OBJECT_CAST (bin));
1607 if (GST_IS_BIN (parent)) {
1608 result = gst_bin_get_by_name_recurse_up (GST_BIN_CAST (parent), name);
1610 gst_object_unref (parent);
1618 compare_interface (GstElement * element, gpointer interface)
1622 if (G_TYPE_CHECK_INSTANCE_TYPE (element, GPOINTER_TO_INT (interface))) {
1625 /* we did not find the element, need to release the ref
1626 * added by the iterator */
1627 gst_object_unref (element);
1634 * gst_bin_get_by_interface:
1635 * @bin: bin to find element in
1636 * @interface: interface to be implemented by interface
1638 * Looks for the first element inside the bin that implements the given
1639 * interface. If such an element is found, it returns the element. You can
1640 * cast this element to the given interface afterwards.
1641 * If you want all elements that implement the interface, use
1642 * gst_bin_iterate_all_by_interface(). The function recurses inside bins.
1646 * Returns: An #GstElement inside the bin implementing the interface.
1650 gst_bin_get_by_interface (GstBin * bin, GType interface)
1652 GstIterator *children;
1653 GstIterator *result;
1655 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1657 children = gst_bin_iterate_recurse (bin);
1658 result = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
1659 GINT_TO_POINTER (interface));
1660 gst_iterator_free (children);
1662 return GST_ELEMENT_CAST (result);
1666 * gst_bin_get_all_by_interface:
1667 * @bin: bin to find elements in
1668 * @interface: interface to be implemented by interface
1670 * Looks for all elements inside the bin that implements the given
1671 * interface. You can safely cast all returned elements to the given interface.
1672 * The function recurses bins inside bins. The iterator will return a series
1673 * of #GstElement that should be unreffed after use.
1677 * Returns: A #GstIterator for the elements inside the bin implementing the
1681 gst_bin_iterate_all_by_interface (GstBin * bin, GType interface)
1683 GstIterator *children;
1684 GstIterator *result;
1686 g_return_val_if_fail (GST_IS_BIN (bin), NULL);
1688 children = gst_bin_iterate_recurse (bin);
1689 result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
1690 GINT_TO_POINTER (interface));
1695 #ifndef GST_DISABLE_LOADSAVE
1697 gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
1699 GstBin *bin = GST_BIN (object);
1700 xmlNodePtr childlist, elementnode;
1704 if (GST_OBJECT_CLASS (parent_class)->save_thyself)
1705 GST_OBJECT_CLASS (parent_class)->save_thyself (GST_OBJECT (bin), parent);
1707 childlist = xmlNewChild (parent, NULL, (xmlChar *) "children", NULL);
1709 GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
1710 GST_ELEMENT_NAME (bin), bin->numchildren);
1712 children = bin->children;
1714 child = GST_ELEMENT (children->data);
1715 elementnode = xmlNewChild (childlist, NULL, (xmlChar *) "element", NULL);
1716 gst_object_save_thyself (GST_OBJECT (child), elementnode);
1717 children = g_list_next (children);
1723 gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
1725 GstBin *bin = GST_BIN (object);
1726 xmlNodePtr field = self->xmlChildrenNode;
1727 xmlNodePtr childlist;
1730 if (!strcmp ((char *) field->name, "children")) {
1731 GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
1732 GST_ELEMENT_NAME (object));
1733 childlist = field->xmlChildrenNode;
1735 if (!strcmp ((char *) childlist->name, "element")) {
1736 GstElement *element =
1737 gst_xml_make_element (childlist, GST_OBJECT (bin));
1739 /* it had to be parented to find the pads, now we ref and unparent so
1740 * we can add it to the bin */
1741 gst_object_ref (element);
1742 gst_object_unparent (GST_OBJECT (element));
1744 gst_bin_add (bin, element);
1746 childlist = childlist->next;
1750 field = field->next;
1752 if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
1753 (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
1755 #endif /* GST_DISABLE_LOADSAVE */