Index: configure.ac
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/configure.ac,v
retrieving revision 1.295
diff -u -r1.295 configure.ac
--- configure.ac	27 Sep 2003 03:15:34 -0000	1.295
+++ configure.ac	30 Sep 2003 14:13:08 -0000
@@ -262,7 +262,7 @@
 	ac3parse adder audioscale auparse avi \
 	asfdemux audioconvert cdxaparse chart \
 	cutter debug deinterlace effectv festival \
-	filter flx goom intfloat law level median mixmatrix \
+	filter flx goom id3 intfloat law level median mixmatrix \
 	mpeg1sys mpeg1videoparse mpeg2enc mpeg2sub \
 	mpegaudio mpegaudioparse mpegstream mpegtypes \
         monoscope oneton overlay passthrough playondemand qtdemux \
@@ -1180,6 +1180,7 @@
 gst/filter/Makefile
 gst/flx/Makefile
 gst/goom/Makefile
+gst/id3/Makefile
 gst/intfloat/Makefile
 gst/law/Makefile
 gst/level/Makefile
Index: ext/Makefile.am
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/Makefile.am,v
retrieving revision 1.80
diff -u -r1.80 Makefile.am
--- ext/Makefile.am	27 Jul 2003 05:29:10 -0000	1.80
+++ ext/Makefile.am	30 Sep 2003 14:13:08 -0000
@@ -278,8 +278,9 @@
 	$(ARTS_DIR) $(ARTSC_DIR) $(AUDIOFILE_DIR) \
 	$(CDPARANOIA_DIR) $(DIVX_DIR) \
 	$(DVDREAD_DIR) $(DVDNAV_DIR) $(ESD_DIR) $(MAS_DIR) \
-	$(FFMPEG_DIR) $(FLAC_DIR) $(GDK_PIXBUF_DIR) $(GNOMEVFS_DIR) $(GSM_DIR) \
-	$(HERMES_DIR) $(JACK_DIR) $(JPEG_DIR) \
+	$(FFMPEG_DIR) $(FLAC_DIR) $(GDK_PIXBUF_DIR) \
+	$(GNOMEVFS_DIR) $(GSM_DIR) $(HERMES_DIR) \
+	$(JACK_DIR) $(JPEG_DIR) \
 	$(LADSPA_DIR) $(LAME_DIR) $(LCS_DIR) \
 	$(LIBDV_DIR) $(LIBFAME_DIR) $(LIBPNG_DIR) \
 	$(MAD_DIR) $(MATROSKA_DIR) $(MIKMOD_DIR) \
Index: ext/a52dec/gsta52dec.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/a52dec/gsta52dec.c,v
retrieving revision 1.23
diff -u -r1.23 gsta52dec.c
--- ext/a52dec/gsta52dec.c	16 Sep 2003 09:59:51 -0000	1.23
+++ ext/a52dec/gsta52dec.c	30 Sep 2003 14:13:08 -0000
@@ -619,10 +619,6 @@
 {
   GstElementFactory *factory;
 
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   /* create an elementfactory for the a52dec element */
   factory = gst_element_factory_new ("a52dec", GST_TYPE_A52DEC, &gst_a52dec_details);
   g_return_val_if_fail (factory != NULL, FALSE);
Index: ext/a52dec/gsta52dec.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/a52dec/gsta52dec.h,v
retrieving revision 1.4
diff -u -r1.4 gsta52dec.h
--- ext/a52dec/gsta52dec.h	18 Jan 2003 17:06:01 -0000	1.4
+++ ext/a52dec/gsta52dec.h	30 Sep 2003 14:13:08 -0000
@@ -23,7 +23,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 G_BEGIN_DECLS
 
Index: ext/alsa/gstalsa.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/alsa/gstalsa.c,v
retrieving revision 1.69
diff -u -r1.69 gstalsa.c
--- ext/alsa/gstalsa.c	16 Sep 2003 09:59:52 -0000	1.69
+++ ext/alsa/gstalsa.c	30 Sep 2003 14:13:09 -0000
@@ -2351,9 +2351,6 @@
 {
   GstElementFactory *factory;
 
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   factory = gst_element_factory_new ("alsasrc", GST_TYPE_ALSA_SRC, &gst_alsa_src_details);
   g_return_val_if_fail (factory != NULL, FALSE);
   gst_element_factory_add_pad_template (factory, gst_alsa_src_pad_factory ());
Index: ext/audiofile/gstafparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/audiofile/gstafparse.c,v
retrieving revision 1.15
diff -u -r1.15 gstafparse.c
--- ext/audiofile/gstafparse.c	6 Jul 2003 20:49:13 -0000	1.15
+++ ext/audiofile/gstafparse.c	30 Sep 2003 14:13:09 -0000
@@ -337,8 +337,7 @@
   /* load audio support library */
   if (!gst_library_load ("gstaudio"))
     return FALSE;
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
+
   return TRUE;
 }
 
Index: ext/audiofile/gstafparse.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/audiofile/gstafparse.h,v
retrieving revision 1.2
diff -u -r1.2 gstafparse.h
--- ext/audiofile/gstafparse.h	26 May 2002 21:59:20 -0000	1.2
+++ ext/audiofile/gstafparse.h	30 Sep 2003 14:13:09 -0000
@@ -27,7 +27,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include <audiofile.h>			/* what else are we to do */
 #include <af_vfs.h>
 
Index: ext/dv/gstdvdec.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/dv/gstdvdec.c,v
retrieving revision 1.40
diff -u -r1.40 gstdvdec.c
--- ext/dv/gstdvdec.c	16 Sep 2003 09:59:52 -0000	1.40
+++ ext/dv/gstdvdec.c	30 Sep 2003 14:13:09 -0000
@@ -159,30 +159,34 @@
 
 /* typefind stuff */
 static GstCaps*
-dv_type_find (GstBuffer *buf, gpointer private)
+dv_type_find (GstByteStream *bs, gpointer private)
 {
-  guint32 head;
+  GstBuffer *buf = NULL;
   GstCaps *new = NULL;
 
-  if (GST_BUFFER_SIZE (buf) < 5)
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 5) == 5) {
+    guint32 head = GUINT32_FROM_BE (*((guint32 *) GST_BUFFER_DATA (buf)));
 
-  head = GUINT32_FROM_BE(*((guint32 *)GST_BUFFER_DATA(buf)));
-
-  /* check for DIF  and DV flag */
-  if ((head & 0xffffff00) == 0x1f070000 && !(GST_BUFFER_DATA(buf)[4] & 0x01)) {
-    gchar *format;
-
-    if ((head & 0x000000ff) & 0x80)
-      format = "PAL";
-    else
-      format = "NTSC";
+    /* check for DIF  and DV flag */
+    if ((head & 0xffffff00) == 0x1f070000 &&
+        !(GST_BUFFER_DATA (buf)[4] & 0x01)) {
+      gchar *format;
+
+      if ((head & 0x000000ff) & 0x80)
+        format = "PAL";
+      else
+        format = "NTSC";
     
-    new = GST_CAPS_NEW ("dv_type_find",
-                        "video/x-dv",
-                          "systemstream", GST_PROPS_BOOLEAN (TRUE)
-		       );
+      new = GST_CAPS_NEW ("dv_type_find",
+                          "video/x-dv",
+                          "systemstream", GST_PROPS_BOOLEAN (TRUE));
+    }
   }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
   return new;
 }
 
@@ -1001,9 +1005,6 @@
 {
   GstElementFactory *factory;
   GstTypeFactory *type;
-
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   /* We need to create an ElementFactory for each element we provide.
    * This consists of the name of the element, the GType identifier,
Index: ext/dv/gstdvdec.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/dv/gstdvdec.h,v
retrieving revision 1.8
diff -u -r1.8 gstdvdec.h
--- ext/dv/gstdvdec.h	2 Nov 2002 13:34:42 -0000	1.8
+++ ext/dv/gstdvdec.h	30 Sep 2003 14:13:09 -0000
@@ -29,7 +29,7 @@
 
 
 #include <libdv/dv.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 
 /* This is the definition of the element's object structure. */
Index: ext/ffmpeg/gstffmpeg.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpeg.c,v
retrieving revision 1.9
diff -u -r1.9 gstffmpeg.c
--- ext/ffmpeg/gstffmpeg.c	6 Jul 2003 20:49:15 -0000	1.9
+++ ext/ffmpeg/gstffmpeg.c	30 Sep 2003 14:13:09 -0000
@@ -46,9 +46,6 @@
   avcodec_register_all ();
   av_register_all ();
 
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   gst_ffmpegenc_register (plugin);
   gst_ffmpegdec_register (plugin);
   /*gst_ffmpegdemux_register (plugin);*/
Index: ext/ffmpeg/gstffmpegdemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegdemux.c,v
retrieving revision 1.10
diff -u -r1.10 gstffmpegdemux.c
--- ext/ffmpeg/gstffmpegdemux.c	16 Sep 2003 09:59:53 -0000	1.10
+++ ext/ffmpeg/gstffmpegdemux.c	30 Sep 2003 14:13:09 -0000
@@ -161,24 +161,27 @@
 }
 
 static GstCaps*
-gst_ffmpegdemux_typefind (GstBuffer *buffer,
-			  gpointer   priv)
+gst_ffmpegdemux_typefind (GstByteStream *bs,
+			  gpointer       priv)
 {
   GstFFMpegDemuxClassParams *params;
   AVInputFormat *in_plugin;
   gint res = 0;
   gint required = AVPROBE_SCORE_MAX * 0.8; /* 80% certainty enough? */
+  gint size_required = 4096;
+  GstBuffer *buf = NULL;
   
   params = g_hash_table_lookup (typefind, priv);
 
   in_plugin = params->in_plugin;
 
-  if (in_plugin->read_probe) {
+  if (in_plugin->read_probe &&
+      gst_bytestream_peek (bs, &buf, size_required) == size_required) {
     AVProbeData probe_data;
 
     probe_data.filename = "";
-    probe_data.buf = GST_BUFFER_DATA (buffer);
-    probe_data.buf_size = GST_BUFFER_SIZE (buffer);
+    probe_data.buf = GST_BUFFER_DATA (buf);
+    probe_data.buf_size = GST_BUFFER_SIZE (buf);
 
     res = in_plugin->read_probe (&probe_data);
     if (res >= required) {
@@ -186,10 +189,15 @@
       caps = GST_PAD_TEMPLATE_CAPS (params->sinktempl);
       /* make sure we still hold a refcount to this caps */
       gst_caps_ref (caps);
+      gst_buffer_unref (buf);
       return caps;
     }
   }
-	
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
   return NULL;
 }
 
Index: ext/ffmpeg/gstffmpegprotocol.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ffmpeg/gstffmpegprotocol.c,v
retrieving revision 1.5
diff -u -r1.5 gstffmpegprotocol.c
--- ext/ffmpeg/gstffmpegprotocol.c	8 Jun 2003 14:35:32 -0000	1.5
+++ ext/ffmpeg/gstffmpegprotocol.c	30 Sep 2003 14:13:09 -0000
@@ -27,7 +27,7 @@
 #endif
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 
 typedef struct _GstProtocolInfo GstProtocolInfo;
Index: ext/flac/gstflac.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/flac/gstflac.c,v
retrieving revision 1.13
diff -u -r1.13 gstflac.c
--- ext/flac/gstflac.c	20 Sep 2003 19:34:31 -0000	1.13
+++ ext/flac/gstflac.c	30 Sep 2003 14:13:09 -0000
@@ -26,7 +26,7 @@
 extern GstElementDetails flacenc_details;
 extern GstElementDetails flacdec_details;
 
-static GstCaps* 	flac_type_find 	(GstBuffer *buf, gpointer private);
+static GstCaps* 	flac_type_find 	(GstByteStream *bs, gpointer private);
 
 GstPadTemplate *gst_flacdec_src_template, *gst_flacdec_sink_template; 
 GstPadTemplate *gst_flacenc_src_template, *gst_flacenc_sink_template;
@@ -70,37 +70,26 @@
 
 
 static GstCaps* 
-flac_type_find (GstBuffer *buf, gpointer private) 
+flac_type_find (GstByteStream *bs, gpointer private) 
 {
-  gint offset;
-  guint8 *data;
-  gint size;
-  guint32 head;
-  
-  if (GST_BUFFER_SIZE (buf) < 4)
-    return NULL;
-
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
-  
-  head = GUINT32_FROM_BE (*((guint32 *)GST_BUFFER_DATA (buf)));
-
-  if (head  == 0x664C6143)
-    return gst_caps_new ("flac_type_find", "application/x-flac", NULL);
-  else {
-    /* checks for existance of flac identification header in case
-     * there's an ID3 tag */
-    for (offset = 0; offset < size-4; offset++) {
-      if (data[offset]   == 'f' && 
-          data[offset+1] == 'L' && 
-          data[offset+2] == 'a' &&
-          data[offset+3] == 'C' ) {
-        return gst_caps_new ("flac_type_find", "application/x-flac", NULL);
-      }
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 4) == 4) {
+    guint32 head = GUINT32_FROM_BE (*((guint32 *) GST_BUFFER_DATA (buf)));
+
+    if (head  == 0x664C6143) {
+      new = GST_CAPS_NEW ("flac_type_find",
+			  "application/x-flac",
+			    NULL);
     }
   }
 
-  return NULL;
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
 }
 
 
@@ -110,10 +99,6 @@
   GstElementFactory *enc, *dec;
   GstTypeFactory *type;
   GstCaps *raw_caps, *flac_caps;
-
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   gst_plugin_set_longname (plugin, "The FLAC Lossless compressor Codec");
 
Index: ext/flac/gstflacdec.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/flac/gstflacdec.h,v
retrieving revision 1.4
diff -u -r1.4 gstflacdec.h
--- ext/flac/gstflacdec.h	27 Apr 2003 12:00:41 -0000	1.4
+++ ext/flac/gstflacdec.h	30 Sep 2003 14:13:09 -0000
@@ -24,7 +24,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #include <FLAC/all.h>
 
Index: ext/ivorbis/vorbis.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ivorbis/vorbis.c,v
retrieving revision 1.5
diff -u -r1.5 vorbis.c
--- ext/ivorbis/vorbis.c	24 Jul 2003 08:49:42 -0000	1.5
+++ ext/ivorbis/vorbis.c	30 Sep 2003 14:13:10 -0000
@@ -21,7 +21,7 @@
 #include <gst/gst.h>
 #include <tremor/ivorbiscodec.h>
 #include <tremor/ivorbisfile.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 extern GType ivorbisfile_get_type(void);
 
@@ -131,10 +131,6 @@
   gst_element_factory_add_pad_template (file, gst_vorbisdec_src_template);
   
   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (file));
-
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   type = gst_type_factory_new (&vorbisdefinition);
   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
Index: ext/ivorbis/vorbisfile.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ivorbis/vorbisfile.c,v
retrieving revision 1.8
diff -u -r1.8 vorbisfile.c
--- ext/ivorbis/vorbisfile.c	16 Sep 2003 09:59:54 -0000	1.8
+++ ext/ivorbis/vorbisfile.c	30 Sep 2003 14:13:10 -0000
@@ -24,7 +24,7 @@
 #include <gst/gst.h>
 #include <tremor/ivorbiscodec.h>
 #include <tremor/ivorbisfile.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #define GST_TYPE_IVORBISFILE \
   (ivorbisfile_get_type())
Index: ext/jack/gstjack.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/jack/gstjack.c,v
retrieving revision 1.31
diff -u -r1.31 gstjack.c
--- ext/jack/gstjack.c	19 Jul 2003 23:25:23 -0000	1.31
+++ ext/jack/gstjack.c	30 Sep 2003 14:13:10 -0000
@@ -499,9 +499,6 @@
 {
     GstElementFactory *factory;
     
-    if (!gst_library_load ("gstbytestream"))
-        return FALSE;
-    
     factory = gst_element_factory_new ("jackbin", GST_TYPE_JACK_BIN, &gst_jack_bin_details);
     g_return_val_if_fail (factory != NULL, FALSE);
     gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
Index: ext/ladspa/gstladspa.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ladspa/gstladspa.c,v
retrieving revision 1.37
diff -u -r1.37 gstladspa.c
--- ext/ladspa/gstladspa.c	16 Sep 2003 09:59:54 -0000	1.37
+++ ext/ladspa/gstladspa.c	30 Sep 2003 14:13:10 -0000
@@ -993,9 +993,6 @@
 
   LADSPAPluginSearch(ladspa_describe_plugin);
 
-  if (! gst_library_load ("gstbytestream"))
-    return FALSE;
-  
   /* initialize dparam support library */
   gst_control_init(NULL,NULL);
   
Index: ext/ladspa/gstladspa.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/ladspa/gstladspa.h,v
retrieving revision 1.6
diff -u -r1.6 gstladspa.h
--- ext/ladspa/gstladspa.h	16 Jul 2003 16:08:12 -0000	1.6
+++ ext/ladspa/gstladspa.h	30 Sep 2003 14:13:10 -0000
@@ -26,7 +26,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #include "ladspa.h"
 
Index: ext/mad/gstmad.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/mad/gstmad.c,v
retrieving revision 1.70
diff -u -r1.70 gstmad.c
--- ext/mad/gstmad.c	16 Sep 2003 09:59:54 -0000	1.70
+++ ext/mad/gstmad.c	30 Sep 2003 14:13:10 -0000
@@ -139,6 +139,7 @@
     "mad_sink",
     "audio/mpeg",
       /* we don't need channel/rate ... */
+      "mpegversion", GST_PROPS_INT (1),
       "layer", GST_PROPS_INT_RANGE (1, 3)
   )
 )
@@ -1184,15 +1185,13 @@
 	                          mad->stream.bufend - mad->stream.this_frame);
 
 	  if (tagsize > mad->tempsize) {
-            GST_INFO (
-		      "mad: got partial id3 tag in buffer, skipping");
+            GST_INFO ("mad: got partial id3 tag in buffer, skipping");
 	  }
 	  else if (tagsize > 0) {
 	    struct id3_tag *tag;
 	    id3_byte_t const *data;
 
-            GST_INFO (
-		      "mad: got ID3 tag size %ld", tagsize);
+            GST_INFO ("mad: got ID3 tag size %ld", tagsize);
 
 	    data = mad->stream.this_frame;
 
Index: ext/matroska/gstmatroska-io.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/matroska/gstmatroska-io.h,v
retrieving revision 1.1
diff -u -r1.1 gstmatroska-io.h
--- ext/matroska/gstmatroska-io.h	14 Jul 2003 17:37:05 -0000	1.1
+++ ext/matroska/gstmatroska-io.h	30 Sep 2003 14:13:10 -0000
@@ -21,7 +21,7 @@
 #define __GST_MATROSKA_IO_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include <IOCallback.h>
 
 using namespace std;
Index: ext/matroska/gstmatroskademux.cpp
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/matroska/gstmatroskademux.cpp,v
retrieving revision 1.6
diff -u -r1.6 gstmatroskademux.cpp
--- ext/matroska/gstmatroskademux.cpp	12 Sep 2003 11:36:24 -0000	1.6
+++ ext/matroska/gstmatroskademux.cpp	30 Sep 2003 14:13:10 -0000
@@ -74,8 +74,8 @@
   "(C) 2003",
 };
 
-static GstCaps * gst_matroska_type_find (GstBuffer *buf,
-					 gpointer   priv);
+static GstCaps * gst_matroska_type_find (GstByteStream *bs,
+					 gpointer      priv);
 
 /* typefactory for 'matroska' */
 static GstTypeDefinition matroskadefinition = {
@@ -251,23 +251,28 @@
 }
 
 static GstCaps *
-gst_matroska_type_find (GstBuffer *buf,
-			gpointer   priv)
+gst_matroska_type_find (GstByteStream *bs,
+			gpointer       priv)
 {
-  guint8 header[16] = { 0x1A, 0x45, 0xDF, 0xA3, 0x93, 0x42, 0x82, 0x88,
-			'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
-  GST_DEBUG ("matroska_demux: typefind");
-
-  if (GST_BUFFER_SIZE (buf) >= 16 &&
-      memcmp(GST_BUFFER_DATA (buf), header, 16) == 0) {
-    GST_DEBUG ("matroska type found!");
-    return GST_CAPS_NEW ("matroska_type",
-			 "video/x-matroska",
-			   NULL);
+  GstBuffer *buf = NULL;
+  GstCaps *newc = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 16) == 16) {
+    guint8 header[16] = { 0x1A, 0x45, 0xDF, 0xA3, 0x93, 0x42, 0x82, 0x88,
+			  'm', 'a', 't', 'r', 'o', 's', 'k', 'a' };
+
+    if (!memcmp(GST_BUFFER_DATA (buf), header, 16)) {
+      newc = GST_CAPS_NEW ("matroska_type",
+			   "video/x-matroska",
+			     NULL);
+    }
   }
 
-  /* nope */
-  return NULL;
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return newc;
 }
 
 static void
@@ -335,15 +340,18 @@
 {
   EbmlElement *child = NULL;
 
-  if (demux->last_level != 0) {
-    g_assert (demux->last_level > 0);
+  if (demux->last_level > 0) {
+    //g_assert (demux->last_level > 0);
     child = demux->last_el;
     demux->last_el = NULL;
     demux->last_level--;
-  } else if (demux->io->eos != TRUE) {
-    g_assert (demux->last_el == NULL);
-    child = demux->str->FindNextElement (parent->Generic ().Context,
-					 demux->last_level, ~0, true, 5);
+  } else {
+    demux->last_level = 0;
+    if (demux->io->eos != TRUE) {
+      //g_assert (demux->last_el == NULL);
+      child = demux->str->FindNextElement (parent->Generic ().Context,
+					   demux->last_level, ~0, true, 5);
+    }
   }
 
   return child;
@@ -1681,7 +1689,8 @@
       res = FALSE;
       break;
     } else if (demux->last_level != 0) {
-      g_assert (0); /* cannot happen, this *is* the top level */
+      //g_assert (0); /* cannot happen, this *is* the top level */
+      demux->last_level = 0;
     }
 
     /* well, cases don't work here since these aren't constants...
Index: ext/matroska/gstmatroskademux.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/matroska/gstmatroskademux.h,v
retrieving revision 1.2
diff -u -r1.2 gstmatroskademux.h
--- ext/matroska/gstmatroskademux.h	29 Jul 2003 20:55:58 -0000	1.2
+++ ext/matroska/gstmatroskademux.h	30 Sep 2003 14:13:10 -0000
@@ -21,7 +21,7 @@
 #define __GST_MATROSKA_DEMUX_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include "gstmatroska-io.h"
 
 using namespace std;
Index: ext/mplex/gstmplex.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/mplex/gstmplex.h,v
retrieving revision 1.3
diff -u -r1.3 gstmplex.h
--- ext/mplex/gstmplex.h	25 Oct 2002 20:46:12 -0000	1.3
+++ ext/mplex/gstmplex.h	30 Sep 2003 14:13:11 -0000
@@ -26,7 +26,7 @@
 #include <stdlib.h>
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #include "outputstream.hh"
 #include "bits.hh"
Index: ext/vorbis/vorbis.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/vorbis/vorbis.c,v
retrieving revision 1.13
diff -u -r1.13 vorbis.c
--- ext/vorbis/vorbis.c	19 Jul 2003 23:25:26 -0000	1.13
+++ ext/vorbis/vorbis.c	30 Sep 2003 14:13:11 -0000
@@ -25,7 +25,7 @@
 extern GstElementDetails vorbisfile_details;
 extern GstElementDetails vorbisenc_details;
 
-static GstCaps* 	vorbis_type_find 	(GstBuffer *buf, gpointer private);
+static GstCaps* 	vorbis_type_find 	(GstByteStream *bs, gpointer private);
 
 GstPadTemplate *gst_vorbisdec_src_template, *gst_vorbisdec_sink_template; 
 GstPadTemplate *gst_vorbisenc_src_template, *gst_vorbisenc_sink_template;
@@ -81,40 +81,26 @@
 };
 
 static GstCaps*
-vorbis_type_find (GstBuffer *buf, gpointer private)
+vorbis_type_find (GstByteStream *bs, gpointer private)
 {
-  guint32 head;
-  gint offset;
-  guint8 *data;
-  gint size;
-
-  data = GST_BUFFER_DATA (buf);
-  size = GST_BUFFER_SIZE (buf);
-
-  if (size < sizeof(guint32))
-    return NULL;
-
-  head = GUINT32_FROM_BE (*((guint32 *)data));
-
-  if (head  == 0x4F676753) {
-    return gst_caps_new ("vorbis_type_find", "application/ogg", NULL);
-  } else {
-    /* checks for existance of vorbis identification header in case
-     * there's an ID3 tag */
-    for (offset = 0; offset < size-7; offset++) {
-      if (data[offset] == 0x01 && 
-          data[offset+1] == 'v' && 
-          data[offset+2] == 'o' &&
-          data[offset+3] == 'r' && 
-          data[offset+4] == 'b' &&
-          data[offset+5] == 'i' && 
-          data[offset+6] == 's' ) {
-        return gst_caps_new ("vorbis_type_find", "application/ogg", NULL);
-      }
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 4) == 4) {
+    guint32 head = GUINT32_FROM_BE (*((guint32 *) GST_BUFFER_DATA (buf)));
+
+    if (head == 0x4F676753) {
+      new = GST_CAPS_NEW ("vorbis_type_find",
+			  "application/ogg",
+			    NULL);
     }
   }
 
-  return NULL;
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
 }
 
 
@@ -171,10 +157,6 @@
   gst_element_factory_add_pad_template (file, gst_vorbisdec_src_template);
   
   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (file));
-
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   type = gst_type_factory_new (&vorbisdefinition);
   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
Index: ext/vorbis/vorbisfile.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/ext/vorbis/vorbisfile.c,v
retrieving revision 1.38
diff -u -r1.38 vorbisfile.c
--- ext/vorbis/vorbisfile.c	16 Sep 2003 09:59:56 -0000	1.38
+++ ext/vorbis/vorbisfile.c	30 Sep 2003 14:13:11 -0000
@@ -24,7 +24,7 @@
 #include <gst/gst.h>
 #include <vorbis/codec.h>
 #include <vorbis/vorbisfile.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #define GST_TYPE_VORBISFILE \
   (vorbisfile_get_type())
Index: gst/adder/gstadder.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/adder/gstadder.c,v
retrieving revision 1.34
diff -u -r1.34 gstadder.c
--- gst/adder/gstadder.c	16 Sep 2003 09:59:56 -0000	1.34
+++ gst/adder/gstadder.c	30 Sep 2003 14:13:11 -0000
@@ -606,9 +606,6 @@
   factory = gst_element_factory_new ("adder", GST_TYPE_ADDER, &adder_details);
   g_return_val_if_fail (factory != NULL, FALSE);
 
-  if (! gst_library_load ("gstbytestream"))
-    return FALSE;
-
   gst_element_factory_add_pad_template (factory,
     GST_PAD_TEMPLATE_GET (gst_adder_src_template_factory));
   gst_element_factory_add_pad_template (factory,
Index: gst/adder/gstadder.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/adder/gstadder.h,v
retrieving revision 1.5
diff -u -r1.5 gstadder.h
--- gst/adder/gstadder.h	19 Jul 2003 23:16:25 -0000	1.5
+++ gst/adder/gstadder.h	30 Sep 2003 14:13:11 -0000
@@ -24,7 +24,7 @@
 #define __GST_ADDER_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #ifdef __cplusplus
 extern "C" {
Index: gst/asfdemux/gstasfdemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/asfdemux/gstasfdemux.c,v
retrieving revision 1.21
diff -u -r1.21 gstasfdemux.c
--- gst/asfdemux/gstasfdemux.c	16 Sep 2003 09:59:56 -0000	1.21
+++ gst/asfdemux/gstasfdemux.c	30 Sep 2003 14:13:11 -0000
@@ -35,123 +35,41 @@
   "(C) 2002",
 };
 
-static GstCaps* asf_asf_type_find (GstBuffer *buf, gpointer private);
-static GstCaps* asf_wma_type_find (GstBuffer *buf, gpointer private);
-static GstCaps* asf_wax_type_find (GstBuffer *buf, gpointer private);
-static GstCaps* asf_wmv_type_find (GstBuffer *buf, gpointer private);
-static GstCaps* asf_wvx_type_find (GstBuffer *buf, gpointer private);
-static GstCaps* asf_wm_type_find (GstBuffer *buf, gpointer private);
+static GstCaps* asf_type_find (GstByteStream *bs, gpointer private);
 
 /* typefactory for 'asf' */
-static GstTypeDefinition asf_type_definitions[] = {
-  { "asfdemux_video/asf",
-    "video/x-ms-asf",
-    ".asf .asx",
-    asf_asf_type_find },
-  { "asfdemux_video/wma",
-    "video/x-ms-wma",
-    ".wma",
-    asf_wma_type_find },
-  { "asfdemux_video/wax",
-    "video/x-ms-wax",
-    ".wax",
-    asf_wax_type_find },
-  { "asfdemux_video/wmv",
-    "video/x-ms-wmv",
-    ".wmv",
-    asf_wmv_type_find },
-  { "asfdemux_video/wvx",
-    "video/x-ms-wvx",
-    ".wvx",
-    asf_wvx_type_find },
-  { "asfdemux_video/wm",
-    "video/x-ms-wm",
-    ".wm",
-    asf_wm_type_find },
-  { NULL, NULL, NULL, NULL }
+static GstTypeDefinition asf_type_definition = {
+  "asfdemux_video/asf",
+  "video/x-ms-asf",
+  /* note: asx/wax/wmx are XML files, we don't handle them */
+  ".asf .wma .wmv .wm",
+  asf_type_find,
 };
 
 static GstCaps*
-asf_asf_type_find (GstBuffer *buf, gpointer private)
+asf_type_find (GstByteStream *bs, gpointer private)
 {
-  GstCaps *new;
+  GstCaps *new = NULL;
+  GstBuffer *buf = NULL;
 
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
-  return new;
-}
-
-static GstCaps*
-asf_wma_type_find (GstBuffer *buf, gpointer private)
-{
-  GstCaps *new;
-
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
-  return new;
-}
-
-static GstCaps*
-asf_wax_type_find (GstBuffer *buf, gpointer private)
-{
-  GstCaps *new;
-
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
-  return new;
-}
-
-static GstCaps*
-asf_wmv_type_find (GstBuffer *buf, gpointer private)
-{
-  GstCaps *new;
-
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
-  return new;
-}
-
-static GstCaps*
-asf_wvx_type_find (GstBuffer *buf, gpointer private)
-{
-  GstCaps *new;
+  if (gst_bytestream_peek (bs, &buf, 16) == 16) {
+    guint32 uid1 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[0]),
+	    uid2 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[1]),
+	    uid3 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[2]),
+	    uid4 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[3]);
 
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
-  return new;
-}
+    if (uid1 == 0x75B22630 && uid2 == 0x11CF668E &&
+        uid3 == 0xAA00D9A6 && uid4 == 0x6CCE6200) {
+      new = GST_CAPS_NEW ("asf_type_find",
+			  "video/x-ms-asf",
+			    NULL);
+    }
+  }
 
-static GstCaps*
-asf_wm_type_find (GstBuffer *buf, gpointer private)
-{
-  GstCaps *new;
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
 
-  new = gst_caps_new (
-                  "asf_type_find",
-                  "video/x-ms-asf",
-                  gst_props_new ("asfversion",
-				 GST_PROPS_INT (1),
-				 NULL));
   return new;
 }
 
@@ -1644,6 +1562,7 @@
 plugin_init (GModule *module, GstPlugin *plugin)
 {
   GstElementFactory *factory;
+  GstTypeFactory *type;
   gint i = 0;
   GstCaps *audcaps = NULL, *vidcaps = NULL, *temp;
   guint32 vid_list[] = {
@@ -1670,23 +1589,13 @@
     -1 /* end */
   };
 
-  /* this filter needs bytestream */
-  if (!gst_library_load ("gstbytestream")) {
-    GST_INFO ("asfdemux: could not load support library: 'gstbytestream'\n");
-    return FALSE;
-  }
-  
   /* create an elementfactory for the asf_demux element */
   factory = gst_element_factory_new ("asfdemux",GST_TYPE_ASF_DEMUX,
                                     &gst_asf_demux_details);
 
-  while (asf_type_definitions[i].name) {
-    GstTypeFactory *type;
-
-    type = gst_type_factory_new (&asf_type_definitions[i]);
-    //gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
-    i++;
-  }
+  /* type finding */
+  type = gst_type_factory_new (&asf_type_definition);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
 
   g_return_val_if_fail (factory != NULL, FALSE);
   gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_NONE);
Index: gst/asfdemux/gstasfdemux.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/asfdemux/gstasfdemux.h,v
retrieving revision 1.6
diff -u -r1.6 gstasfdemux.h
--- gst/asfdemux/gstasfdemux.h	31 Jan 2003 21:41:07 -0000	1.6
+++ gst/asfdemux/gstasfdemux.h	30 Sep 2003 14:13:11 -0000
@@ -24,7 +24,7 @@
 #include <config.h>
 #include <gst/gst.h>
 #include <gst/riff/riff.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include "asfheaders.h"
 
 G_BEGIN_DECLS
Index: gst/asfdemux/gstasfmux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/asfdemux/gstasfmux.c,v
retrieving revision 1.4
diff -u -r1.4 gstasfmux.c
--- gst/asfdemux/gstasfmux.c	9 Sep 2003 20:01:31 -0000	1.4
+++ gst/asfdemux/gstasfmux.c	30 Sep 2003 14:13:12 -0000
@@ -414,6 +414,7 @@
   return GST_PAD_LINK_REFUSED;
 
 done:
+  stream->bitrate = 1024 * 1024;
   stream->header.video.format.size = stream->header.video.stream.size;
   stream->header.video.format.width = stream->header.video.stream.width;
   stream->header.video.format.height = stream->header.video.stream.height;
@@ -465,7 +466,6 @@
 
     stream->header.audio.sample_rate = rate;
     stream->header.audio.channels    = channels;
-    stream->bitrate = 0; /* TODO */
 
     if (!strcmp (mimetype, "audio/x-raw-int")) {
       gint block, size;
@@ -507,7 +507,7 @@
       }
 
       stream->header.audio.block_align = 1;
-      stream->header.audio.byte_rate   = 0;
+      stream->header.audio.byte_rate   = 8 * 1024;
       stream->header.audio.word_size   = 16;
       stream->header.audio.size        = 0;
 
@@ -521,6 +521,7 @@
   return GST_PAD_LINK_REFUSED;
 
 done:
+  stream->bitrate = stream->header.audio.byte_rate * 8;
   return GST_PAD_LINK_OK;
 }
 
@@ -632,9 +633,11 @@
   const GstEventMask *masks = gst_pad_get_event_masks (GST_PAD_PEER (asfmux->srcpad));
 
   /* this is for stream or file-storage */
-  while (masks->type != 0) {
+  while (masks != NULL && masks->type != 0) {
     if (masks->type == GST_EVENT_SEEK) {
       return TRUE;
+    } else {
+      masks++;
     }
   }
 
@@ -724,7 +727,7 @@
 		       guint8    *data,
 		       guint      length)
 {
-  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) > length) {
+  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) >= length) {
     guint8 *pos = GST_BUFFER_DATA (packet) + GST_BUFFER_SIZE (packet);
     memcpy (pos, data, length);
     GST_BUFFER_SIZE (packet) += length;
@@ -737,7 +740,7 @@
 gst_asfmux_put_byte (GstBuffer *packet,
 		     guint8     data)
 {
-  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) > sizeof (data)) {
+  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) >= sizeof (data)) {
     guint8 *pos = GST_BUFFER_DATA (packet) + GST_BUFFER_SIZE (packet);
     * (guint8 *) pos = data;
     GST_BUFFER_SIZE (packet) += 1;
@@ -750,7 +753,7 @@
 gst_asfmux_put_le16 (GstBuffer *packet,
 		     guint16    data)
 {
-  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) > sizeof (data)) {
+  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) >= sizeof (data)) {
     guint8 *pos = GST_BUFFER_DATA (packet) + GST_BUFFER_SIZE (packet);
     * (guint16 *) pos = GUINT16_TO_LE (data);
     GST_BUFFER_SIZE (packet) += 2;
@@ -763,7 +766,7 @@
 gst_asfmux_put_le32 (GstBuffer *packet,
 		     guint32    data)
 {
-  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) > sizeof (data)) {
+  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) >= sizeof (data)) {
     guint8 *pos = GST_BUFFER_DATA (packet) + GST_BUFFER_SIZE (packet);
     * (guint32 *) pos = GUINT32_TO_LE (data);
     GST_BUFFER_SIZE (packet) += 4;
@@ -776,7 +779,7 @@
 gst_asfmux_put_le64 (GstBuffer *packet,
 		     guint64    data)
 {
-  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) > sizeof (data)) {
+  if ((GST_BUFFER_MAXSIZE (packet) - GST_BUFFER_SIZE (packet)) >= sizeof (data)) {
     guint8 *pos = GST_BUFFER_DATA (packet) + GST_BUFFER_SIZE (packet);
     * (guint64 *) pos = GUINT64_TO_LE (data);
     GST_BUFFER_SIZE (packet) += 8;
Index: gst/auparse/gstauparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/auparse/gstauparse.c,v
retrieving revision 1.19
diff -u -r1.19 gstauparse.c
--- gst/auparse/gstauparse.c	16 Sep 2003 09:59:57 -0000	1.19
+++ gst/auparse/gstauparse.c	30 Sep 2003 14:13:12 -0000
@@ -42,16 +42,23 @@
 };
 
 static GstCaps*
-au_type_find (GstBuffer *buf, gpointer private)
+au_type_find (GstByteStream *bs, gpointer private)
 {
+  GstBuffer *buf = NULL;
   GstCaps *new = NULL;
-  gulong *head = (gulong *) GST_BUFFER_DATA (buf);
 
-  if (GST_BUFFER_SIZE (buf) < 4)
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 4) == 4) {
+    guint32 head = * (guint32 *) GST_BUFFER_DATA (buf);
+    if (head == 0x2e736e64 || head == 0x646e732e) {
+      new = gst_caps_new ("au_type_find",
+			  "audio/x-au",
+			    NULL);
+    }
+  }
 
-  if (*head == 0x2e736e64 || *head == 0x646e732e)
-    new = gst_caps_new ("au_type_find", "audio/x-au", NULL);
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
 
   return new;
 }
Index: gst/avi/gstavidemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/avi/gstavidemux.c,v
retrieving revision 1.78
diff -u -r1.78 gstavidemux.c
--- gst/avi/gstavidemux.c	16 Sep 2003 09:59:57 -0000	1.78
+++ gst/avi/gstavidemux.c	30 Sep 2003 14:13:12 -0000
@@ -38,7 +38,7 @@
   "(C) 1999",
 };
 
-static GstCaps* avi_type_find (GstBuffer *buf, gpointer private);
+static GstCaps* avi_type_find (GstByteStream *bs, gpointer private);
 
 /* typefactory for 'avi' */
 static GstTypeDefinition avidefinition = {
@@ -173,25 +173,29 @@
 }
 
 static GstCaps*
-avi_type_find (GstBuffer *buf,
-              gpointer private)
+avi_type_find (GstByteStream *bs,
+               gpointer       private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
-  GstCaps *new;
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
   GST_DEBUG ("avi_demux: typefind");
 
-  if (GST_BUFFER_SIZE (buf) < 12)
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 12) == 12) {
+    guint32 head1 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[0]),
+	    head2 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[2]);
+
+    if (head1 == GST_RIFF_TAG_RIFF && head2 == GST_RIFF_RIFF_AVI) {
+      new = GST_CAPS_NEW ("avi_type_find",
+			  "video/avi", 
+			    NULL);
+    }
+  }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
 
-  if (GUINT32_FROM_LE (((guint32 *)data)[0]) != GST_RIFF_TAG_RIFF)
-    return NULL;
-  if (GUINT32_FROM_LE (((guint32 *)data)[2]) != GST_RIFF_RIFF_AVI)
-    return NULL;
-
-  new = GST_CAPS_NEW ("avi_type_find",
-		      "video/avi", 
-		        NULL);
   return new;
 }
 
@@ -1960,10 +1964,6 @@
     GST_RIFF_WAVE_FORMAT_MULAW,
     -1 /* end */
   };
-
-  /* this filter needs the riff parser */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   if (!gst_library_load ("gstriff"))
     return FALSE;
Index: gst/avi/gstavidemux.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/avi/gstavidemux.h,v
retrieving revision 1.14
diff -u -r1.14 gstavidemux.h
--- gst/avi/gstavidemux.h	31 Jan 2003 19:37:26 -0000	1.14
+++ gst/avi/gstavidemux.h	30 Sep 2003 14:13:12 -0000
@@ -24,7 +24,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include <gst/riff/riff.h>
 
 #ifdef __cplusplus
Index: gst/cdxaparse/gstcdxaparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/cdxaparse/gstcdxaparse.c,v
retrieving revision 1.8
diff -u -r1.8 gstcdxaparse.c
--- gst/cdxaparse/gstcdxaparse.c	24 Jul 2003 08:49:43 -0000	1.8
+++ gst/cdxaparse/gstcdxaparse.c	30 Sep 2003 14:13:12 -0000
@@ -50,7 +50,7 @@
   "(C) 2002",
 };
 
-static GstCaps* cdxa_type_find (GstBuffer *buf, gpointer private);
+static GstCaps* cdxa_type_find (GstByteStream *bs, gpointer private);
 
 /* typefactory for 'cdxa' */
 static GstTypeDefinition cdxadefinition = {
@@ -159,25 +159,28 @@
 }
 
 static GstCaps*
-cdxa_type_find (GstBuffer *buf,
-              gpointer private)
+cdxa_type_find (GstByteStream *bs,
+		gpointer       private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
-  GstCaps *new;
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
   GST_DEBUG ("cdxa_parse: typefind");
 
-  if (GST_BUFFER_SIZE (buf) < 12)
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 12) == 12) {
+    guint32 head1 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[0]),
+	    head2 = GUINT32_FROM_LE (((guint32 *) GST_BUFFER_DATA (buf))[2]);
+
+    if (head1 == GST_RIFF_TAG_RIFF && head2 == GST_RIFF_RIFF_CDXA) {
+      new = GST_CAPS_NEW ("cdxa_type_find",
+			  "video/x-cdxa", 
+			    NULL);
+    }
+  }
 
-  if (GUINT32_FROM_LE (((guint32 *)data)[0]) != GST_RIFF_TAG_RIFF)
-    return NULL;
-  if (GUINT32_FROM_LE (((guint32 *)data)[2]) != GST_RIFF_RIFF_CDXA)
-    return NULL;
-
-  new = GST_CAPS_NEW ("cdxa_type_find",
-		      "video/x-cdxa", 
-		        NULL);
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
 
   return new;
 }
@@ -341,10 +344,6 @@
 {
   GstElementFactory *factory;
   GstTypeFactory *type;
-
-  /* this filter needs the riff parser */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   /* create an elementfactory for the cdxa_parse element */
   factory = gst_element_factory_new ("cdxaparse", GST_TYPE_CDXA_PARSE,
Index: gst/cdxaparse/gstcdxaparse.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/cdxaparse/gstcdxaparse.h,v
retrieving revision 1.1
diff -u -r1.1 gstcdxaparse.h
--- gst/cdxaparse/gstcdxaparse.h	20 Apr 2002 21:42:29 -0000	1.1
+++ gst/cdxaparse/gstcdxaparse.h	30 Sep 2003 14:13:12 -0000
@@ -24,7 +24,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #ifdef __cplusplus
 extern "C" {
Index: gst/festival/gstfestival.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/festival/gstfestival.c,v
retrieving revision 1.6
diff -u -r1.6 gstfestival.c
--- gst/festival/gstfestival.c	24 Jul 2003 08:49:43 -0000	1.6
+++ gst/festival/gstfestival.c	30 Sep 2003 14:13:12 -0000
@@ -80,7 +80,7 @@
 static void		gst_festival_class_init		(GstFestivalClass *klass);
 static void		gst_festival_init		(GstFestival *festival);
 
-static GstCaps*		text_type_find			(GstBuffer *buf, gpointer private);
+static GstCaps*		text_type_find			(GstByteStream *bs, gpointer private);
 
 static void		gst_festival_chain		(GstPad *pad, GstBuffer *buf);
 static GstElementStateReturn 
@@ -198,21 +198,35 @@
 }
 
 static GstCaps*
-text_type_find (GstBuffer *buf, gpointer private)
+text_type_find (GstByteStream *bs, gpointer private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
-  gint i;
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
-  /* 20 is arbitrary.  4 is definitely too small. */
-  if (GST_BUFFER_SIZE (buf) < 20)
-    return NULL;
-
-  for (i=0; i<GST_BUFFER_SIZE (buf); i++) {
-    if (!isprint(data[i]) && data[i]!='\n')
-      return NULL;
+#define TEXT_SIZE 32
+
+  /* read arbitrary number and see if it's textual */
+  if (gst_bytestream_peek (bs, &buf, TEXT_SIZE) == TEXT_SIZE) {
+    gchar *data = GST_BUFFER_DATA (buf);
+    gint i;
+
+    for (i = 0; i < TEXT_SIZE; i++) {
+      if (!isprint (data[i]) && data[i] != '\n') {
+        break;
+      }
+    }
+
+    /* well, we found something that looks like text... */
+    new = gst_caps_new ("text_type_find",
+			"text/plain",
+			  NULL);
+  }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
   }
 
-  return gst_caps_new ("text_type_find", "text/plain", NULL);
+  return new;
 }
 
 
Index: gst/flx/gstflxdec.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/flx/gstflxdec.c,v
retrieving revision 1.26
diff -u -r1.26 gstflxdec.c
--- gst/flx/gstflxdec.c	16 Sep 2003 09:59:58 -0000	1.26
+++ gst/flx/gstflxdec.c	30 Sep 2003 14:13:12 -0000
@@ -28,7 +28,7 @@
 
 #define JIFFIE  (GST_SECOND/70)
 
-static GstCaps* flxdec_type_find(GstBuffer *buf, gpointer private);
+static GstCaps* flxdec_type_find (GstByteStream *bs, gpointer private);
 
 /* flx element information */
 static GstElementDetails flxdec_details = {
@@ -113,27 +113,33 @@
 static GstElementClass *parent_class = NULL;
 
 static GstCaps* 
-flxdec_type_find (GstBuffer *buf, gpointer private)
+flxdec_type_find (GstByteStream *bs, gpointer private)
 {
-  guchar *data = GST_BUFFER_DATA(buf);
-  GstCaps *new;
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
-  if (GST_BUFFER_SIZE(buf) < 134){
-    return NULL;
-  }
+  if (gst_bytestream_peek (bs, &buf, 134) == 134) {
+    guint8 *data = GST_BUFFER_DATA (buf);
 
-  /* check magic */
-  if ((data[4] == 0x11 || data[4] == 0x12
-       || data[4] == 0x30 || data[4] == 0x44) && data[5] == 0xaf) {
+    /* check magic */
+    if ((data[4] == 0x11 || data[4] == 0x12 ||
+         data[4] == 0x30 || data[4] == 0x44) &&
+        data[5] == 0xaf) {
       /* check the frame type of the first frame */
       if ((data[132] == 0x00 || data[132] == 0xfa) && data[133] == 0xf1) {
         GST_DEBUG ("GstFlxDec: found supported flx format");
-        new = gst_caps_new("flxdec_type_find","video/x-fli", NULL);
-        return new;
+        new = gst_caps_new ("flxdec_type_find",
+			    "video/x-fli",
+			      NULL);
       }
+    }
   }
-  
-  return NULL; 
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
 }
 
 
@@ -683,10 +689,6 @@
 {
   GstElementFactory *factory;
   GstTypeFactory *type;
-
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   factory = gst_element_factory_new("flxdec", GST_TYPE_FLXDEC, &flxdec_details);
   g_return_val_if_fail(factory != NULL, FALSE);
Index: gst/flx/gstflxdec.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/flx/gstflxdec.h,v
retrieving revision 1.4
diff -u -r1.4 gstflxdec.h
--- gst/flx/gstflxdec.h	20 Mar 2002 21:44:50 -0000	1.4
+++ gst/flx/gstflxdec.h	30 Sep 2003 14:13:12 -0000
@@ -23,7 +23,7 @@
 #include <gst/gst.h>
 
 #include "flx_color.h"
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 
 #ifdef __cplusplus
Index: gst/intfloat/gstfloat2int.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/intfloat/gstfloat2int.c,v
retrieving revision 1.42
diff -u -r1.42 gstfloat2int.c
--- gst/intfloat/gstfloat2int.c	16 Sep 2003 09:59:58 -0000	1.42
+++ gst/intfloat/gstfloat2int.c	30 Sep 2003 14:13:12 -0000
@@ -510,9 +510,6 @@
 {
   GstElementFactory *factory;
   
-  if (! gst_library_load ("gstbytestream"))
-    return FALSE;
-
   factory = gst_element_factory_new ("float2int", GST_TYPE_FLOAT2INT,
                                      &float2int_details);
   g_return_val_if_fail(factory != NULL, FALSE);
Index: gst/intfloat/gstfloat2int.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/intfloat/gstfloat2int.h,v
retrieving revision 1.12
diff -u -r1.12 gstfloat2int.h
--- gst/intfloat/gstfloat2int.h	16 Jul 2003 16:08:13 -0000	1.12
+++ gst/intfloat/gstfloat2int.h	30 Sep 2003 14:13:12 -0000
@@ -26,7 +26,6 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
 
 
 #define GST_TYPE_FLOAT2INT \
Index: gst/mixmatrix/mixmatrix.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mixmatrix/mixmatrix.c,v
retrieving revision 1.12
diff -u -r1.12 mixmatrix.c
--- gst/mixmatrix/mixmatrix.c	25 Jul 2003 10:50:47 -0000	1.12
+++ gst/mixmatrix/mixmatrix.c	30 Sep 2003 14:13:13 -0000
@@ -22,7 +22,7 @@
 #endif
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include <gst/audio/audio.h>
 #include <string.h>
 
@@ -499,10 +499,6 @@
 plugin_init (GModule *module, GstPlugin *plugin)
 {
   GstElementFactory *factory;
-
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   factory = gst_element_factory_new ("mixmatrix", GST_TYPE_MIXMATRIX, 
                                      &mixmatrix_details);
Index: gst/modplug/gstmodplug.cc
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/modplug/gstmodplug.cc,v
retrieving revision 1.30
diff -u -r1.30 gstmodplug.cc
--- gst/modplug/gstmodplug.cc	16 Sep 2003 09:59:58 -0000	1.30
+++ gst/modplug/gstmodplug.cc	30 Sep 2003 14:13:13 -0000
@@ -130,31 +130,39 @@
 static GstElementClass *parent_class = NULL;
 
 static GstCaps* 
-modplug_type_find (GstBuffer *buf, gpointer priv) 
-{  
-  if (GST_BUFFER_SIZE (buf) < 75)
-    return NULL;
+modplug_type_find (GstByteStream *bs, gpointer priv) 
+{
+  GstBuffer *buf = NULL;
+  GstCaps *newc = NULL;
 
-  if (MOD_CheckType (buf)     ||
-      Mod_669_CheckType (buf) ||
-      Amf_CheckType (buf)     ||
-      Dsm_CheckType (buf)     ||
-      Fam_CheckType (buf)     ||
-      Gdm_CheckType (buf)     ||
-      Imf_CheckType (buf)     ||
-      It_CheckType (buf)      ||
-      M15_CheckType (buf)     ||
-      /*Med_CheckType (buf)     || <- FIXME */
-      Mtm_CheckType (buf)     ||
-      Okt_CheckType (buf)     ||
-      S3m_CheckType (buf)     ||
-      Xm_CheckType (buf)) {
-    return gst_caps_new ("modplug_type_find",
-			 "audio/x-mod",
-			   NULL);
+  if (gst_bytestream_peek (bs, &buf, 75) == 75) {
+    if (MOD_CheckType (buf)     ||
+        Mod_669_CheckType (buf) ||
+        Amf_CheckType (buf)     ||
+        Dsm_CheckType (buf)     ||
+        Fam_CheckType (buf)     ||
+        Gdm_CheckType (buf)     ||
+        Imf_CheckType (buf)     ||
+        It_CheckType (buf)      ||
+        M15_CheckType (buf)     ||
+#if 0
+        Med_CheckType (buf)     || /* FIXME */
+#endif
+        Mtm_CheckType (buf)     ||
+        Okt_CheckType (buf)     ||
+        S3m_CheckType (buf)     ||
+        Xm_CheckType (buf)) {
+      newc = GST_CAPS_NEW ("modplug_type_find",
+			   "audio/x-mod",
+			     NULL);
+    }
   }
-  
-  return NULL;
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return newc;
 }
 
 static GstTypeDefinition modplug_definitions[] = {
Index: gst/modplug/gstmodplug.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/modplug/gstmodplug.h,v
retrieving revision 1.10
diff -u -r1.10 gstmodplug.h
--- gst/modplug/gstmodplug.h	27 Jun 2003 23:46:13 -0000	1.10
+++ gst/modplug/gstmodplug.h	30 Sep 2003 14:13:13 -0000
@@ -28,7 +28,7 @@
 #endif /* __cplusplus */
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 	
 #include "modplug_types.h"	
 
Index: gst/mpegaudioparse/Makefile.am
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegaudioparse/Makefile.am,v
retrieving revision 1.10
diff -u -r1.10 Makefile.am
--- gst/mpegaudioparse/Makefile.am	11 Sep 2003 19:57:57 -0000	1.10
+++ gst/mpegaudioparse/Makefile.am	30 Sep 2003 14:13:13 -0000
@@ -1,17 +1,9 @@
-#FIXME clean me up a bit
-
-plugin_LTLIBRARIES = libgstmpegaudioparse.la libgstmp3types.la
+plugin_LTLIBRARIES = libgstmpegaudioparse.la
 
 libgstmpegaudioparse_la_SOURCES = gstmpegaudioparse.c
 libgstmpegaudioparse_la_CFLAGS = $(GST_CFLAGS)
 libgstmpegaudioparse_la_LIBADD =
 libgstmpegaudioparse_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
-libgstmp3types_la_SOURCES = gstmp3types.c
-libgstmp3types_la_CFLAGS = $(GST_CFLAGS)
-libgstmp3types_la_LIBADD =
-libgstmp3types_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-
 noinst_HEADERS = gstmpegaudioparse.h
 EXTRA_DIST = README
-
Index: gst/mpegaudioparse/gstmpegaudioparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegaudioparse/gstmpegaudioparse.c,v
retrieving revision 1.23
diff -u -r1.23 gstmpegaudioparse.c
--- gst/mpegaudioparse/gstmpegaudioparse.c	16 Sep 2003 09:59:59 -0000	1.23
+++ gst/mpegaudioparse/gstmpegaudioparse.c	30 Sep 2003 14:13:13 -0000
@@ -35,6 +35,15 @@
   "(C) 1999",
 };
 
+static GstCaps * mp3_type_find (GstByteStream *bs, gpointer data);
+
+static GstTypeDefinition mp3type_definition = {
+  "mp3_audio/mpeg",
+  "audio/mpeg",
+  ".mp3 .mp2 .mp1 .mpga",
+  mp3_type_find,
+};
+
 static GstPadTemplate*
 mp3_src_factory (void)
 {
@@ -115,11 +124,221 @@
       0,
       (GInstanceInitFunc)gst_mp3parse_init,
     };
-    mp3parse_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMPEGAudioParse", &mp3parse_info, 0);
+    mp3parse_type = g_type_register_static (GST_TYPE_ELEMENT,
+					    "GstMPEGAudioParse",
+					    &mp3parse_info, 0);
   }
   return mp3parse_type;
 }
 
+static guint mp3types_bitrates[2][3][16] =
+{ { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, },
+    {0, 32, 48, 56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, 384, },
+    {0, 32, 40, 48,  56,  64,  80,  96, 112, 128, 160, 192, 224, 256, 320, } },
+  { {0, 32, 48, 56,  64,  80,  96, 112, 128, 144, 160, 176, 192, 224, 256, },
+    {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, },
+    {0,  8, 16, 24,  32,  40,  48,  56,  64,  80,  96, 112, 128, 144, 160, } },
+};
+
+static guint mp3types_freqs[3][3] =
+{ {44100, 48000, 32000},
+  {22050, 24000, 16000}, 
+  {11025, 12000,  8000}};
+
+static inline guint
+mp3_type_frame_length_from_header (guint32 header, guint *put_layer,
+				   guint *put_channels, guint *put_bitrate,
+				   guint *put_samplerate)
+{
+  guint length;
+  gulong mode, samplerate, bitrate, layer, version, channels;
+
+  /* we don't need extension, copyright, original or
+   * emphasis for the frame length */
+  header >>= 6;
+
+  /* mode */
+  mode = header & 0x3;
+  header >>= 3;
+
+  /* padding */
+  length = header & 0x1;
+  header >>= 1;
+
+  /* sampling frequency */
+  samplerate = header & 0x3;
+  if (samplerate == 3)
+    return 0;
+  header >>= 2;
+
+  /* bitrate index */
+  bitrate = header & 0xF;
+  if (bitrate == 15 || bitrate == 0)
+    return 0;
+
+  /* ignore error correction, too */
+  header >>= 5;
+
+  /* layer */
+  layer = 4 - (header & 0x3);
+  if (layer == 4)
+    return 0;
+  header >>= 2;
+
+  /* version */
+  version = header & 0x3;
+  if (version == 1)
+    return 0;
+
+  /* lookup */
+  channels = (mode == 3) ? 1 : 2;
+  bitrate = mp3types_bitrates[version == 3 ? 0 : 1][layer - 1][bitrate];
+  samplerate = mp3types_freqs[version > 0 ? version - 1 : 0][samplerate];
+
+  /* calculating */
+  if (layer == 1) {
+    length = ((12000 * bitrate / samplerate) + length) * 4;
+  } else {
+    length += ((layer == 3 && version == 0) ? 144000 : 72000) * bitrate / samplerate;
+  }
+
+  GST_DEBUG ("Calculated mp3 frame length of %u bytes", length);
+  GST_DEBUG ("samplerate = %lu - bitrate = %lu - layer = %lu - version = %lu"
+	     " - channels = %lu",
+	     samplerate, bitrate, layer, version, channels);
+
+  if (put_layer)
+    *put_layer = layer;
+  if (put_channels)
+    *put_channels = channels;
+  if (put_bitrate)
+    *put_bitrate = bitrate;
+  if (put_samplerate)
+    *put_samplerate = samplerate;
+
+  return length;
+}
+
+/**
+ * The chance that random data is identified as a valid mp3 header is 63 / 2^18
+ * (0.024%) per try. This makes the function for calculating false positives
+ *   1 - (1 - ((63 / 2 ^18) ^ GST_MP3_TYPEFIND_MIN_HEADERS)) ^ buffersize)
+ * This has the following probabilities of false positives:
+ * bufsize	          MIN_HEADERS
+ * (bytes)	1	2	3	4
+ * 4096		62.6%	 0.02%	 0%	 0%
+ * 16384	98%	 0.09%	 0%	 0%
+ * 1 MiB       100%	 5.88%	 0%	 0%
+ * 1 GiB       100%    100%	 1.44%   0%
+ * 1 TiB       100%    100%    100%      0.35%
+ * This means that the current choice (3 headers by most of the time 4096 byte
+ * buffers is pretty safe for now.
+ *
+ * The max. size of each frame is 1440 bytes, which means that for N frames
+ * to be detected, we need 1440 * GST_MP3_TYPEFIND_MIN_HEADERS + 3 of data.
+ * Assuming we step into the stream right after the frame header, this
+ * means we need 1440 * (GST_MP3_TYPEFIND_MIN_HEADERS + 1) - 1 + 3 bytes
+ * of data (5762) to always detect any mp3.
+ */
+
+/* increase this value when this function finds too many false positives */
+#define GST_MP3_TYPEFIND_MIN_HEADERS 3
+#define GST_MP3_TYPEFIND_MIN_DATA (1440 * (GST_MP3_TYPEFIND_MIN_HEADERS + 1) - 1 + 3)
+
+static GstCaps *
+mp3_caps_create (guint layer, guint channels,
+		 guint bitrate, guint samplerate)
+{
+  GstCaps *new;
+
+  g_assert (layer);
+  g_assert (samplerate);
+  g_assert (bitrate);
+  g_assert (channels);
+
+  new = GST_CAPS_NEW ("mp3_type_find",
+		      "audio/mpeg",
+			"mpegversion", GST_PROPS_INT (1),
+			"layer",       GST_PROPS_INT (layer),
+			/*"bitrate",     GST_PROPS_INT (bitrate),*/
+			"rate",        GST_PROPS_INT (samplerate),
+			"channels",    GST_PROPS_INT (channels));
+
+  return new;
+}
+
+static GstCaps *
+mp3_type_find (GstByteStream *bs, gpointer private)
+{
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
+  guint8 *data;
+  guint size;
+  guint32 head;
+  guint layer = 0, bitrate = 0, samplerate = 0, channels = 0;
+
+  /* note that even if we don't get the requested size,
+   * it might still be a (very small) mp3 */
+  gst_bytestream_peek (bs, &buf, GST_MP3_TYPEFIND_MIN_DATA);
+  if (!buf) {
+    goto done;
+  }
+  
+  data = GST_BUFFER_DATA (buf);
+  size = GST_BUFFER_SIZE (buf);
+  
+  while (size >= 4) {
+    head = GUINT32_FROM_BE(*((guint32 *)data));
+    if ((head & 0xffe00000) == 0xffe00000) {
+      guint length;
+      guint prev_layer = 0, prev_bitrate = 0,
+	    prev_channels = 0, prev_samplerate = 0;
+      guint found = 0; /* number of valid headers found */
+      guint pos = 0;
+
+      do {
+        if (!(length = mp3_type_frame_length_from_header (head, &layer,
+							  &channels, &bitrate,
+							  &samplerate))) {
+          break;
+	}
+	if ((prev_layer && prev_layer != layer) || !layer ||
+	    (prev_bitrate && prev_bitrate != bitrate) || !bitrate ||
+	    (prev_samplerate && prev_samplerate != samplerate) || !samplerate ||
+	    (prev_channels && prev_channels != channels) || !channels) {
+          /* this means an invalid property, or a change, which likely
+	   * indicates that this is not a mp3 but just a random bytestream */
+	  break;
+	}
+	prev_layer = layer;
+	prev_bitrate = bitrate;
+	prev_channels = channels;
+	prev_samplerate = samplerate;
+	pos += length;
+	if (++found >= GST_MP3_TYPEFIND_MIN_HEADERS) {
+          /* we're pretty sure that this is mp3 now */
+          new = mp3_caps_create (layer, channels, bitrate, samplerate);
+	  goto done;
+        }
+
+        /* and now, find a new head */
+        head = GUINT32_FROM_BE(*((guint32 *) &(data[pos])));  
+        if ((head & 0xffe00000) != 0xffe00000)
+	  break;
+      } while (TRUE);
+    }
+    data++;
+    size--;
+  }
+
+done:
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
+}
+
 static void
 gst_mp3parse_class_init (GstMPEGAudioParseClass *klass)
 {
@@ -247,7 +466,10 @@
         header2 = GUINT32_FROM_BE(*((guint32 *)(data+offset+bpf)));
         GST_DEBUG ("mp3parse: header=%08X, header2=%08X, bpf=%d", (unsigned int)header, (unsigned int)header2, bpf );
 
-        #define HDRMASK ~( (0xF<<12)/*bitrate*/ | (1<<9)/*padding*/ | (3<<4)/*mode extension*/ ) /* mask the bits which are allowed to differ between frames */
+/* mask the bits which are allowed to differ between frames */
+#define HDRMASK ~((0xF << 12)  /* bitrate */ | \
+		  (0x1 <<  9)  /* padding */ | \
+		  (0x3 <<  4)) /*mode extension*/
 
         if ( (header2&HDRMASK) != (header&HDRMASK) ) { /* require 2 matching headers in a row */
            GST_DEBUG ("mp3parse: next header doesn't match (header=%08X, header2=%08X, bpf=%d)", (unsigned int)header, (unsigned int)header2, bpf );
@@ -309,56 +531,23 @@
   }
 }
 
-static int mp3parse_tabsel[2][3][16] =
-{ { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, },
-    {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, },
-    {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, } },
-  { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, },
-    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, },
-    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, } },
-};
-
-static long mp3parse_freqs[9] =
-{44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
-
-
 static long
 bpf_from_header (GstMPEGAudioParse *parse, unsigned long header)
 {
-  int layer_index,layer,lsf,samplerate_index,padding,mode;
-  long bpf;
-  gint channels, rate;
-
-  /*mpegver = (header >> 19) & 0x3; // don't need this for bpf */
-  layer_index = (header >> 17) & 0x3;
-  layer = 4 - layer_index;
-  lsf = (header & (1 << 20)) ? ((header & (1 << 19)) ? 0 : 1) : 1;
-  parse->bit_rate = mp3parse_tabsel[lsf][layer - 1][((header >> 12) & 0xf)];
-  samplerate_index = (header >> 10) & 0x3;
-  padding = (header >> 9) & 0x1;
-  mode = (header >> 6) & 0x3;
+  guint bitrate, layer, rate, channels, length;
 
-  if (layer == 1) {
-    bpf = parse->bit_rate * 12000;
-    bpf /= mp3parse_freqs[samplerate_index];
-    bpf = ((bpf + padding) << 2);
-  } else {
-    bpf = parse->bit_rate * 144000;
-    bpf /= mp3parse_freqs[samplerate_index];
-    bpf += padding;
+  if (!(length = mp3_type_frame_length_from_header (header, &layer,
+						    &channels,
+						    &bitrate, &rate))) {
+    return 0;
   }
 
-  channels = (mode == 3) ? 1 : 2;
-  rate = mp3parse_freqs[samplerate_index];
   if (channels != parse->channels ||
       rate     != parse->rate     ||
-      layer    != parse->layer) {
-    GstCaps *caps = GST_CAPS_NEW ("mp3parse_src",
-                                  "audio/mpeg",
-                                    "mpegversion", GST_PROPS_INT (1),
-                                    "layer",    GST_PROPS_INT (layer),
-                                    "channels", GST_PROPS_INT (channels),
-                                    "rate",     GST_PROPS_INT (rate));
+      layer    != parse->layer    ||
+      bitrate  != parse->bit_rate) {
+    GstCaps *caps = mp3_caps_create (layer, channels, bitrate, rate);
+
     if (gst_pad_try_set_caps(parse->srcpad, caps) <= 0) {
       gst_element_error (GST_ELEMENT (parse),
                          "mp3parse: failed to negotiate format with next element");
@@ -367,12 +556,10 @@
     parse->channels = channels;
     parse->layer    = layer;
     parse->rate     = rate;
+    parse->bit_rate = bitrate;
   }
 
-  /*g_print("%08x: layer %d lsf %d bitrate %d samplerate_index %d padding %d - bpf %d\n", */
-/*header,layer,lsf,bitrate,samplerate_index,padding,bpf); */
-
-  return bpf;
+  return length;
 }
 
 static gboolean
@@ -470,6 +657,7 @@
 plugin_init (GModule *module, GstPlugin *plugin)
 {
   GstElementFactory *factory;
+  GstTypeFactory *type;
 
   /* create an elementfactory for the mp3parse element */
   factory = gst_element_factory_new ("mp3parse",
@@ -484,6 +672,10 @@
   gst_element_factory_add_pad_template (factory, src_temp);
 
   gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  /* type finding */
+  type = gst_type_factory_new (&mp3type_definition);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
 
   return TRUE;
 }
Index: gst/mpegstream/gstmpegdemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstmpegdemux.c,v
retrieving revision 1.39
diff -u -r1.39 gstmpegdemux.c
--- gst/mpegstream/gstmpegdemux.c	28 Jul 2003 14:56:01 -0000	1.39
+++ gst/mpegstream/gstmpegdemux.c	30 Sep 2003 14:13:13 -0000
@@ -1235,10 +1235,6 @@
 {
   GstElementFactory *factory;
 
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   /* create an elementfactory for the mpeg_demux element */
   factory = gst_element_factory_new ("mpegdemux", GST_TYPE_MPEG_DEMUX,
                                      &mpeg_demux_details);
Index: gst/mpegstream/gstmpegpacketize.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstmpegpacketize.h,v
retrieving revision 1.7
diff -u -r1.7 gstmpegpacketize.h
--- gst/mpegstream/gstmpegpacketize.h	26 May 2002 21:59:22 -0000	1.7
+++ gst/mpegstream/gstmpegpacketize.h	30 Sep 2003 14:13:13 -0000
@@ -24,7 +24,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 
 #ifdef __cplusplus
Index: gst/mpegstream/gstmpegparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstmpegparse.c,v
retrieving revision 1.42
diff -u -r1.42 gstmpegparse.c
--- gst/mpegstream/gstmpegparse.c	16 Sep 2003 09:59:59 -0000	1.42
+++ gst/mpegstream/gstmpegparse.c	30 Sep 2003 14:13:13 -0000
@@ -915,10 +915,6 @@
 {
   GstElementFactory *factory;
 
-  /* this filter needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   /* create an elementfactory for the mpeg_parse element */
   factory = gst_element_factory_new ("mpegparse", GST_TYPE_MPEG_PARSE,
                                      &mpeg_parse_details);
Index: gst/mpegstream/gstmpegparse.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstmpegparse.h,v
retrieving revision 1.14
diff -u -r1.14 gstmpegparse.h
--- gst/mpegstream/gstmpegparse.h	19 Jan 2003 13:42:43 -0000	1.14
+++ gst/mpegstream/gstmpegparse.h	30 Sep 2003 14:13:13 -0000
@@ -22,7 +22,7 @@
 #define __MPEG_PARSE_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include "gstmpegpacketize.h"
 
 #ifdef __cplusplus
Index: gst/mpegstream/gstmpegstream.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstmpegstream.c,v
retrieving revision 1.6
diff -u -r1.6 gstmpegstream.c
--- gst/mpegstream/gstmpegstream.c	9 Sep 2002 23:24:29 -0000	1.6
+++ gst/mpegstream/gstmpegstream.c	30 Sep 2003 14:13:13 -0000
@@ -25,10 +25,6 @@
 static gboolean
 plugin_init (GModule *module, GstPlugin *plugin)
 {
-  /* mpegdemux needs the bytestream package */
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
-
   /* short-circuit here; this is potentially dangerous since if the second
    * or third init fails then the whole plug-in will be placed on the register
    * stack again and the first _init will be called more than once
Index: gst/mpegstream/gstrfc2250enc.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstrfc2250enc.c,v
retrieving revision 1.11
diff -u -r1.11 gstrfc2250enc.c
--- gst/mpegstream/gstrfc2250enc.c	29 Jun 2003 19:45:47 -0000	1.11
+++ gst/mpegstream/gstrfc2250enc.c	30 Sep 2003 14:13:13 -0000
@@ -328,10 +328,6 @@
 {
   GstElementFactory *factory;
 
-  /* this filter needs the bytestream package */
-  if (!gst_library_load("gstbytestream"))
-    return FALSE;
-
   /* create an elementfactory for the rfc2250_enc element */
   factory = gst_element_factory_new ("rfc2250enc", GST_TYPE_RFC2250_ENC,
                                      &rfc2250_enc_details);
Index: gst/mpegstream/gstrfc2250enc.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegstream/gstrfc2250enc.h,v
retrieving revision 1.2
diff -u -r1.2 gstrfc2250enc.h
--- gst/mpegstream/gstrfc2250enc.h	20 Mar 2002 21:44:57 -0000	1.2
+++ gst/mpegstream/gstrfc2250enc.h	30 Sep 2003 14:13:13 -0000
@@ -24,7 +24,7 @@
 
 #include <config.h>
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 #include "gstmpegpacketize.h"
 
 
Index: gst/mpegtypes/Makefile.am
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/mpegtypes/Makefile.am,v
retrieving revision 1.9
diff -u -r1.9 Makefile.am
--- gst/mpegtypes/Makefile.am	11 Sep 2003 19:57:58 -0000	1.9
+++ gst/mpegtypes/Makefile.am	30 Sep 2003 14:13:13 -0000
@@ -1,12 +1,7 @@
 
-plugin_LTLIBRARIES = libgstmpeg2types.la libgstmpeg1types.la
+plugin_LTLIBRARIES = libgstmpegtypes.la
 
-libgstmpeg2types_la_SOURCES = gstmpeg2types.c
-libgstmpeg2types_la_CFLAGS = $(GST_CFLAGS)
-libgstmpeg2types_la_LIBADD =
-libgstmpeg2types_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-
-libgstmpeg1types_la_SOURCES = gstmpeg1types.c
-libgstmpeg1types_la_CFLAGS = $(GST_CFLAGS)
-libgstmpeg1types_la_LIBADD =
-libgstmpeg1types_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstmpegtypes_la_SOURCES = gstmpegtypes.c
+libgstmpegtypes_la_CFLAGS = $(GST_CFLAGS)
+libgstmpegtypes_la_LIBADD =
+libgstmpegtypes_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
Index: gst/qtdemux/qtdemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/qtdemux/qtdemux.c,v
retrieving revision 1.21
diff -u -r1.21 qtdemux.c
--- gst/qtdemux/qtdemux.c	19 Jul 2003 23:47:41 -0000	1.21
+++ gst/qtdemux/qtdemux.c	30 Sep 2003 14:13:14 -0000
@@ -104,7 +104,7 @@
   "(C) 2003",
 };
 
-static GstCaps* quicktime_type_find (GstBuffer *buf, gpointer private);
+static GstCaps* quicktime_type_find (GstByteStream *bs, gpointer private);
 
 static GstTypeDefinition quicktimedefinition = {
   "qtdemux_video/quicktime",
@@ -187,24 +187,29 @@
 }
 
 static GstCaps*
-quicktime_type_find (GstBuffer *buf, gpointer private)
+quicktime_type_find (GstByteStream *bs, gpointer private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
-  g_return_val_if_fail (data != NULL, NULL);
-  
-  if(GST_BUFFER_SIZE(buf) < 8){
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 8) == 8) {
+    gchar *data = GST_BUFFER_DATA (buf);
+
+    if (!strncmp (&data[4], "wide", 4) ||
+        !strncmp (&data[4], "moov", 4) ||
+        !strncmp (&data[4], "mdat", 4) ||
+        !strncmp (&data[4], "free", 4)) {
+      new = GST_CAPS_NEW ("quicktime_type_find",
+			  "video/quicktime",
+			    NULL);
+    }
   }
-  if (strncmp (&data[4], "wide", 4)==0 ||
-      strncmp (&data[4], "moov", 4)==0 ||
-      strncmp (&data[4], "mdat", 4)==0 ||
-      strncmp (&data[4], "free", 4)==0) {
-    return gst_caps_new ("quicktime_type_find",
-		         "video/quicktime", 
-			 NULL);
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
   }
-  return NULL;
+
+  return new;
 }
 
 static gboolean
@@ -221,9 +226,6 @@
     0,
   };
   gint i;
-
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   factory = gst_element_factory_new ("qtdemux", GST_TYPE_QTDEMUX,
                                      &gst_qtdemux_details);
Index: gst/qtdemux/qtdemux.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/qtdemux/qtdemux.h,v
retrieving revision 1.3
diff -u -r1.3 qtdemux.h
--- gst/qtdemux/qtdemux.h	16 Jun 2003 17:39:26 -0000	1.3
+++ gst/qtdemux/qtdemux.h	30 Sep 2003 14:13:14 -0000
@@ -22,7 +22,7 @@
 #define __GST_QTDEMUX_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #ifdef __cplusplus
 extern "C" {
Index: gst/realmedia/rmdemux.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/realmedia/rmdemux.c,v
retrieving revision 1.5
diff -u -r1.5 rmdemux.c
--- gst/realmedia/rmdemux.c	24 Jul 2003 08:49:44 -0000	1.5
+++ gst/realmedia/rmdemux.c	30 Sep 2003 14:13:14 -0000
@@ -87,7 +87,7 @@
   "(C) 2003",
 };
 
-static GstCaps* realmedia_type_find (GstBuffer *buf, gpointer private);
+static GstCaps* realmedia_type_find (GstByteStream *bs, gpointer private);
 
 static GstTypeDefinition realmediadefinition = {
   "rmdemux_video/realmedia",
@@ -195,21 +195,26 @@
 }
 
 static GstCaps*
-realmedia_type_find (GstBuffer *buf, gpointer private)
+realmedia_type_find (GstByteStream *bs, gpointer private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
 
-  g_return_val_if_fail (data != NULL, NULL);
-  
-  if(GST_BUFFER_SIZE(buf) < 4){
-    return NULL;
+  if (gst_bytestream_peek (bs, &buf, 4) == 4) {
+    gchar *data = GST_BUFFER_DATA (buf);
+
+    if (!strncmp (data, ".RMF", 4)) {
+      new = GST_CAPS_NEW ("realmedia_type_find",
+			  "application/vnd.rn-realmedia", 
+			    NULL);
+    }
   }
-  if (strncmp (data, ".RMF", 4)==0) {
-    return gst_caps_new ("realmedia_type_find",
-		         "application/vnd.rn-realmedia", 
-			 NULL);
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
   }
-  return NULL;
+
+  return new;
 }
 
 static gboolean
@@ -217,9 +222,6 @@
 {
   GstElementFactory *factory;
   GstTypeFactory *type;
-
-  if (!gst_library_load ("gstbytestream"))
-    return FALSE;
 
   factory = gst_element_factory_new ("rmdemux", GST_TYPE_RMDEMUX,
                                      &gst_rmdemux_details);
Index: gst/realmedia/rmdemux.h
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/realmedia/rmdemux.h,v
retrieving revision 1.2
diff -u -r1.2 rmdemux.h
--- gst/realmedia/rmdemux.h	24 Jun 2003 08:05:12 -0000	1.2
+++ gst/realmedia/rmdemux.h	30 Sep 2003 14:13:14 -0000
@@ -22,7 +22,7 @@
 #define __GST_RMDEMUX_H__
 
 #include <gst/gst.h>
-#include <gst/bytestream/bytestream.h>
+#include <gst/gstbytestream.h>
 
 #ifdef __cplusplus
 extern "C" {
Index: gst/wavparse/gstwavparse.c
===================================================================
RCS file: /cvsroot/gstreamer/gst-plugins/gst/wavparse/gstwavparse.c,v
retrieving revision 1.34
diff -u -r1.34 gstwavparse.c
--- gst/wavparse/gstwavparse.c	16 Sep 2003 10:00:01 -0000	1.34
+++ gst/wavparse/gstwavparse.c	30 Sep 2003 14:13:16 -0000
@@ -31,7 +31,8 @@
 static GstElementStateReturn
 			gst_wavparse_change_state 	(GstElement *element);
 
-static GstCaps*		wav_type_find			(GstBuffer *buf, gpointer private);
+static GstCaps*		wav_type_find			(GstByteStream *bs,
+							 gpointer private);
 
 static const GstFormat*	gst_wavparse_get_formats	(GstPad *pad);
 static const GstQueryType *
@@ -213,15 +214,27 @@
 }
 
 static GstCaps*
-wav_type_find (GstBuffer *buf, gpointer private)
+wav_type_find (GstByteStream *bs, gpointer private)
 {
-  gchar *data = GST_BUFFER_DATA (buf);
+  GstCaps *new = NULL;
+  GstBuffer *buf = NULL;
 
-  if (GST_BUFFER_SIZE (buf) < 12) return NULL;
-  if (strncmp (&data[0], "RIFF", 4)) return NULL;
-  if (strncmp (&data[8], "WAVE", 4)) return NULL;
+  if (gst_bytestream_peek (bs, &buf, 12) == 12) {
+    gchar *data = GST_BUFFER_DATA (buf);
 
-  return gst_caps_new ("wav_type_find", "audio/x-wav", NULL);
+    if (!strncmp (&data[0], "RIFF", 4) &&
+        !strncmp (&data[8], "WAVE", 4)) {
+      new = GST_CAPS_NEW ("wav_type_find",
+			  "audio/x-wav",
+			    NULL);
+    }
+  }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
 }
 
 static void wav_new_chunk_callback(GstRiffChunk *chunk, gpointer data)
--- /dev/null	2003-01-30 11:24:37.000000000 +0100
+++ gst/id3/Makefile.am	2003-09-30 08:14:41.000000000 +0200
@@ -0,0 +1,12 @@
+plugin_LTLIBRARIES = libgstid3types.la
+
+libgstid3types_la_SOURCES = gstid3types.c
+libgstid3types_la_CFLAGS = $(GST_CFLAGS)
+if USE_MAD
+libgstid3types_la_LIBADD = -lid3tag
+else
+libgstid3types_la_LIBADD =
+endif
+libgstid3types_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+
+noinst_HEADERS = gstid3types.h
--- /dev/null	2003-01-30 11:24:37.000000000 +0100
+++ gst/id3/gstid3types.c	2003-09-30 08:16:29.000000000 +0200
@@ -0,0 +1,737 @@
+/* GStreamer
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_MAD
+#include <id3tag.h>
+#endif
+
+#include <string.h>
+#include "gstid3types.h"
+
+/* elementfactory information */
+static GstElementDetails id3types_details = {
+  "ID3v1/v2 tag parser",
+  "Codec/Parser",
+#ifdef HAVE_MAD
+  "GPL", /* grmbl, where's a good C LGPL ID3v1/2 reader? */
+#else
+  "LGPL",
+#endif
+  "Parses ID3v1 and ID3v2 tags",
+  VERSION,
+  "Erik Walthinsen <omega@cse.ogi.edu>\n"
+  "Ronald Bultje <rbultje@ronald.bitfreak.net>",
+  "(C) 1999-2003",
+};
+
+GST_PAD_TEMPLATE_FACTORY (sink_templ,
+  "sink",
+  GST_PAD_SINK,
+  GST_PAD_ALWAYS,
+  GST_CAPS_NEW (
+    "id3types_sink",
+    "audio/x-id3",
+      "id3version", GST_PROPS_INT_RANGE (1, 2)
+  )
+);
+
+GST_PAD_TEMPLATE_FACTORY (src_templ,
+  "src",
+  GST_PAD_SRC,
+  GST_PAD_SOMETIMES,
+  NULL
+);
+
+static GstCaps* id3_type_find (GstByteStream *bs, gpointer private);
+
+static GstTypeDefinition id3type_definition = {
+  "id3_audio/x-id3",
+  "audio/x-id3",
+  ".mp3 .mp2 .mp1 .mpga .ogg .flac", /* probably more... *sigh* */
+  id3_type_find,
+};
+
+/* signals */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL,
+};
+
+/* args */
+enum {
+  ARG_0,
+  ARG_METADATA,
+  /* FILL ME */
+};
+
+
+static void	gst_id3types_class_init		(GstID3TypesClass *klass);
+static void	gst_id3types_init		(GstID3Types  *mp3parse);
+
+static const GstEventMask *
+		gst_id3types_event_mask		(GstPad       *pad);
+static gboolean	gst_id3types_event		(GstPad       *pad,
+						 GstEvent     *event);
+
+static const GstQueryType *
+		gst_id3types_get_query_types	(GstPad       *pad);
+static gboolean gst_id3types_handle_query 	(GstPad       *pad,
+						 GstQueryType  type, 
+						 GstFormat    *format,
+						 gint64       *value);
+
+static void	gst_id3types_chain		(GstPad       *pad,
+						 GstBuffer    *buf);
+static void	gst_id3types_loop		(GstElement   *element);
+
+static void	gst_id3types_get_property	(GObject      *object,
+						 guint         prop_id,
+						 GValue       *value,
+						 GParamSpec   *pspec);
+static GstElementStateReturn
+		gst_id3types_change_state	(GstElement   *element);
+
+static GstElementClass *parent_class = NULL;
+/*static guint gst_id3types_signals[LAST_SIGNAL] = { 0 };*/
+
+GType
+gst_id3types_get_type (void)
+{
+  static GType id3types_type = 0;
+
+  if (!id3types_type) {
+    static const GTypeInfo id3types_info = {
+      sizeof (GstID3TypesClass),
+      NULL,
+      NULL,
+      (GClassInitFunc) gst_id3types_class_init,
+      NULL,
+      NULL,
+      sizeof (GstID3Types),
+      0,
+      (GInstanceInitFunc) gst_id3types_init,
+    };
+
+    id3types_type = g_type_register_static (GST_TYPE_ELEMENT,
+					    "GstID3Types",
+					    &id3types_info, 0);
+  }
+
+  return id3types_type;
+}
+
+static gboolean
+gst_id3types_detect (GstByteStream *bs,
+		     guint         *version,
+		     guint         *size)
+{
+  gboolean res = FALSE;
+  GstBuffer *buf = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 10) == 10) {
+    guint8 *data = GST_BUFFER_DATA (buf);
+
+    /* gracefully ripped from libid3 */
+    if (data[0] == 'T' && data[1] == 'A' && data[2] == 'G') {
+      /* ID3v1 tags */
+      res = TRUE;
+      if (size)
+        *size = 128;
+      if (version)
+        *version = 1;
+    } else if (data[0] == 'I' && data[1] == 'D' && data[2] == '3') {
+      /* ID3v2 tags */
+      if (data[3] < 0xff && data[4] < 0xff &&
+	  data[6] < 0x80 && data[7] < 0x80 &&
+	  data[8] < 0x80 && data[9] < 0x80) {
+        guint32 skip = ((data[6] & 0x7f) << 21) |
+		       ((data[7] & 0x7f) << 14) |
+		       ((data[8] & 0x7f) << 7) |
+		       ((data[9] & 0x7f) << 0);
+
+        /* include size of header */
+        skip += 10;
+
+        /* footer present? (only available since version 4) */
+        if (data[3] >= 4 && (data[5] & 0x10))
+          skip += 10;
+
+        res = TRUE;
+        if (size)
+          *size = skip;
+        if (version)
+          *version = 2;
+      }
+    }
+  }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return res;
+}
+
+static GstCaps *
+id3_type_find (GstByteStream *bs,
+	       gpointer       private) 
+{
+  GstCaps *new = NULL;
+  guint version, size;
+
+  if (gst_id3types_detect (bs, &version, &size)) {
+    switch (version) {
+      case 1: case 2:
+        /* ID3v1/v2 tags */
+        GST_DEBUG ("id3typefind: detected ID3 Tag V%d", version);
+        new = GST_CAPS_NEW ("id3_type_find",
+			    "audio/x-id3",
+			      "id3version", GST_PROPS_INT (version));
+        break;
+      default:
+        break;
+    }
+  }
+
+  return new;
+}
+
+static void
+gst_id3types_class_init (GstID3TypesClass *klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) klass;
+
+  g_object_class_install_property (gobject_class, ARG_METADATA,
+    g_param_spec_boxed ("metadata", "Metadata", "Metadata",
+                        GST_TYPE_CAPS, G_PARAM_READABLE));
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  gobject_class->get_property = gst_id3types_get_property;
+
+  gstelement_class->change_state = gst_id3types_change_state;
+}
+
+static inline void
+gst_id3types_start (GstID3Types *id3)
+{
+  id3->pass_through = FALSE;
+  id3->id3_tag_size = 0;
+  id3->metadata = NULL;
+}
+
+static inline void
+gst_id3types_cont (GstID3Types *id3)
+{
+  id3->pass_through = TRUE;
+}
+
+static inline void
+gst_id3types_stop (GstID3Types *id3)
+{
+  gst_caps_replace (&id3->metadata, NULL);
+  id3->pass_through = TRUE;
+}
+
+static void
+gst_id3types_init (GstID3Types *id3)
+{
+  GST_FLAG_SET (id3, GST_ELEMENT_EVENT_AWARE);
+
+  id3->sinkpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (sink_templ),
+					    "sink");
+  gst_element_set_loop_function (GST_ELEMENT (id3), gst_id3types_loop);
+  gst_pad_set_event_function (id3->sinkpad, gst_id3types_event);
+  gst_pad_set_event_mask_function (id3->sinkpad, gst_id3types_event_mask);
+  gst_id3types_start (id3);
+  gst_element_add_pad (GST_ELEMENT (id3), id3->sinkpad);
+
+  id3->metadata = NULL;
+  id3->id3_tag_size = 0;
+}
+
+static const GstEventMask *
+gst_id3types_event_mask (GstPad *pad)
+{
+  GstID3Types *id3 = GST_ID3TYPES (gst_pad_get_parent (pad));
+  const GstEventMask *masks = NULL;
+
+  if (pad == id3->sinkpad) {
+    static const GstEventMask my_masks[] = {
+      { GST_EVENT_DISCONTINUOUS, 0 },
+      { 0, }
+    };
+    masks = my_masks;
+  } else if (pad == id3->srcpad) {
+    static const GstEventMask my_masks[] = {
+      { GST_EVENT_SEEK, GST_SEEK_METHOD_SET },
+      { 0, }
+    };
+    masks = my_masks;
+  } else {
+    g_assert (0);
+  }
+
+  return masks;
+}
+
+static gboolean
+gst_id3types_event (GstPad   *pad,
+		    GstEvent *event)
+{
+  GstID3Types *id3 = GST_ID3TYPES (gst_pad_get_parent (pad));
+  gboolean res = TRUE;
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_DISCONTINUOUS: {
+      /* comes from the sink pad */
+      GstEvent *new = NULL;
+      guint64 offset = 0;
+      gint n;
+
+      /* get new offset in bytes */
+      for (n = 0; n < GST_EVENT_DISCONT_OFFSET_LEN (event); n++) {
+        GstFormatValue *value = &GST_EVENT_DISCONT_OFFSET (event, n);
+        if (value->format == GST_FORMAT_BYTES) {
+          offset = value->value;
+          break;
+        }
+      }
+
+      if (GST_EVENT_DISCONT_NEW_MEDIA (event) ||
+	  offset < id3->id3_tag_size) {
+        gst_id3types_stop (id3);
+        gst_id3types_start (id3);
+        new = gst_event_new_discontinuous (GST_EVENT_DISCONT_NEW_MEDIA (event),
+					   GST_FORMAT_BYTES, 0, 0);
+      } else {
+        gst_id3types_cont (id3);
+        new = gst_event_new_discontinuous (FALSE, GST_FORMAT_BYTES,
+					   offset - id3->id3_tag_size, 0);
+      }
+      gst_pad_event_default (pad, new);
+      break;
+    }
+    case GST_EVENT_SEEK:
+      /* comes from the src pad... */
+      switch (GST_EVENT_SEEK_FORMAT (event)) {
+        case GST_FORMAT_BYTES: {
+          gint64 offset = GST_EVENT_SEEK_OFFSET (event);
+          GstEvent *new = gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES,
+					      offset + id3->id3_tag_size);
+
+          gst_pad_send_event (GST_PAD_PEER (id3->sinkpad), new);
+          break;
+        }
+        default:
+          g_warning ("Non-bytes seek event in id3types");
+          res = FALSE;
+          break;
+      }
+      break;
+    default:
+      res = FALSE;
+      break;
+  }
+
+  gst_event_unref (event);
+
+  return res;
+}
+
+static const GstQueryType *
+gst_id3types_get_query_types (GstPad *pad)
+{
+  static const GstQueryType types[] = {
+    GST_QUERY_TOTAL,
+    GST_QUERY_POSITION,
+    0
+  };
+
+  return types;
+}
+
+static gboolean
+gst_id3types_handle_query (GstPad       *pad,
+			   GstQueryType  type, 
+			   GstFormat    *format,
+			   gint64       *value)
+{
+  GstID3Types *id3 = GST_ID3TYPES (gst_pad_get_parent (pad));
+
+  g_return_val_if_fail (type == GST_QUERY_TOTAL ||
+			type == GST_QUERY_POSITION, FALSE);
+
+  if (*format == GST_FORMAT_BYTES) {
+    gst_pad_query (id3->sinkpad, type, format, value);
+
+    if (*value >= id3->id3_tag_size)
+      *value -= id3->id3_tag_size;
+    else
+      *value = 0;
+
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+static void
+gst_id3types_chain (GstPad    *pad,
+		    GstBuffer *buf)
+{
+  GstID3Types *id3 = GST_ID3TYPES (gst_pad_get_parent (pad));
+
+  if (GST_IS_EVENT (buf)) {
+    gst_id3types_event (id3->sinkpad, GST_EVENT (buf));
+  } else {
+    /* passthrough mode */
+    gst_pad_push (id3->srcpad, buf);
+  }
+}
+
+#ifdef HAVE_MAD
+/* gracefuly ripped from madplay */
+static GstCaps *
+id3_to_caps (struct id3_tag const *tag)
+{
+  unsigned int i;
+  struct id3_frame const *frame;
+  id3_ucs4_t const *ucs4;
+  id3_utf8_t *utf8;
+  GstProps *props;
+  GstPropsEntry *entry;
+  GstCaps *caps;
+  GList *values;
+
+  struct {
+    char const *id;
+    char const *name;
+  } const info[] = {
+    { ID3_FRAME_TITLE,   "Title"        },
+    { "TIT3",            "Subtitle"     },
+    { "TCOP",            "Copyright"    },
+    { "TPRO",            "Produced"     },
+    { "TCOM",            "Composer"     },
+    { ID3_FRAME_ARTIST,  "Artist"       },
+    { "TPE2",            "Orchestra"    },
+    { "TPE3",            "Conductor"    },
+    { "TEXT",            "Lyricist"     },
+    { ID3_FRAME_ALBUM,   "Album"        },
+    { ID3_FRAME_YEAR,    "Year"         },
+    { ID3_FRAME_TRACK,   "Track"        },
+    { "TPUB",            "Publisher"    },
+    { ID3_FRAME_GENRE,   "Genre"        },
+    { "TRSN",            "Station"      },
+    { "TENC",            "Encoder"      },
+  };
+
+  /* text information */
+  props = gst_props_empty_new ();
+
+  for (i = 0; i < sizeof(info) / sizeof(info[0]); ++i) {
+    union id3_field const *field;
+    unsigned int nstrings, namelen, j;
+    char const *name;
+
+    frame = id3_tag_findframe(tag, info[i].id, 0);
+    if (frame == 0)
+      continue;
+
+    field    = &frame->fields[1];
+    nstrings = id3_field_getnstrings(field);
+
+    name = info[i].name;
+
+    if (name) {
+      namelen = name ? strlen(name) : 0;
+
+      values = NULL;
+      for (j = 0; j < nstrings; ++j) {
+        ucs4 = id3_field_getstrings(field, j);
+        g_assert(ucs4);
+
+        if (strcmp(info[i].id, ID3_FRAME_GENRE) == 0)
+	  ucs4 = id3_genre_name(ucs4);
+
+        utf8 = id3_ucs4_utf8duplicate(ucs4);
+        if (utf8 == 0)
+	  goto fail;
+
+        entry = gst_props_entry_new (name, GST_PROPS_STRING_TYPE, utf8);
+	values = g_list_prepend (values, entry);
+        free(utf8);
+      }
+      if (values) {
+        values = g_list_reverse (values);
+
+        if (g_list_length (values) == 1) {
+          gst_props_add_entry (props, (GstPropsEntry *) values->data);
+        }
+        else {
+          entry = gst_props_entry_new(name, GST_PROPS_GLIST_TYPE, values);
+          gst_props_add_entry (props, (GstPropsEntry *) entry);
+        }
+        g_list_free (values);
+      }
+    }
+  }
+
+  values = NULL;
+  i = 0;
+  while ((frame = id3_tag_findframe(tag, ID3_FRAME_COMMENT, i++))) {
+    ucs4 = id3_field_getstring(&frame->fields[2]);
+    g_assert(ucs4);
+
+    if (*ucs4)
+      continue;
+
+    ucs4 = id3_field_getfullstring(&frame->fields[3]);
+    g_assert(ucs4);
+
+    utf8 = id3_ucs4_utf8duplicate(ucs4);
+    if (utf8 == 0)
+      goto fail;
+
+    entry = gst_props_entry_new ("Comment", GST_PROPS_STRING_TYPE, utf8);
+    values = g_list_prepend (values, entry);
+    free(utf8);
+  }
+  if (values) {
+    values = g_list_reverse (values);
+
+    if (g_list_length (values) == 1) {
+      gst_props_add_entry (props, (GstPropsEntry *) values->data);
+    }
+    else {
+      entry = gst_props_entry_new("Comment", GST_PROPS_GLIST_TYPE, values);
+      gst_props_add_entry (props, (GstPropsEntry *) entry);
+    }
+    g_list_free (values);
+  }
+
+  gst_props_debug (props);
+
+  caps = gst_caps_new ("mad_metadata",
+		       "application/x-gst-metadata",
+		       props);
+  if (0) {
+fail:
+    g_warning ("mad: could not parse ID3 tag");
+
+    return NULL;
+  }
+
+  return caps;
+}
+#endif
+
+static void
+gst_id3types_loop (GstElement *element)
+{
+  const GList *type_list = gst_type_get_list ();
+  GstID3Types *id3;
+  GstByteStream *bs;
+  GstBuffer *buf = NULL;
+  guint size = 0, version = 0;
+#ifdef HAVE_MAD
+  struct id3_tag *tag = NULL;
+#endif
+
+  g_return_if_fail (GST_IS_ID3TYPES (element));
+  id3 = GST_ID3TYPES (element);
+
+  if (id3->pass_through) {
+    gst_id3types_chain (id3->sinkpad, gst_pad_pull (id3->sinkpad));
+    return;
+  }
+
+  bs = gst_bytestream_new (id3->sinkpad);
+
+  /* first loop... */
+  if (!gst_id3types_detect (bs, &version, &size)) {
+    gst_element_error (element,
+		       "No ID3 tag detected");
+    goto error;
+  }
+
+  /* OK: so we've now got a ID3 tag of that size, let's read it */
+  if (gst_bytestream_peek (bs, &buf, size) != size) {
+    gst_element_error (element,
+		       "Failed to read ID3 tag - hard disk on fire?");
+    goto error;
+  }
+  gst_bytestream_flush (bs, size);
+
+#ifdef HAVE_MAD
+  /* here, we should parse the ID3 header and notify the app */
+  if (!(tag = id3_tag_parse (GST_BUFFER_DATA (buf), size))) {
+    gst_element_error (element,
+		       "Failed to parse ID3v1/2 tags");
+    goto error;
+  } else {
+    gst_caps_replace_sink (&id3->metadata, id3_to_caps (tag));
+    id3_tag_delete (tag);
+    g_object_notify (G_OBJECT (id3), "metadata");
+  }
+#endif
+
+  /* done */
+  id3->id3_tag_size = size;
+
+  /* this will help us detecting the media stream type after
+   * this id3 thingy... Please note that this is a cruel hack
+   * for as long as spider doesn't support multi-type-finding.
+   */
+  while (type_list) {
+    GSList *factories;
+    GstType *type = (GstType *) type_list->data;
+
+    factories = type->factories;
+
+    while (factories) {
+      GstTypeFactory *factory = GST_TYPE_FACTORY (factories->data);
+      GstTypeFindFunc typefindfunc = (GstTypeFindFunc) factory->typefindfunc;
+      GstCaps *caps;
+
+      if (typefindfunc && (caps = typefindfunc (bs, factory))) {
+        GST_DEBUG ("found type: %d \"%s\" \"%s\"\n",
+		   caps->id, type->mime, gst_caps_get_name (caps));
+
+        id3->srcpad = gst_pad_new_from_template (GST_PAD_TEMPLATE_GET (src_templ),
+						 "src");
+        gst_pad_set_event_function (id3->srcpad, gst_id3types_event);
+        gst_pad_set_event_mask_function (id3->srcpad, gst_id3types_event_mask);
+        gst_pad_set_query_type_function (id3->srcpad, gst_id3types_get_query_types);
+        gst_pad_set_query_function (id3->srcpad, gst_id3types_handle_query);
+        gst_pad_try_set_caps (id3->srcpad, caps);
+        gst_element_add_pad (GST_ELEMENT (id3), id3->srcpad);
+        goto tf_done;
+      }
+      factories = g_slist_next (factories);
+    }
+    type_list = g_list_next (type_list);
+  }
+  gst_element_error (element,
+		     "Media stream type not detected after id3v1/2 header");
+  goto error;
+
+tf_done:
+  if (bs->listavail) {
+    gst_bytestream_read (bs, &buf, bs->listavail);
+    gst_pad_push (id3->srcpad, buf);
+  }
+  gst_id3types_cont (id3);
+error:
+#ifdef HAVE_MAD
+  if (tag) {
+    id3_tag_delete (tag);
+  }
+#endif
+  gst_bytestream_destroy (bs);
+}
+
+static void
+gst_id3types_get_property (GObject    *object,
+			   guint       prop_id,
+			   GValue     *value,
+			   GParamSpec *pspec)
+{
+  GstID3Types *id3;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_ID3TYPES (object));
+  id3 = GST_ID3TYPES (object);
+
+  switch (prop_id) {
+    case ARG_METADATA:
+      g_value_set_boxed (value, id3->metadata);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn 
+gst_id3types_change_state (GstElement *element) 
+{
+  GstID3Types *id3;
+
+  g_return_val_if_fail (GST_IS_ID3TYPES (element), GST_STATE_FAILURE);
+  id3 = GST_ID3TYPES (element);
+
+  switch (GST_STATE_TRANSITION (element)) {
+    case GST_STATE_READY_TO_PAUSED:
+      gst_id3types_start (id3);
+      break;
+    case GST_STATE_PAUSED_TO_READY:
+      gst_id3types_stop (id3);
+      break;
+    default:
+      break;
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+  GstTypeFactory *type;
+  GstElementFactory *factory;
+
+  /* create an elementfactory for the id3types element */
+  factory = gst_element_factory_new ("id3types",
+		                     GST_TYPE_ID3TYPES,
+                                     &id3types_details);
+  g_return_val_if_fail (factory != NULL, FALSE);
+  gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_PRIMARY);
+
+  gst_element_factory_add_pad_template (factory,
+	GST_PAD_TEMPLATE_GET (sink_templ));
+  gst_element_factory_add_pad_template (factory,
+	GST_PAD_TEMPLATE_GET (src_templ));
+
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  /* and typefinding */
+  type = gst_type_factory_new (&id3type_definition);
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
+
+  return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "id3types",
+  plugin_init
+};
--- /dev/null	2003-01-30 11:24:37.000000000 +0100
+++ gst/id3/gstid3types.h	2003-09-28 15:05:12.000000000 +0200
@@ -0,0 +1,60 @@
+/* GStreamer
+ * 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 __ID3TYPES_H__
+#define __ID3TYPES_H__
+
+#include <glib.h>
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_ID3TYPES \
+  (gst_id3types_get_type ())
+#define GST_ID3TYPES(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ID3TYPES, GstID3Types))
+#define GST_ID3TYPES_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ID3TYPES, GstID3Types))
+#define GST_IS_ID3TYPES(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_ID3TYPES))
+#define GST_IS_ID3TYPES_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_ID3TYPES))
+
+typedef struct _GstID3Types GstID3Types;
+typedef struct _GstID3TypesClass GstID3TypesClass;
+
+struct _GstID3Types {
+  GstElement element;
+
+  GstPad *sinkpad, *srcpad;
+
+  GstCaps *metadata;
+  guint id3_tag_size;
+  gboolean pass_through;
+};
+
+struct _GstID3TypesClass {
+  GstElementClass parent_class;
+};
+
+GType gst_id3types_get_type (void);
+
+G_END_DECLS
+
+#endif /* __ID3TYPES_H__ */
--- /dev/null	2003-01-30 11:24:37.000000000 +0100
+++ gst/mpegtypes/gstmpegtypes.c	2003-09-28 16:19:38.000000000 +0200
@@ -0,0 +1,104 @@
+/* GStreamer
+ * 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.
+ */
+
+/*#define DEBUG_ENABLED*/
+#include <gst/gst.h>
+
+static GstCaps* mpegsystem_type_find (GstByteStream *bs, gpointer private);
+#if 0
+static GstCaps* mpegvideo_type_find (GstByteStream *bs, gpointer private);
+#endif
+
+static GstTypeDefinition mpegtype_definitions[] = {
+  { "mpegtypes_video/mpeg;system", "video/mpeg",
+    ".mpg .mpeg .mpe", mpegsystem_type_find },
+#if 0
+  { "mpegtypes_video/mpeg", "video/mpeg",
+    ".mpg .mpeg .mpe", mpegvideo_type_find },
+#endif
+  { NULL, NULL, NULL, NULL },
+};
+
+static GstCaps *
+mpegsystem_type_find (GstByteStream *bs, gpointer private) 
+{
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 5) == 5) {
+    guint32 head1 = GUINT32_FROM_BE (*((guint32 *) GST_BUFFER_DATA (buf)));
+
+    if (head1 == 0x000001ba &&
+	(GST_BUFFER_DATA (buf)[4] & 0xC0) == 0x40) {
+      new = GST_CAPS_NEW ("mpegsystem_type_find",
+			  "video/mpeg",
+        	            "systemstream", GST_PROPS_BOOLEAN (TRUE));
+    }
+  }
+
+  if (buf != NULL) {
+    gst_buffer_unref (buf);
+  }
+
+  return new;
+}
+
+#if 0
+static GstCaps *
+mpegvideo_type_find (GstByteStream *bs, gpointer private) 
+{
+  GstBuffer *buf = NULL;
+  GstCaps *new = NULL;
+
+  if (gst_bytestream_peek (bs, &buf, 4) == 4) {
+    guint32 head = GUINT32_FROM_BE (*((guint32 *) GST_BUFFER_DATA (buf)));
+
+    if (head == 0x000001b3) {
+      new = GST_CAPS_NEW ("mpegvideo_type_find",
+			  "video/mpeg",
+			    "mpegversion",  GST_PROPS_INT (2 | 1), /* FIXME */
+			    "systemstream", GST_PROPS_BOOLEAN (FALSE));
+    }
+  }
+  return new;
+}
+#endif
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+  gint i=0;
+
+  while (mpegtype_definitions[i].name) {
+    GstTypeFactory *type;
+
+    type = gst_type_factory_new (&mpegtype_definitions[i]);
+    gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
+    i++;
+  }
+
+  return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "mpeg2types",
+  plugin_init
+};
