+2005-09-29 Wim Taymans <wim@fluendo.com>
+
+ * check/gst/gstbin.c: (GST_START_TEST):
+ Add bus to bin.
+
+ * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init),
+ (add_to_queue), (clear_queue), (reset_degree), (update_degree),
+ (find_element), (gst_bin_sort_iterator_next),
+ (gst_bin_sort_iterator_resync), (gst_bin_sort_iterator_free),
+ (gst_bin_iterate_sorted), (gst_bin_element_set_state),
+ (gst_bin_change_state), (gst_bin_dispose):
+ A bin does not have a bus, it gets the bus from the parent.
+
+ * gst/gstelement.c: (gst_element_requires_clock),
+ (gst_element_provides_clock), (gst_element_is_indexable),
+ (gst_element_is_locked_state), (gst_element_change_state),
+ (gst_element_set_bus_func):
+ Small cleanups.
+
+ * gst/gstpipeline.c: (gst_pipeline_class_init),
+ (gst_pipeline_init), (gst_pipeline_provide_clock_func):
+ The pipeline provides a bus.
+
2005-09-28 Johan Dahlin <johan@gnome.org>
* gst/gstmessage.c (gst_message_parse_state_changed): Use
fail_unless (bin != NULL, "Could not create bin");
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
- bus = GST_ELEMENT_BUS (bin);
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
/* change state, spawning a message, causing an incref on the bin */
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
fail_unless (bin != NULL, "Could not create bin");
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
+
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
gst_bin_add (bin, src);
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- bus = GST_ELEMENT_BUS (bin);
-
/* change state, spawning two messages:
* - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
* - second for bin, causing an incref on the bin */
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_pipeline_get_bus (pipeline);
/* change state to READY, spawning three messages */
GST_DEBUG ("setting pipeline to READY");
== GST_STATE_CHANGE_SUCCESS);
/* each object is referenced by a message */
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 2);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
/* sink might have an extra reference if it's still blocked on preroll */
ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
bin = gst_element_factory_make ("bin", NULL);
fail_unless (bin != NULL, "Could not create bin");
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
+
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
sink = gst_element_factory_make ("fakesink", NULL);
fail_unless (gst_element_link (src, sink), "could not link src and sink");
- bus = GST_ELEMENT_BUS (bin);
-
/* change state, spawning two times three messages, minus one async */
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED)
== GST_STATE_CHANGE_ASYNC);
pop_messages (bus, 5);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
gst_bin_watch_for_state_change (GST_BIN (bin));
/* should get the bin's state change message now */
pop_messages (bus, 1);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING)
pop_messages (bus, 3);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
/* setting bin to NULL flushes the bus automatically */
== GST_STATE_CHANGE_SUCCESS);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
bin->children_cookie = 0;
bin->eosed = NULL;
- /* Set up a bus for listening to child elements,
- * and one for sending messages up the hierarchy */
+ /* Set up a bus for listening to child elements */
bus = g_object_new (gst_bus_get_type (), NULL);
bin->child_bus = bus;
gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bin_bus_handler, bin);
-
- bus = g_object_new (gst_bus_get_type (), NULL);
- gst_element_set_bus (GST_ELEMENT (bin), bus);
- /* set_bus refs the bus via gst_object_replace, we drop our ref */
- gst_object_unref (bus);
}
/**
bin->eosed = NULL;
gst_object_unref (bin->child_bus);
bin->child_bus = NULL;
- gst_element_set_bus (GST_ELEMENT (bin), NULL);
while (bin->children) {
gst_bin_remove (bin, GST_ELEMENT (bin->children->data));
*
* The name of a GstElement can be get with gst_element_get_name() and set with
* gst_element_set_name(). For speed, GST_ELEMENT_NAME() can be used in the
- * core. Do not use this in plug-ins or applications in order to retain ABI
- * compatibility.
+ * core when using the appropriate locking. Do not use this in plug-ins or
+ * applications in order to retain ABI compatibility.
*
* All elements have pads (of the type #GstPad). These pads link to pads on
* other elements. Buffers flow between these linked pads.
gboolean
gst_element_requires_clock (GstElement * element)
{
- gboolean result = FALSE;
+ gboolean result;
- g_return_val_if_fail (GST_IS_ELEMENT (element), result);
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
result = (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
gboolean
gst_element_provides_clock (GstElement * element)
{
- gboolean result = FALSE;
+ gboolean result;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
* Get the clock provided by the given element.
*
* Returns: the GstClock provided by the element or NULL
- * if no clock could be provided.
+ * if no clock could be provided. Unref after usage.
*
* MT safe.
*/
gboolean
gst_element_is_indexable (GstElement * element)
{
- gboolean result = FALSE;
+ gboolean result;
- g_return_val_if_fail (GST_IS_ELEMENT (element), result);
+ g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
result = (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
* @element: a #GstElement.
* @index: a #GstIndex.
*
- * Set the specified GstIndex on the element.
+ * Set the specified GstIndex on the element. The refcount of the index
+ * will be increased, any previously set index is unreffed.
*
* MT safe.
*/
* see gst_object_set_parent() for refcounting information.
*
* Pads are not automatically activated so elements should perform the needed
- * steps to activate the pad.
+ * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
+ * state.
*
* The pad and the element should be unlocked when calling this function.
*
return pad;
}
-GstIteratorItem
+static GstIteratorItem
iterate_pad (GstIterator * it, GstPad * pad)
{
gst_object_ref (pad);
* gst_element_iterate_pads:
* @element: a #GstElement to iterate pads of.
*
- * Retrieves an iterattor of @element's pads.
+ * Retrieves an iterattor of @element's pads. The iterator should
+ * be freed after usage.
*
* Returns: the #GstIterator of #GstPad. Unref each pad after use.
*
gboolean
gst_element_is_locked_state (GstElement * element)
{
- gboolean result = FALSE;
+ gboolean result;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
pending = GST_STATE_PENDING (element);
/* if the element already is in the given state, we just return success */
- if (pending == GST_STATE_VOID_PENDING || state == GST_STATE_PENDING (element)) {
- GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
- "element is already in the %s state",
- gst_element_state_get_name (state));
- if (GST_STATE_NO_PREROLL (element))
- return GST_STATE_CHANGE_NO_PREROLL;
- else
- return GST_STATE_CHANGE_SUCCESS;
- }
+ if (pending == GST_STATE_VOID_PENDING || state == GST_STATE_PENDING (element))
+ goto was_ok;
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
"default handler tries setting state from %s to %s (%04x)",
if (!gst_element_pads_activate (element, FALSE)) {
result = GST_STATE_CHANGE_FAILURE;
} else {
- GST_LOCK (element);
- element->base_time = 0;
- GST_UNLOCK (element);
+ gst_element_set_base_time (element, 0);
}
break;
default:
gst_element_state_get_name (pending));
break;
}
-
return result;
+
+was_ok:
+ {
+ GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
+ "element is already in the %s state",
+ gst_element_state_get_name (state));
+ if (GST_STATE_NO_PREROLL (element))
+ return GST_STATE_CHANGE_NO_PREROLL;
+ else
+ return GST_STATE_CHANGE_SUCCESS;
+ }
+
}
/**
*
* Retrieves the factory that was used to create this element.
*
- * Returns: the #GstElementFactory used for creating this element.
+ * Returns: the #GstElementFactory used for creating this element.
+ * no refcounting is needed.
*/
GstElementFactory *
gst_element_get_factory (GstElement * element)
GST_LOCK (element);
gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
- GST_OBJECT (bus));
+ GST_OBJECT_CAST (bus));
GST_UNLOCK (element);
}
gst_pipeline_init (GTypeInstance * instance, gpointer g_class)
{
GstPipeline *pipeline = GST_PIPELINE (instance);
+ GstBus *bus;
pipeline->delay = DEFAULT_DELAY;
pipeline->play_timeout = DEFAULT_PLAY_TIMEOUT;
+
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (pipeline), bus);
+ gst_object_unref (bus);
}
static void
fail_unless (bin != NULL, "Could not create bin");
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
- bus = GST_ELEMENT_BUS (bin);
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
/* change state, spawning a message, causing an incref on the bin */
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY);
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
fail_unless (bin != NULL, "Could not create bin");
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
+
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
gst_bin_add (bin, src);
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
- bus = GST_ELEMENT_BUS (bin);
-
/* change state, spawning two messages:
* - first for fakesrc, forwarded to bin's bus, causing incref on fakesrc
* - second for bin, causing an incref on the bin */
ASSERT_OBJECT_REFCOUNT (bin, "bin", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_pipeline_get_bus (pipeline);
/* change state to READY, spawning three messages */
GST_DEBUG ("setting pipeline to READY");
== GST_STATE_CHANGE_SUCCESS);
/* each object is referenced by a message */
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 2);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 2);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
pop_messages (bus, 3);
fail_if ((gst_bus_pop (bus)) != NULL);
- ASSERT_OBJECT_REFCOUNT (bus, "bus", 1);
+ ASSERT_OBJECT_REFCOUNT (bus, "bus", 2);
ASSERT_OBJECT_REFCOUNT (src, "src", 1);
/* sink might have an extra reference if it's still blocked on preroll */
ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 1, 2);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
bin = gst_element_factory_make ("bin", NULL);
fail_unless (bin != NULL, "Could not create bin");
+ bus = g_object_new (gst_bus_get_type (), NULL);
+ gst_element_set_bus (GST_ELEMENT_CAST (bin), bus);
+
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
sink = gst_element_factory_make ("fakesink", NULL);
fail_unless (gst_element_link (src, sink), "could not link src and sink");
- bus = GST_ELEMENT_BUS (bin);
-
/* change state, spawning two times three messages, minus one async */
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED)
== GST_STATE_CHANGE_ASYNC);
pop_messages (bus, 5);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
gst_bin_watch_for_state_change (GST_BIN (bin));
/* should get the bin's state change message now */
pop_messages (bus, 1);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
fail_unless (gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING)
pop_messages (bus, 3);
- fail_unless (gst_bus_have_pending (bus, GST_MESSAGE_ANY) == FALSE,
+ fail_unless (gst_bus_have_pending (bus) == FALSE,
"Unexpected messages on bus");
/* setting bin to NULL flushes the bus automatically */
== GST_STATE_CHANGE_SUCCESS);
/* clean up */
+ gst_object_unref (bus);
gst_object_unref (bin);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}
pipeline = gst_pipeline_new (NULL);
fail_unless (pipeline != NULL, "Could not create pipeline");
- bus = GST_ELEMENT_BUS (pipeline);
+ bus = gst_element_get_bus (pipeline);
fail_unless (bus != NULL, "Pipeline has no bus?!");
src = gst_element_factory_make ("fakesrc", NULL);
ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1);
ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+ gst_object_unref (bus);
gst_object_unref (pipeline);
}