mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
plugins/elements/gsttee.c: Fix flow aggregation of tee. Error out immediately for all flow returns except OK and NOT_...
Original commit message from CVS: * plugins/elements/gsttee.c: (gst_tee_handle_buffer): Fix flow aggregation of tee. Error out immediately for all flow returns except OK and NOT_LINKED, return NOT_LINKED if all pads are not linked and return OK if at least one pad is linked. Before we errored out on "fatal" flow returns (i.e. not for WRONG_STATE) and otherwise returned the flow return of the last pad, which is wrong. * tests/check/elements/tee.c: (_fake_chain), (_fake_chain_error), (GST_START_TEST), (tee_suite): Add unit tests for the flow aggregation.
This commit is contained in:
parent
97ec47cabb
commit
075811e654
3 changed files with 154 additions and 4 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
|||
2008-10-14 Sebastian Dröge <slomo@circular-chaos.org>
|
||||
|
||||
* plugins/elements/gsttee.c: (gst_tee_handle_buffer):
|
||||
Fix flow aggregation of tee. Error out immediately for all flow returns
|
||||
except OK and NOT_LINKED, return NOT_LINKED if all pads are not linked
|
||||
and return OK if at least one pad is linked.
|
||||
|
||||
Before we errored out on "fatal" flow returns (i.e. not for WRONG_STATE)
|
||||
and otherwise returned the flow return of the last pad, which is wrong.
|
||||
|
||||
* tests/check/elements/tee.c: (_fake_chain), (_fake_chain_error),
|
||||
(GST_START_TEST), (tee_suite):
|
||||
Add unit tests for the flow aggregation.
|
||||
|
||||
2008-10-13 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* docs/design/part-TODO.txt:
|
||||
|
|
|
@ -594,13 +594,14 @@ restart:
|
|||
gst_flow_get_name (ret));
|
||||
}
|
||||
/* stop pushing more buffers when we have a fatal error */
|
||||
if (GST_FLOW_IS_FATAL (ret))
|
||||
if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED)
|
||||
goto error;
|
||||
|
||||
/* keep all other return values, overwriting the previous one */
|
||||
GST_LOG_OBJECT (tee, "Replacing ret val %d with %d", cret, ret);
|
||||
if (cret == GST_FLOW_NOT_LINKED)
|
||||
/* keep all other return values, overwriting the previous one. */
|
||||
if (ret != GST_FLOW_NOT_LINKED) {
|
||||
GST_LOG_OBJECT (tee, "Replacing ret val %d with %d", cret, ret);
|
||||
cret = ret;
|
||||
}
|
||||
|
||||
if (GST_ELEMENT_CAST (tee)->pads_cookie != cookie) {
|
||||
GST_LOG_OBJECT (tee, "pad list changed");
|
||||
|
|
|
@ -452,6 +452,140 @@ GST_START_TEST (test_internal_links)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static GstFlowReturn
|
||||
_fake_chain (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
gst_buffer_unref (buffer);
|
||||
return GST_FLOW_OK;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
_fake_chain_error (GstPad * pad, GstBuffer * buffer)
|
||||
{
|
||||
gst_buffer_unref (buffer);
|
||||
return GST_FLOW_ERROR;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_flow_aggregation)
|
||||
{
|
||||
GstPad *mysrc, *mysink1, *mysink2;
|
||||
GstPad *teesink, *teesrc1, *teesrc2;
|
||||
GstElement *tee;
|
||||
GstBuffer *buffer;
|
||||
GstCaps *caps;
|
||||
|
||||
caps = gst_caps_new_simple ("test/test", NULL);
|
||||
|
||||
tee = gst_element_factory_make ("tee", NULL);
|
||||
fail_unless (tee != NULL);
|
||||
teesink = gst_element_get_static_pad (tee, "sink");
|
||||
fail_unless (teesink != NULL);
|
||||
teesrc1 = gst_element_get_request_pad (tee, "src%d");
|
||||
fail_unless (teesrc1 != NULL);
|
||||
teesrc2 = gst_element_get_request_pad (tee, "src%d");
|
||||
fail_unless (teesrc2 != NULL);
|
||||
|
||||
mysink1 = gst_pad_new ("mysink1", GST_PAD_SINK);
|
||||
gst_pad_set_caps (mysink1, caps);
|
||||
mysink2 = gst_pad_new ("mysink2", GST_PAD_SINK);
|
||||
gst_pad_set_caps (mysink2, caps);
|
||||
mysrc = gst_pad_new ("mysrc", GST_PAD_SRC);
|
||||
gst_pad_set_caps (mysrc, caps);
|
||||
|
||||
gst_pad_set_chain_function (mysink1, _fake_chain);
|
||||
gst_pad_set_active (mysink1, TRUE);
|
||||
gst_pad_set_chain_function (mysink2, _fake_chain);
|
||||
gst_pad_set_active (mysink2, TRUE);
|
||||
|
||||
fail_unless (gst_pad_link (mysrc, teesink) == GST_PAD_LINK_OK);
|
||||
fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
|
||||
fail_unless (gst_pad_link (teesrc2, mysink2) == GST_PAD_LINK_OK);
|
||||
|
||||
fail_unless (gst_element_set_state (tee,
|
||||
GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
buffer = gst_buffer_new ();
|
||||
gst_buffer_set_caps (buffer, caps);
|
||||
|
||||
/* First check if everything works in normal state */
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
/* One pad being in wrong state must result in wrong state */
|
||||
gst_pad_set_active (mysink2, FALSE);
|
||||
fail_unless (gst_pad_push (mysrc,
|
||||
gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
|
||||
|
||||
gst_pad_set_active (mysink1, FALSE);
|
||||
gst_pad_set_active (mysink2, TRUE);
|
||||
fail_unless (gst_pad_push (mysrc,
|
||||
gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
|
||||
|
||||
gst_pad_set_active (mysink2, FALSE);
|
||||
fail_unless (gst_pad_push (mysrc,
|
||||
gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
|
||||
|
||||
/* Test if everything still works in normal state */
|
||||
gst_pad_set_active (mysink1, TRUE);
|
||||
gst_pad_set_active (mysink2, TRUE);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
/* One unlinked pad must return OK, two unlinked pads must return NOT_LINKED */
|
||||
fail_unless (gst_pad_unlink (teesrc1, mysink1) == TRUE);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
|
||||
fail_unless (gst_pad_unlink (teesrc2, mysink2) == TRUE);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
fail_unless (gst_pad_unlink (teesrc1, mysink1) == TRUE);
|
||||
fail_unless (gst_pad_push (mysrc,
|
||||
gst_buffer_ref (buffer)) == GST_FLOW_NOT_LINKED);
|
||||
|
||||
/* Test if everything still works in normal state */
|
||||
fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
|
||||
fail_unless (gst_pad_link (teesrc2, mysink2) == GST_PAD_LINK_OK);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
/* One pad returning ERROR should result in ERROR */
|
||||
gst_pad_set_chain_function (mysink1, _fake_chain_error);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
|
||||
|
||||
gst_pad_set_chain_function (mysink1, _fake_chain);
|
||||
gst_pad_set_chain_function (mysink2, _fake_chain_error);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
|
||||
|
||||
gst_pad_set_chain_function (mysink1, _fake_chain_error);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
|
||||
|
||||
/* And now everything still needs to work */
|
||||
gst_pad_set_chain_function (mysink1, _fake_chain);
|
||||
gst_pad_set_chain_function (mysink2, _fake_chain);
|
||||
fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
|
||||
|
||||
fail_unless (gst_element_set_state (tee,
|
||||
GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS);
|
||||
|
||||
fail_unless (gst_pad_unlink (mysrc, teesink) == TRUE);
|
||||
fail_unless (gst_pad_unlink (teesrc1, mysink1) == TRUE);
|
||||
fail_unless (gst_pad_unlink (teesrc2, mysink2) == TRUE);
|
||||
|
||||
|
||||
gst_object_unref (teesink);
|
||||
gst_object_unref (teesrc1);
|
||||
gst_object_unref (teesrc2);
|
||||
gst_element_release_request_pad (tee, teesrc1);
|
||||
gst_element_release_request_pad (tee, teesrc2);
|
||||
gst_object_unref (tee);
|
||||
|
||||
gst_object_unref (mysink1);
|
||||
gst_object_unref (mysink2);
|
||||
gst_object_unref (mysrc);
|
||||
gst_caps_unref (caps);
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
static Suite *
|
||||
tee_suite (void)
|
||||
{
|
||||
|
@ -464,6 +598,7 @@ tee_suite (void)
|
|||
tcase_add_test (tc_chain, test_release_while_buffer_alloc);
|
||||
tcase_add_test (tc_chain, test_release_while_second_buffer_alloc);
|
||||
tcase_add_test (tc_chain, test_internal_links);
|
||||
tcase_add_test (tc_chain, test_flow_aggregation);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue