📄 gstbin.c
字号:
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 (bus); gst_object_unref (pipeline);}GST_END_TEST;GST_START_TEST (test_children_state_change_order_semi_sink){ GstElement *src, *identity, *sink, *pipeline; GstStateChangeReturn ret; GstState current, pending; 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_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"); 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); /* this is not very nice but should work just fine in this case. */ GST_OBJECT_FLAG_UNSET (sink, GST_ELEMENT_IS_SINK); /* <======== */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); fail_if (ret != GST_STATE_CHANGE_ASYNC, "State change to PLAYING not 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, 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 */ GST_DEBUG ("popping READY -> PAUSED messages"); ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_READY, GST_STATE_PAUSED, 205);#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, 206); ASSERT_STATE_CHANGE_MSG (bus, sink, GST_STATE_READY, GST_STATE_PAUSED, 207);#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, 208); pop_async_done (bus); /* PAUSED => PLAYING */ GST_DEBUG ("popping PAUSED -> PLAYING messages"); 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);#endif /* 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 */ GST_DEBUG ("waiting for pipeline to reach refcount 1"); while (GST_OBJECT_REFCOUNT_VALUE (pipeline) > 1) THREAD_SWITCH (); GST_DEBUG ("checking refcount"); 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"); GST_DEBUG ("checking refcount"); ASSERT_OBJECT_REFCOUNT (src, "src", 1); ASSERT_OBJECT_REFCOUNT (sink, "sink", 1); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); GST_DEBUG ("cleanup"); gst_object_unref (bus); gst_object_unref (pipeline);}GST_END_TEST;GST_START_TEST (test_children_state_change_order_two_sink){ GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline; GstStateChangeReturn ret; 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"); tee = gst_element_factory_make ("tee", NULL); fail_if (tee == NULL, "Could not create tee"); identity = gst_element_factory_make ("identity", NULL); fail_if (identity == NULL, "Could not create identity"); sink1 = gst_element_factory_make ("fakesink", NULL); fail_if (sink1 == NULL, "Could not create fakesink1"); sink2 = gst_element_factory_make ("fakesink", NULL); fail_if (sink2 == NULL, "Could not create fakesink2"); gst_bin_add_many (GST_BIN (pipeline), src, tee, identity, sink1, sink2, NULL); fail_unless (gst_element_link (src, tee) == TRUE); fail_unless (gst_element_link (tee, identity) == TRUE); fail_unless (gst_element_link (identity, sink1) == TRUE); fail_unless (gst_element_link (tee, sink2) == TRUE); ret = gst_element_set_state (pipeline, GST_STATE_READY); fail_if (ret != GST_STATE_CHANGE_SUCCESS, "State change to READY failed"); /* NULL => READY */ { GstMessage *msg; GstState old = 0, new = 0, pending = 0; GstObject *first, *second; msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); fail_if (msg == NULL, "No state change message within 1 second (#201)"); gst_message_parse_state_changed (msg, &old, &new, &pending); first = gst_object_ref (msg->src); fail_if (first != GST_OBJECT (sink1) && first != GST_OBJECT (sink2), "sink1 or sink2 should have changed state next #(202)"); gst_message_unref (msg); msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED, GST_SECOND); fail_if (msg == NULL, "No state change message within 1 second (#201)"); gst_message_parse_state_changed (msg, &old, &new, &pending); second = gst_object_ref (msg->src); fail_if (second != GST_OBJECT (sink1) && second != GST_OBJECT (sink2), "sink1 or sink2 should have changed state next #(202)"); gst_message_unref (msg); fail_if (second == first, "got state change from same object"); gst_object_unref (first); gst_object_unref (second); } ASSERT_STATE_CHANGE_MSG (bus, identity, GST_STATE_NULL, GST_STATE_READY, 203); ASSERT_STATE_CHANGE_MSG (bus, tee, GST_STATE_NULL, GST_STATE_READY, 204); ASSERT_STATE_CHANGE_MSG (bus, src, GST_STATE_NULL, GST_STATE_READY, 205); ASSERT_STATE_CHANGE_MSG (bus, pipeline, GST_STATE_NULL, GST_STATE_READY, 206); ASSERT_OBJECT_REFCOUNT (src, "src", 1); ASSERT_OBJECT_REFCOUNT (tee, "tee", 1); ASSERT_OBJECT_REFCOUNT (identity, "identity", 1); ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1); ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 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 (tee, "tee", 1); ASSERT_OBJECT_REFCOUNT (identity, "identity", 1); ASSERT_OBJECT_REFCOUNT (sink1, "sink1", 1); ASSERT_OBJECT_REFCOUNT (sink2, "sink2", 1); ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1); gst_object_unref (bus); gst_object_unref (pipeline);}GST_END_TEST;GST_START_TEST (test_iterate_sorted){ GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline, *bin; GstIterator *it; gpointer elem; pipeline = gst_pipeline_new (NULL); fail_unless (pipeline != NULL, "Could not create pipeline"); bin = gst_bin_new (NULL); fail_unless (bin != NULL, "Could not create bin"); src = gst_element_factory_make ("fakesrc", NULL); fail_if (src == NULL, "Could not create fakesrc"); tee = gst_element_factory_make ("tee", NULL); fail_if (tee == NULL, "Could not create tee"); sink1 = gst_element_factory_make ("fakesink", NULL); fail_if (sink1 == NULL, "Could not create fakesink1"); gst_bin_add_many (GST_BIN (bin), src, tee, sink1, NULL); fail_unless (gst_element_link (src, tee) == TRUE); fail_unless (gst_element_link (tee, sink1) == TRUE); identity = gst_element_factory_make ("identity", NULL); fail_if (identity == NULL, "Could not create identity"); sink2 = gst_element_factory_make ("fakesink", NULL); fail_if (sink2 == NULL, "Could not create fakesink2"); gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL); fail_unless (gst_element_link (tee, identity) == TRUE); fail_unless (gst_element_link (identity, sink2) == TRUE); it = gst_bin_iterate_sorted (GST_BIN (pipeline)); fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK); fail_unless (elem == sink2); gst_object_unref (elem); fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK); fail_unless (elem == identity); gst_object_unref (elem); fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK); fail_unless (elem == bin); gst_object_unref (elem); gst_iterator_free (it); gst_object_unref (pipeline);}GST_END_TEST;Suite *gst_bin_suite (void){ Suite *s = suite_create ("GstBin"); TCase *tc_chain = tcase_create ("bin tests"); tcase_set_timeout (tc_chain, 0); 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_children_state_change_order_two_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); tcase_add_test (tc_chain, test_watch_for_state_change); tcase_add_test (tc_chain, test_add_linked); tcase_add_test (tc_chain, test_add_self); tcase_add_test (tc_chain, test_iterate_sorted); return s;}GST_CHECK_MAIN (gst_bin);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -