summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2001-03-03 19:08:07 +0000
committerWim Taymans <wim.taymans@gmail.com>2001-03-03 19:08:07 +0000
commit3987dbee2255b301c3200e1323be14d16a42f819 (patch)
treefa94eadb0667efaf4c8522da8f895395628a5b91
parent90ac5da6d6fe07dc902502cfed96a779b1717e23 (diff)
Added an API for element construction and renderer autopluggers.
Original commit message from CVS: Added an API for element construction and renderer autopluggers. Added another autoplugger to render things. Updated the player to use the new autoplugger.
-rw-r--r--gst/autoplug/Makefile.am8
-rw-r--r--gst/autoplug/gststaticautoplug.c80
-rw-r--r--gst/autoplug/gststaticautoplugrender.c650
-rw-r--r--gst/autoplug/gststaticautoplugrender.h64
-rw-r--r--gst/gstautoplug.c32
-rw-r--r--gst/gstautoplug.h19
-rw-r--r--gstplay/gstplay.c85
-rw-r--r--gstplay/gstplayprivate.h2
-rw-r--r--tests/Makefile.am2
-rw-r--r--tests/autoplug.c2
-rw-r--r--tests/autoplug2.c38
11 files changed, 823 insertions, 159 deletions
diff --git a/gst/autoplug/Makefile.am b/gst/autoplug/Makefile.am
index a6a7c8bce6..0ddb2a8a74 100644
--- a/gst/autoplug/Makefile.am
+++ b/gst/autoplug/Makefile.am
@@ -1,8 +1,12 @@
filterdir = $(libdir)/gst
-filter_LTLIBRARIES = libgststaticautoplug.la
+filter_LTLIBRARIES = libgststaticautoplug.la libgststaticautoplugrender.la
libgststaticautoplug_la_SOURCES = \
- gststaticautoplug.c
+ gststaticautoplug.c
+
+libgststaticautoplugrender_la_SOURCES = \
+ gststaticautoplugrender.c
libgststaticautoplug_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgststaticautoplugrender_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
diff --git a/gst/autoplug/gststaticautoplug.c b/gst/autoplug/gststaticautoplug.c
index 3eab16d77c..a39ac579fe 100644
--- a/gst/autoplug/gststaticautoplug.c
+++ b/gst/autoplug/gststaticautoplug.c
@@ -30,17 +30,19 @@ typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointe
typedef GList* (*GstAutoplugListFunction) (gpointer data);
-static void gst_static_autoplug_class_init (GstStaticAutoplugClass *klass);
-static void gst_static_autoplug_init (GstStaticAutoplug *autoplug);
+static void gst_static_autoplug_class_init (GstStaticAutoplugClass *klass);
+static void gst_static_autoplug_init (GstStaticAutoplug *autoplug);
-static GList* gst_autoplug_func (gpointer src, gpointer sink,
- GstAutoplugListFunction list_function,
- GstAutoplugCostFunction cost_function,
- gpointer data);
+static GList* gst_autoplug_func (gpointer src, gpointer sink,
+ GstAutoplugListFunction list_function,
+ GstAutoplugCostFunction cost_function,
+ gpointer data);
-static GstElement* gst_static_autoplug_caps_list (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args);
+static GstElement* gst_static_autoplug_to_caps (GstAutoplug *autoplug,
+ GList *srccaps, GList *sinkcaps, va_list args);
+
static GstAutoplugClass *parent_class = NULL;
GtkType gst_static_autoplug_get_type(void)
@@ -72,7 +74,7 @@ gst_static_autoplug_class_init(GstStaticAutoplugClass *klass)
parent_class = gtk_type_class(GST_TYPE_AUTOPLUG);
- gstautoplug_class->autoplug_caps_list = gst_static_autoplug_caps_list;
+ gstautoplug_class->autoplug_to_caps = gst_static_autoplug_to_caps;
}
static void gst_static_autoplug_init(GstStaticAutoplug *autoplug) {
@@ -265,7 +267,7 @@ gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data)
}
static GstElement*
-gst_static_autoplug_caps_list (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args)
+gst_static_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args)
{
caps_struct caps;
GList *capslist;
@@ -401,9 +403,6 @@ differ:
for (i = 0; i < numsinks; i++) {
GstElement *thesrcelement = srcelement;
GstElement *thebin = GST_ELEMENT(result);
- gboolean use_thread;
-
- use_thread = have_common;
while (factories[i]) {
// fase 4: add other elements...
@@ -415,59 +414,10 @@ differ:
GST_DEBUG (0,"factory \"%s\"\n", factory->name);
element = gst_elementfactory_create(factory, factory->name);
- // this element suggests the use of a thread, so we set one up...
- if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) {
- GstElement *queue;
- GList *sinkpads;
- GstPad *srcpad, *sinkpad;
-
- use_thread = FALSE;
-
- GST_DEBUG (0,"sugest new thread for \"%s\" %08x\n", GST_ELEMENT_NAME (element), GST_FLAGS(element));
-
- // create a new queue and add to the previous bin
- queue = gst_elementfactory_make("queue", g_strconcat("queue_", GST_ELEMENT_NAME(element), NULL));
- GST_DEBUG (0,"adding element \"%s\"\n", GST_ELEMENT_NAME (element));
- gst_bin_add(GST_BIN(thebin), queue);
- gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (queue));
-
- // this will be the new bin for all following elements
- thebin = gst_elementfactory_make("thread", g_strconcat("thread_", GST_ELEMENT_NAME(element), NULL));
-
- srcpad = gst_element_get_pad(queue, "src");
-
- sinkpads = gst_element_get_pad_list(element);
- while (sinkpads) {
- sinkpad = (GstPad *)sinkpads->data;
-
- // FIXME connect matching pads, not just the first one...
- if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
- !GST_PAD_CONNECTED(sinkpad)) {
- GList *caps = gst_pad_get_caps_list (sinkpad);
-
- // the queue has the type of the elements it connects
- gst_pad_set_caps_list (srcpad, caps);
- gst_pad_set_caps_list (gst_element_get_pad(queue, "sink"), caps);
- break;
- }
- sinkpads = g_list_next(sinkpads);
- }
- gst_autoplug_pads_autoplug(thesrcelement, queue);
-
- GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
- gst_bin_add(GST_BIN(thebin), element);
- gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
- GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin));
- gst_bin_add(GST_BIN(result), thebin);
- gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (thebin));
- thesrcelement = queue;
- }
- // no thread needed, easy case
- else {
- GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
- gst_bin_add(GST_BIN(thebin), element);
- gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
- }
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
+ gst_bin_add(GST_BIN(thebin), element);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+
gst_autoplug_pads_autoplug(thesrcelement, element);
// this element is now the new source element
diff --git a/gst/autoplug/gststaticautoplugrender.c b/gst/autoplug/gststaticautoplugrender.c
new file mode 100644
index 0000000000..5533d69178
--- /dev/null
+++ b/gst/autoplug/gststaticautoplugrender.c
@@ -0,0 +1,650 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ *
+ * gststaticautoplug.c: A static Autoplugger of pipelines
+ *
+ * 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 "gststaticautoplugrender.h"
+
+#include <gst/gst.h>
+
+#define GST_AUTOPLUG_MAX_COST 999999
+
+typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data);
+typedef GList* (*GstAutoplugListFunction) (gpointer data);
+
+
+static void gst_static_autoplug_render_class_init (GstStaticAutoplugRenderClass *klass);
+static void gst_static_autoplug_render_init (GstStaticAutoplugRender *autoplug);
+
+static GList* gst_autoplug_func (gpointer src, gpointer sink,
+ GstAutoplugListFunction list_function,
+ GstAutoplugCostFunction cost_function,
+ gpointer data);
+
+
+
+static GstElement* gst_static_autoplug_to_render (GstAutoplug *autoplug,
+ GList *srccaps, GstElement *target, va_list args);
+
+static GstAutoplugClass *parent_class = NULL;
+
+GtkType gst_static_autoplug_render_get_type(void)
+{
+ static GtkType static_autoplug_type = 0;
+
+ if (!static_autoplug_type) {
+ static const GtkTypeInfo static_autoplug_info = {
+ "GstStaticAutoplugRender",
+ sizeof(GstElement),
+ sizeof(GstElementClass),
+ (GtkClassInitFunc)gst_static_autoplug_render_class_init,
+ (GtkObjectInitFunc)gst_static_autoplug_render_init,
+ (GtkArgSetFunc)NULL,
+ (GtkArgGetFunc)NULL,
+ (GtkClassInitFunc)NULL,
+ };
+ static_autoplug_type = gtk_type_unique (GST_TYPE_AUTOPLUG, &static_autoplug_info);
+ }
+ return static_autoplug_type;
+}
+
+static void
+gst_static_autoplug_render_class_init(GstStaticAutoplugRenderClass *klass)
+{
+ GstAutoplugClass *gstautoplug_class;
+
+ gstautoplug_class = (GstAutoplugClass*) klass;
+
+ parent_class = gtk_type_class(GST_TYPE_AUTOPLUG);
+
+ gstautoplug_class->autoplug_to_renderers = gst_static_autoplug_to_render;
+}
+
+static void gst_static_autoplug_render_init(GstStaticAutoplugRender *autoplug) {
+}
+
+GstPlugin*
+plugin_init (GModule *module)
+{
+ GstPlugin *plugin;
+ GstAutoplugFactory *factory;
+
+ plugin = gst_plugin_new("gststaticautoplugrender");
+ g_return_val_if_fail(plugin != NULL,NULL);
+
+ gst_plugin_set_longname (plugin, "A static autoplugger");
+
+ factory = gst_autoplugfactory_new ("staticrender",
+ "A static autoplugger, it constructs the complete element before running it",
+ gst_static_autoplug_render_get_type ());
+
+ if (factory != NULL) {
+ gst_plugin_add_autoplugger (plugin, factory);
+ }
+ return plugin;
+}
+
+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_list_check_compatibility (srctemp->caps, desttemp->caps)) {
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
+ "factory \"%s\" can connect with factory \"%s\"", src->name, dest->name);
+ return TRUE;
+ }
+ }
+
+ desttemps = g_list_next (desttemps);
+ }
+ srctemps = g_list_next (srctemps);
+ }
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,
+ "factory \"%s\" cannot connect with factory \"%s\"", src->name, dest->name);
+ return FALSE;
+}
+
+static gboolean
+gst_autoplug_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
+{
+ GList *sinkpads;
+ gboolean connected = FALSE;
+
+ GST_DEBUG (0,"gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n",
+ GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink));
+
+ sinkpads = gst_element_get_pad_list(sink);
+ while (sinkpads) {
+ GstPad *sinkpad = (GstPad *)sinkpads->data;
+
+ // if we have a match, connect the pads
+ if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
+ !GST_PAD_CONNECTED(sinkpad))
+ {
+ if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) {
+ gst_pad_connect(pad, sinkpad);
+ GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad),
+ GST_ELEMENT_NAME(src));
+ GST_DEBUG (0,"pad \"%s\" in element %s\n", GST_PAD_NAME (sinkpad),
+ GST_ELEMENT_NAME(sink));
+ connected = TRUE;
+ break;
+ }
+ else {
+ GST_DEBUG (0,"pads incompatible %s, %s\n", GST_PAD_NAME (pad), GST_PAD_NAME (sinkpad));
+ }
+ }
+ sinkpads = g_list_next(sinkpads);
+ }
+
+ if (!connected) {
+ GST_DEBUG (0,"gstpipeline: no path to sinks for type\n");
+ }
+ return connected;
+}
+
+typedef struct {
+ GstElement *result;
+ GList *endcap;
+ gint i;
+} dynamic_pad_struct;
+
+static void
+autoplug_dynamic_pad (GstElement *element, GstPad *pad, gpointer data)
+{
+ dynamic_pad_struct *info = (dynamic_pad_struct *)data;
+ GList *pads = gst_element_get_pad_list (element);
+
+ GST_DEBUG (0,"attempting to dynamically create a ghostpad for %s=%s\n", GST_ELEMENT_NAME (element),
+ GST_PAD_NAME (pad));
+
+ while (pads) {
+ GstPad *pad = GST_PAD (pads->data);
+ pads = g_list_next (pads);
+
+ if (gst_caps_list_check_compatibility (gst_pad_get_caps_list (pad), info->endcap)) {
+ gst_element_add_ghost_pad (info->result, pad, g_strdup_printf("src_%02d", info->i));
+ GST_DEBUG (0,"gstpipeline: new dynamic pad %s\n", GST_PAD_NAME (pad));
+ break;
+ }
+ }
+}
+
+static void
+gst_autoplug_pads_autoplug (GstElement *src, GstElement *sink)
+{
+ GList *srcpads;
+ gboolean connected = FALSE;
+
+ srcpads = gst_element_get_pad_list(src);
+
+ while (srcpads && !connected) {
+ GstPad *srcpad = (GstPad *)srcpads->data;
+
+ if (gst_pad_get_direction(srcpad) == GST_PAD_SRC)
+ connected = gst_autoplug_pads_autoplug_func (src, srcpad, sink);
+
+ srcpads = g_list_next(srcpads);
+ }
+
+ if (!connected) {
+ GST_DEBUG (0,"gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n",
+ GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink));
+ gtk_signal_connect(GTK_OBJECT(src),"new_pad",
+ GTK_SIGNAL_FUNC(gst_autoplug_pads_autoplug_func), sink);
+ gtk_signal_connect(GTK_OBJECT(src),"new_ghost_pad",
+ GTK_SIGNAL_FUNC(gst_autoplug_pads_autoplug_func), sink);
+ }
+}
+
+static GList*
+gst_autoplug_elementfactory_get_list (gpointer data)
+{
+ return gst_elementfactory_get_list ();
+}
+
+typedef struct {
+ GList *src;
+ GList *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_list_check_compatibility ((GList *)src, (GList *)dest);
+ //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res);
+ }
+ else if (IS_CAPS (src)) {
+ res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src);
+ //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res);
+ }
+ else if (IS_CAPS (dest)) {
+ res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest);
+ //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res);
+ }
+ else {
+ res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest);
+ }
+
+ if (res)
+ return 1;
+ else
+ return GST_AUTOPLUG_MAX_COST;
+}
+
+static GstElement*
+gst_static_autoplug_to_render (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args)
+{
+ caps_struct caps;
+ GstElement *targetelement;
+ GstElement *result = NULL, *srcelement = NULL;
+ GList **factories;
+ GList *chains = NULL;
+ GList *endelements = NULL;
+ guint numsinks = 0, i;
+ gboolean have_common = FALSE;
+
+ targetelement = target;
+
+ /*
+ * We first create a list of elements that are needed
+ * to convert the srcpad caps to the different sinkpad caps.
+ * and add the list of elementfactories to a list (chains).
+ */
+ caps.src = srccaps;
+
+ while (targetelement) {
+ GList *elements;
+ GstPad *pad;
+
+ pad = GST_PAD (gst_element_get_pad_list (targetelement)->data);
+
+ caps.sink = gst_pad_get_caps_list (pad);
+
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
+
+ elements = gst_autoplug_func (caps.src, caps.sink,
+ gst_autoplug_elementfactory_get_list,
+ gst_autoplug_caps_find_cost,
+ &caps);
+
+ if (elements) {
+ chains = g_list_append (chains, elements);
+ endelements = g_list_append (endelements, targetelement);
+ numsinks++;
+ }
+ else {
+ }
+
+ targetelement = va_arg (args, GstElement *);
+ }
+
+ /*
+ * If no list could be found the pipeline cannot be autoplugged and
+ * we return a NULL element
+ */
+ if (numsinks == 0)
+ return NULL;
+
+ /*
+ * We now have a list of lists. We will turn this into an array
+ * of lists, this will make it much more easy to manipulate it
+ * in the next steps.
+ */
+ factories = g_new0 (GList *, numsinks);
+
+ for (i = 0; chains; i++) {
+ GList *elements = (GList *) chains->data;
+
+ factories[i] = elements;
+
+ chains = g_list_next (chains);
+ }
+ //FIXME, free the list
+
+ result = gst_bin_new ("autoplug_bin");
+
+ /*
+ * We now hav a list of lists that is probably like:
+ *
+ * !
+ * A -> B -> C
+ * !
+ * A -> D -> E
+ *
+ * we now try to find the common elements (A) and add them to
+ * the bin. We remove them from both lists too.
+ */
+ while (factories[0]) {
+ GstElementFactory *factory;
+ GstElement *element;
+
+ // fase 3: add common elements
+ factory = (GstElementFactory *) (factories[0]->data);
+
+ // check to other paths for matching elements (factories)
+ for (i=1; i<numsinks; i++) {
+ if (factory != (GstElementFactory *) (factories[i]->data)) {
+ goto differ;
+ }
+ }
+
+ GST_DEBUG (0,"common factory \"%s\"\n", factory->name);
+
+ element = gst_elementfactory_create (factory, factory->name);
+ gst_bin_add (GST_BIN(result), element);
+
+ if (srcelement != NULL) {
+ gst_autoplug_pads_autoplug (srcelement, element);
+ }
+ // this is the first element, find a good ghostpad
+ else {
+ GList *pads;
+
+ pads = gst_element_get_pad_list (element);
+
+ while (pads) {
+ GstPad *pad = GST_PAD (pads->data);
+
+ if (gst_caps_list_check_compatibility (srccaps, gst_pad_get_caps_list (pad))) {
+ gst_element_add_ghost_pad (result, pad, "sink");
+ break;
+ }
+
+ pads = g_list_next (pads);
+ }
+ }
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+
+ srcelement = element;
+
+ // advance the pointer in all lists
+ for (i=0; i<numsinks; i++) {
+ factories[i] = g_list_next (factories[i]);
+ }
+
+ have_common = TRUE;
+ }
+
+differ:
+
+ // loop over all the sink elements
+ for (i = 0; i < numsinks; i++) {
+ GstElement *thesrcelement = srcelement;
+ GstElement *thebin = GST_ELEMENT(result);
+ GstElement *sinkelement;
+ gboolean use_thread;
+
+ sinkelement = GST_ELEMENT (endelements->data);
+ endelements = g_list_next (endelements);
+
+ use_thread = have_common;
+
+ while (factories[i] || sinkelement) {
+ // fase 4: add other elements...
+ GstElementFactory *factory;
+ GstElement *element;
+
+ if (factories[i]) {
+ factory = (GstElementFactory *)(factories[i]->data);
+
+ GST_DEBUG (0,"factory \"%s\"\n", factory->name);
+ element = gst_elementfactory_create(factory, factory->name);
+ }
+ else {
+ element = sinkelement;
+ sinkelement = NULL;
+ }
+
+ // this element suggests the use of a thread, so we set one up...
+ if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) {
+ GstElement *queue;
+ GList *sinkpads;
+ GstPad *srcpad, *sinkpad;
+
+ use_thread = FALSE;
+
+ GST_DEBUG (0,"sugest new thread for \"%s\" %08x\n", GST_ELEMENT_NAME (element), GST_FLAGS(element));
+
+ // create a new queue and add to the previous bin
+ queue = gst_elementfactory_make("queue", g_strconcat("queue_", GST_ELEMENT_NAME(element), NULL));
+ GST_DEBUG (0,"adding element \"%s\"\n", GST_ELEMENT_NAME (element));
+ gst_bin_add(GST_BIN(thebin), queue);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (queue));
+
+ // this will be the new bin for all following elements
+ thebin = gst_elementfactory_make("thread", g_strconcat("thread_", GST_ELEMENT_NAME(element), NULL));
+
+ srcpad = gst_element_get_pad(queue, "src");
+
+ sinkpads = gst_element_get_pad_list(element);
+ while (sinkpads) {
+ sinkpad = (GstPad *)sinkpads->data;
+
+ // FIXME connect matching pads, not just the first one...
+ if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK &&
+ !GST_PAD_CONNECTED(sinkpad)) {
+ GList *caps = gst_pad_get_caps_list (sinkpad);
+
+ // the queue has the type of the elements it connects
+ gst_pad_set_caps_list (srcpad, caps);
+ gst_pad_set_caps_list (gst_element_get_pad(queue, "sink"), caps);
+ break;
+ }
+ sinkpads = g_list_next(sinkpads);
+ }
+ gst_autoplug_pads_autoplug(thesrcelement, queue);
+
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
+ gst_bin_add(GST_BIN(thebin), element);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin));
+ gst_bin_add(GST_BIN(result), thebin);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (thebin));
+ thesrcelement = queue;
+ }
+ // no thread needed, easy case
+ else {
+ GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element));
+ gst_bin_add(GST_BIN(thebin), element);
+ gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
+ }
+ gst_autoplug_pads_autoplug(thesrcelement, element);
+
+ // this element is now the new source element
+ thesrcelement = element;
+
+ factories[i] = g_list_next(factories[i]);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * shortest path algorithm
+ *
+ */
+struct _gst_autoplug_node
+{
+ gpointer iNode;
+ gpointer iPrev;
+ gint iDist;
+};
+
+typedef struct _gst_autoplug_node gst_autoplug_node;
+
+static gint
+find_factory (gst_autoplug_node *rgnNodes, gpointer 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, gpointer factory)
+{
+ GstElementFactory *current;
+ GList *factories = NULL;
+
+ current = rgnNodes[find_factory(rgnNodes, factory)].iPrev;
+
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factories found in autoplugging (reversed order)");
+
+ while (current != NULL)
+ {
+ gpointer next = NULL;
+
+ next = rgnNodes[find_factory(rgnNodes, current)].iPrev;
+ if (next) {
+ factories = g_list_prepend (factories, current);
+ GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name);
+ }
+ current = next;
+ }
+ return factories;
+}
+
+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 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;
+
+ 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 = GST_AUTOPLUG_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 != GST_AUTOPLUG_MAX_COST) {
+ if ((GST_AUTOPLUG_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/autoplug/gststaticautoplugrender.h b/gst/autoplug/gststaticautoplugrender.h
new file mode 100644
index 0000000000..351d4cdcaf
--- /dev/null
+++ b/gst/autoplug/gststaticautoplugrender.h
@@ -0,0 +1,64 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstautoplug.h: Header for autoplugging functionality
+ *
+ * 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_STATIC_AUTOPLUG_RENDER_H__
+#define __GST_STATIC_AUTOPLUG_RENDER_H__
+
+#include <gst/gstautoplug.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GST_TYPE_STATIC_AUTOPLUG_RENDER \
+ (gst_static_autoplug_render_get_type())
+#define GST_STATIC_AUTOPLUG_RENDER(obj) \
+ (GTK_CHECK_CAST((obj),GST_TYPE_STATIC_AUTOPLUG_RENDER,GstStaticAutoplugRender))
+#define GST_STATIC_AUTOPLUG_RENDER_CLASS(klass) \
+ (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_STATIC_AUTOPLUG_RENDER,GstStaticAutoplugRenderClass))
+#define GST_IS_STATIC_AUTOPLUG_RENDER(obj) \
+ (GTK_CHECK_TYPE((obj),GST_TYPE_STATIC_AUTOPLUG_RENDER))
+#define GST_IS_STATIC_AUTOPLUG_RENDER_CLASS(obj) \
+ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_STATIC_AUTOPLUG_RENDER))
+
+typedef struct _GstStaticAutoplugRender GstStaticAutoplugRender;
+typedef struct _GstStaticAutoplugRenderClass GstStaticAutoplugRenderClass;
+
+struct _GstStaticAutoplugRender {
+ GstAutoplug object;
+};
+
+struct _GstStaticAutoplugRenderClass {
+ GstAutoplugClass parent_class;
+};
+
+
+GtkType gst_static_autoplug_render_get_type (void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_STATIC_AUTOPLUG_H__ */
+
diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c
index 16eafbf27c..3f74b25bb1 100644
--- a/gst/gstautoplug.c
+++ b/gst/gstautoplug.c
@@ -59,7 +59,7 @@ GtkType gst_autoplug_get_type(void)
(GtkArgGetFunc)NULL,
(GtkClassInitFunc)NULL,
};
- autoplug_type = gtk_type_unique (GTK_TYPE_OBJECT, &autoplug_info);
+ autoplug_type = gtk_type_unique (GST_TYPE_OBJECT, &autoplug_info);
}
return autoplug_type;
}
@@ -68,10 +68,12 @@ static void
gst_autoplug_class_init(GstAutoplugClass *klass)
{
GtkObjectClass *gtkobject_class;
+ GstObjectClass *gstobject_class;
gtkobject_class = (GtkObjectClass*) klass;
+ gstobject_class = (GstObjectClass*) klass;
- parent_class = gtk_type_class(GTK_TYPE_OBJECT);
+ parent_class = gtk_type_class(GST_TYPE_OBJECT);
gst_autoplug_signals[NEW_OBJECT] =
gtk_signal_new ("new_object", GTK_RUN_LAST, gtkobject_class->type,
@@ -100,17 +102,35 @@ gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object)
GstElement*
-gst_autoplug_caps_list (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, ...)
+gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...)
{
GstAutoplugClass *oclass;
GstElement *element = NULL;
va_list args;
- va_start (args, sinkpad);
+ va_start (args, sinkcaps);
oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
- if (oclass->autoplug_caps_list)
- element = (oclass->autoplug_caps_list) (autoplug, srcpad, sinkpad, args);
+ if (oclass->autoplug_to_caps)
+ element = (oclass->autoplug_to_caps) (autoplug, srccaps, sinkcaps, args);
+
+ va_end (args);
+
+ return element;
+}
+
+GstElement*
+gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps, GstElement *target, ...)
+{
+ GstAutoplugClass *oclass;
+ GstElement *element = NULL;
+ va_list args;
+
+ va_start (args, target);
+
+ oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass);
+ if (oclass->autoplug_to_renderers)
+ element = (oclass->autoplug_to_renderers) (autoplug, srccaps, target, args);
va_end (args);
diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h
index 484471ffc6..14d96d55d3 100644
--- a/gst/gstautoplug.h
+++ b/gst/gstautoplug.h
@@ -44,18 +44,27 @@ extern "C" {
typedef struct _GstAutoplug GstAutoplug;
typedef struct _GstAutoplugClass GstAutoplugClass;
+typedef enum {
+ GST_AUTOPLUG_TO_CAPS = GST_OBJECT_FLAG_LAST,
+ GST_AUTOPLUG_TO_RENDERER,
+
+ GST_AUTOPLUG_FLAG_LAST = GST_OBJECT_FLAG_LAST + 8,
+} GstAutoplugFlags;
+
+
struct _GstAutoplug {
- GtkObject object;
+ GstObject object;
};
struct _GstAutoplugClass {
- GtkObjectClass parent_class;
+ GstObjectClass parent_class;
/* signal callbacks */
void (*new_object) (GstAutoplug *autoplug, GstObject *object);
/* perform the autoplugging */
- GstElement* (*autoplug_caps_list) (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, va_list args);
+ GstElement* (*autoplug_to_caps) (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, va_list args);
+ GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GList *srccaps, GstElement *target, va_list args);
};
typedef struct _GstAutoplugFactory GstAutoplugFactory;
@@ -70,7 +79,9 @@ GtkType gst_autoplug_get_type (void);
void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object);
-GstElement* gst_autoplug_caps_list (GstAutoplug *autoplug, GList *srcpad, GList *sinkpad, ...);
+GstElement* gst_autoplug_to_caps (GstAutoplug *autoplug, GList *srccaps, GList *sinkcaps, ...);
+GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GList *srccaps,
+ GstElement *target, ...);
/*
diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c
index 3ce0457c79..f0b7459dce 100644
--- a/gstplay/gstplay.c
+++ b/gstplay/gstplay.c
@@ -125,44 +125,17 @@ gst_play_init (GstPlay *play)
priv->bin = gst_bin_new ("main_bin");
g_assert (priv->bin != NULL);
- /* and an audio sink */
- priv->audio_play = gst_thread_new ("audio_render_thread");
- g_return_if_fail (priv->audio_play != NULL);
-
priv->audio_element = gst_elementfactory_make ("audiosink", "play_audio");
g_return_if_fail (priv->audio_element != NULL);
gtk_signal_connect (GTK_OBJECT (priv->audio_element), "handoff",
GTK_SIGNAL_FUNC (gst_play_audio_handoff), play);
- priv->audio_queue = gst_elementfactory_make ("queue", "audio_queue");
-
- gst_bin_add (GST_BIN (priv->audio_play), priv->audio_element),
-
- gst_element_connect (priv->audio_queue, "src", priv->audio_element, "sink");
- // FIXME, we need caps negiciation
- gst_pad_set_caps_list (gst_element_get_pad (priv->audio_queue, "sink"),
- gst_pad_get_caps_list (
- gst_element_get_pad (priv->audio_element, "sink")));
-
- /* and a video sink */
- priv->video_show = gst_thread_new ("video_render_thread");
- g_return_if_fail (priv->video_show != NULL);
-
priv->video_element = gst_elementfactory_make ("videosink", "show");
g_return_if_fail (priv->video_element != NULL);
gtk_object_set (GTK_OBJECT (priv->video_element), "xv_enabled", FALSE, NULL);
gtk_signal_connect (GTK_OBJECT (priv->video_element), "frame_displayed",
GTK_SIGNAL_FUNC (gst_play_frame_displayed), play);
- priv->video_queue = gst_elementfactory_make ("queue", "video_queue");
-
- gst_bin_add (GST_BIN (priv->video_show), priv->video_element),
-
- gst_element_connect (priv->video_queue, "src", priv->video_element, "sink");
- gst_pad_set_caps_list (gst_element_get_pad (priv->video_queue, "sink"),
- gst_pad_get_caps_list (
- gst_element_get_pad (priv->video_element, "sink")));
-
play->state = GST_PLAY_STOPPED;
play->flags = 0;
@@ -193,6 +166,14 @@ static void
gst_play_frame_displayed (GstElement *element,
GstPlay *play)
{
+ GstPlayPrivate *priv;
+
+ priv = (GstPlayPrivate *)play->priv;
+
+ gdk_threads_enter ();
+ gtk_widget_show (GTK_WIDGET (priv->video_widget));
+ gdk_threads_leave ();
+
gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_FRAME_DISPLAYED],
NULL);
}
@@ -338,27 +319,6 @@ connect_pads (GstElement *new_element, GstElement *target, gboolean add)
return FALSE;
}
-static void
-dynamic_connect_pads (GstElement *new_element, GstPad *pad, gpointer data)
-{
- GstPlay *play = (GstPlay *)data;
- GstPlayPrivate *priv;
-
- priv = (GstPlayPrivate *)play->priv;
-
- gdk_threads_enter();
- if (!(play->flags & GST_PLAY_TYPE_AUDIO) &&
- (connect_pads (new_element, priv->audio_queue, FALSE))) {
- play->flags |= GST_PLAY_TYPE_AUDIO;
- }
- if (!(play->flags & GST_PLAY_TYPE_VIDEO) &&
- (connect_pads (new_element, priv->video_queue, FALSE))) {
- play->flags |= GST_PLAY_TYPE_VIDEO;
- gtk_widget_show (priv->video_widget);
- }
- gdk_threads_leave();
-}
-
GstPlayReturn
gst_play_set_uri (GstPlay *play,
const guchar *uri)
@@ -394,14 +354,15 @@ gst_play_set_uri (GstPlay *play,
return GST_PLAY_UNKNOWN_MEDIA;
}
- autoplug = gst_autoplugfactory_make ("static");
+ autoplug = gst_autoplugfactory_make ("staticrender");
+ g_assert (autoplug != NULL);
gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play);
- new_element = gst_autoplug_caps_list (autoplug,
+ new_element = gst_autoplug_to_renderers (autoplug,
gst_pad_get_caps_list (gst_element_get_pad (priv->src, "src")),
- gst_pad_get_caps_list (gst_element_get_pad (priv->video_queue, "sink")),
- gst_pad_get_caps_list (gst_element_get_pad (priv->audio_queue, "sink")),
+ priv->video_element,
+ priv->audio_element,
NULL);
if (!new_element) {
@@ -415,26 +376,6 @@ gst_play_set_uri (GstPlay *play,
gst_element_connect (priv->src, "src", new_element, "sink");
- if (connect_pads (new_element, priv->video_queue, TRUE)) {
- gst_bin_add (GST_BIN (priv->bin), priv->video_show),
- play->flags |= GST_PLAY_TYPE_VIDEO;
- gtk_widget_show (priv->video_widget);
- }
- else {
- gst_bin_add (GST_BIN (priv->bin), priv->video_show),
- gtk_signal_connect (GTK_OBJECT (new_element), "new_pad", dynamic_connect_pads, play);
- gtk_signal_connect (GTK_OBJECT (new_element), "new_ghost_pad", dynamic_connect_pads, play);
- }
- if (connect_pads (new_element, priv->audio_queue, TRUE)) {
- gst_bin_add (GST_BIN (priv->bin), priv->audio_play),
- play->flags |= GST_PLAY_TYPE_AUDIO;
- }
- else {
- gst_bin_add (GST_BIN (priv->bin), priv->audio_play),
- gtk_signal_connect (GTK_OBJECT (new_element), "new_pad", dynamic_connect_pads, play);
- gtk_signal_connect (GTK_OBJECT (new_element), "new_ghost_pad", dynamic_connect_pads, play);
- }
-
gst_bin_add (GST_BIN (priv->thread), priv->bin);
gtk_signal_connect (GTK_OBJECT (priv->thread), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play);
diff --git a/gstplay/gstplayprivate.h b/gstplay/gstplayprivate.h
index f0abf4bc06..31e4e17f10 100644
--- a/gstplay/gstplayprivate.h
+++ b/gstplay/gstplayprivate.h
@@ -13,9 +13,7 @@ typedef struct _GstPlayPrivate GstPlayPrivate;
struct _GstPlayPrivate {
GstElement *thread;
GstElement *bin;
- GstElement *audio_play, *video_show;
GstElement *video_element, *audio_element;
- GstElement *video_queue, *audio_queue;
GtkWidget *video_widget;
GstElement *src;
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d40db412c7..1d82923671 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,7 +1,7 @@
SUBDIRS = sched eos
noinst_PROGRAMS = init loadall simplefake states caps queue registry \
-paranoia rip mp3encode autoplug props case4 markup load tee autoplug2
+paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3
# we have nothing but apps here, we can do this safely
LIBS += $(GST_LIBS)
diff --git a/tests/autoplug.c b/tests/autoplug.c
index 198824c487..87913c6f4f 100644
--- a/tests/autoplug.c
+++ b/tests/autoplug.c
@@ -33,7 +33,7 @@ main (int argc, char *argv[])
gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL);
- element = gst_autoplug_caps_list (autoplugger, testcaps,
+ element = gst_autoplug_to_caps (autoplugger, testcaps,
gst_pad_get_caps_list (gst_element_get_pad (audiosink, "sink")),
gst_pad_get_caps_list (gst_element_get_pad (videosink, "sink")),
NULL);
diff --git a/tests/autoplug2.c b/tests/autoplug2.c
index 8a90882b28..64f0a9f58d 100644
--- a/tests/autoplug2.c
+++ b/tests/autoplug2.c
@@ -1,30 +1,33 @@
#include <gst/gst.h>
static GstElement*
-autoplug_caps (gchar *mime1, gchar *mime2)
+autoplug_caps (GstAutoplug *autoplug, gchar *mime1, gchar *mime2)
{
GList *caps1, *caps2;
caps1 = g_list_append (NULL, gst_caps_new ("tescaps1", mime1));
caps2 = g_list_append (NULL, gst_caps_new ("tescaps2", mime2));
- return gst_autoplug_caps_list (caps1, caps2, NULL);
+ return gst_autoplug_to_caps (autoplug, caps1, caps2, NULL);
}
int
main (int argc, char *argv[])
{
GstElement *element;
+ GstAutoplug *autoplug;
gst_init(&argc,&argv);
- element = autoplug_caps ("audio/mp3", "audio/raw");
+ autoplug = gst_autoplugfactory_make ("static");
+
+ element = autoplug_caps (autoplug, "audio/mp3", "audio/raw");
xmlSaveFile ("autoplug2_1.gst", gst_xml_write (element));
- element = autoplug_caps ("video/mpeg", "audio/raw");
+ element = autoplug_caps (autoplug, "video/mpeg", "audio/raw");
xmlSaveFile ("autoplug2_2.gst", gst_xml_write (element));
- element = gst_autoplug_caps_list (
+ element = gst_autoplug_to_caps (autoplug,
g_list_append (NULL, gst_caps_new_with_props(
"testcaps3",
"video/mpeg",
@@ -36,7 +39,7 @@ main (int argc, char *argv[])
NULL);
xmlSaveFile ("autoplug2_3.gst", gst_xml_write (element));
- element = gst_autoplug_caps_list (
+ element = gst_autoplug_to_caps (autoplug,
g_list_append (NULL, gst_caps_new_with_props(
"testcaps5",
"video/mpeg",
@@ -48,5 +51,28 @@ main (int argc, char *argv[])
NULL);
xmlSaveFile ("autoplug2_4.gst", gst_xml_write (element));
+ element = gst_autoplug_to_caps (autoplug,
+ g_list_append (NULL, gst_caps_new(
+ "testcaps7",
+ "video/avi")),
+ g_list_append (NULL, gst_caps_new("testcaps8", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps9", "audio/raw")),
+ NULL);
+ xmlSaveFile ("autoplug2_5.gst", gst_xml_write (element));
+
+ element = gst_autoplug_to_caps (autoplug,
+ g_list_append (NULL, gst_caps_new_with_props(
+ "testcaps10",
+ "video/mpeg",
+ gst_props_new (
+ "mpegversion", GST_PROPS_INT (1),
+ "systemstream", GST_PROPS_BOOLEAN (TRUE),
+ NULL))),
+ g_list_append (NULL, gst_caps_new("testcaps10", "video/raw")),
+ g_list_append (NULL, gst_caps_new("testcaps11", "audio/raw")),
+ NULL);
+ xmlSaveFile ("autoplug2_6.gst", gst_xml_write (element));
+
+ exit (0);
exit (0);
}