+ GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->sink);
+ GList *endelements = NULL, *templist = NULL;
+ GstElement *element;
+
+ /* exit if plugging is already done */
+ if ((GstElement *) conn->src == conn->current)
+ return GST_PAD_CONNECT_DONE;
+
+ /* try to shorten the list at the end and not duplicate connection code */
+ if (plugpath != NULL)
+ {
+ templist = g_list_last (plugpath);
+ element = (GstElement *) conn->src;
+ while ((plugpath != NULL) && (element = gst_spider_find_element_to_plug (element, (GstElementFactory *) plugpath->data, GST_PAD_SINK)))
+ {
+ GList *cur = templist;
+ endelements = g_list_prepend (endelements, element);
+ templist = g_list_previous (templist);
+ g_list_delete_link (cur, cur);
+ }
+ }
+
+ /* do the connecting */
+ while (conn->current != (GstElement *) (endelements == NULL ? conn->src : endelements->data))
+ {
+ /* get sink element to plug, src is conn->current */
+ if (plugpath == NULL)
+ {
+ element = (GstElement *) (endelements == NULL ? conn->src : endelements->data);
+ } else {
+ element = gst_elementfactory_create ((GstElementFactory *) plugpath->data,
+ gst_spider_unused_elementname (GST_BIN (spider), GST_OBJECT_NAME (plugpath->data)));
+ gst_bin_add (GST_BIN (spider), element);
+ }
+ /* insert and connect new element */
+ if (!gst_element_connect_elements (conn->current, element))
+ {
+ /* check if the src has SOMETIMES templates. If so, connect a callback */
+ GList *templs = gst_element_get_padtemplate_list (conn->current);
+
+ /* remove element that couldn't be connected, if it wasn't the endpoint */
+ if (element != (GstElement *) conn->src)
+ gst_bin_remove (GST_BIN (spider), element);
+
+ while (templs) {
+ GstPadTemplate *templ = (GstPadTemplate *) templs->data;
+ if ((GST_PADTEMPLATE_DIRECTION (templ) == GST_PAD_SRC) && (GST_PADTEMPLATE_PRESENCE(templ) == GST_PAD_SOMETIMES))
+ {
+ GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, "adding callback to connect element %s to %s\n", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
+ conn->signal_id = g_signal_connect (G_OBJECT (conn->current), "new_pad",
+ G_CALLBACK (gst_spider_connect_sometimes), conn);
+ g_list_free (plugpath);
+ return GST_PAD_CONNECT_DELAYED;
+ }
+ templs = g_list_next (templs);
+ }
+ GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, "no chance to connect element %s to %s\n", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src));
+ g_list_free (plugpath);
+ return GST_PAD_CONNECT_REFUSED;
+ }
+ GST_DEBUG (GST_CAT_AUTOPLUG_ATTEMPT, "added element %s and attached it to element %s\n", GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (conn->current));
+ gst_spider_connection_add (conn, element);
+ if (plugpath != NULL)
+ plugpath = g_list_delete_link (plugpath, plugpath);
+ }
+
+ /* ref all elements at the end */
+ while (endelements)
+ {
+ gst_spider_connection_add (conn, endelements->data);
+ endelements = g_list_delete_link (endelements, endelements);
+ }
+
+ return GST_PAD_CONNECT_DONE;
+}
+/* checks, if src is already connected to an element from factory fac on direction dir */
+static GstElement *
+gst_spider_find_element_to_plug (GstElement *src, GstElementFactory *fac, GstPadDirection dir)
+{
+ GList *padlist = GST_ELEMENT_PADS (src);
+
+ while (padlist)
+ {
+ GstPad *pad = (GstPad *) GST_PAD_REALIZE (padlist->data);
+ /* is the pad on the right side and is it connected? */
+ if ((GST_PAD_DIRECTION (pad) == dir) && (pad = GST_PAD (GST_RPAD_PEER (pad))))
+ {
+ /* is the element the pad is connected to of the right type? */
+ GstElement *element = GST_PAD_PARENT (pad);
+ if (GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element))->elementfactory == fac) {
+ return element;
+ }
+ }
+ padlist = g_list_next (padlist);
+ }
+
+ return NULL;
+}
+/* try to establish the connection */
+static GstPadConnectReturn
+gst_spider_plug (GstSpiderConnection *conn)
+{
+ if ((GstElement *) conn->src == conn->current)
+ return GST_PAD_CONNECT_DONE;
+ if ((GstElement *) conn->sink == conn->current)
+ return gst_spider_plug_from_srcpad (conn, conn->sink->src);
+ g_warning ("FIXME: autoplugging only possible from GstSpiderIdentity conn->sink yet (yep, that's technical)\n");
+ return GST_PAD_CONNECT_REFUSED;
+}
+/* try to establish the connection using this pad */
+static GstPadConnectReturn
+gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad)
+{
+ GstElement *element;