aboutsummaryrefslogtreecommitdiff
path: root/gst/gstbin.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/gstbin.c')
-rw-r--r--gst/gstbin.c196
1 files changed, 114 insertions, 82 deletions
diff --git a/gst/gstbin.c b/gst/gstbin.c
index 1eebc0f..665259e 100644
--- a/gst/gstbin.c
+++ b/gst/gstbin.c
@@ -154,28 +154,19 @@
* </para>
* </refsect2>
*
- * Last reviewed on 2006-04-28 (0.10.6)
+ * Last reviewed on 2012-03-28 (0.11.3)
*/
#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
@@ -198,8 +189,11 @@ struct _GstBinPrivate
guint32 structure_cookie;
+#if 0
/* cached index */
GstIndex *index;
+#endif
+
/* forward messages from our children */
gboolean message_forward;
@@ -235,8 +229,10 @@ 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);
@@ -283,7 +279,6 @@ static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
#define _do_init \
{ \
- const gchar *compat; \
static const GInterfaceInfo iface_info = { \
gst_bin_child_proxy_init, \
NULL, \
@@ -294,20 +289,12 @@ static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
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)
{
@@ -321,7 +308,7 @@ gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
gst_object_ref (res);
GST_OBJECT_UNLOCK (bin);
- return res;
+ return (GObject *) res;
}
static guint
@@ -403,7 +390,7 @@ gst_bin_class_init (GstBinClass * klass)
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
@@ -414,7 +401,7 @@ gst_bin_class_init (GstBinClass * klass)
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
@@ -436,7 +423,7 @@ gst_bin_class_init (GstBinClass * klass)
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);
/**
@@ -470,8 +457,10 @@ gst_bin_class_init (GstBinClass * klass)
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);
@@ -526,7 +515,6 @@ gst_bin_dispose (GObject * object)
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");
@@ -534,7 +522,6 @@ gst_bin_dispose (GObject * object)
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);
@@ -555,7 +542,7 @@ gst_bin_dispose (GObject * 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)
@@ -613,6 +600,7 @@ gst_bin_get_property (GObject * object, guint prop_id,
}
}
+#if 0
/* return the cached index */
static GstIndex *
gst_bin_get_index_func (GstElement * element)
@@ -696,6 +684,7 @@ was_set:
return;
}
}
+#endif
/* set the clock on all elements in this bin
*
@@ -741,6 +730,9 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
g_value_unset (&data);
gst_iterator_free (it);
+ if (res)
+ res = GST_ELEMENT_CLASS (parent_class)->set_clock (element, clock);
+
return res;
}
@@ -1042,7 +1034,7 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
{
gchar *elem_name;
GstIterator *it;
- gboolean is_sink, is_source;
+ gboolean is_sink, is_source, provides_clock, requires_clock;
GstMessage *clock_message = NULL, *async_message = NULL;
GstStateChangeReturn ret;
@@ -1055,8 +1047,12 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
/* get the element name to make sure it is unique in this bin. */
GST_OBJECT_LOCK (element);
elem_name = g_strdup (GST_ELEMENT_NAME (element));
- is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
- is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SOURCE);
+ 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_PROVIDE_CLOCK);
+ requires_clock =
+ GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
GST_OBJECT_UNLOCK (element);
GST_OBJECT_LOCK (bin);
@@ -1077,17 +1073,22 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
if (is_sink) {
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was sink",
elem_name);
- GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SINK);
+ GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SINK);
}
if (is_source) {
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "element \"%s\" was source",
elem_name);
- GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_IS_SOURCE);
+ GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_SOURCE);
}
- if (gst_element_provides_clock (element)) {
+ if (provides_clock) {
GST_DEBUG_OBJECT (bin, "element \"%s\" can provide a clock", elem_name);
clock_message =
gst_message_new_clock_provide (GST_OBJECT_CAST (element), NULL, TRUE);
+ GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
+ }
+ if (requires_clock) {
+ GST_DEBUG_OBJECT (bin, "element \"%s\" requires a clock", elem_name);
+ GST_OBJECT_FLAG_SET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
}
bin->children = g_list_prepend (bin->children, element);
@@ -1105,9 +1106,12 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
* 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 */
@@ -1156,10 +1160,11 @@ no_state_recalc:
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 ((GObject *) bin, (GObject *) element, elem_name);
+
+ g_free (elem_name);
return TRUE;
@@ -1252,7 +1257,8 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
{
gchar *elem_name;
GstIterator *it;
- gboolean is_sink, is_source, othersink, othersource, found;
+ gboolean is_sink, is_source, provides_clock, requires_clock;
+ gboolean othersink, othersource, otherprovider, otherrequirer, found;
GstMessage *clock_message = NULL;
GstClock **provided_clock_p;
GstElement **clock_provider_p;
@@ -1265,14 +1271,19 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
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_UNPARENTING)))
+ if (G_UNLIKELY (GST_OBJECT_FLAG_IS_SET (element,
+ GST_ELEMENT_FLAG_UNPARENTING)))
goto already_removing;
- GST_OBJECT_FLAG_SET (element, GST_ELEMENT_UNPARENTING);
+ 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_IS_SINK);
- is_source = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SOURCE);
+ 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_PROVIDE_CLOCK);
+ requires_clock =
+ GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
GST_OBJECT_UNLOCK (element);
/* unlink all linked pads */
@@ -1284,6 +1295,8 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
found = FALSE;
othersink = FALSE;
othersource = FALSE;
+ otherprovider = FALSE;
+ otherrequirer = FALSE;
have_no_preroll = FALSE;
/* iterate the elements, we collect which ones are async and no_preroll. We
* also remove the element when we find it. */
@@ -1297,16 +1310,24 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
/* remove the element */
bin->children = g_list_delete_link (bin->children, walk);
} else {
- gboolean child_sink, child_source;
+ gboolean child_sink, child_source, child_provider, child_requirer;
GST_OBJECT_LOCK (child);
- child_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK);
- child_source = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SOURCE);
+ child_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);
+ child_source = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);
+ child_provider =
+ GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
+ child_requirer =
+ GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
/* when we remove a sink, check if there are other sinks. */
if (is_sink && !othersink && child_sink)
othersink = TRUE;
if (is_source && !othersource && child_source)
othersource = TRUE;
+ if (provides_clock && !otherprovider && child_provider)
+ otherprovider = TRUE;
+ if (requires_clock && !otherrequirer && child_requirer)
+ otherrequirer = TRUE;
/* check if we have NO_PREROLL children */
if (GST_STATE_RETURN (child) == GST_STATE_CHANGE_NO_PREROLL)
have_no_preroll = TRUE;
@@ -1327,14 +1348,23 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
if (is_sink && !othersink) {
/* we're not a sink anymore */
GST_DEBUG_OBJECT (bin, "we removed the last sink");
- GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_IS_SINK);
+ GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SINK);
}
if (is_source && !othersource) {
/* we're not a source anymore */
GST_DEBUG_OBJECT (bin, "we removed the last source");
- GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_IS_SOURCE);
+ GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_SOURCE);
+ }
+ if (provides_clock && !otherprovider) {
+ /* we're not a clock provider anymore */
+ GST_DEBUG_OBJECT (bin, "we removed the last clock provider");
+ GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_PROVIDE_CLOCK);
+ }
+ if (requires_clock && !otherrequirer) {
+ /* we're not a clock requirer anymore */
+ GST_DEBUG_OBJECT (bin, "we removed the last clock requirer");
+ GST_OBJECT_FLAG_UNSET (bin, GST_ELEMENT_FLAG_REQUIRE_CLOCK);
}
-
/* if the clock provider for this element is removed, we lost
* the clock as well, we need to inform the parent of this
@@ -1451,7 +1481,6 @@ no_state_recalc:
GST_CAT_INFO_OBJECT (GST_CAT_PARENTAGE, bin, "removed child \"%s\"",
elem_name);
- g_free (elem_name);
gst_element_set_bus (element, NULL);
@@ -1464,12 +1493,14 @@ no_state_recalc:
gst_object_unparent (GST_OBJECT_CAST (element));
GST_OBJECT_LOCK (element);
- GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_UNPARENTING);
+ 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 ((GObject *) bin, (GObject *) element,
+ elem_name);
+ g_free (elem_name);
/* element is really out of our control now */
gst_object_unref (element);
@@ -1626,7 +1657,7 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
/* we lock the child here for the remainder of the function to
* get its name and flag safely. */
GST_OBJECT_LOCK (child);
- is_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SINK);
+ is_sink = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SINK);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"child %s %s sink", GST_OBJECT_NAME (child), is_sink ? "is" : "is not");
@@ -1649,7 +1680,7 @@ sink_iterator_filter (const GValue * vchild, GValue * vbin)
* @bin: a #GstBin
*
* Gets an iterator for all elements in the bin that have the
- * #GST_ELEMENT_IS_SINK flag set.
+ * #GST_ELEMENT_FLAG_SINK flag set.
*
* Each element yielded by the iterator will have its refcount increased, so
* unref after use.
@@ -1689,7 +1720,7 @@ bin_element_is_src (GstElement * child, GstBin * bin)
/* we lock the child here for the remainder of the function to
* get its name and other info safely. */
GST_OBJECT_LOCK (child);
- is_src = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_IS_SOURCE);
+ is_src = GST_OBJECT_FLAG_IS_SET (child, GST_ELEMENT_FLAG_SOURCE);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"child %s %s src", GST_OBJECT_NAME (child), is_src ? "is" : "is not");
@@ -1712,7 +1743,7 @@ src_iterator_filter (const GValue * vchild, GValue * vbin)
* @bin: a #GstBin
*
* Gets an iterator for all elements in the bin that have the
- * #GST_ELEMENT_IS_SOURCE flag set.
+ * #GST_ELEMENT_FLAG_SOURCE flag set.
*
* Each element yielded by the iterator will have its refcount increased, so
* unref after use.
@@ -1775,7 +1806,7 @@ gst_bin_get_state_func (GstElement * element, GstState * state,
typedef struct _GstBinSortIterator
{
GstIterator it;
- GQueue *queue; /* elements queued for state change */
+ GQueue queue; /* elements queued for state change */
GstBin *bin; /* bin we iterate */
gint mode; /* adding or removing dependency */
GstElement *best; /* next element with least dependencies */
@@ -1791,8 +1822,8 @@ gst_bin_sort_iterator_copy (const GstBinSortIterator * it,
GHashTableIter iter;
gpointer key, value;
- copy->queue = g_queue_copy (it->queue);
- g_queue_foreach (copy->queue, (GFunc) gst_object_ref, NULL);
+ copy->queue = it->queue;
+ g_queue_foreach (&copy->queue, (GFunc) gst_object_ref, NULL);
copy->bin = gst_object_ref (it->bin);
if (it->best)
@@ -1819,7 +1850,7 @@ add_to_queue (GstBinSortIterator * bit, GstElement * element)
GST_DEBUG_OBJECT (bit->bin, "adding '%s' to queue",
GST_ELEMENT_NAME (element));
gst_object_ref (element);
- g_queue_push_tail (bit->queue, element);
+ g_queue_push_tail (&bit->queue, element);
HASH_SET_DEGREE (bit, element, -1);
}
@@ -1828,11 +1859,11 @@ remove_from_queue (GstBinSortIterator * bit, GstElement * element)
{
GList *find;
- if ((find = g_queue_find (bit->queue, element))) {
+ if ((find = g_queue_find (&bit->queue, element))) {
GST_DEBUG_OBJECT (bit->bin, "removing '%s' from queue",
GST_ELEMENT_NAME (element));
- g_queue_delete_link (bit->queue, find);
+ g_queue_delete_link (&bit->queue, find);
gst_object_unref (element);
} else {
GST_DEBUG_OBJECT (bit->bin, "unable to remove '%s' from queue",
@@ -1863,7 +1894,7 @@ reset_degree (GstElement * element, GstBinSortIterator * bit)
/* sinks are added right away */
GST_OBJECT_LOCK (element);
- is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_IS_SINK);
+ is_sink = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_FLAG_SINK);
GST_OBJECT_UNLOCK (element);
if (is_sink) {
@@ -1989,8 +2020,7 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, GValue * result)
GstBin *bin = bit->bin;
/* empty queue, we have to find a next best element */
- if (g_queue_is_empty (bit->queue)) {
-
+ if (g_queue_is_empty (&bit->queue)) {
bit->best = NULL;
bit->best_deg = G_MAXINT;
g_list_foreach (bin->children, (GFunc) find_element, bit);
@@ -2015,7 +2045,7 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, GValue * result)
}
} else {
/* everything added to the queue got reffed */
- best = g_queue_pop_head (bit->queue);
+ best = g_queue_pop_head (&bit->queue);
g_value_set_object (result, best);
gst_object_unref (best);
}
@@ -2035,7 +2065,7 @@ gst_bin_sort_iterator_resync (GstBinSortIterator * bit)
GST_DEBUG_OBJECT (bin, "resync");
bit->dirty = FALSE;
- clear_queue (bit->queue);
+ clear_queue (&bit->queue);
/* reset degrees */
g_list_foreach (bin->children, (GFunc) reset_degree, bit);
/* calc degrees, incrementing */
@@ -2052,8 +2082,7 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
GstBin *bin = bit->bin;
GST_DEBUG_OBJECT (bin, "free");
- clear_queue (bit->queue);
- g_queue_free (bit->queue);
+ clear_queue (&bit->queue);
g_hash_table_destroy (bit->hash);
gst_object_unref (bin);
}
@@ -2076,7 +2105,7 @@ gst_bin_sort_iterator_new (GstBin * bin)
(GstIteratorItemFunction) NULL,
(GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
(GstIteratorFreeFunction) gst_bin_sort_iterator_free);
- result->queue = g_queue_new ();
+ g_queue_init (&result->queue);
result->hash = g_hash_table_new (NULL, NULL);
gst_object_ref (bin);
result->bin = bin;
@@ -2134,7 +2163,7 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
GST_ELEMENT_START_TIME (element) = start_time;
element->base_time = base_time;
/* peel off the locked flag */
- locked = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
+ locked = GST_ELEMENT_IS_LOCKED_STATE (element);
/* Get the previous set_state result to preserve NO_PREROLL and ASYNC */
ret = GST_STATE_RETURN (element);
child_current = GST_STATE (element);
@@ -2179,18 +2208,9 @@ gst_bin_element_set_state (GstBin * bin, GstElement * element,
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:
@@ -2567,12 +2587,12 @@ restart:
break;
}
case GST_ITERATOR_RESYNC:
- GST_CAT_DEBUG (GST_CAT_STATES, "iterator doing resync");
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator doing resync");
gst_iterator_resync (it);
goto restart;
default:
case GST_ITERATOR_DONE:
- GST_CAT_DEBUG (GST_CAT_STATES, "iterator done");
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "iterator done");
done = TRUE;
break;
}
@@ -2583,12 +2603,13 @@ restart:
goto done;
if (have_no_preroll) {
- GST_CAT_DEBUG (GST_CAT_STATES,
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
"we have NO_PREROLL elements %s -> NO_PREROLL",
gst_element_state_change_return_get_name (ret));
ret = GST_STATE_CHANGE_NO_PREROLL;
} else if (have_async) {
- GST_CAT_DEBUG (GST_CAT_STATES, "we have ASYNC elements %s -> ASYNC",
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, bin,
+ "we have ASYNC elements %s -> ASYNC",
gst_element_state_change_return_get_name (ret));
ret = GST_STATE_CHANGE_ASYNC;
}
@@ -2688,7 +2709,8 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
gst_event_ref (event);
res &= gst_element_send_event (child, event);
- g_value_reset (&data);
+ GST_LOG_OBJECT (child, "After handling %s event: %d",
+ GST_EVENT_TYPE_NAME (event), res);
break;
}
case GST_ITERATOR_RESYNC:
@@ -3036,6 +3058,16 @@ bin_do_eos (GstBin * bin)
&& 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,