Added multiple types to the pads.
authorWim Taymans <wim.taymans@gmail.com>
Sun, 3 Dec 2000 17:51:29 +0000 (17:51 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Sun, 3 Dec 2000 17:51:29 +0000 (17:51 +0000)
Original commit message from CVS:
Added multiple types to the pads.
Added first preview of the capabilities system.
Autoplugging is seriously broken with these (and other) changes.

gst/Makefile.am
gst/gst.h
gst/gstcaps.c [new file with mode: 0644]
gst/gstcaps.h [new file with mode: 0644]
gst/gstcapsprivate.h [new file with mode: 0644]
gst/gstpad.c
gst/gstpad.h
gst/gstpipeline.c

index 26942f8..f3076dc 100644 (file)
@@ -37,6 +37,7 @@ libgst_la_SOURCES =   \
        gstsink.c       \
        gstconnection.c \
        gsttype.c       \
+       gstcaps.c       \
        gstplugin.c     \
        gstutils.c      \
        gsttrace.c      \
@@ -65,6 +66,7 @@ libgstinclude_HEADERS =       \
        gstsink.h       \
        gstconnection.h \
        gsttype.h       \
+       gstcaps.h       \
        gstplugin.h     \
        gstutils.h      \
        gsttrace.h      \
@@ -78,7 +80,7 @@ noinst_HEADERS =      \
        gsti386.h       \
        gstppc.h        
 
-CFLAGS += -O2 -Wall 
+CFLAGS += -g -O6 -Wall 
 
 libgst_la_LIBADD = $(GLIB_LIBS) $(GTK_LIBS) $(XML_LIBS)
 libgst_la_LDFLAGS = -version-info $(STREAMER_CURRENT):$(STREAMER_REVISION):$(STREAMER_AGE)
index 88e3665..9058234 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -41,6 +41,7 @@
 #include <gst/gstsink.h>
 #include <gst/gstconnection.h>
 #include <gst/gsttype.h>
+#include <gst/gstcaps.h>
 #include <gst/gstplugin.h>
 #include <gst/gstutils.h>
 #include <gst/gsttrace.h>
diff --git a/gst/gstcaps.c b/gst/gstcaps.c
new file mode 100644 (file)
index 0000000..91755b8
--- /dev/null
@@ -0,0 +1,328 @@
+/* Gnome-Streamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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 <stdarg.h>
+#include <gst/gstcapsprivate.h>
+
+void 
+_gst_caps_initialize (void) 
+{
+}
+
+static GstCapsEntry *
+gst_caps_create_entry (GstCapsFactory factory, gint *skipped)
+{
+  GstCapsFactoryEntry tag;
+  GstCapsEntry *entry;
+  guint i=0;
+
+  entry = g_new0 (GstCapsEntry, 1);
+
+  tag = factory[i++];
+  switch (GPOINTER_TO_INT (tag)) {
+    case GST_CAPS_INT_ID:
+      entry->capstype = GST_CAPS_INT_ID_NUM;
+      entry->data.int_data = GPOINTER_TO_INT (factory[i++]);
+      break;
+    case GST_CAPS_INT_RANGE_ID:
+      entry->capstype = GST_CAPS_INT_RANGE_ID_NUM;
+      entry->data.int_range_data.min = GPOINTER_TO_INT (factory[i++]);
+      entry->data.int_range_data.max = GPOINTER_TO_INT (factory[i++]);
+      break;
+    case GST_CAPS_LIST_ID:
+      g_print("gstcaps: list not allowed in list\n");
+      break;
+    default:
+      g_print("gstcaps: unknown caps id found\n");
+      g_free (entry);
+      entry = NULL;
+      break;
+  }
+
+  *skipped = i;
+
+  return entry;
+}
+
+
+static gint 
+caps_compare_func (gconstpointer a,
+                  gconstpointer b) 
+{
+  GstCapsEntry *entry1 = (GstCapsEntry *)a;
+  GstCapsEntry *entry2 = (GstCapsEntry *)b;
+
+  return (entry1->propid - entry2->propid);
+}
+
+/**
+ * gst_caps_register:
+ * @factory: the factory to register
+ *
+ * Register the factory. 
+ *
+ * Returns: The registered capability
+ */
+GstCaps *
+gst_caps_register (GstCapsFactory factory)
+{
+  GstCapsFactoryEntry tag;
+  gint i = 0;
+  guint16 typeid;
+  GstCaps *caps;
+  gint skipped;
+  
+  g_return_val_if_fail (factory != NULL, NULL);
+
+  tag = factory[i++];
+
+  g_return_val_if_fail (tag != NULL, NULL);
+  
+  typeid = gst_type_find_by_mime ((gchar *)tag);
+  if (typeid == 0) {
+     GstTypeFactory *factory = g_new0 (GstTypeFactory, 1);
+
+     factory->mime = g_strdup ((gchar *)tag);
+     factory->exts = NULL;
+     factory->typefindfunc = NULL;
+
+     typeid = gst_type_register (factory);
+  }
+
+  caps = g_new0 (GstCaps, 1);
+  g_return_val_if_fail (caps != NULL, NULL);
+
+  caps->id = typeid;
+  caps->properties = NULL;
+
+  tag = factory[i++];
+  
+  while (tag) {
+    GQuark quark;
+    GstCapsEntry *entry;
+    
+    quark = g_quark_from_string ((gchar *)tag);
+
+    tag = factory[i];
+    switch (GPOINTER_TO_INT (tag)) {
+      case GST_CAPS_LIST_ID: 
+      {
+        GstCapsEntry *list_entry;
+
+        entry = g_new0 (GstCapsEntry, 1);
+       entry->propid = quark;
+       entry->capstype = GST_CAPS_LIST_ID_NUM;
+       entry->data.list_data.entries = NULL;
+
+       i++; // skip list tag
+        tag = factory[i];
+       while (tag) {
+         list_entry = gst_caps_create_entry (&factory[i], &skipped);
+         i += skipped;
+          tag = factory[i];
+         entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, list_entry);
+       }
+       entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries);
+       i++; //skip NULL (list end)
+       break;
+      }
+      default:
+      {
+       entry = gst_caps_create_entry (&factory[i], &skipped);
+       entry->propid = quark;
+       i += skipped;
+       break;
+      }
+    }
+    caps->properties = g_slist_insert_sorted (caps->properties, entry, caps_compare_func);
+     
+    tag = factory[i++];
+  }
+
+  return caps;
+}
+
+static void
+gst_caps_dump_entry_func (GstCapsEntry *entry)
+{
+  switch (entry->capstype) {
+    case GST_CAPS_INT_ID_NUM: 
+      g_print("gstcaps:    int %d\n", entry->data.int_data);
+      break;
+    case GST_CAPS_INT_RANGE_ID_NUM: 
+      g_print("gstcaps:    int range %d %d\n", 
+                     entry->data.int_range_data.min,
+                     entry->data.int_range_data.max);
+      break;
+    case GST_CAPS_INT32_ID_NUM: 
+      g_print("gstcaps:    int32 %d\n", entry->data.int_data);
+      break;
+    case GST_CAPS_BOOL_ID_NUM: 
+      g_print("gstcaps:    boolean %d\n", entry->data.bool_data);
+      break;
+    default:
+      g_print("gstcaps:    **illegal entry**\n");
+      break;
+  }
+}
+
+static void
+gst_caps_dump_list_func (gpointer entry,
+                        gpointer list_entry)
+{
+  gst_caps_dump_entry_func ((GstCapsEntry *)entry);
+}
+
+static void
+gst_caps_dump_func (gpointer data,
+                   gpointer user_data)
+{
+  GstCapsEntry *entry;
+
+  entry = (GstCapsEntry *)data;
+
+  g_print("gstcaps:  property type \"%s\"\n", g_quark_to_string (entry->propid));
+
+  switch (entry->capstype) {
+    case GST_CAPS_LIST_ID_NUM: 
+    {
+      g_print("gstcaps:   list type (\n");
+      g_list_foreach (entry->data.list_data.entries, gst_caps_dump_list_func, entry);
+      g_print("gstcaps:   )\n");
+      break;
+    }
+    default:
+      gst_caps_dump_entry_func (entry);
+      break;
+  }
+}
+
+/**
+ * gst_caps_dump:
+ * @caps: the capability to dump
+ *
+ * Dumps the contents of the capabilty one the console
+ */
+void
+gst_caps_dump (GstCaps *caps)
+{
+  g_return_if_fail (caps != NULL);
+
+  g_print("gstcaps: {\ngstcaps:  mime type \"%d\"\n", caps->id);
+
+  g_slist_foreach (caps->properties, gst_caps_dump_func, caps);
+  g_print("gstcaps: }\n");
+}
+       
+static gboolean
+gst_caps_entry_check_compatibility (GstCapsEntry *entry1, GstCapsEntry *entry2)
+{
+  g_print ("compare: %s %s\n", g_quark_to_string (entry1->propid),
+                              g_quark_to_string (entry2->propid));
+}
+
+/**
+ * gst_caps_check_compatibility:
+ * @fromcaps: a capabilty
+ * @tocaps: a capabilty
+ *
+ * Checks whether two capabilities are compatible
+ *
+ * Returns: true if compatible, false otherwise
+ */
+gboolean
+gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
+{
+  GSList *sourcelist;
+  GSList *sinklist;
+  gint missing = 0;
+  gint more = 0;
+
+  g_return_val_if_fail (fromcaps != NULL, FALSE);
+  g_return_val_if_fail (tocaps != NULL, FALSE);
+       
+  if (fromcaps->id != tocaps->id)
+    return FALSE;
+
+  sourcelist = fromcaps->properties;
+  sinklist   = tocaps->properties;
+
+  while (sourcelist && sinklist) {
+    GstCapsEntry *entry1;
+    GstCapsEntry *entry2;
+
+    entry1 = (GstCapsEntry *)sourcelist->data;
+    entry2 = (GstCapsEntry *)sinklist->data;
+
+    while (entry1->propid < entry2->propid) {
+      g_print ("source is more specific in \"%s\"\n", g_quark_to_string (entry1->propid));
+      more++;
+      sourcelist = g_slist_next (sourcelist);
+      if (sourcelist) entry1 = (GstCapsEntry *)sourcelist->data;
+      else goto end;
+    }
+    while (entry1->propid > entry2->propid) {
+      g_print ("source has missing property \"%s\"\n", g_quark_to_string (entry2->propid));
+      missing++;
+      sinklist = g_slist_next (sinklist);
+      if (sinklist) entry2 = (GstCapsEntry *)sinklist->data;
+      else goto end;
+    }
+
+    gst_caps_entry_check_compatibility (entry1, entry2);
+
+    sourcelist = g_slist_next (sourcelist);
+    sinklist = g_slist_next (sinklist);
+  }
+end:
+
+  if (missing)
+    return FALSE;
+
+  return TRUE;
+}
+
+/**
+ * gst_caps_register_va:
+ * @factory: the factories to register
+ *
+ * Register the given factories. 
+ *
+ * Returns: A list of the registered factories
+ */
+GList *
+gst_caps_register_va (GstCapsFactory factory, ...)
+{
+  va_list var_args;
+  GstCapsFactoryEntry *current_factory;
+
+  va_start (var_args, factory);
+
+  current_factory = (GstCapsFactoryEntry *) factory;
+  
+  while (current_factory) {
+    gst_caps_register (current_factory);
+    
+    current_factory = va_arg (var_args, GstCapsFactoryEntry *);
+  }
+  
+  va_end(var_args);
+
+  return NULL;
+}
diff --git a/gst/gstcaps.h b/gst/gstcaps.h
new file mode 100644 (file)
index 0000000..50950cc
--- /dev/null
@@ -0,0 +1,68 @@
+/* Gnome-Streamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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_CAPS_H__
+#define __GST_CAPS_H__
+
+#include <gst/gst.h>
+
+typedef struct _GstCaps GstCaps;
+typedef gpointer GstCapsFactoryEntry;
+typedef GstCapsFactoryEntry GstCapsFactory[];
+
+typedef enum {
+   GST_CAPS_END_ID_NUM = 0,
+   GST_CAPS_LIST_ID_NUM,
+   GST_CAPS_INT_ID_NUM,
+   GST_CAPS_INT_RANGE_ID_NUM,
+   GST_CAPS_INT32_ID_NUM,
+   GST_CAPS_BOOL_ID_NUM,
+} GstCapsId;
+
+#define GST_CAPS_LIST_ID GINT_TO_POINTER(GST_CAPS_LIST_ID_NUM)
+#define GST_CAPS_INT_ID GINT_TO_POINTER(GST_CAPS_INT_ID_NUM)
+#define GST_CAPS_INT_RANGE_ID GINT_TO_POINTER(GST_CAPS_INT_RANGE_ID_NUM)
+#define GST_CAPS_INT32_ID GINT_TO_POINTER(GST_CAPS_INT32_ID_NUM)
+#define GST_CAPS_BOOL_ID GINT_TO_POINTER(GST_CAPS_BOOL_ID_NUM)
+
+#define GST_CAPS_LIST(a...) GST_CAPS_LIST_ID,##a,NULL
+#define GST_CAPS_INT(a) GST_CAPS_INT_ID,(GINT_TO_POINTER(a))
+#define GST_CAPS_INT_RANGE(a,b) GST_CAPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b))
+#define GST_CAPS_INT32(a) GST_CAPS_INT_ID,(GINT_TO_POINTER(a))
+#define GST_CAPS_BOOLEAN(a) GST_CAPS_BOOL_ID,(GINT_TO_POINTER(a))
+
+
+struct _GstCaps {
+  guint16 id;                  /* type id (major type) */
+
+  GSList *properties;          /* properties for this capability */
+};
+
+/* initialize the subsystem */
+void           _gst_caps_initialize            (void);
+
+GstCaps*       gst_caps_register               (GstCapsFactory factory);
+GList*         gst_caps_register_va            (GstCapsFactory factory,...);
+
+void           gst_caps_dump                   (GstCaps *caps);
+
+gboolean       gst_caps_check_compatibility    (GstCaps *caps1, GstCaps *caps2);
+
+#endif /* __GST_CAPS_H__ */
diff --git a/gst/gstcapsprivate.h b/gst/gstcapsprivate.h
new file mode 100644 (file)
index 0000000..978e4e6
--- /dev/null
@@ -0,0 +1,49 @@
+/* Gnome-Streamer
+ * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
+ *
+ * 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_CAPS_PRIV_H__
+#define __GST_CAPS_PRIV_H__
+
+#include <gst/gstcaps.h>
+
+typedef struct _GstCapsEntry GstCapsEntry;
+
+struct _GstCapsEntry {
+  GQuark    propid;
+  GstCapsId capstype;          
+
+  union {
+    /* flat values */
+    gboolean bool_data;
+    guint32  fourcc_data;
+    gint     int_data;
+
+    /* structured values */
+    struct {
+      GList *entries;
+    } list_data;
+    struct {
+      gint min;
+      gint max;
+    } int_range_data;
+  } data;
+};
+
+#endif /* __GST_CAPS_PRIV_H__ */
index 135a88f..81cde7d 100644 (file)
@@ -97,7 +97,6 @@ gst_pad_class_init (GstPadClass *klass)
 static void 
 gst_pad_init (GstPad *pad) 
 {
-  pad->type = 0;
   pad->direction = GST_PAD_UNKNOWN;
   pad->peer = NULL;
   pad->chainfunc = NULL;
@@ -107,6 +106,7 @@ gst_pad_init (GstPad *pad)
   pad->qosfunc = NULL;
   pad->parent = NULL;
   pad->ghostparents = NULL;
+  pad->types = NULL;
 }
 
 static void
@@ -645,22 +645,28 @@ gst_pad_get_ghost_parents (GstPad *pad)
 }
 
 /**
- * gst_pad_get_type_id:
- * @pad: the pad to get the type id from
+ * gst_pad_get_type_ids:
+ * @pad: the pad to get the type ids from
  *
- * get the type of this pad
+ * get the list of types for this pad
  *
- * Returns: the type of this pad
+ * Returns: a GList of types of this pad
  */
-guint16 
-gst_pad_get_type_id (GstPad *pad) 
+GList*
+gst_pad_get_type_ids (GstPad *pad) 
 {
   g_return_val_if_fail (pad != NULL, 0);
   g_return_val_if_fail (GST_IS_PAD (pad), 0);
 
-  return pad->type;
+  return pad->types;
+}
+// FIXME remove...
+void 
+gst_pad_set_type_id (GstPad *pad, 
+                    guint16 id) 
+{
+  gst_pad_add_type_id (pad, id);
 }
-
 /**
  * gst_pad_set_type_id:
  * @pad: the pad to set the type id to
@@ -669,14 +675,14 @@ gst_pad_get_type_id (GstPad *pad)
  * set the type of this pad
  */
 void 
-gst_pad_set_type_id (GstPad *pad, 
+gst_pad_add_type_id (GstPad *pad, 
                     guint16 id) 
 {
   g_return_if_fail (pad != NULL);
   g_return_if_fail (GST_IS_PAD (pad));
   g_return_if_fail (gst_type_find_by_id (id) != NULL);
 
-  pad->type = id;
+  g_list_append(pad->types, GINT_TO_POINTER((gint)id));
 }
 
 /**
index 1875eff..ad0b97a 100644 (file)
@@ -68,7 +68,7 @@ struct _GstPad {
   GstObject object;
 
   gchar *name;
-  guint16 type;
+  GList *types;
 
   GstPadDirection direction;
 
@@ -104,8 +104,11 @@ void                       gst_pad_set_chain_function      (GstPad *pad, GstPadChainFunction chain);
 void                   gst_pad_set_pull_function       (GstPad *pad, GstPadPullFunction pull);
 void                   gst_pad_set_qos_function        (GstPad *pad, GstPadQoSFunction qos);
 
-guint16                gst_pad_get_type_id             (GstPad *pad);
-void                   gst_pad_set_type_id             (GstPad *pad, guint16 id);
+// FIXME is here for backward compatibility until we have GstCaps working...
+void                   gst_pad_set_type_id             (GstPad *pad, guint16 id);
+
+GList*                 gst_pad_get_type_ids            (GstPad *pad);
+void                   gst_pad_add_type_id             (GstPad *pad, guint16 id);
 
 void                   gst_pad_set_name                (GstPad *pad, const gchar *name);
 const gchar*           gst_pad_get_name                (GstPad *pad);
index d3c70c3..610da96 100644 (file)
@@ -169,7 +169,7 @@ gst_pipeline_typefind (GstPipeline *pipeline, GstElement *element)
 
   if (found) {
     type_id = gst_util_get_int_arg (GTK_OBJECT (typefind), "type");
-    gst_pad_set_type_id (gst_element_get_pad (element, "src"), type_id);
+    gst_pad_add_type_id (gst_element_get_pad (element, "src"), type_id);
   }
 
   gst_pad_disconnect (gst_element_get_pad (element, "src"),
@@ -184,25 +184,28 @@ static void
 gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) 
 {
   GList *sinkpads;
-  GstPad *sinkpad;
   gboolean connected = FALSE;
+  guint16 type;
 
-  g_print("gstpipeline: autoplug pad connect function type %d for \"%s\" to \"%s\"\n", pad->type, 
+  type = ((GstType *)pad->types->data)->id;
+
+  g_print("gstpipeline: autoplug pad connect function type %d for \"%s\" to \"%s\"\n", type, 
                  gst_element_get_name(src), gst_element_get_name(sink));
 
   sinkpads = gst_element_get_pad_list(sink);
   while (sinkpads) {
-    sinkpad = (GstPad *)sinkpads->data;
+    GstPad *sinkpad = (GstPad *)sinkpads->data;
+    guint16 sinktype = ((GstType *)sinkpad->types->data)->id;
 
     // if we have a match, connect the pads
-    if (sinkpad->type == pad->type && 
+    if (sinktype == type && 
         sinkpad->direction == GST_PAD_SINK && 
         !GST_PAD_CONNECTED(sinkpad)) 
     {
       gst_pad_connect(pad, sinkpad);
       g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", pad->name, 
-                     pad->type, gst_element_get_name(src));
-      g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinkpad->type, 
+                     type, gst_element_get_name(src));
+      g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, sinktype, 
                      gst_element_get_name(sink));
       connected = TRUE;
       break;
@@ -211,7 +214,7 @@ gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink)
   }
 
   if (!connected) {
-    g_print("gstpipeline: no path to sinks for type %d\n", pad->type);
+    g_print("gstpipeline: no path to sinks for type %d\n", type);
   }
 }
 
@@ -225,24 +228,29 @@ gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink)
 
   while (srcpads) {
     GstPad *srcpad = (GstPad *)srcpads->data;
-    GstPad *sinkpad;
+    guint16 srctype = 0;
+    if (srcpad)
+      srctype = ((GstType *)srcpad->types->data)->id;
 
     if (srcpad->direction == GST_PAD_SRC && !GST_PAD_CONNECTED(srcpad)) {
 
       sinkpads = gst_element_get_pad_list(sink);
       // FIXME could O(n) if the types were sorted...
       while (sinkpads) {
-        sinkpad = (GstPad *)sinkpads->data;
+        GstPad *sinkpad = (GstPad *)sinkpads->data;
+        guint16 sinktype = 0;
+        if (srcpad)
+          sinktype = ((GstType *)sinkpad->types->data)->id;
 
        // if we have a match, connect the pads
-       if (sinkpad->type == srcpad->type && 
+       if (sinktype == srctype && 
            sinkpad->direction == GST_PAD_SINK && 
            !GST_PAD_CONNECTED(sinkpad)) {
           gst_pad_connect(srcpad, sinkpad);
           g_print("gstpipeline: autoconnect pad \"%s\" (%d) in element %s <-> ", 
-                         srcpad->name, srcpad->type, gst_element_get_name(src));
+                         srcpad->name, srctype, gst_element_get_name(src));
           g_print("pad \"%s\" (%d) in element %s\n", sinkpad->name, 
-                         sinkpad->type, gst_element_get_name(sink));
+                         sinktype, gst_element_get_name(sink));
          connected = TRUE;
          goto end;
        }
@@ -391,7 +399,11 @@ gst_pipeline_autoplug (GstPipeline *pipeline)
       pad = (GstPad *)pads->data;
 
       if (pad->direction == GST_PAD_SINK) {
-       sink_type = gst_pad_get_type_id(pad);
+        GList *types = gst_pad_get_type_ids(pad);
+        if (types)
+          sink_type = GPOINTER_TO_INT (types->data);
+       else
+         sink_type = 0;
        break;
       }
 
@@ -485,13 +497,15 @@ differ:
           sinkpad = (GstPad *)sinkpads->data;
 
          // FIXME connect matching pads, not just the first one...
+         /*
           if (sinkpad->direction == GST_PAD_SINK && 
              !GST_PAD_CONNECTED(sinkpad)) {
-           // the queue has the types of the element it connects
+           // the queue has the type of the elements it connects
            srcpad->type = sinkpad->type;
             gst_element_get_pad(queue, "sink")->type = sinkpad->type;
            break;
          }
+         */
           sinkpads = g_list_next(sinkpads);
         }
         gst_pipeline_pads_autoplug(thesrcelement, queue);