mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-19 20:46:22 +00:00
gst/gstutils.c (gst_element_link_pads): Instead of calling gst_pad_link, call pad_link_maybe_ghosting,
Original commit message from CVS: 2005-05-13 Andy Wingo <wingo@pobox.com> * gst/gstutils.c (gst_element_link_pads): Instead of calling gst_pad_link, call pad_link_maybe_ghosting, (pad_link_maybe_ghosting): Links pads, making sure that the elements being linked are in the same bin. (find_common_root, object_has_ancestor, ghost_up, remove_pad): Helpers for pad_link_maybe_ghosting.
This commit is contained in:
parent
8eb7e12669
commit
79d4977020
2 changed files with 185 additions and 4 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2005-05-13 Andy Wingo <wingo@pobox.com>
|
||||||
|
|
||||||
|
* gst/gstutils.c (gst_element_link_pads): Instead of calling
|
||||||
|
gst_pad_link, call pad_link_maybe_ghosting,
|
||||||
|
(pad_link_maybe_ghosting): Links pads, making sure that the
|
||||||
|
elements being linked are in the same bin.
|
||||||
|
(find_common_root, object_has_ancestor, ghost_up, remove_pad):
|
||||||
|
Helpers for pad_link_maybe_ghosting.
|
||||||
|
|
||||||
2005-05-13 Tim-Philipp Müller <tim at centricular dot net>
|
2005-05-13 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* configure.ac:
|
* configure.ac:
|
||||||
|
|
180
gst/gstutils.c
180
gst/gstutils.c
|
@ -736,6 +736,178 @@ gst_element_state_get_name (GstElementState state)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if return val is true, *direct_child is a caller-owned ref on the direct
|
||||||
|
* child of ancestor that is part of object's ancestry */
|
||||||
|
static gboolean
|
||||||
|
object_has_ancestor (GstObject * object, GstObject * ancestor,
|
||||||
|
GstObject ** direct_child)
|
||||||
|
{
|
||||||
|
GstObject *child, *parent;
|
||||||
|
|
||||||
|
if (direct_child)
|
||||||
|
*direct_child = NULL;
|
||||||
|
|
||||||
|
child = gst_object_ref (object);
|
||||||
|
parent = gst_object_get_parent (object);
|
||||||
|
|
||||||
|
while (parent) {
|
||||||
|
if (ancestor == parent) {
|
||||||
|
if (direct_child)
|
||||||
|
*direct_child = child;
|
||||||
|
else
|
||||||
|
gst_object_unref (child);
|
||||||
|
gst_object_unref (parent);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (child);
|
||||||
|
child = parent;
|
||||||
|
parent = gst_object_get_parent (parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_object_unref (child);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* caller owns return */
|
||||||
|
static GstObject *
|
||||||
|
find_common_root (GstObject * o1, GstObject * o2)
|
||||||
|
{
|
||||||
|
GstObject *top = o1;
|
||||||
|
GstObject *kid1, *kid2;
|
||||||
|
GstObject *root = NULL;
|
||||||
|
|
||||||
|
while (GST_OBJECT_PARENT (top))
|
||||||
|
top = GST_OBJECT_PARENT (top);
|
||||||
|
|
||||||
|
/* the itsy-bitsy spider... */
|
||||||
|
|
||||||
|
if (!object_has_ancestor (o2, top, &kid2))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
root = gst_object_ref (top);
|
||||||
|
while (TRUE) {
|
||||||
|
if (!object_has_ancestor (o1, kid2, &kid1)) {
|
||||||
|
gst_object_unref (kid2);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
root = kid2;
|
||||||
|
if (!object_has_ancestor (o2, kid1, &kid2)) {
|
||||||
|
gst_object_unref (kid1);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
root = kid1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* caller does not own return */
|
||||||
|
static GstPad *
|
||||||
|
ghost_up (GstElement * e, GstPad * pad)
|
||||||
|
{
|
||||||
|
static gint ghost_pad_index = 0;
|
||||||
|
GstPad *gpad;
|
||||||
|
gchar *name;
|
||||||
|
|
||||||
|
name = g_strdup_printf ("ghost%d", ghost_pad_index++);
|
||||||
|
gpad = gst_ghost_pad_new (name, pad);
|
||||||
|
g_free (name);
|
||||||
|
|
||||||
|
if (!gst_element_add_pad ((GstElement *) GST_OBJECT_PARENT (e), gpad)) {
|
||||||
|
g_warning ("Pad named %s already exists in element %s\n",
|
||||||
|
GST_OBJECT_NAME (gpad), GST_OBJECT_NAME (GST_OBJECT_PARENT (e)));
|
||||||
|
gst_object_unref ((GstObject *) gpad);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return gpad;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
remove_pad (gpointer ppad, gpointer unused)
|
||||||
|
{
|
||||||
|
GstPad *pad = ppad;
|
||||||
|
|
||||||
|
if (!gst_element_remove_pad ((GstElement *) GST_OBJECT_PARENT (pad), pad))
|
||||||
|
g_warning ("Couldn't remove pad %s from element %s",
|
||||||
|
GST_OBJECT_NAME (pad), GST_OBJECT_NAME (GST_OBJECT_PARENT (pad)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
prepare_link_maybe_ghosting (GstPad ** src, GstPad ** sink,
|
||||||
|
GSList ** pads_created)
|
||||||
|
{
|
||||||
|
GstObject *root;
|
||||||
|
GstObject *e1, *e2;
|
||||||
|
GSList *pads_created_local = NULL;
|
||||||
|
|
||||||
|
g_assert (pads_created);
|
||||||
|
|
||||||
|
e1 = GST_OBJECT_PARENT (*src);
|
||||||
|
e2 = GST_OBJECT_PARENT (*sink);
|
||||||
|
|
||||||
|
if (GST_OBJECT_PARENT (e1) == GST_OBJECT_PARENT (e2)) {
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "%s and %s in same bin, no need for ghost pads",
|
||||||
|
GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_CAT_INFO (GST_CAT_PADS, "%s and %s not in same bin, making ghost pads",
|
||||||
|
GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
|
||||||
|
|
||||||
|
/* we need to setup some ghost pads */
|
||||||
|
root = find_common_root (e1, e2);
|
||||||
|
if (!root) {
|
||||||
|
g_warning
|
||||||
|
("Trying to connect elements that don't share a common ancestor: %s and %s\n",
|
||||||
|
GST_ELEMENT_NAME (e1), GST_ELEMENT_NAME (e2));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (GST_OBJECT_PARENT (e1) != root) {
|
||||||
|
*src = ghost_up ((GstElement *) e1, *src);
|
||||||
|
if (!*src)
|
||||||
|
goto cleanup_fail;
|
||||||
|
e1 = GST_OBJECT_PARENT (*src);
|
||||||
|
pads_created_local = g_slist_prepend (pads_created_local, *src);
|
||||||
|
}
|
||||||
|
while (GST_OBJECT_PARENT (e2) != root) {
|
||||||
|
*sink = ghost_up ((GstElement *) e2, *sink);
|
||||||
|
if (!*sink)
|
||||||
|
goto cleanup_fail;
|
||||||
|
e2 = GST_OBJECT_PARENT (*sink);
|
||||||
|
pads_created_local = g_slist_prepend (pads_created_local, *sink);
|
||||||
|
}
|
||||||
|
|
||||||
|
*pads_created = g_slist_concat (*pads_created, pads_created_local);
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
cleanup_fail:
|
||||||
|
g_slist_foreach (pads_created_local, remove_pad, NULL);
|
||||||
|
g_slist_free (pads_created_local);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
pad_link_maybe_ghosting (GstPad * src, GstPad * sink)
|
||||||
|
{
|
||||||
|
GSList *pads_created = NULL;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
if (!prepare_link_maybe_ghosting (&src, &sink, &pads_created)) {
|
||||||
|
ret = FALSE;
|
||||||
|
} else {
|
||||||
|
ret = (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ret) {
|
||||||
|
g_slist_foreach (pads_created, remove_pad, NULL);
|
||||||
|
}
|
||||||
|
g_slist_free (pads_created);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_element_link_pads:
|
* gst_element_link_pads:
|
||||||
* @src: a #GstElement containing the source pad.
|
* @src: a #GstElement containing the source pad.
|
||||||
|
@ -835,7 +1007,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
|
||||||
/* two explicitly specified pads */
|
/* two explicitly specified pads */
|
||||||
result = gst_pad_link (srcpad, destpad);
|
result = pad_link_maybe_ghosting (srcpad, destpad);
|
||||||
|
|
||||||
gst_object_unref (GST_OBJECT (srcpad));
|
gst_object_unref (GST_OBJECT (srcpad));
|
||||||
gst_object_unref (GST_OBJECT (destpad));
|
gst_object_unref (GST_OBJECT (destpad));
|
||||||
|
@ -862,7 +1034,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
|
||||||
gst_object_ref (GST_OBJECT (temp));
|
gst_object_ref (GST_OBJECT (temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp && gst_pad_link (srcpad, temp) == GST_PAD_LINK_OK) {
|
if (temp && pad_link_maybe_ghosting (srcpad, temp)) {
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
|
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
|
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
|
||||||
if (destpad)
|
if (destpad)
|
||||||
|
@ -904,7 +1076,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
|
||||||
(GST_PAD_PEER (destpad) == NULL)) {
|
(GST_PAD_PEER (destpad) == NULL)) {
|
||||||
GstPad *temp = gst_element_get_compatible_pad (src, destpad, NULL);
|
GstPad *temp = gst_element_get_compatible_pad (src, destpad, NULL);
|
||||||
|
|
||||||
if (temp && gst_pad_link (temp, destpad) == GST_PAD_LINK_OK) {
|
if (temp && pad_link_maybe_ghosting (temp, destpad)) {
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
|
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
|
GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
|
||||||
gst_object_unref (GST_OBJECT (temp));
|
gst_object_unref (GST_OBJECT (temp));
|
||||||
|
@ -958,7 +1130,7 @@ gst_element_link_pads (GstElement * src, const gchar * srcpadname,
|
||||||
gst_element_get_request_pad (src, srctempl->name_template);
|
gst_element_get_request_pad (src, srctempl->name_template);
|
||||||
destpad =
|
destpad =
|
||||||
gst_element_get_request_pad (dest, desttempl->name_template);
|
gst_element_get_request_pad (dest, desttempl->name_template);
|
||||||
if (gst_pad_link (srcpad, destpad) == GST_PAD_LINK_OK) {
|
if (pad_link_maybe_ghosting (srcpad, destpad)) {
|
||||||
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
|
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
|
||||||
"linked pad %s:%s to pad %s:%s",
|
"linked pad %s:%s to pad %s:%s",
|
||||||
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
|
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
|
||||||
|
|
Loading…
Reference in a new issue