mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-18 14:26:43 +00:00
do not call the unlink function on the target pad when the ghostpad
is unlinked. Add some unit tests for this behaviour. Fixes #566936.
This commit is contained in:
parent
044b46ec98
commit
ae76b3d606
2 changed files with 203 additions and 14 deletions
|
@ -652,23 +652,14 @@ link_failed:
|
||||||
static void
|
static void
|
||||||
gst_ghost_pad_do_unlink (GstPad * pad)
|
gst_ghost_pad_do_unlink (GstPad * pad)
|
||||||
{
|
{
|
||||||
GstPad *target;
|
|
||||||
GstPad *internal;
|
GstPad *internal;
|
||||||
|
|
||||||
target = gst_proxy_pad_get_target (pad);
|
|
||||||
internal = GST_PROXY_PAD_INTERNAL (pad);
|
internal = GST_PROXY_PAD_INTERNAL (pad);
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
|
GST_DEBUG_OBJECT (pad, "unlinking ghostpad");
|
||||||
|
|
||||||
/* The target of the internal pad is no longer valid */
|
/* The target of the internal pad is no longer valid */
|
||||||
gst_proxy_pad_set_target (internal, NULL);
|
gst_proxy_pad_set_target (internal, NULL);
|
||||||
|
|
||||||
if (target) {
|
|
||||||
if (GST_PAD_UNLINKFUNC (target))
|
|
||||||
GST_PAD_UNLINKFUNC (target) (target);
|
|
||||||
|
|
||||||
gst_object_unref (target);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -821,7 +812,6 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
|
||||||
gst_pad_set_unlink_function (pad,
|
gst_pad_set_unlink_function (pad,
|
||||||
GST_DEBUG_FUNCPTR (gst_ghost_pad_do_unlink));
|
GST_DEBUG_FUNCPTR (gst_ghost_pad_do_unlink));
|
||||||
|
|
||||||
|
|
||||||
/* INTERNAL PAD, it always exists and is child of the ghostpad */
|
/* INTERNAL PAD, it always exists and is child of the ghostpad */
|
||||||
otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
|
otherdir = (dir == GST_PAD_SRC) ? GST_PAD_SINK : GST_PAD_SRC;
|
||||||
if (templ) {
|
if (templ) {
|
||||||
|
|
|
@ -554,9 +554,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (test_ghost_pads_new_from_template)
|
GST_START_TEST (test_ghost_pads_new_from_template)
|
||||||
{
|
{
|
||||||
GstPad *sinkpad, *ghostpad;
|
GstPad *sinkpad, *ghostpad;
|
||||||
|
|
||||||
GstPadTemplate *padtempl, *ghosttempl;
|
GstPadTemplate *padtempl, *ghosttempl;
|
||||||
|
|
||||||
GstCaps *padcaps, *ghostcaps, *newcaps;
|
GstCaps *padcaps, *ghostcaps, *newcaps;
|
||||||
GstCaps *copypadcaps;
|
GstCaps *copypadcaps;
|
||||||
|
|
||||||
|
@ -607,9 +605,7 @@ GST_END_TEST;
|
||||||
GST_START_TEST (test_ghost_pads_new_no_target_from_template)
|
GST_START_TEST (test_ghost_pads_new_no_target_from_template)
|
||||||
{
|
{
|
||||||
GstPad *sinkpad, *ghostpad;
|
GstPad *sinkpad, *ghostpad;
|
||||||
|
|
||||||
GstPadTemplate *padtempl, *ghosttempl;
|
GstPadTemplate *padtempl, *ghosttempl;
|
||||||
|
|
||||||
GstCaps *padcaps, *ghostcaps, *newcaps;
|
GstCaps *padcaps, *ghostcaps, *newcaps;
|
||||||
GstCaps *copypadcaps, *copyghostcaps;
|
GstCaps *copypadcaps, *copyghostcaps;
|
||||||
|
|
||||||
|
@ -767,7 +763,208 @@ GST_START_TEST (test_ghost_pads_forward_setcaps)
|
||||||
gst_object_unref (src_template);
|
gst_object_unref (src_template);
|
||||||
gst_object_unref (sink_template);
|
gst_object_unref (sink_template);
|
||||||
}
|
}
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
static gint linked_count1;
|
||||||
|
static gint unlinked_count1;
|
||||||
|
static gint linked_count2;
|
||||||
|
static gint unlinked_count2;
|
||||||
|
|
||||||
|
static GstPadLinkReturn
|
||||||
|
pad_linked1 (GstPad *pad, GstPad *peer)
|
||||||
|
{
|
||||||
|
linked_count1++;
|
||||||
|
|
||||||
|
return GST_PAD_LINK_OK;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
pad_unlinked1 (GstPad *pad)
|
||||||
|
{
|
||||||
|
unlinked_count1++;
|
||||||
|
}
|
||||||
|
static GstPadLinkReturn
|
||||||
|
pad_linked2 (GstPad *pad, GstPad *peer)
|
||||||
|
{
|
||||||
|
linked_count2++;
|
||||||
|
|
||||||
|
return GST_PAD_LINK_OK;
|
||||||
|
}
|
||||||
|
static void
|
||||||
|
pad_unlinked2 (GstPad *pad)
|
||||||
|
{
|
||||||
|
unlinked_count2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_START_TEST (test_ghost_pads_sink_link_unlink)
|
||||||
|
{
|
||||||
|
GstCaps *padcaps;
|
||||||
|
GstPad *srcpad, *sinkpad, *ghostpad;
|
||||||
|
GstPadTemplate *srctempl, *sinktempl;
|
||||||
|
GstPadLinkReturn ret;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
padcaps = gst_caps_from_string ("some/caps");
|
||||||
|
fail_unless (padcaps != NULL);
|
||||||
|
|
||||||
|
srctempl = gst_pad_template_new ("srctempl", GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS, padcaps);
|
||||||
|
sinktempl = gst_pad_template_new ("sinktempl", GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS, padcaps);
|
||||||
|
gst_caps_unref (padcaps);
|
||||||
|
|
||||||
|
srcpad = gst_pad_new_from_template (srctempl, "src");
|
||||||
|
fail_unless (srcpad != NULL);
|
||||||
|
sinkpad = gst_pad_new_from_template (sinktempl, "sink");
|
||||||
|
fail_unless (sinkpad != NULL);
|
||||||
|
|
||||||
|
/* set up link/unlink functions for the pad */
|
||||||
|
linked_count1 = unlinked_count1 = 0;
|
||||||
|
gst_pad_set_link_function (sinkpad, pad_linked1);
|
||||||
|
gst_pad_set_unlink_function (sinkpad, pad_unlinked1);
|
||||||
|
linked_count2 = unlinked_count2 = 0;
|
||||||
|
gst_pad_set_link_function (srcpad, pad_linked2);
|
||||||
|
gst_pad_set_unlink_function (srcpad, pad_unlinked2);
|
||||||
|
|
||||||
|
/* this should trigger a link from the internal pad to the sinkpad */
|
||||||
|
ghostpad = gst_ghost_pad_new ("ghostpad", sinkpad);
|
||||||
|
fail_unless (ghostpad != NULL);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 0);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
/* this should not trigger anything because we are not directly
|
||||||
|
* linking/unlinking the sink pad. */
|
||||||
|
ret = gst_pad_link (srcpad, ghostpad);
|
||||||
|
fail_unless (ret == GST_PAD_LINK_OK);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
res = gst_pad_unlink (srcpad, ghostpad);
|
||||||
|
fail_unless (res == TRUE);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
/* this should trigger the unlink */
|
||||||
|
res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ghostpad), NULL);
|
||||||
|
fail_unless (res == TRUE);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 1);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
gst_object_unref (ghostpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
gst_object_unref (srctempl);
|
||||||
|
gst_object_unref (sinktempl);
|
||||||
|
}
|
||||||
|
GST_END_TEST;
|
||||||
|
|
||||||
|
GST_START_TEST (test_ghost_pads_src_link_unlink)
|
||||||
|
{
|
||||||
|
GstCaps *padcaps;
|
||||||
|
GstPad *srcpad, *sinkpad, *ghostpad, *dummy;
|
||||||
|
GstPadTemplate *srctempl, *sinktempl;
|
||||||
|
GstPadLinkReturn ret;
|
||||||
|
gboolean res;
|
||||||
|
|
||||||
|
padcaps = gst_caps_from_string ("some/caps");
|
||||||
|
fail_unless (padcaps != NULL);
|
||||||
|
|
||||||
|
srctempl = gst_pad_template_new ("srctempl", GST_PAD_SRC,
|
||||||
|
GST_PAD_ALWAYS, padcaps);
|
||||||
|
sinktempl = gst_pad_template_new ("sinktempl", GST_PAD_SINK,
|
||||||
|
GST_PAD_ALWAYS, padcaps);
|
||||||
|
gst_caps_unref (padcaps);
|
||||||
|
|
||||||
|
srcpad = gst_pad_new_from_template (srctempl, "src");
|
||||||
|
fail_unless (srcpad != NULL);
|
||||||
|
sinkpad = gst_pad_new_from_template (sinktempl, "sink");
|
||||||
|
fail_unless (sinkpad != NULL);
|
||||||
|
|
||||||
|
/* set up link/unlink functions for the pad */
|
||||||
|
linked_count1 = unlinked_count1 = 0;
|
||||||
|
gst_pad_set_link_function (srcpad, pad_linked1);
|
||||||
|
gst_pad_set_unlink_function (srcpad, pad_unlinked1);
|
||||||
|
linked_count2 = unlinked_count2 = 0;
|
||||||
|
gst_pad_set_link_function (sinkpad, pad_linked2);
|
||||||
|
gst_pad_set_unlink_function (sinkpad, pad_unlinked2);
|
||||||
|
|
||||||
|
/* this should trigger a link from the internal pad to the srcpad */
|
||||||
|
ghostpad = gst_ghost_pad_new ("ghostpad", srcpad);
|
||||||
|
fail_unless (ghostpad != NULL);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 0);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
/* this should fail with a critial */
|
||||||
|
ASSERT_CRITICAL (dummy = gst_ghost_pad_new ("ghostpad", srcpad));
|
||||||
|
fail_unless (dummy == NULL);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 0);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
/* this should not trigger anything because we are not directly
|
||||||
|
* linking/unlinking the src pad. */
|
||||||
|
ret = gst_pad_link (ghostpad, sinkpad);
|
||||||
|
fail_unless (ret == GST_PAD_LINK_OK);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
/* this link should fail because we are already linked. Let's make sure the
|
||||||
|
* link functions are not called */
|
||||||
|
ret = gst_pad_link (ghostpad, sinkpad);
|
||||||
|
fail_unless (ret == GST_PAD_LINK_WAS_LINKED);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 0);
|
||||||
|
|
||||||
|
res = gst_pad_unlink (ghostpad, sinkpad);
|
||||||
|
fail_unless (res == TRUE);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
res = gst_pad_unlink (ghostpad, sinkpad);
|
||||||
|
fail_unless (res == FALSE);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 0);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
/* this should trigger the unlink function */
|
||||||
|
res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ghostpad), NULL);
|
||||||
|
fail_unless (res == TRUE);
|
||||||
|
fail_unless (linked_count1 == 1);
|
||||||
|
fail_unless (unlinked_count1 == 1);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
/* and this the link function again */
|
||||||
|
res = gst_ghost_pad_set_target (GST_GHOST_PAD_CAST (ghostpad), srcpad);
|
||||||
|
fail_unless (res == TRUE);
|
||||||
|
fail_unless (linked_count1 == 2);
|
||||||
|
fail_unless (unlinked_count1 == 1);
|
||||||
|
fail_unless (linked_count2 == 1);
|
||||||
|
fail_unless (unlinked_count2 == 1);
|
||||||
|
|
||||||
|
gst_object_unref (ghostpad);
|
||||||
|
gst_object_unref (sinkpad);
|
||||||
|
gst_object_unref (srcpad);
|
||||||
|
gst_object_unref (srctempl);
|
||||||
|
gst_object_unref (sinktempl);
|
||||||
|
}
|
||||||
GST_END_TEST;
|
GST_END_TEST;
|
||||||
|
|
||||||
static Suite *
|
static Suite *
|
||||||
|
@ -789,6 +986,8 @@ gst_ghost_pad_suite (void)
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
tcase_add_test (tc_chain, test_ghost_pads_new_from_template);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
|
tcase_add_test (tc_chain, test_ghost_pads_new_no_target_from_template);
|
||||||
tcase_add_test (tc_chain, test_ghost_pads_forward_setcaps);
|
tcase_add_test (tc_chain, test_ghost_pads_forward_setcaps);
|
||||||
|
tcase_add_test (tc_chain, test_ghost_pads_sink_link_unlink);
|
||||||
|
tcase_add_test (tc_chain, test_ghost_pads_src_link_unlink);
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue