mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
check/gst/gstbin.c: Added test to check state change order in bins (can still be made to fail here under heavy disk l...
Original commit message from CVS: * 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
This commit is contained in:
parent
f74399ea55
commit
705936d1bf
6 changed files with 392 additions and 17 deletions
20
ChangeLog
20
ChangeLog
|
@ -1,3 +1,23 @@
|
|||
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:
|
||||
|
|
|
@ -392,7 +392,7 @@ GST_START_TEST (test_add_linked)
|
|||
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);
|
||||
|
@ -432,6 +432,183 @@ GST_START_TEST (test_add_linked)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -440,6 +617,8 @@ 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);
|
||||
|
|
|
@ -223,7 +223,7 @@ gst_bin_class_init (GstBinClass * klass)
|
|||
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:
|
||||
|
@ -1359,7 +1359,7 @@ restart:
|
|||
|
||||
/* 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 {
|
||||
|
|
16
gst/gstbus.c
16
gst/gstbus.c
|
@ -43,7 +43,7 @@
|
|||
* 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
|
||||
|
@ -65,10 +65,6 @@
|
|||
|
||||
#include "gstbus.h"
|
||||
|
||||
enum
|
||||
{
|
||||
ARG_0,
|
||||
};
|
||||
|
||||
static void gst_bus_class_init (GstBusClass * klass);
|
||||
static void gst_bus_init (GstBus * bus);
|
||||
|
@ -116,7 +112,7 @@ gst_bus_class_init (GstBusClass * klass)
|
|||
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);
|
||||
|
@ -590,11 +586,11 @@ gst_bus_create_watch (GstBus * bus, GstMessageType events)
|
|||
* @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.
|
||||
*
|
||||
|
@ -631,7 +627,7 @@ gst_bus_add_watch_full (GstBus * bus, gint priority, GstMessageType events,
|
|||
* @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.
|
||||
*
|
||||
|
|
|
@ -1737,7 +1737,8 @@ gst_element_commit_state (GstElement * element)
|
|||
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;
|
||||
|
@ -1892,7 +1893,7 @@ gst_element_set_state (GstElement * element, GstState state)
|
|||
"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,
|
||||
|
@ -1900,7 +1901,7 @@ gst_element_set_state (GstElement * element, GstState state)
|
|||
/* 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;
|
||||
|
|
|
@ -392,7 +392,7 @@ GST_START_TEST (test_add_linked)
|
|||
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);
|
||||
|
@ -432,6 +432,183 @@ GST_START_TEST (test_add_linked)
|
|||
|
||||
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)
|
||||
{
|
||||
|
@ -440,6 +617,8 @@ 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);
|
||||
|
|
Loading…
Reference in a new issue