mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-31 11:32:38 +00:00
bin: emit deep-element-{added,removed} for children of newly-added/removed bin
https://bugzilla.gnome.org/show_bug.cgi?id=578933
This commit is contained in:
parent
81dec8cc4d
commit
ef1444cfe4
2 changed files with 75 additions and 5 deletions
53
gst/gstbin.c
53
gst/gstbin.c
|
@ -1112,6 +1112,53 @@ unlink_pads (const GValue * item, gpointer user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
bin_deep_iterator_foreach (const GValue * item, gpointer user_data)
|
||||||
|
{
|
||||||
|
GQueue *queue = user_data;
|
||||||
|
|
||||||
|
g_queue_push_tail (queue, g_value_dup_object (item));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_bin_do_deep_add_remove (GstBin * bin, gint sig_id, const gchar * sig_name,
|
||||||
|
GstElement * element)
|
||||||
|
{
|
||||||
|
g_signal_emit (bin, sig_id, 0, bin, element);
|
||||||
|
|
||||||
|
/* When removing a bin, emit deep-element-* for everything in the bin too */
|
||||||
|
if (GST_IS_BIN (element)) {
|
||||||
|
GstIterator *it;
|
||||||
|
GstIteratorResult ires;
|
||||||
|
GQueue elements = G_QUEUE_INIT;
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (bin, "Recursing into bin %" GST_PTR_FORMAT " for %s",
|
||||||
|
element, sig_name);
|
||||||
|
it = gst_bin_iterate_recurse (GST_BIN_CAST (element));
|
||||||
|
do {
|
||||||
|
ires = gst_iterator_foreach (it, bin_deep_iterator_foreach, &elements);
|
||||||
|
if (ires != GST_ITERATOR_DONE) {
|
||||||
|
g_queue_foreach (&elements, (GFunc) g_object_unref, NULL);
|
||||||
|
g_queue_clear (&elements);
|
||||||
|
}
|
||||||
|
} while (ires == GST_ITERATOR_RESYNC);
|
||||||
|
if (ires != GST_ITERATOR_ERROR) {
|
||||||
|
GstElement *e;
|
||||||
|
|
||||||
|
while ((e = g_queue_pop_head (&elements))) {
|
||||||
|
GstObject *parent = gst_object_get_parent (GST_OBJECT_CAST (e));
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (bin, "calling %s for element %" GST_PTR_FORMAT
|
||||||
|
" in bin %" GST_PTR_FORMAT, sig_name, e, parent);
|
||||||
|
g_signal_emit (bin, sig_id, 0, parent, e);
|
||||||
|
gst_object_unref (parent);
|
||||||
|
g_object_unref (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gst_iterator_free (it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* vmethod that adds an element to a bin
|
/* vmethod that adds an element to a bin
|
||||||
*
|
*
|
||||||
* MT safe
|
* MT safe
|
||||||
|
@ -1327,7 +1374,8 @@ no_state_recalc:
|
||||||
gst_child_proxy_child_added ((GstChildProxy *) bin, (GObject *) element,
|
gst_child_proxy_child_added ((GstChildProxy *) bin, (GObject *) element,
|
||||||
elem_name);
|
elem_name);
|
||||||
|
|
||||||
g_signal_emit (bin, gst_bin_signals[DEEP_ELEMENT_ADDED], 0, bin, element);
|
gst_bin_do_deep_add_remove (bin, gst_bin_signals[DEEP_ELEMENT_ADDED],
|
||||||
|
"deep-element-added", element);
|
||||||
|
|
||||||
g_free (elem_name);
|
g_free (elem_name);
|
||||||
|
|
||||||
|
@ -1710,7 +1758,8 @@ no_state_recalc:
|
||||||
gst_child_proxy_child_removed ((GstChildProxy *) bin, (GObject *) element,
|
gst_child_proxy_child_removed ((GstChildProxy *) bin, (GObject *) element,
|
||||||
elem_name);
|
elem_name);
|
||||||
|
|
||||||
g_signal_emit (bin, gst_bin_signals[DEEP_ELEMENT_REMOVED], 0, bin, element);
|
gst_bin_do_deep_add_remove (bin, gst_bin_signals[DEEP_ELEMENT_REMOVED],
|
||||||
|
"deep-element-removed", element);
|
||||||
|
|
||||||
g_free (elem_name);
|
g_free (elem_name);
|
||||||
/* element is really out of our control now */
|
/* element is really out of our control now */
|
||||||
|
|
|
@ -1571,8 +1571,6 @@ add_cb (GstBin * pipeline, GstBin * bin, GstElement * element, GList ** list)
|
||||||
static void
|
static void
|
||||||
remove_cb (GstBin * pipeline, GstBin * bin, GstElement * element, GList ** list)
|
remove_cb (GstBin * pipeline, GstBin * bin, GstElement * element, GList ** list)
|
||||||
{
|
{
|
||||||
fail_unless (GST_OBJECT_PARENT (element) == NULL);
|
|
||||||
|
|
||||||
*list = g_list_prepend (*list, element);
|
*list = g_list_prepend (*list, element);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1597,7 +1595,7 @@ GST_START_TEST (test_deep_added_removed)
|
||||||
gst_bin_remove (GST_BIN (pipe), e);
|
gst_bin_remove (GST_BIN (pipe), e);
|
||||||
fail_unless (element_was_removed (e));
|
fail_unless (element_was_removed (e));
|
||||||
|
|
||||||
/* let's try with a deeper hierarchy */
|
/* let's try with a deeper hierarchy, construct it from top-level down */
|
||||||
bin0 = gst_bin_new (NULL);
|
bin0 = gst_bin_new (NULL);
|
||||||
gst_bin_add (GST_BIN (pipe), bin0);
|
gst_bin_add (GST_BIN (pipe), bin0);
|
||||||
bin1 = gst_bin_new (NULL);
|
bin1 = gst_bin_new (NULL);
|
||||||
|
@ -1610,11 +1608,34 @@ GST_START_TEST (test_deep_added_removed)
|
||||||
fail_unless (added == NULL);
|
fail_unless (added == NULL);
|
||||||
fail_unless (removed == NULL);
|
fail_unless (removed == NULL);
|
||||||
|
|
||||||
|
gst_object_ref (e); /* keep e alive */
|
||||||
gst_bin_remove (GST_BIN (bin1), e);
|
gst_bin_remove (GST_BIN (bin1), e);
|
||||||
fail_unless (element_was_removed (e));
|
fail_unless (element_was_removed (e));
|
||||||
fail_unless (added == NULL);
|
fail_unless (added == NULL);
|
||||||
fail_unless (removed == NULL);
|
fail_unless (removed == NULL);
|
||||||
|
|
||||||
|
/* now add existing bin hierarchy to pipeline (first remove it so we can re-add it) */
|
||||||
|
gst_object_ref (bin0); /* keep bin0 alive */
|
||||||
|
gst_bin_remove (GST_BIN (pipe), bin0);
|
||||||
|
fail_unless (element_was_removed (bin0));
|
||||||
|
fail_unless (element_was_removed (bin1));
|
||||||
|
fail_unless (added == NULL);
|
||||||
|
fail_unless (removed == NULL);
|
||||||
|
|
||||||
|
/* re-adding element to removed bin should not trigger our callbacks */
|
||||||
|
gst_bin_add (GST_BIN (bin1), e);
|
||||||
|
fail_unless (added == NULL);
|
||||||
|
fail_unless (removed == NULL);
|
||||||
|
|
||||||
|
gst_bin_add (GST_BIN (pipe), bin0);
|
||||||
|
fail_unless (element_was_added (bin0));
|
||||||
|
fail_unless (element_was_added (bin1));
|
||||||
|
fail_unless (element_was_added (e));
|
||||||
|
fail_unless (added == NULL);
|
||||||
|
fail_unless (removed == NULL);
|
||||||
|
gst_object_unref (bin0);
|
||||||
|
gst_object_unref (e);
|
||||||
|
|
||||||
/* disconnect signals, unref will trigger remove callbacks otherwise */
|
/* disconnect signals, unref will trigger remove callbacks otherwise */
|
||||||
g_signal_handler_disconnect (pipe, id_added);
|
g_signal_handler_disconnect (pipe, id_added);
|
||||||
g_signal_handler_disconnect (pipe, id_removed);
|
g_signal_handler_disconnect (pipe, id_removed);
|
||||||
|
|
Loading…
Reference in a new issue