element: set pads need-parent flag to false when removing
authorThiago Santos <ts.santos@sisa.samsung.com>
Thu, 29 May 2014 17:07:15 +0000 (14:07 -0300)
committerThiago Santos <ts.santos@sisa.samsung.com>
Thu, 29 May 2014 20:01:20 +0000 (17:01 -0300)
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.

gst/gstelement.c
tests/check/gst/gstelement.c

index cc96d25..a01a290 100644 (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);
index 8732611..faa95a5 100644 (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);