📄 gstbin.c
字号:
ASSERT_OBJECT_REFCOUNT_BETWEEN (pipeline, "pipeline", 2, 3); pop_messages (bus, 3); pop_async_done (bus); fail_if ((gst_bus_pop (bus)) != NULL); ASSERT_OBJECT_REFCOUNT (bus, "bus", 2); ASSERT_OBJECT_REFCOUNT (src, "src", 2); ASSERT_OBJECT_REFCOUNT (sink, "sink", 2); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); /* change state to PLAYING, spawning three messages */ GST_DEBUG ("setting pipeline to PLAYING"); ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); ret = gst_element_get_state (GST_ELEMENT (pipeline), ¤t, &pending, GST_CLOCK_TIME_NONE); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); fail_unless (current == GST_STATE_PLAYING); fail_unless (pending == GST_STATE_VOID_PENDING); /* each object is referenced by one message * src might have an extra reference if it's still pushing * sink might have an extra reference if it's still blocked on preroll * pipeline posted a new-clock message too. */ ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 2, 3); ASSERT_OBJECT_REFCOUNT_BETWEEN (sink, "sink", 2, 3); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3); pop_messages (bus, 3); fail_if ((gst_bus_pop (bus)) != NULL); ASSERT_OBJECT_REFCOUNT (bus, "bus", 2); /* src might have an extra reference if it's still pushing */ ASSERT_OBJECT_REFCOUNT_BETWEEN (src, "src", 1, 2); /* 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); /* go back to READY, spawning six messages */ GST_DEBUG ("setting pipeline to READY"); ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); /* each object is referenced by two messages */ ASSERT_OBJECT_REFCOUNT (src, "src", 3); ASSERT_OBJECT_REFCOUNT (sink, "sink", 3); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 3); pop_messages (bus, 6); fail_if ((gst_bus_pop (bus)) != NULL); ASSERT_OBJECT_REFCOUNT (src, "src", 1); ASSERT_OBJECT_REFCOUNT (sink, "sink", 1); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); /* setting pipeline to NULL flushes the bus automatically */ ret = gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); ASSERT_OBJECT_REFCOUNT (src, "src", 1); ASSERT_OBJECT_REFCOUNT (sink, "sink", 1); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); /* clean up */ gst_object_unref (bus); gst_object_unref (pipeline);}GST_END_TEST;GST_START_TEST (test_watch_for_state_change){ GstElement *src, *sink, *bin; GstBus *bus; GstStateChangeReturn ret; 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_if (sink == NULL, "Could not create fakesink"); gst_bin_add (GST_BIN (bin), sink); gst_bin_add (GST_BIN (bin), src); fail_unless (gst_element_link (src, sink), "could not link src and sink"); /* change state, spawning two times three messages */ ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED); fail_unless (ret == GST_STATE_CHANGE_ASYNC); ret = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); pop_messages (bus, 6); pop_async_done (bus); fail_unless (gst_bus_have_pending (bus) == FALSE, "Unexpected messages on bus"); ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); pop_messages (bus, 3); /* this one might return either SUCCESS or ASYNC, likely SUCCESS */ ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED); gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); pop_messages (bus, 3); if (ret == GST_STATE_CHANGE_ASYNC) pop_async_done (bus); fail_unless (gst_bus_have_pending (bus) == FALSE, "Unexpected messages on bus"); /* setting bin to NULL flushes the bus automatically */ ret = gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); fail_unless (ret == GST_STATE_CHANGE_SUCCESS); /* clean up */ gst_object_unref (bus); gst_object_unref (bin);}GST_END_TEST;/* adding an element with linked pads to a bin unlinks the * pads */GST_START_TEST (test_add_linked){ GstElement *src, *sink; GstPad *srcpad, *sinkpad; GstElement *pipeline; pipeline = gst_pipeline_new (NULL); fail_unless (pipeline != NULL, "Could not create pipeline"); src = gst_element_factory_make ("fakesrc", NULL); fail_if (src == NULL, "Could not create fakesrc"); sink = gst_element_factory_make ("fakesink", NULL); fail_if (sink == NULL, "Could not create fakesink"); srcpad = gst_element_get_pad (src, "src"); fail_unless (srcpad != NULL); sinkpad = gst_element_get_pad (sink, "sink"); fail_unless (sinkpad != NULL); fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK); /* pads are linked now */ fail_unless (gst_pad_is_linked (srcpad)); fail_unless (gst_pad_is_linked (sinkpad)); /* adding element to bin voids hierarchy so pads are unlinked */ gst_bin_add (GST_BIN (pipeline), src); /* check if pads really are unlinked */ fail_unless (!gst_pad_is_linked (srcpad)); fail_unless (!gst_pad_is_linked (sinkpad)); /* cannot link pads in wrong hierarchy */ fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_WRONG_HIERARCHY); /* adding other element to bin as well */ gst_bin_add (GST_BIN (pipeline), sink); /* now we can link again */ fail_unless (gst_pad_link (srcpad, sinkpad) == GST_PAD_LINK_OK); /* check if pads really are linked */ fail_unless (gst_pad_is_linked (srcpad)); fail_unless (gst_pad_is_linked (sinkpad)); gst_object_unref (srcpad); gst_object_unref (sinkpad); gst_object_unref (pipeline);}GST_END_TEST;/* adding ourself should fail */GST_START_TEST (test_add_self){ GstElement *bin; bin = gst_bin_new (NULL); fail_unless (bin != NULL, "Could not create bin"); ASSERT_WARNING (gst_bin_add (GST_BIN (bin), bin)); gst_object_unref (bin);}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, pending = 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, &pending); \ 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; GstState current, pending; GstBus *bus; pipeline = gst_pipeline_new (NULL); fail_unless (pipeline != NULL, "Could not create pipeline"); bus = gst_element_get_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"); g_object_set (src, "num-buffers", 5, NULL); 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_ASYNC, "State change to PLAYING did not return ASYNC"); ret = gst_element_get_state (pipeline, ¤t, &pending, GST_CLOCK_TIME_NONE); fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to PLAYING failed"); fail_if (current != GST_STATE_PLAYING, "State change to PLAYING failed"); fail_if (pending != GST_STATE_VOID_PENDING, "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 */ GST_DEBUG ("popping READY -> PAUSED messages"); ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED, 105);#if 0 /* From here on, all bets are off. Usually the source changes state next, * but it might just as well be that the first buffer produced by the * source reaches the sink before the source has finished its state change, * in which case the sink will commit its new state before the source ... */ 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);#else pop_messages (bus, 2); /* pop remaining ready => paused messages off the bus */ ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_READY, GST_STATE_PAUSED, 108); pop_async_done (bus);#endif /* PAUSED => PLAYING */ GST_DEBUG ("popping PAUSED -> PLAYING messages"); 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"); ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); 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 */ while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1) THREAD_SWITCH ();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -