element: set pads need-parent flag to false when removing

When a pad is added the need-parent flag is set to true, so when
they are removed the flag should be set back to false

This was preventing GstPads to be reused in elements (removed and
later re-added). A unit tests was added to verify that this is
working now.

The use case is tsdemux that has a program-number property and
allows the user to switch programs. In order to do that tsdemux
will remove the pads of the current program and add from the new
ones. The removed pads are kept in the demuxer for later if the
user selects the old program again.
This commit is contained in:
Thiago Santos 2014-05-29 14:07:15 -03:00
parent 01c9ae2630
commit 1911554cff
2 changed files with 36 additions and 0 deletions

View file

@ -795,6 +795,7 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
break;
}
element->pads = g_list_remove (element->pads, pad);
GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLAG_NEED_PARENT);
element->numpads--;
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);

View file

@ -50,6 +50,40 @@ GST_START_TEST (test_add_remove_pad)
GST_END_TEST;
GST_START_TEST (test_add_remove_readd_pad)
{
GstElement *e;
GstPad *p;
/* getting an existing element class is cheating, but easier */
e = gst_element_factory_make ("fakesrc", "source");
/* create a new floating pad with refcount 1 */
p = gst_pad_new ("source", GST_PAD_SRC);
gst_object_ref (p);
/* simulate a real scenario where the pad is activated before added */
fail_unless (gst_pad_set_active (p, TRUE));
gst_element_add_pad (e, p);
/* now remove and deactivate it */
fail_unless (gst_pad_set_active (p, FALSE));
gst_element_remove_pad (e, p);
/* should be able to reuse the same pad */
fail_unless (gst_pad_set_active (p, TRUE));
fail_unless (gst_element_add_pad (e, p));
/* clean up our own reference */
gst_object_unref (p);
gst_object_unref (e);
}
GST_END_TEST;
GST_START_TEST (test_add_pad_unref_element)
{
GstElement *e;
@ -355,6 +389,7 @@ gst_element_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_add_remove_pad);
tcase_add_test (tc_chain, test_add_remove_readd_pad);
tcase_add_test (tc_chain, test_add_pad_unref_element);
tcase_add_test (tc_chain, test_error_no_bus);
tcase_add_test (tc_chain, test_link);