+2005-09-23 Tim-Philipp Müller <tim at centricular dot net>
+
+ * check/gst/gstbin.c: (test_children_state_change_order_flagged_sink),
+ (test_children_state_change_order_semi_sink), (gst_bin_suite):
+ Added test to check state change order in bins (can still be made
+ to fail here under heavy disk load; bails out with 'Push on pad
+ fakesink:sink0, but it was not activated in push mode').
+
+ * gst/gstbin.c: (gst_bin_class_init), (gst_bin_change_state):
+ Fix state change order when there is only a semi sink (#316856)
+
+ * gst/gstbus.c: (gst_bus_class_init):
+ Use _class_peek_parent(), not _class_ref(); fix docs to say
+ 'default main context' instead of 'mainloop' where that is
+ what's meant.
+
+ * gst/gstelement.c: (gst_element_commit_state),
+ (gst_element_set_state):
+ Fix typos in debug messages
+
2005-09-23 Thomas Vander Stichele <thomas at apestaart dot org>
* docs/README:
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
sink = gst_element_factory_make ("fakesink", NULL);
- fail_if (src == NULL, "Could not create fakesink");
+ fail_if (sink == NULL, "Could not create fakesink");
srcpad = gst_element_get_pad (src, "src");
fail_unless (srcpad != NULL);
GST_END_TEST;
+/* g_print ("%10s: %4d => %4d\n", GST_OBJECT_NAME (msg->src), old, new); */
+
+#define ASSERT_STATE_CHANGE_MSG(bus,element,old_state,new_state,num) \
+ { \
+ GstMessage *msg; \
+ GstState old = 0, new = 0; \
+ msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); \
+ fail_if (msg == NULL, "No state change message within 1 second (#" \
+ G_STRINGIFY (num) ")"); \
+ gst_message_parse_state_changed (msg, &old, &new); \
+ fail_if (msg->src != GST_OBJECT (element), G_STRINGIFY(element) \
+ " should have changed state next (#" G_STRINGIFY (num) ")"); \
+ fail_if (old != old_state || new != new_state, "state change is not " \
+ G_STRINGIFY (old_state) " => " G_STRINGIFY (new_state)); \
+ gst_message_unref (msg); \
+ }
+
+GST_START_TEST (test_children_state_change_order_flagged_sink)
+{
+ GstElement *src, *identity, *sink, *pipeline;
+ GstStateChangeReturn ret;
+ GstBus *bus;
+
+ pipeline = gst_pipeline_new (NULL);
+ fail_unless (pipeline != NULL, "Could not create pipeline");
+
+ bus = GST_ELEMENT_BUS (pipeline);
+ fail_unless (bus != NULL, "Pipeline has no bus?!");
+
+ src = gst_element_factory_make ("fakesrc", NULL);
+ fail_if (src == NULL, "Could not create fakesrc");
+
+ identity = gst_element_factory_make ("identity", NULL);
+ fail_if (identity == NULL, "Could not create identity");
+
+ sink = gst_element_factory_make ("fakesink", NULL);
+ fail_if (sink == NULL, "Could not create fakesink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
+
+ fail_unless (gst_element_link (src, identity) == TRUE);
+ fail_unless (gst_element_link (identity, sink) == TRUE);
+
+ /* (1) Test state change with fakesink being a regular sink */
+ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
+
+ /* NULL => READY */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 101);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 102);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 103);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 104);
+
+ /* READY => PAUSED */
+ /* because of pre-rolling, sink will return ASYNC on state
+ * change and change state later when it has a buffer */
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
+ 105);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 106);
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
+ 108);
+
+ /* PAUSED => PLAYING */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 109);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 110);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 111);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 112);
+
+ /* don't set to NULL that will set the bus flushing and kill our messages */
+ ret = gst_element_set_state (pipeline, GST_STATE_READY);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
+
+ /* TODO: do we need to check downwards state change order as well? */
+ pop_messages (bus, 4); /* pop playing => paused messages off the bus */
+ pop_messages (bus, 4); /* pop paused => ready messages off the bus */
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ ret = gst_element_set_state (pipeline, GST_STATE_NULL);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_children_state_change_order_semi_sink)
+{
+ GstElement *src, *identity, *sink, *pipeline;
+ GstStateChangeReturn ret;
+ GstBus *bus;
+
+ /* (2) Now again, but check other code path where we don't have
+ * a proper sink correctly flagged as such, but a 'semi-sink' */
+ pipeline = gst_pipeline_new (NULL);
+ fail_unless (pipeline != NULL, "Could not create pipeline");
+
+ bus = GST_ELEMENT_BUS (pipeline);
+ fail_unless (bus != NULL, "Pipeline has no bus?!");
+
+ src = gst_element_factory_make ("fakesrc", NULL);
+ fail_if (src == NULL, "Could not create fakesrc");
+
+ identity = gst_element_factory_make ("identity", NULL);
+ fail_if (identity == NULL, "Could not create identity");
+
+ sink = gst_element_factory_make ("fakesink", NULL);
+ fail_if (sink == NULL, "Could not create fakesink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
+
+ fail_unless (gst_element_link (src, identity) == TRUE);
+ fail_unless (gst_element_link (identity, sink) == TRUE);
+
+ GST_FLAG_UNSET (sink, GST_ELEMENT_IS_SINK); /* <======== */
+
+ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
+
+ /* NULL => READY */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 201);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 202);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 203);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 204);
+
+ /* READY => PAUSED */
+ /* because of pre-rolling, sink will return ASYNC on state
+ * change and change state later when it has a buffer */
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
+ 205);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
+ 208);
+
+ /* PAUSED => PLAYING */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 209);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 210);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 211);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 212);
+
+ /* don't set to NULL that will set the bus flushing and kill our messages */
+ ret = gst_element_set_state (pipeline, GST_STATE_READY);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
+
+ /* TODO: do we need to check downwards state change order as well? */
+ pop_messages (bus, 4); /* pop playing => paused messages off the bus */
+ pop_messages (bus, 4); /* pop paused => ready messages off the bus */
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ ret = gst_element_set_state (pipeline, GST_STATE_NULL);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
+
Suite *
gst_bin_suite (void)
{
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_interface);
+ tcase_add_test (tc_chain, test_children_state_change_order_flagged_sink);
+ tcase_add_test (tc_chain, test_children_state_change_order_semi_sink);
tcase_add_test (tc_chain, test_message_state_changed);
tcase_add_test (tc_chain, test_message_state_changed_child);
tcase_add_test (tc_chain, test_message_state_changed_children);
gstobject_class = (GstObjectClass *) klass;
gstelement_class = (GstElementClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+ parent_class = g_type_class_peek_parent (klass);
/**
* GstBin::element-added:
/* was reffed before pushing on the queue by the
* gst_object_get_parent() call we used to get the element. */
- g_queue_push_tail (elem_queue, peer_parent);
+ g_queue_push_head (elem_queue, peer_parent);
/* so that we don't unref it */
peer_parent = NULL;
} else {
* is posted on the bus. The application can then _pop() the messages from the
* bus to handle them.
* Alternatively the application can register an asynchronous bus function using
- * gst_bus_add_watch_full() orgst_bus_add_watch(). This function will receive
+ * gst_bus_add_watch_full() or gst_bus_add_watch(). This function will receive
* messages a short while after they have been posted.
*
* It is also possible to get messages from the bus without any thread
#include "gstbus.h"
-enum
-{
- ARG_0,
-};
static void gst_bus_class_init (GstBusClass * klass);
static void gst_bus_init (GstBus * bus);
gobject_class = (GObjectClass *) klass;
gstobject_class = (GstObjectClass *) klass;
- parent_class = g_type_class_ref (GST_TYPE_OBJECT);
+ parent_class = g_type_class_peek_parent (klass);
if (!g_thread_supported ())
g_thread_init (NULL);
* @user_data: user data passed to @func.
* @notify: the function to call when the source is removed.
*
- * Adds the bus to the mainloop with the given priority. If the func returns
- * FALSE, the func will be removed.
+ * Adds a bus watch to the default main context with the given priority.
+ * If the func returns FALSE, the source will be removed.
*
* When the func is called, the message belongs to the caller; if you want to
- * keep a copy of it, call gst_message_ref before leaving the func.
+ * keep a copy of it, call gst_message_ref() before leaving the func.
*
* Returns: The event source id.
*
* @func: A function to call when a message is received.
* @user_data: user data passed to @func.
*
- * Adds the bus to the mainloop with the default priority.
+ * Adds a bus watch to the default main context with the default priority.
*
* Returns: The event source id.
*
GstState old_state = GST_STATE (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
- "commiting state from %s to %s", gst_element_state_get_name (old_state),
+ "committing state from %s to %s",
+ gst_element_state_get_name (old_state),
gst_element_state_get_name (pending));
GST_STATE (element) = pending;
"element changed state successfully");
/* we can commit the state now and proceed to the next state */
gst_element_commit_state (element);
- GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
break;
case GST_STATE_CHANGE_NO_PREROLL:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
/* we can commit the state now and proceed to the next state */
gst_element_commit_state (element);
GST_STATE_NO_PREROLL (element) = TRUE;
- GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "commited state");
+ GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
break;
default:
goto invalid_return;
src = gst_element_factory_make ("fakesrc", NULL);
fail_if (src == NULL, "Could not create fakesrc");
sink = gst_element_factory_make ("fakesink", NULL);
- fail_if (src == NULL, "Could not create fakesink");
+ fail_if (sink == NULL, "Could not create fakesink");
srcpad = gst_element_get_pad (src, "src");
fail_unless (srcpad != NULL);
GST_END_TEST;
+/* g_print ("%10s: %4d => %4d\n", GST_OBJECT_NAME (msg->src), old, new); */
+
+#define ASSERT_STATE_CHANGE_MSG(bus,element,old_state,new_state,num) \
+ { \
+ GstMessage *msg; \
+ GstState old = 0, new = 0; \
+ msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); \
+ fail_if (msg == NULL, "No state change message within 1 second (#" \
+ G_STRINGIFY (num) ")"); \
+ gst_message_parse_state_changed (msg, &old, &new); \
+ fail_if (msg->src != GST_OBJECT (element), G_STRINGIFY(element) \
+ " should have changed state next (#" G_STRINGIFY (num) ")"); \
+ fail_if (old != old_state || new != new_state, "state change is not " \
+ G_STRINGIFY (old_state) " => " G_STRINGIFY (new_state)); \
+ gst_message_unref (msg); \
+ }
+
+GST_START_TEST (test_children_state_change_order_flagged_sink)
+{
+ GstElement *src, *identity, *sink, *pipeline;
+ GstStateChangeReturn ret;
+ GstBus *bus;
+
+ pipeline = gst_pipeline_new (NULL);
+ fail_unless (pipeline != NULL, "Could not create pipeline");
+
+ bus = GST_ELEMENT_BUS (pipeline);
+ fail_unless (bus != NULL, "Pipeline has no bus?!");
+
+ src = gst_element_factory_make ("fakesrc", NULL);
+ fail_if (src == NULL, "Could not create fakesrc");
+
+ identity = gst_element_factory_make ("identity", NULL);
+ fail_if (identity == NULL, "Could not create identity");
+
+ sink = gst_element_factory_make ("fakesink", NULL);
+ fail_if (sink == NULL, "Could not create fakesink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
+
+ fail_unless (gst_element_link (src, identity) == TRUE);
+ fail_unless (gst_element_link (identity, sink) == TRUE);
+
+ /* (1) Test state change with fakesink being a regular sink */
+ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
+
+ /* NULL => READY */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 101);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 102);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 103);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 104);
+
+ /* READY => PAUSED */
+ /* because of pre-rolling, sink will return ASYNC on state
+ * change and change state later when it has a buffer */
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
+ 105);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 106);
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 107);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
+ 108);
+
+ /* PAUSED => PLAYING */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 109);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 110);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 111);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 112);
+
+ /* don't set to NULL that will set the bus flushing and kill our messages */
+ ret = gst_element_set_state (pipeline, GST_STATE_READY);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
+
+ /* TODO: do we need to check downwards state change order as well? */
+ pop_messages (bus, 4); /* pop playing => paused messages off the bus */
+ pop_messages (bus, 4); /* pop paused => ready messages off the bus */
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ ret = gst_element_set_state (pipeline, GST_STATE_NULL);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
+
+
+GST_START_TEST (test_children_state_change_order_semi_sink)
+{
+ GstElement *src, *identity, *sink, *pipeline;
+ GstStateChangeReturn ret;
+ GstBus *bus;
+
+ /* (2) Now again, but check other code path where we don't have
+ * a proper sink correctly flagged as such, but a 'semi-sink' */
+ pipeline = gst_pipeline_new (NULL);
+ fail_unless (pipeline != NULL, "Could not create pipeline");
+
+ bus = GST_ELEMENT_BUS (pipeline);
+ fail_unless (bus != NULL, "Pipeline has no bus?!");
+
+ src = gst_element_factory_make ("fakesrc", NULL);
+ fail_if (src == NULL, "Could not create fakesrc");
+
+ identity = gst_element_factory_make ("identity", NULL);
+ fail_if (identity == NULL, "Could not create identity");
+
+ sink = gst_element_factory_make ("fakesink", NULL);
+ fail_if (sink == NULL, "Could not create fakesink");
+
+ gst_bin_add_many (GST_BIN (pipeline), src, identity, sink, NULL);
+
+ fail_unless (gst_element_link (src, identity) == TRUE);
+ fail_unless (gst_element_link (identity, sink) == TRUE);
+
+ GST_FLAG_UNSET (sink, GST_ELEMENT_IS_SINK); /* <======== */
+
+ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed");
+
+ /* NULL => READY */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_NULL, GST_STATE_READY, 201);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 202);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 203);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 204);
+
+ /* READY => PAUSED */
+ /* because of pre-rolling, sink will return ASYNC on state
+ * change and change state later when it has a buffer */
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED,
+ 205);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_READY, GST_STATE_PAUSED, 206);
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED,
+ 208);
+
+ /* PAUSED => PLAYING */
+ ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_PAUSED, GST_STATE_PLAYING, 209);
+ ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 210);
+ ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_PAUSED, GST_STATE_PLAYING, 211);
+ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_PAUSED, GST_STATE_PLAYING,
+ 212);
+
+ /* don't set to NULL that will set the bus flushing and kill our messages */
+ ret = gst_element_set_state (pipeline, GST_STATE_READY);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed");
+
+ /* TODO: do we need to check downwards state change order as well? */
+ pop_messages (bus, 4); /* pop playing => paused messages off the bus */
+ pop_messages (bus, 4); /* pop paused => ready messages off the bus */
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ ret = gst_element_set_state (pipeline, GST_STATE_NULL);
+ fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to NULL failed");
+
+ ASSERT_OBJECT_REFCOUNT (src, "src", 1);
+ ASSERT_OBJECT_REFCOUNT (sink, "sink", 1);
+ ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
+
+ gst_object_unref (pipeline);
+}
+
+GST_END_TEST;
+
Suite *
gst_bin_suite (void)
{
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_interface);
+ tcase_add_test (tc_chain, test_children_state_change_order_flagged_sink);
+ tcase_add_test (tc_chain, test_children_state_change_order_semi_sink);
tcase_add_test (tc_chain, test_message_state_changed);
tcase_add_test (tc_chain, test_message_state_changed_child);
tcase_add_test (tc_chain, test_message_state_changed_children);