* </para>
* </refsect2>
*
- * Last reviewed on 2006-04-28 (0.10.6)
+ * Last reviewed on 2012-03-28 (0.11.3)
*/
-/* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
- * with newer GLib versions (>= 2.31.0) */
-#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "gst_private.h"
#include "gstevent.h"
#include "gstbin.h"
-#include "gstmarshal.h"
#include "gstinfo.h"
#include "gsterror.h"
-#include "gstindex.h"
-#include "gstindexfactory.h"
#include "gstutils.h"
#include "gstchildproxy.h"
-/* latency is by default enabled now.
- * live-preroll and no-live-preroll in the environment var GST_COMPAT
- * to enables or disable it respectively.
- */
-static gboolean enable_latency = TRUE;
-
GST_DEBUG_CATEGORY_STATIC (bin_debug);
#define GST_CAT_DEFAULT bin_debug
guint32 structure_cookie;
+#if 0
/* cached index */
GstIndex *index;
+#endif
+
/* forward messages from our children */
gboolean message_forward;
static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout);
static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
- gboolean flag_pending, gboolean reset_time);
+ gboolean flag_pending, GstClockTime running_time);
static void bin_handle_async_start (GstBin * bin);
static void bin_push_state_continue (BinContinueData * data);
static void bin_do_eos (GstBin * bin);
static gboolean gst_bin_add_func (GstBin * bin, GstElement * element);
static gboolean gst_bin_remove_func (GstBin * bin, GstElement * element);
+#if 0
static void gst_bin_set_index_func (GstElement * element, GstIndex * index);
static GstIndex *gst_bin_get_index_func (GstElement * element);
+#endif
static GstClock *gst_bin_provide_clock_func (GstElement * element);
static gboolean gst_bin_set_clock_func (GstElement * element, GstClock * clock);
#define _do_init \
{ \
- const gchar *compat; \
static const GInterfaceInfo iface_info = { \
gst_bin_child_proxy_init, \
NULL, \
GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, \
"debugging info for the 'bin' container element"); \
\
- /* compatibility stuff */ \
- compat = g_getenv ("GST_COMPAT"); \
- if (compat != NULL) { \
- if (strstr (compat, "no-live-preroll")) \
- enable_latency = FALSE; \
- else if (strstr (compat, "live-preroll")) \
- enable_latency = TRUE; \
- } \
}
#define gst_bin_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT, _do_init);
-static GstObject *
+static GObject *
gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
guint index)
{
gst_object_ref (res);
GST_OBJECT_UNLOCK (bin);
- return res;
+ return (GObject *) res;
}
static guint
gobject_class->get_property = gst_bin_get_property;
/**
- * GstBin:async-handling
+ * GstBin:async-handling:
*
* If set to #TRUE, the bin will handle asynchronous state changes.
* This should be used only if the bin subclass is modifying the state
* of its children on its own.
- *
- * Since: 0.10.13
*/
g_object_class_install_property (gobject_class, PROP_ASYNC_HANDLING,
g_param_spec_boolean ("async-handling", "Async Handling",
gst_bin_signals[ELEMENT_ADDED] =
g_signal_new ("element-added", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_added), NULL,
- NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+ NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
/**
* GstBin::element-removed:
* @bin: the #GstBin
gst_bin_signals[ELEMENT_REMOVED] =
g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL,
- NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
+ NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
/**
* GstBin::do-latency:
* @bin: the #GstBin
* Connect to this signal if the default latency calculations are not
* sufficient, like when you need different latencies for different sinks in
* the same pipeline.
- *
- * Since: 0.10.22
*/
gst_bin_signals[DO_LATENCY] =
g_signal_new ("do-latency", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstBinClass, do_latency),
- _gst_boolean_accumulator, NULL, gst_marshal_BOOLEAN__VOID,
+ _gst_boolean_accumulator, NULL, g_cclosure_marshal_generic,
G_TYPE_BOOLEAN, 0, G_TYPE_NONE);
/**
- * GstBin:message-forward
+ * GstBin:message-forward:
*
* Forward all children messages, even those that would normally be filtered by
* the bin. This can be interesting when one wants to be notified of the EOS
* source. The structure of the message is named 'GstBinForwarded' and contains
* a field named 'message' of type GST_TYPE_MESSAGE that contains the original
* forwarded message.
- *
- * Since: 0.10.31
*/
g_object_class_install_property (gobject_class, PROP_MESSAGE_FORWARD,
g_param_spec_boolean ("message-forward", "Message Forward",
GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
gstelement_class->state_changed = GST_DEBUG_FUNCPTR (gst_bin_state_changed);
gstelement_class->get_state = GST_DEBUG_FUNCPTR (gst_bin_get_state_func);
+#if 0
gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_bin_get_index_func);
gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_bin_set_index_func);
+#endif
gstelement_class->provide_clock =
GST_DEBUG_FUNCPTR (gst_bin_provide_clock_func);
gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_bin_set_clock_func);
bin->child_bus = bus;
GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
bus);
- gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
+ gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin,
+ NULL);
bin->priv = GST_BIN_GET_PRIVATE (bin);
bin->priv->asynchandling = DEFAULT_ASYNC_HANDLING;
GstBus **child_bus_p = &bin->child_bus;
GstClock **provided_clock_p = &bin->provided_clock;
GstElement **clock_provider_p = &bin->clock_provider;
- GstIndex **index_p = &bin->priv->index;
GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object, "dispose");
gst_object_replace ((GstObject **) child_bus_p, NULL);
gst_object_replace ((GstObject **) provided_clock_p, NULL);
gst_object_replace ((GstObject **) clock_provider_p, NULL);
- gst_object_replace ((GstObject **) index_p, NULL);
bin_remove_messages (bin, NULL, GST_MESSAGE_ANY);
GST_OBJECT_UNLOCK (object);
*
* Creates a new bin with the given name.
*
- * Returns: (transfer full): a new #GstBin
+ * Returns: (transfer floating): a new #GstBin
*/
GstElement *
gst_bin_new (const gchar * name)
}
}
+#if 0
/* return the cached index */
static GstIndex *
gst_bin_get_index_func (GstElement * element)
return;
}
}
+#endif
/* set the clock on all elements in this bin
*
return result && n_eos > 0;
}
+
+/* Check if the bin is STREAM_START. We do this by scanning all sinks and
+ * checking if they posted an STREAM_START message.
+ *
+ * call with bin LOCK */
+static gboolean
+is_stream_start (GstBin * bin, guint32 * seqnum)
+{
+ gboolean result;
+ gint n_stream_start = 0;
+ GList *walk, *msgs;
+
+ result = TRUE;
+ for (walk = bin->children; walk; walk = g_list_next (walk)) {
+ GstElement *element;
+
+ element = GST_ELEMENT_CAST (walk->data);
+ if (bin_element_is_sink (element, bin) == 0) {
+ /* check if element posted STREAM_START */
+ if ((msgs =
+ find_message (bin, GST_OBJECT_CAST (element),
+ GST_MESSAGE_STREAM_START))) {
+ GST_DEBUG ("sink '%s' posted STREAM_START", GST_ELEMENT_NAME (element));
+ *seqnum = gst_message_get_seqnum (GST_MESSAGE_CAST (msgs->data));
+ n_stream_start++;
+ } else {
+ GST_DEBUG ("sink '%s' did not post STREAM_START yet",
+ GST_ELEMENT_NAME (element));
+ result = FALSE;
+ break;
+ }
+ }
+ }
+
+ return result;
+}
+
static void
unlink_pads (const GValue * item, gpointer user_data)
{
* that is not important right now. When the pipeline goes to PLAYING,
* a new clock will be selected */
gst_element_set_clock (element, GST_ELEMENT_CLOCK (bin));
+
+#if 0
/* set the cached index on the children */
if (bin->priv->index)
gst_element_set_index (element, bin->priv->index);
+#endif
ret = GST_STATE_RETURN (bin);
/* no need to update the state if we are in error */
}
case GST_STATE_CHANGE_NO_PREROLL:
/* ignore all async elements we might have and commit our state */
- bin_handle_async_done (bin, ret, FALSE, FALSE);
+ bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
break;
case GST_STATE_CHANGE_FAILURE:
break;
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
elem_name);
- g_free (elem_name);
g_signal_emit (bin, gst_bin_signals[ELEMENT_ADDED], 0, element);
- gst_child_proxy_child_added ((GstObject *) bin, (GstObject *) element);
+ gst_child_proxy_child_added ((GstChildProxy *) bin, (GObject *) element,
+ elem_name);
+
+ g_free (elem_name);
return TRUE;
GST_DEBUG_OBJECT (bin, "element :%s", GST_ELEMENT_NAME (element));
+ GST_OBJECT_LOCK (bin);
+
GST_OBJECT_LOCK (element);
- /* Check if the element is already being removed and immediately
- * return */
- if (G_UNLIKELY (GST_OBJECT_FLAG_IS_SET (element,
- GST_ELEMENT_FLAG_UNPARENTING)))
- goto already_removing;
+ elem_name = g_strdup (GST_ELEMENT_NAME (element));
+
+ if (GST_OBJECT_PARENT (element) != GST_OBJECT_CAST (bin))
+ goto not_in_bin;
+
+ /* remove the parent ref */
+ GST_OBJECT_PARENT (element) = NULL;
- GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_UNPARENTING);
/* grab element name so we can print it */
- elem_name = g_strdup (GST_ELEMENT_NAME (element));
is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SOURCE);
provides_clock =
GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
GST_OBJECT_UNLOCK (element);
- /* unlink all linked pads */
- it = gst_element_iterate_pads (element);
- gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
- gst_iterator_free (it);
-
- GST_OBJECT_LOCK (bin);
found = FALSE;
othersink = FALSE;
othersource = FALSE;
else
ret = GST_STATE_CHANGE_SUCCESS;
- bin_handle_async_done (bin, ret, FALSE, FALSE);
+ bin_handle_async_done (bin, ret, FALSE, GST_CLOCK_TIME_NONE);
} else {
GST_DEBUG_OBJECT (bin,
"recalc state preroll: %d, other async: %d, this async %d",
GST_STATE_RETURN (bin) = ret;
}
no_state_recalc:
+ /* clear bus */
+ gst_element_set_bus (element, NULL);
+ /* Clear the clock we provided to the element */
+ gst_element_set_clock (element, NULL);
GST_OBJECT_UNLOCK (bin);
if (clock_message)
gst_element_post_message (GST_ELEMENT_CAST (bin), clock_message);
+ /* unlink all linked pads */
+ it = gst_element_iterate_pads (element);
+ gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
+ gst_iterator_free (it);
+
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
elem_name);
- g_free (elem_name);
-
- gst_element_set_bus (element, NULL);
-
- /* Clear the clock we provided to the element */
- gst_element_set_clock (element, NULL);
-
- /* we ref here because after the _unparent() the element can be disposed
- * and we still need it to reset the UNPARENTING flag and fire a signal. */
- gst_object_ref (element);
- gst_object_unparent (GST_OBJECT_CAST (element));
-
- GST_OBJECT_LOCK (element);
- GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_UNPARENTING);
- GST_OBJECT_UNLOCK (element);
g_signal_emit (bin, gst_bin_signals[ELEMENT_REMOVED], 0, element);
- gst_child_proxy_child_removed ((GstObject *) bin, (GstObject *) element);
+ gst_child_proxy_child_removed ((GstChildProxy *) bin, (GObject *) element,
+ elem_name);
+ g_free (elem_name);
/* element is really out of our control now */
gst_object_unref (element);
{
g_warning ("Element '%s' is not in bin '%s'", elem_name,
GST_ELEMENT_NAME (bin));
+ GST_OBJECT_UNLOCK (element);
GST_OBJECT_UNLOCK (bin);
g_free (elem_name);
return FALSE;
}
-already_removing:
- {
- GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "already removing child");
- GST_OBJECT_UNLOCK (element);
- return FALSE;
- }
}
/**
GstState next)
{
GstStateChangeReturn ret;
- GstState pending, child_current, child_pending;
+ GstState child_current, child_pending;
gboolean locked;
GList *found;
goto no_preroll;
}
- GST_OBJECT_LOCK (bin);
- pending = GST_STATE_PENDING (bin);
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
+ "current %s pending %s, desired next %s",
+ gst_element_state_get_name (child_current),
+ gst_element_state_get_name (child_pending),
+ gst_element_state_get_name (next));
+
+ /* always recurse into bins so that we can set the base time */
+ if (GST_IS_BIN (element))
+ goto do_state;
/* Try not to change the state of elements that are already in the state we're
* going to */
- if (!(next == GST_STATE_PLAYING || child_pending != GST_STATE_VOID_PENDING ||
- (child_pending == GST_STATE_VOID_PENDING &&
- ((pending > child_current && next > child_current) ||
- (pending < child_current && next < child_current)))))
+ if (child_current == next && child_pending == GST_STATE_VOID_PENDING) {
+ /* child is already at the requested state, return previous return. Note that
+ * if the child has a pending state to next, we will still call the
+ * set_state function */
goto unneeded;
+ } else if (next > current) {
+ /* upward state change */
+ if (child_pending == GST_STATE_VOID_PENDING) {
+ /* .. and the child is not busy doing anything */
+ if (child_current > next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else if (child_pending > child_current) {
+ /* .. and the child is busy going upwards */
+ if (child_current >= next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else {
+ /* .. and the child is busy going downwards */
+ if (child_current > next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ }
+ } else if (next < current) {
+ /* downward state change */
+ if (child_pending == GST_STATE_VOID_PENDING) {
+ /* .. and the child is not busy doing anything */
+ if (child_current < next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else if (child_pending < child_current) {
+ /* .. and the child is busy going downwards */
+ if (child_current <= next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ } else {
+ /* .. and the child is busy going upwards */
+ if (child_current < next) {
+ /* .. and is already past the requested state, assume it got there
+ * without error */
+ ret = GST_STATE_CHANGE_SUCCESS;
+ goto unneeded;
+ }
+ }
+ }
+do_state:
+ GST_OBJECT_LOCK (bin);
/* the element was busy with an upwards async state change, we must wait for
* an ASYNC_DONE message before we attemp to change the state. */
if ((found =
if (next > current) {
/* We found an async element check if we can force its state to change or
* if we have to wait for it to preroll. */
- if (G_UNLIKELY (!enable_latency)) {
- g_warning ("Future versions of GStreamer will wait for element \"%s\"\n"
- "\tto preroll in order to perform correct latency calculations.\n"
- "\tPlease verify that the application continues to work correctly by\n"
- "\tsetting the environment variable GST_COMPAT to a value containing\n"
- "\tthe string 'live-preroll'.", GST_ELEMENT_NAME (element));
- goto no_latency;
- }
goto was_busy;
}
}
-no_latency:
GST_OBJECT_UNLOCK (bin);
no_preroll:
GST_STATE_UNLOCK (element);
return ret;
}
-was_busy:
- {
- GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
- GST_OBJECT_UNLOCK (bin);
- GST_STATE_UNLOCK (element);
- return GST_STATE_CHANGE_ASYNC;
- }
unneeded:
{
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "skipping transition from %s to %s, since bin pending"
- " is %s : last change state return follows",
+ "skipping transition from %s to %s",
gst_element_state_get_name (child_current),
- gst_element_state_get_name (next),
- gst_element_state_get_name (pending));
- GST_OBJECT_UNLOCK (bin);
+ gst_element_state_get_name (next));
GST_STATE_UNLOCK (element);
return ret;
}
+was_busy:
+ {
+ GST_DEBUG_OBJECT (element, "element was busy, delaying state change");
+ GST_OBJECT_UNLOCK (bin);
+ GST_STATE_UNLOCK (element);
+ return GST_STATE_CHANGE_ASYNC;
+ }
}
/* gst_iterator_fold functions for pads_activate
GstIterator *iter;
gboolean fold_ok;
- GST_DEBUG_OBJECT (bin, "src_pads_activate with active %d", active);
+ GST_DEBUG_OBJECT (bin, "%s pads", active ? "activate" : "deactivate");
iter = gst_element_iterate_src_pads ((GstElement *) bin);
fold_ok = iterator_activate_fold_with_resync (iter, &active);
if (G_UNLIKELY (!fold_ok))
goto failed;
- GST_DEBUG_OBJECT (bin, "pads_activate successful");
+ GST_DEBUG_OBJECT (bin, "pad %sactivation successful", active ? "" : "de");
return TRUE;
/* ERRORS */
failed:
{
- GST_DEBUG_OBJECT (bin, "source pads_activate failed");
+ GST_DEBUG_OBJECT (bin, "pad %sactivation failed", active ? "" : "de");
return FALSE;
}
}
* calculations will be performed.
*
* Returns: %TRUE if the latency could be queried and reconfigured.
- *
- * Since: 0.10.22.
*/
gboolean
gst_bin_recalculate_latency (GstBin * bin)
GST_DEBUG_OBJECT (element, "clearing EOS elements");
bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
bin->priv->posted_eos = FALSE;
+ if (current == GST_STATE_READY)
+ bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
GST_OBJECT_UNLOCK (bin);
if (current == GST_STATE_READY)
if (!(gst_bin_src_pads_activate (bin, TRUE)))
bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
GST_DEBUG_OBJECT (bin, "async elements commited");
- bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE, FALSE);
+ bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE,
+ GST_CLOCK_TIME_NONE);
}
state_end:
*/
static void
bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
- gboolean flag_pending, gboolean reset_time)
+ gboolean flag_pending, GstClockTime running_time)
{
GstState current, pending, target;
GstStateChangeReturn old_ret;
target = GST_STATE_TARGET (bin);
pending = GST_STATE_PENDING (bin) = target;
- amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin), reset_time);
+ amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin), running_time);
old_state = GST_STATE (bin);
/* this is the state we should go to next */
&& g_atomic_int_compare_and_exchange (&bin->priv->posted_eos, FALSE,
TRUE)) {
GstMessage *tmessage;
+
+ /* Clear out any further messages, and reset posted_eos so we can
+ detect any new EOS that happens (eg, after a seek). Since all
+ sinks have now posted an EOS, there will be no further EOS events
+ seen unless there is a new logical EOS */
+ GST_OBJECT_LOCK (bin);
+ bin_remove_messages (bin, NULL, GST_MESSAGE_EOS);
+ bin->priv->posted_eos = FALSE;
+ GST_OBJECT_UNLOCK (bin);
+
tmessage = gst_message_new_eos (GST_OBJECT_CAST (bin));
gst_message_set_seqnum (tmessage, seqnum);
GST_DEBUG_OBJECT (bin,
}
}
+static void
+bin_do_stream_start (GstBin * bin)
+{
+ guint32 seqnum = 0;
+ gboolean stream_start;
+
+ GST_OBJECT_LOCK (bin);
+ /* If all sinks are STREAM_START we forward the STREAM_START message
+ * to the parent bin or application
+ */
+ stream_start = is_stream_start (bin, &seqnum);
+ GST_OBJECT_UNLOCK (bin);
+
+ if (stream_start) {
+ GstMessage *tmessage;
+
+ GST_OBJECT_LOCK (bin);
+ bin_remove_messages (bin, NULL, GST_MESSAGE_STREAM_START);
+ GST_OBJECT_UNLOCK (bin);
+
+ tmessage = gst_message_new_stream_start (GST_OBJECT_CAST (bin));
+ gst_message_set_seqnum (tmessage, seqnum);
+ GST_DEBUG_OBJECT (bin,
+ "all sinks posted STREAM_START, posting seqnum #%" G_GUINT32_FORMAT,
+ seqnum);
+ gst_element_post_message (GST_ELEMENT_CAST (bin), tmessage);
+ }
+}
+
/* must be called with the object lock. This function releases the lock to post
* the message. */
static void
bin_do_eos (bin);
break;
}
+ case GST_MESSAGE_STREAM_START:
+ {
+
+ /* collect all stream_start messages from the children */
+ GST_OBJECT_LOCK (bin);
+ /* ref message for future use */
+ bin_replace_message (bin, message, GST_MESSAGE_STREAM_START);
+ GST_OBJECT_UNLOCK (bin);
+
+ bin_do_stream_start (bin);
+ break;
+ }
case GST_MESSAGE_STATE_DIRTY:
{
GST_WARNING_OBJECT (bin, "received deprecated STATE_DIRTY message");
}
case GST_MESSAGE_ASYNC_DONE:
{
- gboolean reset_time;
+ GstClockTime running_time;
GstState target;
GST_DEBUG_OBJECT (bin, "ASYNC_DONE message %p, %s", message,
src ? GST_OBJECT_NAME (src) : "(NULL)");
- gst_message_parse_async_done (message, &reset_time);
+ gst_message_parse_async_done (message, &running_time);
GST_OBJECT_LOCK (bin);
bin_do_message_forward (bin, message);
* need to set the pending_done flag so that at the end of the state
* change we can see if we need to verify pending async elements, hence
* the TRUE argument here. */
- bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE, reset_time);
+ bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE,
+ running_time);
} else {
GST_DEBUG_OBJECT (bin, "there are more async elements pending");
}