/* GStreamer
*
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- * 2004 Wim Taymans <wim@fluendo.com>
+ * 2004 Wim Taymans <wim.taymans@gmail.com>
*
* gstbin.c: GstBin container object and support code
*
GST_ELEMENT_DETAILS ("Generic bin",
"Generic/Bin",
"Simple container object",
- "Erik Walthinsen <omega@cse.ogi.edu>," "Wim Taymans <wim@fluendo.com>");
+ "Erik Walthinsen <omega@cse.ogi.edu>,"
+ "Wim Taymans <wim.taymans@gmail.com>");
/* a bin is toplevel if it has no parent or when it is configured to behave like
* a toplevel bin */
LAST_SIGNAL
};
+#define DEFAULT_ASYNC_HANDLING FALSE
+
enum
{
PROP_0,
g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
g_param_spec_boolean ("async-handling", "Async Handling",
"The bin will handle Asynchronous state changes",
- FALSE, G_PARAM_READWRITE));
+ DEFAULT_ASYNC_HANDLING, G_PARAM_READWRITE));
/**
* GstBin::element-added:
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
bin->priv = g_new0 (GstBinPrivate, 1);
- bin->priv->asynchandling = FALSE;
+ bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
}
static void
bin->numchildren++;
bin->children_cookie++;
- ret = GST_STATE_RETURN (bin);
-
- /* no need to update the state if we are in error */
- if (ret == GST_STATE_CHANGE_FAILURE)
- goto no_state_recalc;
-
/* distribute the bus */
gst_element_set_bus (element, bin->child_bus);
* a new clock will be selected */
gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
+ ret = GST_STATE_RETURN (bin);
+ /* no need to update the state if we are in error */
+ if (ret == GST_STATE_CHANGE_FAILURE)
+ goto no_state_recalc;
+
/* update the bin state, the new element could have been an ASYNC or
* NO_PREROLL element */
ret = GST_STATE_RETURN (element);
}
already_removing:
{
+ GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "already removing child");
GST_OBJECT_UNLOCK (element);
return FALSE;
}
* the most downstream elements (sinks) to the sources.
*
* This function is used internally to perform the state changes
- * of the bin elements.
+ * of the bin elements and for clock selection.
*
* Each element yielded by the iterator will have its refcount increased, so
* unref after use.
}
}
+/* do latency correction. We do a latency query on the bin, and then send a
+ * LATENCY event on the elements fo configure them */
static gboolean
do_bin_latency (GstElement * element)
{
break;
}
+ /* this flag is used to make the async state changes return immediatly. We
+ * don't want them to interfere with this state change */
GST_OBJECT_LOCK (bin);
bin->polling = TRUE;
GST_OBJECT_UNLOCK (bin);
return res;
}
+/* this is the function called by the threadpool. When async elements commit
+ * their state, this function will attempt to bring the bin to the next state.
+ */
static void
gst_bin_continue_func (BinContinueData * data)
{
GST_DEBUG_OBJECT (bin, "doing state continue");
GST_OBJECT_LOCK (bin);
+ /* if a new state change happened after this thread was scheduled, we return
+ * immediatly. */
if (data->cookie != GST_ELEMENT_CAST (bin)->state_cookie)
goto interrupted;
return;
interrupted:
- GST_OBJECT_UNLOCK (bin);
- GST_STATE_UNLOCK (bin);
- GST_DEBUG_OBJECT (bin, "state continue aborted due to intervening change");
- gst_object_unref (bin);
- g_free (data);
+ {
+ GST_OBJECT_UNLOCK (bin);
+ GST_STATE_UNLOCK (bin);
+ GST_DEBUG_OBJECT (bin, "state continue aborted due to intervening change");
+ gst_object_unref (bin);
+ g_free (data);
+ return;
+ }
}
static GstBusSyncReply
gst_object_unref (item);
return TRUE;
}
+
static void
bin_query_latency_done (GstBin * bin, QueryFold * fold)
{
fold->live);
}
-
/* generic fold, return first valid result */
static gboolean
bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)