From 0b1967b4400cddc1f13f44ac705bbf9ba702a025 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 19 Dec 2000 13:44:23 +0000 Subject: [PATCH] Added the autoplugger. some .dia drawings of the objects the autoplug test program. Original commit message from CVS: Added the autoplugger. some .dia drawings of the objects the autoplug test program. --- docs/random/plugins.dia | Bin 0 -> 1407 bytes editor/editor.dia | Bin 0 -> 1039 bytes gst/gstautoplug.c | 311 ++++++++++++++++++++++++++++++++++++++++ gst/gstautoplug.h | 49 +++++++ tests/autoplug.c | 55 +++++++ 5 files changed, 415 insertions(+) create mode 100644 docs/random/plugins.dia create mode 100644 editor/editor.dia create mode 100644 gst/gstautoplug.c create mode 100644 gst/gstautoplug.h create mode 100644 tests/autoplug.c diff --git a/docs/random/plugins.dia b/docs/random/plugins.dia new file mode 100644 index 0000000000000000000000000000000000000000..de76551a42a020e6d2f88ab86b7c14f9dba6dcfd GIT binary patch literal 1407 zcmV-_1%Ub=iwFP!000001MOT*bK*DiF%Nht@aK<%fN^`ut6v_1a#yd=gWVjR=t-gJO%ew^HmBMf5( zmxgRi_y_sz-dqTgez2^krzb#G916++!5QGl`VSHUEoo$#lRLxMT^vCH)pz*|6oTPd zCXkW9CAv3fF#H)ankA9Bv5+<)C6pPDkldS{`TEbawwGJ`>o4G?Fh%SbYMD}wWwThN zXUzrItIwl$X~CsI5>GmxdY!Sg{c^be)S*I9v4kwfNgkIWNH&9X!NA>(usrCj4N%es zC~E^0^Jz+%U=WKu@QhM|V6wp$EJM|?c?gM|=1UGc)e+}d2>ODbb4d6#N5|Hl&1F|Z z%y4vhG2~hcu71LiSWKTAybT+~RfC9+nBy5ir(WVj+zh#@30Y^JG8`fP!c67c3lJ7t z6YHgco!VUUbZnh$;9~+;h;8BiIBea<_MUAQ+!l<^{zakK4&k4_z8k+Ap9$pLJVY7W zG;nlp{%s$|e(JSEkt;nn_>}G^!vn70bvzLG$HO|GlOojF>==|uUttmxvQ@V^?wy&g4Zf%#HS?O}UhFS(-A$`E=jFTY;zY7z2e|LXE=j zcD@qM=L2gM@OE4;cKLK4&6Z?unBU#6o&%5gtJ(_Af*0aT(RnaW-W+%wE+8|0y9r<3 z#Oy)`RxLa=b(mnWIt4{Zw%p8_ZPtP=ScD}`N9FND6>z3Jq~~|MRu^X>vqhc}n#8Sg zO;b%%ZNr2)CP;5)Vk`@ol{r3b9@l^-63$BmhKd=!X0@w z@cp6Nb$ZQ9cXhqLCf!M22h!(;wL1ygn0EK)=KS_mE>Fr)ziW<`k_(ckIK_H#-(YgtHMoN= zGa_(Ga9FU1-T(_3qfc#ZoiL6WilIQaZTeRtw4Q~VXTfPMZiO^SHfxXPCTsVrv4BaW zN*`r75OiJ3XdGIVP?#^cJVC23yn1!RjvJ`5Lk|QEha80~VSRtpvw<@h2Hk<&v6~iN zYkGfGclE$Py8H|4t`9K!u|2wI(N&ACZ&Y-hic1{U>Z_I~npVYj$L2P5F}W{)X`~-b zy7!@p$v}gW5Vg#?hbFqwlzSJH3t`%-^#57n>xila*k4qD?bUvI&<5-0@4Tin;UTd7 zZeMZ0AycYOg)j&OXSi)iewBV`*S1q{eS!iEytuKfAH`JkeUDv5vB3h;l z)%6vyiUKwWhP|#UgMr^dC2Af2uL`0Pw%7DCw?E#JU7kr);nA zyybI?&su7pX`UUGI?r(u&9fwIQ;b?ie%a60Tl>+x(~?wMl2mYWP2d3ZTdN7|18?No zz?12TTm98p<%^P=$+EE!Ihv)~K{br8O!&3vZ$*uwS|;aBQt#x;VMpzm0Kn N_dojzty8R5005u|v|j)K literal 0 HcmV?d00001 diff --git a/editor/editor.dia b/editor/editor.dia new file mode 100644 index 0000000000000000000000000000000000000000..9f4416433c0ba5c3365e9cf5de8234b2b3a47aa6 GIT binary patch literal 1039 zcmV+q1n~PGiwFP!000001MQkkZ{s!)hVS_mf^zjz-;}knz32vuy|idAJqMJ<*lcA{ zAn9b?Lw|cmAGRznn6KaI24G}Ar)VYF^xG2&_Q+r?G_0Vt#XgmZ| z3;|{GDdj>5!c-j`avoEX6l^87v^`rcNes(;E@7)Z@tG;b-^uft#PU+2Gvn|!U%MMt zf<@;yLv6HS_A86j`sqiHA45Uh^+v@$fIYRAmW&{`RZ(NqdZmlzMf_n7YQI zx&FIZ)qa{aP++Imick4rF+MrSn>aq2ddFqGU6Uqi7#>3fDn+z!k&WvjJnhT6z(M?5)94@c>DslG)F ze8V?*Bu&(tgY_D?R8&x&y-PM8Q_- z6~9-&E0V7tux;R1q~0EWl(BJs?^jPgAEf9ejftXtey)3_to&@Dk?jT3>MWSBiyg=E zC$5KF7x%52K%bU$C%_Lb@-c|##PtylaPR7QOD&fq6r;d1gAXsEUs*EB=O~|}d^XDG zcM9qO&D=kE!VNlVchyk~SyrYzCNlfBo+h#}pdB!A56~QAJOu&8$Z4(C0-CKn<#t6h z$Jod}R`7a|jZ7;~^SUUI>!3?9TrjYU$HmZOyJ>36s{7`d`&J)9Z2T{hyW~j%uSmA# zjwV)jwKYkitowquTJgM{(yCE7%IYoO39P#bac(vto`uX{FcXr|UHpKN@A$Se@tpR1 zsD%mXQp+V1GDU%He*8Y}kt8ofjy`1cA)^oJ=0n`hQfeX##102}kJW!e2clNASU5Y` z!H?Lv9|5ro`u8K}i#Zz?AnUy0u#j6Aj;o?N9Y#N^E$QwWyv~-}MK&zd#2vyk0NlbQ z96W;!FNGbzTNvCCk$NBhQ`92;x_)$Vf3H|9MbY|qgN?6<-ey*^%`ws@3 JSuo8e006ft^!5M% literal 0 HcmV?d00001 diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c new file mode 100644 index 0000000000..ece5dfe0a6 --- /dev/null +++ b/gst/gstautoplug.c @@ -0,0 +1,311 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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. + */ + +#include "gstdebug.h" +#include "gstautoplug.h" + +#define MAX_COST 999999 + +typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data); +typedef GList* (*GstAutoplugListFunction) (gpointer data); + +static GList* gst_autoplug_func (gpointer src, gpointer sink, + GstAutoplugListFunction list_function, + GstAutoplugCostFunction cost_function, + gpointer data); + + +struct _gst_autoplug_node +{ + gpointer iNode; + gpointer iPrev; + gint iDist; +}; + +typedef struct _gst_autoplug_node gst_autoplug_node; + +static GList* +gst_autoplug_enqueue (GList *queue, gpointer iNode, gint iDist, gpointer iPrev) +{ + gst_autoplug_node *node = g_malloc (sizeof (gst_autoplug_node)); + + node->iNode = iNode; + node->iDist = iDist; + node->iPrev = iPrev; + + queue = g_list_append (queue, node); + + return queue; +} + +static GList* +gst_autoplug_dequeue (GList *queue, gpointer *iNode, gint *iDist, gpointer *iPrev) +{ + GList *head; + gst_autoplug_node *node; + + head = g_list_first (queue); + + if (head) { + node = (gst_autoplug_node *)head->data; + *iNode = node->iNode; + *iPrev = node->iPrev; + *iDist = node->iDist; + head = g_list_remove (queue, node); + } + + return head; +} + +static gint +find_factory (gst_autoplug_node *rgnNodes, GstElementFactory *factory) +{ + gint i=0; + + while (rgnNodes[i].iNode) { + if (rgnNodes[i].iNode == factory) return i; + i++; + } + + return 0; +} + +static GList* +construct_path (gst_autoplug_node *rgnNodes, GstElementFactory *factory) +{ + GstElementFactory *current; + GList *factories = NULL; + + current = rgnNodes[find_factory(rgnNodes, factory)].iPrev; + + while (current != NULL) + { + gpointer next; + next = rgnNodes[find_factory(rgnNodes, current)].iPrev; + if (next) factories = g_list_prepend (factories, current); + current = next; + } + + return factories; +} + +static gboolean +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_caps_check_compatibility (srctemp->caps, desttemp->caps)) { + DEBUG ("gstautoplug: \"%s\" connects with \"%s\"\n", src->name, dest->name); + return TRUE; + } + else { + DEBUG ("gstautoplug: \"%s\" does not connect with \"%s\"\n", src->name, dest->name); + } + } + + desttemps = g_list_next (desttemps); + } + srctemps = g_list_next (srctemps); + } + return FALSE; +} + +static GList* +gst_autoplug_elementfactory_get_list (gpointer data) +{ + return gst_elementfactory_get_list (); +} + +static guint +gst_autoplug_elementfactory_find_cost (gpointer src, gpointer dest, gpointer data) +{ + if (gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest)) { + return 1; + } + return MAX_COST; +} + + +GList* +gst_autoplug_factories (GstElementFactory *srcfactory, GstElementFactory *sinkfactory) +{ + return gst_autoplug_func (srcfactory, sinkfactory, + gst_autoplug_elementfactory_get_list, + gst_autoplug_elementfactory_find_cost, + NULL); +} + +typedef struct { + GstCaps *src; + GstCaps *sink; +} caps_struct; + +#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink) + +static guint +gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data) +{ + caps_struct *caps = (caps_struct *)data; + gboolean res; + + if (IS_CAPS (src) && IS_CAPS (dest)) { + res = gst_caps_check_compatibility ((GstCaps *)src, (GstCaps *)dest); + DEBUG ("caps %d to caps %d %d\n", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res); + } + else if (IS_CAPS (src)) { + res = gst_elementfactory_can_sink_caps ((GstElementFactory *)dest, src); + DEBUG ("factory %s to sink caps %d %d\n", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res); + } + else if (IS_CAPS (dest)) { + res = gst_elementfactory_can_src_caps ((GstElementFactory *)src, dest); + DEBUG ("factory %s to src caps %d %d\n", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res); + } + else { + res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest); + } + + if (res) return 1; + return MAX_COST; +} + +GList* +gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps) +{ + caps_struct caps; + + caps.src = srccaps; + caps.sink = sinkcaps; + + return gst_autoplug_func (srccaps, sinkcaps, + gst_autoplug_elementfactory_get_list, + gst_autoplug_caps_find_cost, + &caps); +} + +GList* +gst_autoplug_elements (GstElement *src, GstElement *sink) +{ + return NULL; +} + +GList* +gst_autoplug_caps_to_factory (GstCaps *srccaps, GstElementFactory *sinkfactory) +{ + return NULL; +} + +GList* +gst_autoplug_factory_to_caps (GstElementFactory *srcfactory, GstCaps *sinkcaps) +{ + return NULL; +} + +/** + * gst_type_get_sink_to_src: + * @sinkid: the id of the sink + * @srcid: the id of the source + * + * return a list of elementfactories that convert the source + * type id to the sink type id + * + * Returns: a list of elementfactories + */ +static GList* +gst_autoplug_func (gpointer src, gpointer sink, + GstAutoplugListFunction list_function, + GstAutoplugCostFunction cost_function, + gpointer data) +{ + gst_autoplug_node *rgnNodes; + GList *queue = NULL; + gpointer iNode, iPrev; + gint iDist, i, iCost; + + GList *elements = g_list_copy (list_function(data)); + GList *factories; + guint num_factories; + + DEBUG ("%p %p\n", src, sink); + + elements = g_list_append (elements, sink); + elements = g_list_append (elements, src); + + factories = elements; + + num_factories = g_list_length (factories); + + rgnNodes = g_new0 (gst_autoplug_node, num_factories+1); + + for (i=0; i< num_factories; i++) { + gpointer fact = factories->data; + + rgnNodes[i].iNode = fact; + rgnNodes[i].iPrev = NULL; + + if (fact == src) { + rgnNodes[i].iDist = 0; + } + else { + rgnNodes[i].iDist = MAX_COST; + } + + factories = g_list_next (factories); + } + rgnNodes[num_factories].iNode = NULL; + + queue = gst_autoplug_enqueue (queue, src, 0, NULL); + + while (g_list_length (queue) > 0) { + GList *factories2 = elements; + + queue = gst_autoplug_dequeue (queue, &iNode, &iDist, &iPrev); + + for (i=0; i< num_factories; i++) { + gpointer current = factories2->data; + + iCost = cost_function (iNode, current, data); + if (iCost != MAX_COST) { + if((MAX_COST == rgnNodes[i].iDist) || + (rgnNodes[i].iDist > (iCost + iDist))) { + rgnNodes[i].iDist = iDist + iCost; + rgnNodes[i].iPrev = iNode; + + queue = gst_autoplug_enqueue (queue, current, iDist + iCost, iNode); + } + } + + factories2 = g_list_next (factories2); + } + } + + return construct_path (rgnNodes, sink); +} + diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h new file mode 100644 index 0000000000..3f2ba438e0 --- /dev/null +++ b/gst/gstautoplug.h @@ -0,0 +1,49 @@ +/* Gnome-Streamer + * Copyright (C) <1999> Erik Walthinsen + * + * 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_AUTOPLUG_H__ +#define __GST_AUTOPLUG_H__ + +#include "gstelement.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +GList* gst_autoplug_factories (GstElementFactory *srcfactory, + GstElementFactory *sinkfactory); +GList* gst_autoplug_elements (GstElement *src, + GstElement *sink); + +GList* gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps); + +GList* gst_autoplug_caps_to_factory (GstCaps *srccaps, GstElementFactory *sinkfactory); + +GList* gst_autoplug_factory_to_caps (GstElementFactory *srcfactory, GstCaps *sinkcaps); + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __GST_AUTOPLUG_H__ */ + diff --git a/tests/autoplug.c b/tests/autoplug.c new file mode 100644 index 0000000000..686eb380ad --- /dev/null +++ b/tests/autoplug.c @@ -0,0 +1,55 @@ +#include + +static GList* +autoplug_factories (gchar *factory1, gchar *factory2) +{ + GstElementFactory *mp3parse, *audiosink; + mp3parse = gst_elementfactory_find ("mpeg1parse"); + g_assert (mp3parse != NULL); + + audiosink = gst_elementfactory_find ("videosink"); + g_assert (audiosink != NULL); + + return gst_autoplug_factories (mp3parse, audiosink); +} + +static GList* +autoplug_caps (gchar *mime1, gchar *mime2) +{ + GstCaps *caps1, *caps2; + + caps1 = gst_caps_new (mime1); + caps2 = gst_caps_new (mime2); + + return gst_autoplug_caps (caps1, caps2); +} + +static void +dump_factories (GList *factories) +{ + g_print ("dumping factories\n"); + + while (factories) { + GstElementFactory *factory = (GstElementFactory *)factories->data; + + g_print ("factory: \"%s\"\n", factory->name); + + factories = g_list_next (factories); + } +} + +int main(int argc,char *argv[]) +{ + GList *factories; + + gst_init(&argc,&argv); + + factories = autoplug_factories ("mpeg1parse", "videosink"); + dump_factories (factories); + + factories = autoplug_caps ("audio/mp3", "audio/raw"); + dump_factories (factories); + + factories = autoplug_caps ("video/mpeg", "audio/raw"); + dump_factories (factories); +}