From 778981a34e44a89627f75c663349fcc3cb2c9680 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 25 Apr 2005 09:51:06 +0000 Subject: [PATCH] gst/autoplug/: Die, spider, die. Original commit message from CVS: * gst/autoplug/.cvsignore: * gst/autoplug/Makefile.am: * gst/autoplug/gstsearchfuncs.c: * gst/autoplug/gstsearchfuncs.h: * gst/autoplug/gstspider.c: * gst/autoplug/gstspider.h: * gst/autoplug/gstspideridentity.c: * gst/autoplug/gstspideridentity.h: * gst/autoplug/spidertest.c: Die, spider, die. --- ChangeLog | 13 + gst/autoplug/.gitignore | 6 - gst/autoplug/Makefile.am | 18 - gst/autoplug/gstsearchfuncs.c | 440 ------------------ gst/autoplug/gstsearchfuncs.h | 64 --- gst/autoplug/gstspider.c | 765 ------------------------------- gst/autoplug/gstspider.h | 93 ---- gst/autoplug/gstspideridentity.c | 608 ------------------------ gst/autoplug/gstspideridentity.h | 72 --- gst/autoplug/spidertest.c | 138 ------ 10 files changed, 13 insertions(+), 2204 deletions(-) delete mode 100644 gst/autoplug/.gitignore delete mode 100644 gst/autoplug/Makefile.am delete mode 100644 gst/autoplug/gstsearchfuncs.c delete mode 100644 gst/autoplug/gstsearchfuncs.h delete mode 100644 gst/autoplug/gstspider.c delete mode 100644 gst/autoplug/gstspider.h delete mode 100644 gst/autoplug/gstspideridentity.c delete mode 100644 gst/autoplug/gstspideridentity.h delete mode 100644 gst/autoplug/spidertest.c diff --git a/ChangeLog b/ChangeLog index a8f2a473ab..43740de64f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2005-04-25 Ronald S. Bultje + + * gst/autoplug/.cvsignore: + * gst/autoplug/Makefile.am: + * gst/autoplug/gstsearchfuncs.c: + * gst/autoplug/gstsearchfuncs.h: + * gst/autoplug/gstspider.c: + * gst/autoplug/gstspider.h: + * gst/autoplug/gstspideridentity.c: + * gst/autoplug/gstspideridentity.h: + * gst/autoplug/spidertest.c: + Die, spider, die. + 2005-04-25 Wim Taymans * gst/gstpad.c: (gst_pad_set_active), (gst_pad_peer_set_active), diff --git a/gst/autoplug/.gitignore b/gst/autoplug/.gitignore deleted file mode 100644 index cd961510f1..0000000000 --- a/gst/autoplug/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -autoplugtest -spidertest -*.bb -*.bbg -*.da -*.def diff --git a/gst/autoplug/Makefile.am b/gst/autoplug/Makefile.am deleted file mode 100644 index ea317fab58..0000000000 --- a/gst/autoplug/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ - -plugin_LTLIBRARIES = libgstspider.la - -libgstspider_la_SOURCES = \ - gstspider.c gstspideridentity.c \ - gstsearchfuncs.c -libgstspider_la_CFLAGS = $(GST_OBJ_CFLAGS) -libgstspider_la_LIBADD = $(GST_OBJ_LIBS) -libgstspider_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) - -noinst_HEADERS = gstspider.h gstspideridentity.h gstsearchfuncs.h - -noinst_PROGRAMS = spidertest - -spidertest_SOURCES = spidertest.c -spidertest_CFLAGS = $(GST_OBJ_CFLAGS) -spidertest_LDADD = $(GST_OBJ_LIBS) - diff --git a/gst/autoplug/gstsearchfuncs.c b/gst/autoplug/gstsearchfuncs.c deleted file mode 100644 index a0f7362ede..0000000000 --- a/gst/autoplug/gstsearchfuncs.c +++ /dev/null @@ -1,440 +0,0 @@ -/* GStreamer - * Copyright (C) 1999-2002 Erik Walthinsen - * 2000-2002 Wim Taymans - * - * gstsearchfuncs.c: functions needed when doing searches while - * autoplugging - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gstsearchfuncs.h" - -/* FIXME: "evil hack" alarm, we need a better way to get a category in here */ -GST_DEBUG_CATEGORY_EXTERN (GST_CAT_AUTOPLUG_ATTEMPT); -#define GST_CAT_DEFAULT GST_CAT_AUTOPLUG_ATTEMPT - -/* function that really misses in GLib - * though the GLib version should take a function as argument... - */ -static void -g_list_free_list_and_elements (GList * list) -{ - GList *walk = list; - - while (walk) { - g_free (walk->data); - walk = g_list_next (walk); - } - g_list_free (list); -} - -/** - * gst_autoplug_caps_intersect: - * @src: a source #GstCaps - * @sink: the sink #GstCaps - * - * Checks if the given caps have a non-null intersection. - * - * Returns: TRUE, if both caps intersect. - */ -gboolean -gst_autoplug_caps_intersect (const GstCaps * src, const GstCaps * sink) -{ - GstCaps *caps; - - /* get an intersection */ - caps = gst_caps_intersect (src, sink); - - /* if the caps can't link, there is no intersection */ - if (gst_caps_is_empty (caps)) { - gst_caps_unref (caps); - return FALSE; - } - - /* hurrah, we can link, now remove the intersection */ - gst_caps_unref (caps); - return TRUE; -} - -/** - * gst_autoplug_can_connect_src: - * @fac: factory to connect to - * @src: caps to check - * - * Checks if a factory's sink can connect to the given caps - * - * Returns: #GstPadTemplate that can connect to the given caps - */ -GstPadTemplate * -gst_autoplug_can_connect_src (GstElementFactory * fac, const GstCaps * src) -{ - GList *templs; - - templs = fac->padtemplates; - - while (templs) { - if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK) && - gst_autoplug_caps_intersect (src, - GST_PAD_TEMPLATE_CAPS (templs->data))) { - return GST_PAD_TEMPLATE (templs->data); - } - templs = g_list_next (templs); - } - - return NULL; -} - -/** - * gst_autoplug_can_connect_sink: - * @fac: factory to connect to - * @sink: caps to check - * - * Checks if a factory's src can connect to the given caps - * - * Returns: #GstPadTemplate that can connect to the given caps - */ -GstPadTemplate * -gst_autoplug_can_connect_sink (GstElementFactory * fac, const GstCaps * sink) -{ - GList *templs; - - templs = fac->padtemplates; - - while (templs) { - GstCaps *caps = GST_PAD_TEMPLATE_CAPS (templs->data); - - if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SRC) && - gst_autoplug_caps_intersect (caps, sink)) { - return GST_PAD_TEMPLATE (templs->data); - } - templs = g_list_next (templs); - } - - return NULL; -} - -GstPadTemplate * -gst_autoplug_can_match (GstElementFactory * src, GstElementFactory * dest) -{ - GList *srctemps, *desttemps; - - srctemps = src->padtemplates; - - while (srctemps) { - GstPadTemplate *srctemp = (GstPadTemplate *) srctemps->data; - - desttemps = dest->padtemplates; - - while (desttemps) { - GstPadTemplate *desttemp = (GstPadTemplate *) desttemps->data; - - if (srctemp->direction == GST_PAD_SRC && - desttemp->direction == GST_PAD_SINK) { - if (gst_autoplug_caps_intersect (gst_pad_template_get_caps (srctemp), - gst_pad_template_get_caps (desttemp))) { - GST_DEBUG ("factory \"%s\" can connect with factory \"%s\"", - GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest)); - return desttemp; - } - } - - desttemps = g_list_next (desttemps); - } - srctemps = g_list_next (srctemps); - } - GST_DEBUG ("factory \"%s\" cannot connect with factory \"%s\"", - GST_OBJECT_NAME (src), GST_OBJECT_NAME (dest)); - return NULL; -} - -/* returns TRUE if the factory has padtemplates with the specified direction */ -gboolean -gst_autoplug_factory_has_direction (GstElementFactory * fac, - GstPadDirection dir) -{ - GList *templs = fac->padtemplates; - - while (templs) { - if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) { - return TRUE; - } - templs = g_list_next (templs); - } - - return FALSE; -} - -/* Decisions are based on the padtemplates. - * These functions return a new list so be sure to free it. - */ -GList * -gst_autoplug_factories_sinks (GList * factories) -{ - GList *ret = NULL; - - while (factories) { - if (gst_autoplug_factory_has_sink (factories->data)) - ret = g_list_prepend (ret, factories->data); - factories = g_list_next (factories); - } - return ret; -} - -GList * -gst_autoplug_factories_srcs (GList * factories) -{ - GList *ret = NULL; - - while (factories) { - if (gst_autoplug_factory_has_src (factories->data)) - ret = g_list_prepend (ret, factories->data); - factories = g_list_next (factories); - } - return ret; -} - -GList * -gst_autoplug_factories_filters (GList * factories) -{ - GList *ret = NULL; - - while (factories) { - /* if you want it faster do src/sink check at once, don't call two functions */ - if (gst_autoplug_factory_has_src (factories->data) - && gst_autoplug_factory_has_sink (factories->data)) - ret = g_list_prepend (ret, factories->data); - factories = g_list_next (factories); - } - return ret; -} - - -static gint -gst_autoplug_rank_compare (const GstElementFactory * a, - const GstElementFactory * b) -{ - if (GST_PLUGIN_FEATURE (a)->rank > GST_PLUGIN_FEATURE (b)->rank) - return -1; - return (GST_PLUGIN_FEATURE (a)->rank < GST_PLUGIN_FEATURE (b)->rank) ? 1 : 0; -} - -/* returns all factories which have sinks with non-NULL caps and srcs with - * any caps. also only returns factories with a non-zero rank, and sorts by - * rank descending. - */ -GList * -gst_autoplug_factories_filters_with_sink_caps (GList * factories) -{ - GList *ret = NULL; - GstElementFactory *factory; - GList *templs; - - while (factories) { - factory = (GstElementFactory *) factories->data; - templs = factory->padtemplates; - - if (GST_PLUGIN_FEATURE (factory)->rank > 0) { - gboolean have_src = FALSE; - gboolean have_sink = FALSE; - - while (templs) { - if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SRC) { - have_src = TRUE; - } - if ((GST_PAD_TEMPLATE_DIRECTION (templs->data) == GST_PAD_SINK) - && (GST_PAD_TEMPLATE_CAPS (templs->data) != NULL)) { - have_sink = TRUE; - } - if (have_src && have_sink) { - ret = g_list_prepend (ret, factory); - break; - } - templs = g_list_next (templs); - } - } - factories = g_list_next (factories); - } - return g_list_sort (ret, (GCompareFunc) gst_autoplug_rank_compare); -} - - - -/* returns all factories which have a maximum of maxtemplates GstPadTemplates in direction dir - */ -GList * -gst_autoplug_factories_at_most_templates (GList * factories, - GstPadDirection dir, guint maxtemplates) -{ - GList *ret = NULL; - - while (factories) { - guint count = 0; - GList *templs = ((GstElementFactory *) factories->data)->padtemplates; - - while (templs) { - if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) { - count++; - } - if (count > maxtemplates) - break; - templs = g_list_next (templs); - } - if (count <= maxtemplates) - ret = g_list_prepend (ret, factories->data); - - factories = g_list_next (factories); - } - return ret; -} - -/********************************************************************* - * - * SHORTEST PATH ALGORITHM - */ -/** - * gst_autoplug_sp: - * @src_caps: a #GstCaps to plug from. - * @sink_caps: the #GstCaps to plug to. - * @factories: a #GList containing all allowed #GstElementFactory entries. - * - * Finds the shortest path of elements that together make up a possible - * connection between the source and sink caps. - * - * Returns: a #GList of #GstElementFactory items which have to be connected - * to get the shortest path. - */ -GList * -gst_autoplug_sp (const GstCaps * srccaps, const GstCaps * sinkcaps, - GList * factories) -{ - GList *factory_nodes = NULL; - guint curcost = GST_AUTOPLUG_MAX_COST; /* below this cost, there is no path */ - GstAutoplugNode *bestnode = NULL; /* best (unconnected) endpoint currently */ - - g_return_val_if_fail (srccaps != NULL, NULL); - g_return_val_if_fail (sinkcaps != NULL, NULL); - - GST_INFO ("attempting to autoplug via shortest path from %" - GST_PTR_FORMAT " to %" GST_PTR_FORMAT, srccaps, sinkcaps); - - /* wrap all factories as GstAutoplugNode - * initialize the cost */ - while (factories) { - GstAutoplugNode *node = g_new0 (GstAutoplugNode, 1); - - node->prev = NULL; - node->fac = (GstElementFactory *) factories->data; - GST_DEBUG ("trying with %s", node->fac->details.longname); - node->templ = gst_autoplug_can_connect_src (node->fac, srccaps); - node->cost = (node->templ ? gst_autoplug_get_cost (node->fac) - : GST_AUTOPLUG_MAX_COST); - node->endpoint = gst_autoplug_can_connect_sink (node->fac, sinkcaps); - if (node->templ && node->endpoint) - GST_DEBUG ("%s makes connection possible", node->fac->details.longname); - else - GST_DEBUG ("direct connection with %s not possible", - node->fac->details.longname); - if ((node->endpoint != NULL) && - ((bestnode == NULL) || (node->cost < bestnode->cost))) { - bestnode = node; - } - factory_nodes = g_list_prepend (factory_nodes, node); - /* make curcost the minimum cost of any plugin */ - curcost = node->cost < curcost ? node->cost : curcost; - factories = g_list_next (factories); - } - - /* check if we even have possible endpoints */ - if (bestnode == NULL) { - GST_DEBUG ("no factory found that could connect to sink caps"); - g_list_free_list_and_elements (factory_nodes); - return NULL; - } - - /* iterate until we found the best path */ - while (curcost < GST_AUTOPLUG_MAX_COST) { - GList *nodes = factory_nodes; - guint nextcost = GST_AUTOPLUG_MAX_COST; /* next cost to check */ - - GST_DEBUG ("iterating at current cost %d, bestnode %s at %d", curcost, - GST_OBJECT_NAME (bestnode->fac), bestnode->cost); - /* check if we already have a valid best connection to the sink */ - if (bestnode->cost <= curcost) { - GList *ret; - - GST_DEBUG ("found a way to connect via %s", - GST_OBJECT_NAME ((GstObject *) bestnode->fac)); - /* enter all factories into the return list */ - ret = g_list_prepend (NULL, bestnode->fac); - bestnode = bestnode->prev; - while (bestnode != NULL) { - ret = g_list_prepend (ret, bestnode->fac); - bestnode = bestnode->prev; - } - g_list_free_list_and_elements (factory_nodes); - return ret; - } - - /* iterate over all factories we have - * if they have the current cost, calculate if this - * factory supplies shorter paths to other elements - */ - while (nodes) { - if (((GstAutoplugNode *) nodes->data)->cost == curcost) { - /* now check all elements if we got a shorter path */ - GList *sinknodes = factory_nodes; - GstAutoplugNode *srcnode = (GstAutoplugNode *) nodes->data; - - while (sinknodes) { - GstAutoplugNode *sinknode = (GstAutoplugNode *) sinknodes->data; - GstPadTemplate *templ; - - if ((sinknode->cost > - srcnode->cost + gst_autoplug_get_cost (sinknode->fac)) - && (templ = gst_autoplug_can_match (srcnode->fac, sinknode->fac))) { - /* we got a shorter path - * now enter that path to that node */ - sinknode->prev = srcnode; - sinknode->templ = templ; - sinknode->cost = - srcnode->cost + gst_autoplug_get_cost (sinknode->fac); - /* make sure to set which cost to view next */ - nextcost = (nextcost > sinknode->cost) ? sinknode->cost : nextcost; - /* did we get a new best node? */ - if (sinknode->endpoint && (sinknode->cost < bestnode->cost)) { - bestnode = sinknode; - } - } - sinknodes = g_list_next (sinknodes); - } - /* FIXME: for speed remove the item we just iterated with from the factory_nodes - * but don't free it yet and don't forget to free it. - */ - } - nodes = g_list_next (nodes); - } - curcost = nextcost; - } - - GST_DEBUG ("found no path from source caps to sink caps"); - g_list_free_list_and_elements (factory_nodes); - return NULL; -} diff --git a/gst/autoplug/gstsearchfuncs.h b/gst/autoplug/gstsearchfuncs.h deleted file mode 100644 index 0b8d8dfa06..0000000000 --- a/gst/autoplug/gstsearchfuncs.h +++ /dev/null @@ -1,64 +0,0 @@ -/* GStreamer - * Copyright (C) 1999-2002 Erik Walthinsen - * 2000-2002 Wim Taymans - * - * gstsearchfuncs.h: Header for gstsearchfuncs.c - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_SEARCHFUNCS_H__ -#define __GST_SEARCHFUNCS_H__ - -#include - -/* placeholder for maximum cost when plugging */ -#define GST_AUTOPLUG_MAX_COST 999999 - -/* struct for a node, in the search tree */ -typedef struct _GstAutoplugNode GstAutoplugNode; - -struct _GstAutoplugNode { - GstAutoplugNode *prev; /* previous node */ - GstElementFactory *fac; /* factory of element to connect to */ - GstPadTemplate *templ; /* template which can connect */ - guint cost; /* total cost to get here */ - GstPadTemplate *endpoint; /* pad template that can connect to sink caps */ -}; - -/* helper functions */ -gboolean gst_autoplug_caps_intersect (const GstCaps *src, const GstCaps *sink); -GstPadTemplate * gst_autoplug_can_connect_src (GstElementFactory *fac, const GstCaps *src); -GstPadTemplate * gst_autoplug_can_connect_sink (GstElementFactory *fac, const GstCaps *sink); -GstPadTemplate * gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest); -gboolean gst_autoplug_factory_has_direction (GstElementFactory *fac, GstPadDirection dir); -#define gst_autoplug_factory_has_sink(fac) gst_autoplug_factory_has_direction((fac), GST_PAD_SINK) -#define gst_autoplug_factory_has_src(fac) gst_autoplug_factory_has_direction((fac), GST_PAD_SRC) - -/* cost functions */ -#define gst_autoplug_get_cost(fac) 1 - -/* factory selections */ -GList * gst_autoplug_factories_sinks (GList *factories); -GList * gst_autoplug_factories_srcs (GList *factories); -GList * gst_autoplug_factories_filters (GList *factories); -GList * gst_autoplug_factories_filters_with_sink_caps(GList *factories); -GList * gst_autoplug_factories_at_most_templates(GList *factories, GstPadDirection dir, guint maxtemplates); - -/* shortest path algorithm */ -GList * gst_autoplug_sp (const GstCaps *src_caps, const GstCaps *sink_caps, GList *factories); - -#endif /* __GST_SEARCHFUNCS_H__ */ diff --git a/gst/autoplug/gstspider.c b/gst/autoplug/gstspider.c deleted file mode 100644 index 4bc001a655..0000000000 --- a/gst/autoplug/gstspider.c +++ /dev/null @@ -1,765 +0,0 @@ -/* GStreamer - * Copyright (C) 2002 Erik Walthinsen - * 2002 Wim Taymans - * - * gstspider.c: element to automatically link sinks and sources - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* - * TODO: - * - handle automatic removal of unneeded elements - * - make the spider handle and send events (esp. new media) - * - decide if we plug pads or elements, currently it's a mess - * - allow unlinking - * - implement proper saving/loading from xml - * - implement a way to allow merging/splitting (aka tee) - * - find ways to define which elements to use when plugging - * - remove pads - * - improve typefinding - * - react to errors inside the pipeline - * - implement more properties, change the current - * - emit signals (most important: "NOT PLUGGABLE") - * - implement something for reporting the state of the spider - * to allow easier debugging. - * (could be useful for bins in general) - * - fix bugs - * ... - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "../gst-i18n-lib.h" -#include "gstspider.h" -#include "gstspideridentity.h" -#include "gstsearchfuncs.h" - -static GstElementDetails gst_spider_details = GST_ELEMENT_DETAILS ("Spider", - "Generic", - "Automatically link sinks and sources", - "Benjamin Otte "); - -GST_DEBUG_CATEGORY (gst_spider_debug); -#define GST_CAT_DEFAULT gst_spider_debug - -/* signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_FACTORIES, - /* FILL ME TOO */ -}; - -/* generic templates */ -static GstStaticPadTemplate spider_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); -static GstStaticPadTemplate spider_src_factory = -GST_STATIC_PAD_TEMPLATE ("src_%d", - GST_PAD_SRC, - GST_PAD_REQUEST, - GST_STATIC_CAPS_ANY); - -/* standard GObject stuff */ -static void gst_spider_class_init (GstSpiderClass * klass); -static void gst_spider_init (GstSpider * spider); -static void gst_spider_dispose (GObject * object); - -/* element class functions */ -static GstPad *gst_spider_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name); -static void gst_spider_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_spider_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -/* link functions */ -static GstSpiderConnection *gst_spider_link_new (GstSpiderIdentity * src); -static void gst_spider_link_destroy (GstSpiderConnection * conn); -static void gst_spider_link_reset (GstSpiderConnection * conn, GstElement * to); -static void gst_spider_link_add (GstSpiderConnection * conn, - GstElement * element); -static GstSpiderConnection *gst_spider_link_find (GstSpiderIdentity * src); -static GstSpiderConnection *gst_spider_link_get (GstSpiderIdentity * src); - -/* autoplugging functions */ -static GstElement *gst_spider_find_element_to_plug (GstElement * src, - GstElementFactory * fac, GstPadDirection dir); -static GstPadLinkReturn gst_spider_plug (GstSpiderConnection * conn); -static GstPadLinkReturn gst_spider_plug_from_srcpad (GstSpiderConnection * conn, - GstPad * srcpad); -/*static GstPadLinkReturn gst_spider_plug_peers (GstSpider *spider, GstPad *srcpad, GstPad *sinkpad); */ -static GstPadLinkReturn gst_spider_create_and_plug (GstSpiderConnection * conn, - GList * plugpath); - -/* random functions */ -static gchar *gst_spider_unused_elementname (GstBin * bin, - const gchar * startwith); - -/* debugging stuff -static void print_spider_contents (GstSpider *spider); -static void print_spider_link (GstSpiderConnection *conn); */ - -/* === variables === */ -static GstElementClass *parent_class = NULL; - -/* no signals yet -static guint gst_spider_signals[LAST_SIGNAL] = { 0 };*/ - -/* GObject and GStreamer init functions */ -GType -gst_spider_get_type (void) -{ - static GType spider_type = 0; - - if (!spider_type) { - static const GTypeInfo spider_info = { - sizeof (GstSpiderClass), - NULL, - NULL, - (GClassInitFunc) gst_spider_class_init, - NULL, - NULL, - sizeof (GstSpider), - 0, - (GInstanceInitFunc) gst_spider_init, - }; - - spider_type = - g_type_register_static (GST_TYPE_BIN, "GstSpider", &spider_info, 0); - } - return spider_type; -} - -static void -gst_spider_class_init (GstSpiderClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_BIN); - - /* properties */ - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FACTORIES, - g_param_spec_pointer ("factories", "allowed factories", - "allowed factories for autoplugging", G_PARAM_READWRITE)); - - gobject_class->set_property = gst_spider_set_property; - gobject_class->get_property = gst_spider_get_property; - gobject_class->dispose = gst_spider_dispose; - - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&spider_sink_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&spider_src_factory)); - gst_element_class_set_details (gstelement_class, &gst_spider_details); - - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_spider_request_new_pad); -} -static void -gst_spider_init (GstSpider * spider) -{ - /* use only elements which have sources and sinks and where the sinks have caps */ - /* FIXME: How do we handle factories that are added after the spider was constructed? */ - GList *list = gst_registry_pool_feature_list (GST_TYPE_ELEMENT_FACTORY); - - spider->factories = gst_autoplug_factories_filters_with_sink_caps (list); - g_list_free (list); - - spider->links = NULL; - - spider->sink_ident = gst_spider_identity_new_sink ("sink_ident"); - gst_bin_add (GST_BIN (spider), GST_ELEMENT (spider->sink_ident)); - gst_element_add_ghost_pad (GST_ELEMENT (spider), spider->sink_ident->sink, - "sink"); - -} - -static void -gst_spider_dispose (GObject * object) -{ - GstSpider *spider; - GList *list; - - spider = GST_SPIDER (object); - g_list_free (spider->factories); - spider->factories = NULL; - - for (list = spider->links; list; list = list->next) { - GstSpiderConnection *conn = list->data; - - g_list_free (conn->path); - g_free (conn); - } - g_list_free (spider->links); - spider->links = NULL; - - ((GObjectClass *) parent_class)->dispose (object); -} -static GstPad * -gst_spider_request_new_pad (GstElement * element, GstPadTemplate * templ, - const gchar * name) -{ - GstPad *returnpad; - gchar *padname; - GstSpiderIdentity *identity; - GstSpider *spider; - - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL); - g_return_val_if_fail (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC, - NULL); - - spider = GST_SPIDER (element); - - /* create an identity object, so we have a pad */ - padname = gst_spider_unused_elementname ((GstBin *) spider, "src_"); - identity = gst_spider_identity_new_src (padname); - returnpad = identity->src; - - /* FIXME: use the requested name for the pad */ - - gst_object_replace ((GstObject **) & returnpad->padtemplate, - (GstObject *) templ); - - gst_bin_add (GST_BIN (element), GST_ELEMENT (identity)); - - returnpad = gst_element_add_ghost_pad (element, returnpad, padname); - g_free (padname); - gst_spider_link_new (identity); - GST_DEBUG ("successfully created requested pad %s:%s", - GST_DEBUG_PAD_NAME (returnpad)); - - return returnpad; -} - -static void -gst_spider_set_property (GObject * object, guint prop_id, const GValue * value, - GParamSpec * pspec) -{ - GstSpider *spider; - GList *list; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_SPIDER (object)); - - spider = GST_SPIDER (object); - - switch (prop_id) { - case ARG_FACTORIES: - list = (GList *) g_value_get_pointer (value); - for (; list; list = list->next) { - g_return_if_fail (list->data != NULL); - g_return_if_fail (GST_IS_ELEMENT_FACTORY (list->data)); - } - g_list_free (spider->factories); - spider->factories = (GList *) g_value_get_pointer (value); - break; - default: - break; - } -} -static void -gst_spider_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstSpider *spider; - - /* it's not null if we got it, but it might not be ours */ - spider = GST_SPIDER (object); - - switch (prop_id) { - case ARG_FACTORIES: - g_value_set_pointer (value, spider->factories); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -/* get a name for an element that isn't used yet */ -static gchar * -gst_spider_unused_elementname (GstBin * bin, const gchar * startwith) -{ - gchar *name = g_strdup_printf ("%s%d", startwith, 0); - guint i; - - for (i = 0; gst_bin_get_by_name (bin, name) != NULL;) { - g_free (name); - name = g_strdup_printf ("%s%d", startwith, ++i); - } - - return name; -} -static void -gst_spider_link_sometimes (GstElement * src, GstPad * pad, - GstSpiderConnection * conn) -{ - gulong signal_id = conn->signal_id; - - GST_INFO ("plugging from new sometimes pad %s:%s", GST_DEBUG_PAD_NAME (pad)); - /* try to autoplug the elements */ - if (gst_spider_plug_from_srcpad (conn, pad) != GST_PAD_LINK_REFUSED) { - GST_DEBUG ("%s:%s was autoplugged to %s:%s, removing callback", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (conn->src->sink)); - g_signal_handler_disconnect (src, signal_id); - signal_id = 0; - } -} - -/* create a new link from those two elements */ -static GstSpiderConnection * -gst_spider_link_new (GstSpiderIdentity * src) -{ - GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (src)); - - GstSpiderConnection *conn = g_new0 (GstSpiderConnection, 1); - - conn->src = src; - conn->path = NULL; - conn->current = (GstElement *) spider->sink_ident; - spider->links = g_list_prepend (spider->links, conn); - - return conn; -} -static void -gst_spider_link_destroy (GstSpiderConnection * conn) -{ - GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (conn->src)); - - /* reset link to unplugged */ - gst_spider_link_reset (conn, (GstElement *) spider->sink_ident); - g_free (conn); -} -static void -gst_spider_link_reset (GstSpiderConnection * conn, GstElement * to) -{ - GstSpider *spider = GST_SPIDER (GST_OBJECT_PARENT (conn->src)); - - GST_DEBUG ("resetting link from %s to %s, currently at %s to %s", - GST_ELEMENT_NAME (spider->sink_ident), GST_ELEMENT_NAME (conn->src), - GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (to)); - while ((conn->path != NULL) && ((GstElement *) conn->path->data != to)) { - gst_object_unref ((GstObject *) conn->path->data); - conn->path = g_list_delete_link (conn->path, conn->path); - } - if (conn->path == NULL) { - conn->current = (GstElement *) spider->sink_ident; - } else { - conn->current = to; - } -} - -/* add an element to the link */ -static void -gst_spider_link_add (GstSpiderConnection * conn, GstElement * element) -{ - conn->path = g_list_prepend (conn->path, element); - conn->current = element; -} - -/* find the link from those two elements */ -static GstSpiderConnection * -gst_spider_link_find (GstSpiderIdentity * src) -{ - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (src); - GList *list; - - for (list = spider->links; list; list = list->next) { - GstSpiderConnection *conn = (GstSpiderConnection *) list->data; - - if (conn->src == src) { - return conn; - } - } - return NULL; -} - -/* get a new link from those two elements - * search first; if none is found, create a new one */ -static GstSpiderConnection * -gst_spider_link_get (GstSpiderIdentity * src) -{ - GstSpiderConnection *ret; - - if ((ret = gst_spider_link_find (src)) != NULL) { - return ret; - } - return gst_spider_link_new (src); -} - -void -gst_spider_identity_plug (GstSpiderIdentity * ident) -{ - GstSpider *spider; - const GList *padlist; - GstPadDirection dir; - GstSpiderConnection *conn; - - /* checks */ - g_return_if_fail (ident != NULL); - g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident)); - spider = GST_SPIDER (GST_ELEMENT_PARENT (ident)); - g_assert (spider != NULL); - g_assert (GST_IS_SPIDER (spider)); - - /* return if we're already plugged */ - if (ident->plugged) - return; - - /* check if there is at least one element factory that can handle the - identity's src caps */ - { - GstCaps *src_caps = gst_pad_get_caps (ident->src); - - if (!gst_caps_is_empty (src_caps) && !gst_caps_is_any (src_caps)) { - GList *factories; - GstPadTemplate *padtemp; - gboolean found = FALSE; - - factories = spider->factories; - while (factories) { - if ((padtemp = - gst_autoplug_can_connect_src (factories->data, src_caps))) { - GST_DEBUG ("can connect src to %s pad template: %" GST_PTR_FORMAT, - GST_PLUGIN_FEATURE_NAME (factories->data), - gst_pad_template_get_caps (padtemp)); - found = TRUE; - } - factories = factories->next; - } - if (!found) { - const char *mime; - - mime = gst_structure_get_name (gst_caps_get_structure (src_caps, 0)); - - GST_ELEMENT_ERROR (spider, STREAM, CODEC_NOT_FOUND, - (_("There is no element present to handle the stream's mime type %s."), mime), (NULL)); - gst_caps_unref (src_caps); - return; - } - } - gst_caps_unref (src_caps); - } - - /* get the direction of our ident */ - if (GST_PAD_PEER (ident->sink)) { - if (GST_PAD_PEER (ident->src)) { - /* Hey, the ident is linked on both sides */ - g_warning ("Trying to autoplug a linked element. Aborting..."); - return; - } else { - dir = GST_PAD_SINK; - } - } else { - if (GST_PAD_PEER (ident->src)) { - dir = GST_PAD_SRC; - } else { - /* the ident isn't linked on either side */ - g_warning ("Trying to autoplug an unlinked element. Aborting..."); - return; - } - } - - /* now iterate all possible pads and link when needed */ - padlist = GST_ELEMENT (spider)->pads; - for (; padlist; padlist = padlist->next) { - GstPad *otherpad; - GstSpiderIdentity *peer; - - g_assert (GST_IS_PAD (padlist->data)); - otherpad = (GstPad *) GST_GPAD_REALPAD (padlist->data); - peer = (GstSpiderIdentity *) GST_PAD_PARENT (otherpad); - /* we only want to link to the other side */ - if (dir != GST_PAD_DIRECTION (otherpad)) { - /* we only link to plugged in elements */ - if (peer->plugged == TRUE) { - /* plug in the right direction */ - if (dir == GST_PAD_SINK) { - conn = gst_spider_link_get (peer); - } else { - conn = gst_spider_link_get (ident); - } - if ((GstElement *) spider->sink_ident == conn->current) { - gst_spider_plug (conn); - } - } - } - } - - ident->plugged = TRUE; -} - -void -gst_spider_identity_unplug (GstSpiderIdentity * ident) -{ - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (ident); - GList *list; - - for (list = spider->links; list; list = list->next) { - GstSpiderConnection *conn = list->data; - - if (conn->src == ident) { - g_list_delete_link (spider->links, list); - gst_spider_link_destroy (conn); - } - } - ident->plugged = FALSE; -} - -/* links src to sink using the elementfactories in plugpath - * plugpath will be removed afterwards */ -static GstPadLinkReturn -gst_spider_create_and_plug (GstSpiderConnection * conn, GList * plugpath) -{ - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->src); - GList *endelements = NULL, *templist = NULL; - GstElement *element; - - /* exit if plugging is already done */ - if ((GstElement *) conn->src == conn->current) - return GST_PAD_LINK_DONE; - - /* try to shorten the list at the end and not duplicate link 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 linking */ - 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_element_factory_create ((GstElementFactory *) plugpath->data, - NULL); - GST_DEBUG - ("Adding element %s of type %s and syncing state with autoplugger", - GST_ELEMENT_NAME (element), GST_PLUGIN_FEATURE_NAME (plugpath->data)); - gst_bin_add (GST_BIN (spider), element); - } - /* insert and link new element */ - if (gst_element_link (conn->current, element)) { - gst_element_sync_state_with_parent (element); - } else { - /* check if the src has SOMETIMES templates. If so, link a callback */ - GList *templs = gst_element_get_pad_template_list (conn->current); - - /* remove element that couldn't be linked, if it wasn't the endpoint */ - if (element != (GstElement *) conn->src) - gst_bin_remove (GST_BIN (spider), element); - - for (; templs; templs = templs->next) { - GstPadTemplate *templ = (GstPadTemplate *) templs->data; - - if ((GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) - && (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES)) { - GST_DEBUG ("adding callback to link element %s to %s", - 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_link_sometimes), conn); - g_list_free (plugpath); - return GST_PAD_LINK_DELAYED; - } - } - GST_DEBUG ("no chance to link element %s to %s", - GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src)); - g_list_free (plugpath); - return GST_PAD_LINK_REFUSED; - } - GST_DEBUG ("coupling %s and %s", - GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (conn->current)); - gst_spider_link_add (conn, element); - if (plugpath != NULL) - plugpath = g_list_delete_link (plugpath, plugpath); - } - - /* ref all elements at the end */ - while (endelements) { - gst_spider_link_add (conn, endelements->data); - endelements = g_list_delete_link (endelements, endelements); - } - - return GST_PAD_LINK_DONE; -} - -/* checks, if src is already linked 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); - - for (; padlist; padlist = padlist->next) { - GstPad *pad = (GstPad *) GST_PAD_REALIZE (padlist->data); - - /* is the pad on the right side and is it linked? */ - if ((GST_PAD_DIRECTION (pad) == dir) - && (pad = (GstPad *) (GST_RPAD_PEER (pad)))) { - /* is the element the pad is linked to of the right type? */ - GstElement *element = GST_PAD_PARENT (pad); - - if (G_TYPE_FROM_INSTANCE (element) == - gst_element_factory_get_element_type (fac)) { - return element; - } - } - } - - return NULL; -} - -/* try to establish the link */ -static GstPadLinkReturn -gst_spider_plug (GstSpiderConnection * conn) -{ - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->src); - - if ((GstElement *) conn->src == conn->current) - return GST_PAD_LINK_DONE; - if ((GstElement *) spider->sink_ident == conn->current) - return gst_spider_plug_from_srcpad (conn, spider->sink_ident->src); - g_warning - ("FIXME: autoplugging only possible from GstSpiderIdentity conn->sink yet (yep, that's technical)\n"); - return GST_PAD_LINK_REFUSED; -} - -/* try to establish the link using this pad */ -static GstPadLinkReturn -gst_spider_plug_from_srcpad (GstSpiderConnection * conn, GstPad * srcpad) -{ - GstElement *element; - GList *plugpath; - gboolean result = TRUE; - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (conn->src); - GstElement *startelement = conn->current; - GstCaps *caps1; - GstCaps *caps2; - - g_assert ((GstElement *) GST_OBJECT_PARENT (srcpad) == conn->current); - GST_DEBUG ("trying to plug from %s:%s to %s", - GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (conn->src)); - - /* see if they match already */ - if (gst_pad_link (srcpad, conn->src->sink)) { - GST_DEBUG ("%s:%s and %s:%s can link directly", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (conn->src->sink)); - gst_pad_unlink (srcpad, conn->src->sink); - gst_spider_create_and_plug (conn, NULL); - return GST_PAD_LINK_OK; - } - - /* find a path from src to sink */ - caps1 = gst_pad_get_caps (srcpad); - caps2 = gst_pad_get_caps (conn->src->sink); - plugpath = gst_autoplug_sp (caps1, caps2, spider->factories); - gst_caps_unref (caps1); - gst_caps_unref (caps2); - - /* prints out the path that was found for plugging */ - /* g_print ("found path from %s to %s:\n", GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src)); - templist = plugpath; - while (templist) - { - g_print("%s\n", GST_OBJECT_NAME (templist->data)); - templist = g_list_next (templist); - } */ - - /* if there is no way to plug: return */ - if (plugpath == NULL) { - GST_DEBUG ("no chance to plug from %s to %s", - GST_ELEMENT_NAME (conn->current), GST_ELEMENT_NAME (conn->src)); - return GST_PAD_LINK_REFUSED; - } - GST_DEBUG ("found a link that needs %d elements", g_list_length (plugpath)); - - /* now remove non-needed elements from the beginning of the path - * alter src to point to the new element where we need to start - * plugging and alter the plugpath to represent the elements, that must be plugged - */ - element = conn->current; - while ((plugpath != NULL) - && (element = - gst_spider_find_element_to_plug (element, - (GstElementFactory *) plugpath->data, GST_PAD_SRC))) { - gst_spider_link_add (conn, element); - plugpath = g_list_delete_link (plugpath, plugpath); - } - - GST_DEBUG ("%d elements must be inserted to establish the link", - g_list_length (plugpath)); - /* create the elements and plug them */ - result = gst_spider_create_and_plug (conn, plugpath); - - /* reset the "current" element */ - if (result == GST_PAD_LINK_REFUSED) { - gst_spider_link_reset (conn, startelement); - } - - return result; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - GST_DEBUG_CATEGORY_INIT (gst_spider_debug, "spider", 0, - "spider autoplugging element"); - - if (!gst_element_register (plugin, "spider", GST_RANK_NONE, GST_TYPE_SPIDER)) - return FALSE; - if (!gst_element_register (plugin, "spideridentity", GST_RANK_NONE, - GST_TYPE_SPIDER_IDENTITY)) - return FALSE; - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstspider", - "a 1:n autoplugger", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) diff --git a/gst/autoplug/gstspider.h b/gst/autoplug/gstspider.h deleted file mode 100644 index 89ff7ac75b..0000000000 --- a/gst/autoplug/gstspider.h +++ /dev/null @@ -1,93 +0,0 @@ -/* GStreamer - * Copyright (C) 2002 Erik Walthinsen - * 2002 Wim Taymans - * - * gstspider.h: Header for GstSpider object - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef __GST_SPIDER_H__ -#define __GST_SPIDER_H__ - -#include -#include "gstspideridentity.h" - -G_BEGIN_DECLS - -GST_DEBUG_CATEGORY_EXTERN(gst_spider_debug); - -/* - * Theory of operation: - * When connecting a sink to a source, GstSpiderConnections are used to keep track - * of the current status of the link. sink -> src is the path we intend to - * plug. current is how far we've come. If current equals - * - NULL, there is no possible path, - * - src, the link is established. - * - sink, it wasn't tried to establish a link. - * - something else, we have come that far while plugging. - * signal_id is used to remember the signal_id when we are waiting for a "new_pad" - * callback during link. - * When a path is established, the elements in the path (excluding sink and src) - * are refcounted once for every path. - * A GstSpider keeps a list of all GstSpiderConnections in it. - */ -typedef struct { - GstSpiderIdentity *src; - /* dunno if the path should stay here or if its too much load. - * it's at least easier then always searching it */ - GList *path; - GstElement *current; - gulong signal_id; -} GstSpiderConnection; - -#define GST_TYPE_SPIDER \ - (gst_spider_get_type()) -#define GST_SPIDER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPIDER,GstSpider)) -#define GST_SPIDER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPIDER,GstSpiderClass)) -#define GST_IS_SPIDER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPIDER)) -#define GST_IS_SPIDER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPIDER)) - -typedef struct _GstSpider GstSpider; -typedef struct _GstSpiderClass GstSpiderClass; - -struct _GstSpider { - GstBin parent; - - GstSpiderIdentity *sink_ident; - GList * factories; /* factories to use for plugging */ - - GList * links; /* GStSpiderConnection list of all links */ -}; - -struct _GstSpiderClass { - GstBinClass parent_class; -}; - -/* default initialization stuff */ -GType gst_spider_get_type (void); - -/* private link functions to be called by GstSpiderIdentity */ -void gst_spider_identity_plug (GstSpiderIdentity *ident); -void gst_spider_identity_unplug (GstSpiderIdentity *ident); - -G_END_DECLS - -#endif /* __GST_SPIDER_H__ */ diff --git a/gst/autoplug/gstspideridentity.c b/gst/autoplug/gstspideridentity.c deleted file mode 100644 index 832c617e01..0000000000 --- a/gst/autoplug/gstspideridentity.c +++ /dev/null @@ -1,608 +0,0 @@ -/* GStreamer - * Copyright (C) 2002 Erik Walthinsen - * 2002 Wim Taymans - * - * gstspideridentity.c: identity element for the spider autoplugger - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "gstspideridentity.h" -#include "gstspider.h" - -GST_DEBUG_CATEGORY_STATIC (gst_spider_identity_debug); -#define GST_CAT_DEFAULT gst_spider_identity_debug - -static GstElementDetails gst_spider_identity_details = -GST_ELEMENT_DETAILS ("SpiderIdentity", - "Generic", - "Link between spider and outside elements", - "Benjamin Otte "); - - -/* generic templates - * delete me when meging with spider.c - */ -static GstStaticPadTemplate spider_src_factory = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate spider_sink_factory = -GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -/* SpiderIdentity signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0 - /* FILL ME */ -}; - -/* GObject stuff */ -static void gst_spider_identity_class_init (GstSpiderIdentityClass * klass); -static void gst_spider_identity_init (GstSpiderIdentity * spider_identity); - -/* functions set in pads, elements and stuff */ -static void gst_spider_identity_chain (GstPad * pad, GstBuffer * buf); -static GstElementStateReturn gst_spider_identity_change_state (GstElement * - element); -static GstPadLinkReturn gst_spider_identity_link (GstPad * pad, - const GstCaps * caps); -static GstCaps *gst_spider_identity_getcaps (GstPad * pad); - -/* loop functions */ -static void gst_spider_identity_dumb_loop (GstSpiderIdentity * ident); -static void gst_spider_identity_src_loop (GstSpiderIdentity * ident); -static void gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity * - ident); - -static gboolean gst_spider_identity_handle_src_event (GstPad * pad, - GstEvent * event); - -/* other functions */ -static void gst_spider_identity_start_type_finding (GstSpiderIdentity * ident); - -static GstElementClass *parent_class = NULL; - -/* no signals -static guint gst_spider_identity_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_spider_identity_get_type (void) -{ - static GType spider_identity_type = 0; - - if (!spider_identity_type) { - static const GTypeInfo spider_identity_info = { - sizeof (GstSpiderIdentityClass), NULL, - NULL, - (GClassInitFunc) gst_spider_identity_class_init, - NULL, - NULL, - sizeof (GstSpiderIdentity), - 0, - (GInstanceInitFunc) gst_spider_identity_init, - }; - - spider_identity_type = - g_type_register_static (GST_TYPE_ELEMENT, "GstSpiderIdentity", - &spider_identity_info, 0); - GST_DEBUG_CATEGORY_INIT (gst_spider_identity_debug, "spideridentity", 0, - "spider autoplugging proxy element"); - } - return spider_identity_type; -} - -static void -gst_spider_identity_class_init (GstSpiderIdentityClass * klass) -{ - GstElementClass *gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - - /* add our two pad templates */ - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&spider_src_factory)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&spider_sink_factory)); - gst_element_class_set_details (gstelement_class, - &gst_spider_identity_details); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_spider_identity_change_state); - gstelement_class->request_new_pad = - GST_DEBUG_FUNCPTR (gst_spider_identity_request_new_pad); -} - -static void -gst_spider_identity_init (GstSpiderIdentity * ident) -{ - /* sink */ - ident->sink = - gst_pad_new_from_template (gst_static_pad_template_get - (&spider_sink_factory), "sink"); - gst_element_add_pad (GST_ELEMENT (ident), ident->sink); - gst_pad_set_link_function (ident->sink, - GST_DEBUG_FUNCPTR (gst_spider_identity_link)); - gst_pad_set_getcaps_function (ident->sink, - GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps)); - /* src */ - ident->src = - gst_pad_new_from_template (gst_static_pad_template_get - (&spider_src_factory), "src"); - gst_element_add_pad (GST_ELEMENT (ident), ident->src); - gst_pad_set_link_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_link)); - gst_pad_set_getcaps_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps)); - gst_pad_set_event_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event)); - - /* variables */ - ident->plugged = FALSE; -} - -static void -gst_spider_identity_chain (GstPad * pad, GstBuffer * buf) -{ - GstSpiderIdentity *ident; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - - if (buf == NULL) - return; - - ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad)); - - if (GST_IS_EVENT (buf)) { - GST_DEBUG_OBJECT (ident, "spider identity received event %p", buf); - /* start hack for current event stuff here */ - /* check for unlinked elements and send them the EOS event, too */ - if (GST_EVENT_TYPE (GST_EVENT (buf)) == GST_EVENT_EOS) { - GstSpider *spider = (GstSpider *) GST_OBJECT_PARENT (ident); - GList *list = spider->links; - - while (list) { - GstSpiderConnection *conn = (GstSpiderConnection *) list->data; - - list = g_list_next (list); - if (conn->current != (GstElement *) conn->src) { - GstEvent *event; - - event = gst_event_new (GST_EVENT_EOS); - GST_DEBUG_OBJECT (ident, - "sending EOS event %p to unconnected element %s from %s", - event, GST_ELEMENT_NAME (conn->src), GST_ELEMENT_NAME (ident)); - gst_pad_push (conn->src->src, GST_DATA (event)); - gst_element_set_eos (GST_ELEMENT (conn->src)); - } - } - } - /* end hack for current event stuff here */ - GST_DEBUG_OBJECT (ident, - "calling default handler for event %p on pad %s:%s", - buf, GST_DEBUG_PAD_NAME (pad)); - - gst_pad_event_default (pad, GST_EVENT (buf)); - return; - } - - if ((ident->src != NULL) && (GST_PAD_PEER (ident->src) != NULL)) { - GST_LOG_OBJECT (ident, "pushing buffer %p " - "(refcount %d, size %u, offset %" G_GINT64_FORMAT ") ", - buf, GST_BUFFER_REFCOUNT_VALUE (buf), - GST_BUFFER_SIZE (buf), GST_BUFFER_OFFSET (buf)); - gst_pad_push (ident->src, GST_DATA (buf)); - } else if (GST_IS_BUFFER (buf)) { - gst_buffer_unref (buf); - } -} - -GstSpiderIdentity * -gst_spider_identity_new_src (gchar * name) -{ - GstSpiderIdentity *ret = - (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name); - /* set the right functions */ - gst_element_set_loop_function (GST_ELEMENT (ret), (GstElementLoopFunction) - GST_DEBUG_FUNCPTR (gst_spider_identity_src_loop)); - - return ret; -} - -GstSpiderIdentity * -gst_spider_identity_new_sink (gchar * name) -{ - GstSpiderIdentity *ret = - (GstSpiderIdentity *) gst_element_factory_make ("spideridentity", name); - - /* set the right functions */ - gst_element_set_loop_function (GST_ELEMENT (ret), (GstElementLoopFunction) - GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop)); - - return ret; -} - -/* shamelessly stolen from gstqueue.c to get proxy links */ -static GstPadLinkReturn -gst_spider_identity_link (GstPad * pad, const GstCaps * caps) -{ - GstSpiderIdentity *spider_identity = - GST_SPIDER_IDENTITY (gst_pad_get_parent (pad)); - GstPad *otherpad; - - if (pad == spider_identity->src) { - otherpad = spider_identity->sink; - if (GST_PAD_PEER (otherpad) == NULL) - return GST_PAD_LINK_DELAYED; - } else { - otherpad = spider_identity->src; - } - - g_return_val_if_fail (otherpad != NULL, GST_PAD_LINK_REFUSED); - - return gst_pad_try_set_caps (otherpad, caps); -} - -static GstCaps * -gst_spider_identity_getcaps (GstPad * pad) -{ - GstSpiderIdentity *ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad)); - GstPad *otherpad; - - if (pad == ident->src) - otherpad = ident->sink; - else - otherpad = ident->src; - - if (otherpad != NULL) { - if (GST_PAD_PEER (otherpad)) { - GstCaps *ret = gst_pad_get_allowed_caps (otherpad); - - if (ident->caps) { - GstCaps *ret2 = gst_caps_intersect (ident->caps, ret); - - gst_caps_unref (ret); - ret = ret2; - } - return ret; - } - } - if (ident->caps) - return gst_caps_copy (ident->caps); - - return gst_caps_new_any (); -} - -GstPad * -gst_spider_identity_request_new_pad (GstElement * element, - GstPadTemplate * templ, const gchar * name) -{ - GstSpiderIdentity *ident; - - /*checks */ - g_return_val_if_fail (templ != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL); - ident = GST_SPIDER_IDENTITY (element); - g_return_val_if_fail (ident != NULL, NULL); - g_return_val_if_fail (GST_IS_SPIDER_IDENTITY (ident), NULL); - - switch (GST_PAD_TEMPLATE_DIRECTION (templ)) { - case GST_PAD_SINK: - if (ident->sink != NULL) - break; - /* sink */ - GST_DEBUG ("element %s requests new sink pad", GST_ELEMENT_NAME (ident)); - ident->sink = - gst_pad_new_from_template (gst_static_pad_template_get - (&spider_sink_factory), "sink"); - gst_element_add_pad (GST_ELEMENT (ident), ident->sink); - gst_pad_set_link_function (ident->sink, - GST_DEBUG_FUNCPTR (gst_spider_identity_link)); - gst_pad_set_getcaps_function (ident->sink, - GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps)); - return ident->sink; - case GST_PAD_SRC: - /* src */ - if (ident->src != NULL) - break; - GST_DEBUG ("element %s requests new src pad", GST_ELEMENT_NAME (ident)); - ident->src = - gst_pad_new_from_template (gst_static_pad_template_get - (&spider_src_factory), "src"); - gst_element_add_pad (GST_ELEMENT (ident), ident->src); - gst_pad_set_link_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_link)); - gst_pad_set_getcaps_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_getcaps)); - gst_pad_set_event_function (ident->src, - GST_DEBUG_FUNCPTR (gst_spider_identity_handle_src_event)); - return ident->src; - default: - break; - } - - GST_DEBUG ("element %s requested a new pad but none could be created", - GST_ELEMENT_NAME (ident)); - return NULL; -} - -/* this function has to - * - start the autoplugger - * - start type finding - * ... - */ -static GstElementStateReturn -gst_spider_identity_change_state (GstElement * element) -{ - GstSpiderIdentity *ident; - GstSpider *spider; - GstElementStateReturn ret = GST_STATE_SUCCESS; - - /* element check */ - ident = GST_SPIDER_IDENTITY (element); - g_return_val_if_fail (ident != NULL, GST_STATE_FAILURE); - g_return_val_if_fail (GST_IS_SPIDER_IDENTITY (ident), GST_STATE_FAILURE); - - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_PAUSED_TO_READY: - gst_caps_replace (&ident->caps, NULL); - break; - case GST_STATE_PAUSED_TO_PLAYING: - /* autoplugger check */ - spider = GST_SPIDER (GST_ELEMENT_PARENT (ident)); - g_return_val_if_fail (spider != NULL, GST_STATE_FAILURE); - g_return_val_if_fail (GST_IS_SPIDER (spider), GST_STATE_FAILURE); - - /* start typefinding or plugging */ - if ((GST_RPAD_PEER (ident->sink) != NULL) - && (GST_RPAD_PEER (ident->src) == NULL)) { - GstCaps *caps = - gst_pad_get_caps ((GstPad *) GST_PAD_PEER (ident->sink)); - if (gst_caps_is_any (caps) || gst_caps_is_empty (caps)) { - gst_spider_identity_start_type_finding (ident); - gst_caps_unref (caps); - break; - } else { - gst_spider_identity_plug (ident); - } - gst_caps_unref (caps); - } - /* autoplug on src */ - if ((GST_RPAD_PEER (ident->src) != NULL) - && (GST_RPAD_PEER (ident->sink) == NULL)) { - gst_spider_identity_plug (ident); - } - default: - break; - } - - if ((ret != GST_STATE_FAILURE) - && (GST_ELEMENT_CLASS (parent_class)->change_state)) - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return ret; -} - -static void -gst_spider_identity_start_type_finding (GstSpiderIdentity * ident) -{ -/* GstElement* typefind; - gchar *name;*/ - gboolean restart = FALSE; - - GST_DEBUG ("element %s starts typefinding", GST_ELEMENT_NAME (ident)); - if (GST_STATE (GST_ELEMENT_PARENT (ident)) == GST_STATE_PLAYING) { - gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)), - GST_STATE_PAUSED); - restart = TRUE; - } - - gst_element_set_loop_function (GST_ELEMENT (ident), (GstElementLoopFunction) - GST_DEBUG_FUNCPTR (gst_spider_identity_sink_loop_type_finding)); - - if (restart) { - gst_element_set_state (GST_ELEMENT (GST_ELEMENT_PARENT (ident)), - GST_STATE_PLAYING); - } -} - -/* since we can't set the loop function to NULL if there's a cothread for us, - * we have to use a dumb one - */ -static void -gst_spider_identity_dumb_loop (GstSpiderIdentity * ident) -{ - GstBuffer *buf; - - g_return_if_fail (ident != NULL); - g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident)); - g_assert (ident->sink != NULL); - - buf = GST_BUFFER (gst_pad_pull (ident->sink)); - - gst_spider_identity_chain (ident->sink, buf); -} - -/* do nothing until we're linked - then disable yourself - */ -static void -gst_spider_identity_src_loop (GstSpiderIdentity * ident) -{ - /* checks - disable for speed */ - g_return_if_fail (ident != NULL); - g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident)); - - /* we don't want a loop function if we're plugged */ - if (ident->sink && GST_PAD_PEER (ident->sink)) { - gst_element_set_loop_function (GST_ELEMENT (ident), (GstElementLoopFunction) - GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop)); - gst_spider_identity_dumb_loop (ident); - return; - } - gst_element_interrupt (GST_ELEMENT (ident)); -} - -/* This loop function is only needed when typefinding. - */ -typedef struct -{ - GstBuffer *buffer; - guint best_probability; - GstCaps *caps; -} -SpiderTypeFind; -static guint8 * -spider_find_peek (gpointer data, gint64 offset, guint size) -{ - SpiderTypeFind *find = (SpiderTypeFind *) data; - gint64 buffer_offset = GST_BUFFER_OFFSET_IS_VALID (find->buffer) ? - GST_BUFFER_OFFSET (find->buffer) : 0; - - if (offset >= buffer_offset - && offset + size <= buffer_offset + GST_BUFFER_SIZE (find->buffer)) { - GST_LOG ("peek %" G_GINT64_FORMAT ", %u successful", offset, size); - return GST_BUFFER_DATA (find->buffer) + offset - buffer_offset; - } else { - GST_LOG ("peek %" G_GINT64_FORMAT ", %u failed", offset, size); - return NULL; - } -} -static void -spider_find_suggest (gpointer data, guint probability, const GstCaps * caps) -{ - SpiderTypeFind *find = (SpiderTypeFind *) data; - - GST_INFO ("suggest %u, %" GST_PTR_FORMAT, probability, caps); - if (probability > find->best_probability) { - gst_caps_replace (&find->caps, gst_caps_copy (caps)); - find->best_probability = probability; - } -} -static void -gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity * ident) -{ - GstData *data; - GstTypeFind gst_find; - SpiderTypeFind find; - GList *walk, *type_list = NULL; - - g_return_if_fail (GST_IS_SPIDER_IDENTITY (ident)); - - data = gst_pad_pull (ident->sink); - if (!GST_IS_BUFFER (data)) { - gst_spider_identity_chain (ident->sink, GST_BUFFER (data)); - return; - } - - find.buffer = GST_BUFFER (data); - /* maybe there are already valid caps now? */ - find.caps = gst_pad_get_allowed_caps (ident->sink); - if (!gst_caps_is_empty (find.caps) && !gst_caps_is_any (find.caps)) { - goto plug; - } else { - gst_caps_unref (find.caps); - find.caps = NULL; - } - - /* now do the actual typefinding with the supplied buffer */ - walk = type_list = gst_type_find_factory_get_list (); - - find.best_probability = 0; - find.caps = NULL; - gst_find.data = &find; - gst_find.get_length = NULL; - gst_find.peek = spider_find_peek; - gst_find.suggest = spider_find_suggest; - while (walk) { - GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data); - - GST_DEBUG ("trying typefind function %s", - GST_PLUGIN_FEATURE_NAME (factory)); - gst_type_find_factory_call_function (factory, &gst_find); - if (find.best_probability >= GST_TYPE_FIND_MAXIMUM) - goto plug; - walk = g_list_next (walk); - } - if (find.best_probability > 0) - goto plug; - GST_ELEMENT_ERROR (ident, STREAM, TYPE_NOT_FOUND, (NULL), (NULL)); - find.buffer = GST_BUFFER (gst_event_new (GST_EVENT_EOS)); - -end: - /* remove loop function */ - gst_element_set_loop_function (GST_ELEMENT (ident), (GstElementLoopFunction) - GST_DEBUG_FUNCPTR (gst_spider_identity_dumb_loop)); - - /* push the buffer */ - gst_spider_identity_chain (ident->sink, find.buffer); - - return; - -plug: - GST_INFO ("typefind function found caps"); - ident->caps = find.caps; - if (GST_PAD_IS_LINKED (ident->src)) { - GstPadLinkReturn ret; - - ret = gst_pad_try_set_caps (ident->src, find.caps); - if (GST_PAD_LINK_FAILED (ret)) { - g_critical ("could not set caps on spideridentity src pad\n"); - } - } - GST_LOG_OBJECT (ident, "spider starting caps: %" GST_PTR_FORMAT, find.caps); - if (type_list) - g_list_free (type_list); - - gst_spider_identity_plug (ident); - - goto end; -} - -static gboolean -gst_spider_identity_handle_src_event (GstPad * pad, GstEvent * event) -{ - gboolean res = TRUE; - GstSpiderIdentity *ident; - - GST_DEBUG ("spider_identity src_event"); - - ident = GST_SPIDER_IDENTITY (gst_pad_get_parent (pad)); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - case GST_EVENT_SEEK: - default: - res = gst_pad_event_default (pad, event); - break; - } - - return res; -} diff --git a/gst/autoplug/gstspideridentity.h b/gst/autoplug/gstspideridentity.h deleted file mode 100644 index 1e09aba586..0000000000 --- a/gst/autoplug/gstspideridentity.h +++ /dev/null @@ -1,72 +0,0 @@ -/* GStreamer - * Copyright (C) 2002 Erik Walthinsen - * 2002 Wim Taymans - * - * gstspideridentity.h: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __GST_SPIDER_IDENTITY_H__ -#define __GST_SPIDER_IDENTITY_H__ - -#include - -G_BEGIN_DECLS - -#define GST_TYPE_SPIDER_IDENTITY \ - (gst_spider_identity_get_type()) -#define GST_SPIDER_IDENTITY(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SPIDER_IDENTITY,GstSpiderIdentity)) -#define GST_SPIDER_IDENTITY_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SPIDER_IDENTITY,GstSpiderIdentityClass)) -#define GST_IS_SPIDER_IDENTITY(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SPIDER_IDENTITY)) -#define GST_IS_SPIDER_IDENTITY_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SPIDER_IDENTITY)) - -typedef struct _GstSpiderIdentity GstSpiderIdentity; -typedef struct _GstSpiderIdentityClass GstSpiderIdentityClass; - -struct _GstSpiderIdentity { - GstElement element; - - /* sink and source */ - GstPad *sink; - GstPad *src; - - /* plugged into autoplugger yet? */ - gboolean plugged; - - /* Caps from typefinding */ - GstCaps *caps; -}; - -struct _GstSpiderIdentityClass { - GstElementClass parent_class; - -}; - -GType gst_spider_identity_get_type (void); - -GstSpiderIdentity* gst_spider_identity_new_sink (gchar *name); -GstSpiderIdentity* gst_spider_identity_new_src (gchar *name); -GstPad* gst_spider_identity_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *name); - -G_END_DECLS - -#endif /* __GST_SPIDER_IDENTITY_H__ */ diff --git a/gst/autoplug/spidertest.c b/gst/autoplug/spidertest.c deleted file mode 100644 index 3c147c6c30..0000000000 --- a/gst/autoplug/spidertest.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include - -/* returns all factories which have a maximum of maxtemplates GstPadTemplates in direction dir - */ -GList * -gst_factories_at_most_templates (GList * factories, GstPadDirection dir, - guint maxtemplates) -{ - GList *ret = NULL; - - while (factories) { - guint count = 0; - GList *templs = ((GstElementFactory *) factories->data)->padtemplates; - - while (templs) { - if (GST_PAD_TEMPLATE_DIRECTION (templs->data) == dir) { - count++; - } - if (count > maxtemplates) - break; - templs = g_list_next (templs); - } - if (count <= maxtemplates) - ret = g_list_prepend (ret, factories->data); - - factories = g_list_next (factories); - } - return ret; -} - -static void -property_change_callback (GObject * object, GstObject * orig, - GParamSpec * pspec) -{ - GValue value = { 0, }; /* the important thing is that value.type = 0 */ - gchar *str = 0; - - if (pspec->flags & G_PARAM_READABLE) { - g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); - g_object_get_property (G_OBJECT (orig), pspec->name, &value); - if (G_IS_PARAM_SPEC_STRING (pspec)) - str = g_value_dup_string (&value); - else if (G_IS_PARAM_SPEC_ENUM (pspec)) - str = g_strdup_printf ("%d", g_value_get_enum (&value)); - else if (G_IS_PARAM_SPEC_INT64 (pspec)) - str = g_strdup_printf ("%" G_GINT64_FORMAT, g_value_get_int64 (&value)); - else - str = g_strdup_value_contents (&value); - - g_print ("%s: %s = %s\n", GST_OBJECT_NAME (orig), pspec->name, str); - g_free (str); - g_value_unset (&value); - } else { - g_warning ("Parameter not readable. What's up with that?"); - } -} - -static void -error_callback (GObject * object, GstObject * orig, gchar * error) -{ - g_print ("ERROR: %s: %s\n", GST_OBJECT_NAME (orig), error); -} - -/* - * Test program for the autoplugger. - * Uses new API extensions (2002-01-28), too. - * - * USAGE: spidertest - * If mediafile can be recognized, xvideo and oss audio output are tried. - */ -int -main (int argc, char *argv[]) -{ - GstElement *bin, *filesrc, *decoder, *osssink, *videosink; - GList *facs; - - if (argc < 2) { - g_print ("usage: %s \n", argv[0]); - exit (-1); - } - - gst_init (&argc, &argv); - - /* create a new bin to hold the elements */ - bin = gst_pipeline_new ("pipeline"); - g_signal_connect (bin, "deep_notify", G_CALLBACK (property_change_callback), - NULL); - g_signal_connect (bin, "error", G_CALLBACK (error_callback), NULL); - - /* create a disk reader */ - filesrc = gst_element_factory_make ("filesrc", "disk_source"); - g_object_set (G_OBJECT (filesrc), "location", argv[1], NULL); - - /* now it's time to get the decoder */ - decoder = gst_element_factory_make ("spider", "spider"); - if (!decoder) { - g_print ("could not find plugin \"spider\"\n"); - exit (-2); - } - - /* only use decoding plugins */ - g_object_get (decoder, "factories", &facs, NULL); - facs = gst_factories_at_most_templates (facs, GST_PAD_SINK, 1); - g_object_set (decoder, "factories", facs, NULL); - - /* create video and audio sink */ - osssink = gst_element_factory_make ("osssink", "audio"); - videosink = gst_element_factory_make ("xvideosink", "video"); - - if ((!osssink) || (!videosink)) { - g_print ("could not create output plugins\n"); - exit (-3); - } - - /* add objects to the main pipeline */ - gst_bin_add (GST_BIN (bin), filesrc); - gst_bin_add (GST_BIN (bin), decoder); - gst_bin_add (GST_BIN (bin), osssink); - gst_bin_add (GST_BIN (bin), videosink); - - /* link objects */ - if (!(gst_element_link (filesrc, decoder) && - gst_element_link (decoder, osssink) && - gst_element_link (decoder, videosink))) { - g_print ("the pipeline could not be linked\n"); - exit (-4); - } - -/* gst_bin_use_clock (GST_BIN (bin), gst_system_clock_obtain ());*/ - - /* start playing */ - gst_element_set_state (bin, GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (bin))); - - exit (0); -}