More ffmpeg wrapping going on here
authorWim Taymans <wim.taymans@gmail.com>
Mon, 25 Nov 2002 21:37:26 +0000 (21:37 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 25 Nov 2002 21:37:26 +0000 (21:37 +0000)
Original commit message from CVS:
More ffmpeg wrapping going on here

ext/ffmpeg/Makefile.am
ext/ffmpeg/gstffmpeg.c
ext/ffmpeg/gstffmpegcodecmap.c
ext/ffmpeg/gstffmpegdec.c
ext/ffmpeg/gstffmpegdemux.c
ext/ffmpeg/gstffmpegprotocol.c
ext/ffmpeg/gstffmpegtypes.c [new file with mode: 0644]

index a4df85c..133d3a3 100644 (file)
@@ -3,12 +3,13 @@ plugindir = $(libdir)/gst
 plugin_LTLIBRARIES = libgstffmpeg.la
 
 libgstffmpeg_la_SOURCES = gstffmpeg.c          \
-                         gstffmpegenc.c        \
+                         gstffmpegcodecmap.c   \
                          gstffmpegdec.c        \
                          gstffmpegdemux.c      \
+                         gstffmpegenc.c        \
                          gstffmpegmux.c        \
                          gstffmpegprotocol.c   \
-                         gstffmpegcodecmap.c
+                         gstffmpegtypes.c      
 
 libgstffmpeg_la_CFLAGS = $(GST_CFLAGS) -I/opt/src/sourceforge/ffmpeg/ -I/opt/src/sourceforge/ffmpeg/libavcodec/
 libgstffmpeg_la_LIBADD = 
index dde73cc..e9d04ec 100644 (file)
@@ -29,6 +29,9 @@
 extern gboolean gst_ffmpegdemux_register (GstPlugin *plugin);
 extern gboolean gst_ffmpegdec_register (GstPlugin *plugin);
 extern gboolean gst_ffmpegenc_register (GstPlugin *plugin);
+extern gboolean gst_ffmpegtypes_register (GstPlugin *plugin);
+       
+extern URLProtocol gstreamer_protocol;
 
 static gboolean
 plugin_init (GModule *module, GstPlugin *plugin)
@@ -43,6 +46,9 @@ plugin_init (GModule *module, GstPlugin *plugin)
   gst_ffmpegenc_register (plugin);
   gst_ffmpegdec_register (plugin);
   gst_ffmpegdemux_register (plugin);
+  gst_ffmpegtypes_register (plugin);
+
+  register_protocol (&gstreamer_protocol);
 
   /* Now we can return the pointer to the newly created Plugin object. */
   return TRUE;
index fa66f7f..13add65 100644 (file)
@@ -21,9 +21,9 @@
 #include <gst/gst.h>
 
 GstCaps *
-gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context)
+gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context, int codec_id)
 {
-  switch (context->codec_id) {
+  switch (codec_id) {
     case CODEC_ID_NONE:
       return GST_CAPS_NEW ("ffmpeg_none",
                           "unkown/unkown",
@@ -72,13 +72,24 @@ gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context)
                           NULL);
       break;
     case CODEC_ID_MPEG4:
-      return GST_CAPS_NEW ("ffmpeg_mpeg4",
-                          "video/avi",
-                            "format",  GST_PROPS_STRING ("strf_vids"),
-                             "fourcc",  GST_PROPS_FOURCC (context->fourcc),
-                             "width",   GST_PROPS_INT (context->width),
-                             "height",  GST_PROPS_INT (context->height)
-                         );
+      if (context) {
+        return GST_CAPS_NEW ("ffmpeg_mpeg4",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (context->fourcc),
+                               "width",   GST_PROPS_INT (context->width),
+                               "height",  GST_PROPS_INT (context->height)
+                           );
+      }
+      else {
+        return GST_CAPS_NEW ("ffmpeg_mpeg4",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("DIV3")),
+                               "width",   GST_PROPS_INT_RANGE (0, 4096),
+                               "height",  GST_PROPS_INT_RANGE (0, 4096)
+                           );
+      }
       break;
     case CODEC_ID_RAWVIDEO:
       return GST_CAPS_NEW ("ffmpeg_rawvideo",
@@ -86,40 +97,81 @@ gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context)
                           NULL);
       break;
     case CODEC_ID_MSMPEG4V1:
-      return GST_CAPS_NEW ("ffmpeg_msmpeg4v1",
-                          "video/avi",
-                            "format",  GST_PROPS_STRING ("strf_vids"),
-                             "fourcc",  GST_PROPS_FOURCC (context->fourcc),
-                             "width",   GST_PROPS_INT (context->width),
-                             "height",  GST_PROPS_INT (context->height)
-                         );
+      if (context) {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v1",
+                            "video/avi",
+                              "format",        GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("MPG4")),
+                               "width",        GST_PROPS_INT (context->width),
+                               "height",       GST_PROPS_INT (context->height)
+                           );
+      }
+      else {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v1",
+                            "video/avi",
+                              "format",        GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("MPG4")),
+                               "width",        GST_PROPS_INT_RANGE (0, 4096),
+                               "height",       GST_PROPS_INT_RANGE (0, 4096)
+                           );
+      }
       break;
     case CODEC_ID_MSMPEG4V2:
-      return GST_CAPS_NEW ("ffmpeg_msmpeg4v2",
-                          "video/avi",
-                            "format",  GST_PROPS_STRING ("strf_vids"),
-                             "fourcc",  GST_PROPS_FOURCC (context->fourcc),
-                             "width",   GST_PROPS_INT (context->width),
-                             "height",  GST_PROPS_INT (context->height)
-                         );
+      if (context) {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v2",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("MP42")),
+                               "width",   GST_PROPS_INT (context->width),
+                               "height",  GST_PROPS_INT (context->height)
+                           );
+      }
+      else {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v2",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("MP42")),
+                               "width",   GST_PROPS_INT_RANGE (0, 4096),
+                               "height",  GST_PROPS_INT_RANGE (0, 4096)
+                           );
+      }
       break;
     case CODEC_ID_MSMPEG4V3:
-      return GST_CAPS_NEW ("ffmpeg_msmpeg4v3",
-                          "video/avi",
-                            "format",  GST_PROPS_STRING ("strf_vids"),
-                             "fourcc",  GST_PROPS_FOURCC (context->fourcc),
-                             "width",   GST_PROPS_INT (context->width),
-                             "height",  GST_PROPS_INT (context->height)
-                         );
+      if (context) {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v3",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("DIV3")),
+                               "width",   GST_PROPS_INT (context->width),
+                               "height",  GST_PROPS_INT (context->height)
+                           );
+      }
+      else {
+        return GST_CAPS_NEW ("ffmpeg_msmpeg4v3",
+                            "video/avi",
+                              "format",  GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("DIV3")),
+                               "width",   GST_PROPS_INT_RANGE (0, 4096),
+                               "height",  GST_PROPS_INT_RANGE (0, 4096)
+                           );
+      }
       break;
     case CODEC_ID_WMV1:
-      return GST_CAPS_NEW ("ffmpeg_wmv1",
-                          "video/avi",
-                            "format",  GST_PROPS_STRING ("strf_vids"),
-                             "fourcc",  GST_PROPS_FOURCC (GST_STR_FOURCC ("WMV1")),
-                             "width",   GST_PROPS_INT (context->width),
-                             "height",  GST_PROPS_INT (context->height)
-                         );
+      if (context) {
+        return GST_CAPS_NEW ("ffmpeg_wmv1",
+                            "video/avi",
+                              "format",        GST_PROPS_STRING ("strf_vids"),
+                               "compression",  GST_PROPS_FOURCC (GST_STR_FOURCC ("WMV1")),
+                               "width",        GST_PROPS_INT (context->width),
+                               "height",       GST_PROPS_INT (context->height)
+                           );
+      }
+      else {
+        return GST_CAPS_NEW ("ffmpeg_wmv1",
+                            "video/x-wmv1",
+                            NULL
+                           );
+      }
       break;
     case CODEC_ID_WMV2:
       return GST_CAPS_NEW ("ffmpeg_wmv2",
@@ -229,7 +281,7 @@ gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context)
                           NULL);
       break;
     default:
-      g_warning ("no caps found for codec id %d\n", context->codec_id);
+      g_warning ("no caps found for codec id %d\n", codec_id);
       break;
   }
 
index d756f55..46b499d 100644 (file)
@@ -23,6 +23,9 @@
 
 #include <gst/gst.h>
 
+extern GstCaps*        gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *ctx, int id);
+
+       
 typedef struct _GstFFMpegDec GstFFMpegDec;
 
 struct _GstFFMpegDec {
@@ -42,8 +45,14 @@ struct _GstFFMpegDecClass {
   GstElementClass parent_class;
 
   AVCodec *in_plugin;
+  GstPadTemplate *templ;
 };
 
+typedef struct {
+  AVCodec *in_plugin;
+  GstPadTemplate *templ;
+} GstFFMpegClassParams;
+
 #define GST_TYPE_FFMPEGDEC \
   (gst_ffmpegdec_get_type())
 #define GST_FFMPEGDEC(obj) \
@@ -66,23 +75,6 @@ enum {
 };
 
 /* This factory is much simpler, and defines the source pad. */
-GST_PAD_TEMPLATE_FACTORY (gst_ffmpegdec_sink_factory,
-  "sink",
-  GST_PAD_SINK,
-  GST_PAD_ALWAYS,
-  GST_CAPS_NEW (
-    "ffmpegdec_sink",
-    "video/avi",
-      "format",                GST_PROPS_STRING ("strf_vids")
-  ),
-  GST_CAPS_NEW (
-    "ffmpegdec_sink",
-    "video/mpeg",
-    NULL
-  )
-)
-
-/* This factory is much simpler, and defines the source pad. */
 GST_PAD_TEMPLATE_FACTORY (gst_ffmpegdec_audio_src_factory,
   "src",
   GST_PAD_SRC,
@@ -140,15 +132,19 @@ gst_ffmpegdec_class_init (GstFFMpegDecClass *klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
+  GstFFMpegClassParams *params;
 
   gobject_class = (GObjectClass*)klass;
   gstelement_class = (GstElementClass*)klass;
 
   parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
 
-  klass->in_plugin = g_hash_table_lookup (global_plugins,
+  params = g_hash_table_lookup (global_plugins,
                  GINT_TO_POINTER (G_OBJECT_CLASS_TYPE (gobject_class)));
 
+  klass->in_plugin = params->in_plugin;
+  klass->templ = params->templ;
+
   gobject_class->set_property = gst_ffmpegdec_set_property;
   gobject_class->get_property = gst_ffmpegdec_get_property;
 }
@@ -168,7 +164,6 @@ gst_ffmpegdec_sinkconnect (GstPad *pad, GstCaps *caps)
     gst_caps_get_int (caps, "height", &ffmpegdec->context->height);
 
   ffmpegdec->context->pix_fmt = PIX_FMT_YUV420P;
-  ffmpegdec->context->frame_rate = 23 * FRAME_RATE_BASE;
   ffmpegdec->context->bit_rate = 0;
 
   /* FIXME bug in ffmpeg */
@@ -191,8 +186,7 @@ gst_ffmpegdec_init(GstFFMpegDec *ffmpegdec)
 
   ffmpegdec->context = g_malloc0 (sizeof (AVCodecContext));
 
-  ffmpegdec->sinkpad = gst_pad_new_from_template (
-                 GST_PAD_TEMPLATE_GET (gst_ffmpegdec_sink_factory), "sink");
+  ffmpegdec->sinkpad = gst_pad_new_from_template (oclass->templ, "sink");
   gst_pad_set_connect_function (ffmpegdec->sinkpad, gst_ffmpegdec_sinkconnect);
 
   if (oclass->in_plugin->type == CODEC_TYPE_VIDEO) {
@@ -367,6 +361,9 @@ gst_ffmpegdec_register (GstPlugin *plugin)
   while (in_plugin) {
     gchar *type_name;
     gchar *codec_type;
+    GstPadTemplate *sinktempl;
+    GstCaps *sinkcaps;
+    GstFFMpegClassParams *params;
 
     if (in_plugin->decode) {
       codec_type = "dec";
@@ -396,18 +393,23 @@ gst_ffmpegdec_register (GstPlugin *plugin)
     details->author = g_strdup("The FFMPEG crew, GStreamer plugin by Wim Taymans <wim.taymans@chello.be>");
     details->copyright = g_strdup("(c) 2001");
 
-    g_hash_table_insert (global_plugins, 
-                        GINT_TO_POINTER (type), 
-                        (gpointer) in_plugin);
-
     /* register the plugin with gstreamer */
     factory = gst_element_factory_new(type_name,type,details);
     g_return_val_if_fail(factory != NULL, FALSE);
 
     gst_element_factory_set_rank (factory, GST_ELEMENT_RANK_NONE);
 
-    gst_element_factory_add_pad_template (factory, 
-                   GST_PAD_TEMPLATE_GET (gst_ffmpegdec_sink_factory));
+    sinkcaps = gst_ffmpegcodec_codec_context_to_caps (NULL, in_plugin->id);
+    sinktempl = gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sinkcaps, NULL);
+    gst_element_factory_add_pad_template (factory, sinktempl);
+
+    params = g_new0 (GstFFMpegClassParams, 1);
+    params->in_plugin = in_plugin;
+    params->templ = sinktempl;
+
+    g_hash_table_insert (global_plugins, 
+                        GINT_TO_POINTER (type), 
+                        (gpointer) params);
 
     if (in_plugin->type == CODEC_TYPE_VIDEO) {
       gst_element_factory_add_pad_template (factory, 
index c066c2c..6a620a9 100644 (file)
 
 #include <gst/gst.h>
 
-extern URLProtocol gstreamer_protocol;
+extern GstCaps*        gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *context, int codec_id);
 
 typedef enum {
   STATE_OPEN,
-  STATE_STREAM_INFO,
   STATE_DEMUX,
-  STATE_END,
 } DemuxState;
 
 typedef struct _GstFFMpegDemux GstFFMpegDemux;
@@ -164,9 +162,6 @@ gst_ffmpegdemux_loop (GstElement *element)
                            0,
                            NULL);
 
-      /* this doesn't work */
-      av_set_pts_info (ffmpegdemux->context, 33, 1, 100000);
-
       ffmpegdemux->state = STATE_DEMUX;
       break;
     }
@@ -180,44 +175,53 @@ gst_ffmpegdemux_loop (GstElement *element)
       
       res = av_read_packet(ct, &pkt);
       if (res < 0) {
-       gint i;
+       if (url_feof (&ct->pb)) {
+         gint i;
 
-       for (i = 0; i < ct->nb_streams; i++) {
-          GstPad *pad;
+         for (i = 0; i < ct->nb_streams; i++) {
+            GstPad *pad;
 
-         pad = ffmpegdemux->srcpads[i];
+           pad = ffmpegdemux->srcpads[i];
 
-         if (GST_PAD_IS_USABLE (pad)) {
-           gst_pad_push (pad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
+           if (GST_PAD_IS_USABLE (pad)) {
+             gst_pad_push (pad, GST_BUFFER (gst_event_new (GST_EVENT_EOS)));
+           }
          }
+         gst_element_set_eos (element);
        }
-       gst_element_set_eos (element);
        return;
       }
 
       st = ct->streams[pkt.stream_index];
 
       if (st->codec_info_state == 0) {
-       gchar *padname = NULL;
-       GstPadTemplate *templ = NULL;
+       gchar *templname = NULL;
        
         st->codec_info_state = 1;
 
        if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
-         padname = g_strdup_printf ("video_%02d", pkt.stream_index);
-         templ = GST_PAD_TEMPLATE_GET (gst_ffmpegdemux_video_src_factory);
+         templname = "video_%02d";
        }
        else if (st->codec.codec_type == CODEC_TYPE_AUDIO) {
-         padname = g_strdup_printf ("audio_%02d", pkt.stream_index);
-         templ = GST_PAD_TEMPLATE_GET (gst_ffmpegdemux_audio_src_factory);
+         templname = "audio_%02d";
        }
 
-       if (padname != NULL) {
+       if (templname != NULL) {
+         gchar *padname;
+          GstCaps *caps;
+         GstPadTemplate *templ;
+
+         caps = gst_ffmpegcodec_codec_context_to_caps (&st->codec, st->codec.codec_id);
+         templ = gst_pad_template_new (templname,
+                                       GST_PAD_SRC,
+                                       GST_PAD_SOMETIMES,
+                                       caps, NULL);
+
+         padname = g_strdup_printf (templname, pkt.stream_index);
           pad = gst_pad_new_from_template (templ, padname);
 
          ffmpegdemux->srcpads[pkt.stream_index] = pad;
           gst_element_add_pad (GST_ELEMENT (ffmpegdemux), pad);
-         g_print ("new pad\n");
        }
        else {
           g_warning ("unkown pad type %d", st->codec.codec_type);
@@ -234,8 +238,9 @@ gst_ffmpegdemux_loop (GstElement *element)
         outbuf = gst_buffer_new ();
         GST_BUFFER_DATA (outbuf) = pkt.data;
         GST_BUFFER_SIZE (outbuf) = pkt.size;
-       if (pkt.pts != 0) {
-          GST_BUFFER_TIMESTAMP (outbuf) = pkt.pts * GST_SECOND / 90000LL;
+
+       if (pkt.pts != AV_NOPTS_VALUE && ct->pts_den) {
+          GST_BUFFER_TIMESTAMP (outbuf) = pkt.pts * GST_SECOND * ct->pts_num / ct->pts_den;
        }
        else {
           GST_BUFFER_TIMESTAMP (outbuf) = -1;
@@ -364,7 +369,5 @@ next:
     in_plugin = in_plugin->next;
   }
 
-  register_protocol (&gstreamer_protocol);
-
   return TRUE;
 }
index 21d3858..9d9cdb4 100644 (file)
@@ -28,10 +28,11 @@ typedef struct _GstProtocolInfo GstProtocolInfo;
 
 struct _GstProtocolInfo
 {
-  GstPad *pad;
+  GstPad       *pad;
 
-  int flags;
+  int           flags;
   GstByteStream *bs;
+  gboolean      eos;
 };
 
 static int 
@@ -54,6 +55,7 @@ gst_open (URLContext *h, const char *filename, int flags)
   }
 
   info->bs = gst_bytestream_new (pad);
+  info->eos = FALSE;
   
   h->priv_data = (void *) info;
 
@@ -71,10 +73,36 @@ gst_read (URLContext *h, unsigned char *buf, int size)
   info = (GstProtocolInfo *) h->priv_data;
   bs = info->bs;
 
+  if (info->eos) 
+    return 0;
+
   total = gst_bytestream_peek_bytes (bs, &data, size);
-  memcpy (buf, data, total);
 
-  gst_bytestream_flush_fast (bs, total);
+  if (total < size) {
+    GstEvent *event;
+    guint32 remaining;
+
+    gst_bytestream_get_status (bs, &remaining, &event);
+
+    if (!event) {
+      g_warning ("gstffmpegprotocol: no bytestream event");
+      return total;
+    }
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_DISCONTINUOUS:
+        gst_bytestream_flush_fast (bs, remaining);
+      case GST_EVENT_EOS:
+       info->eos = TRUE;
+       break;
+      default:
+        break;
+    }
+    gst_event_unref (event);
+  }
+  
+  memcpy (buf, data, total);
+  gst_bytestream_flush (bs, total);
 
   return total;
 }
diff --git a/ext/ffmpeg/gstffmpegtypes.c b/ext/ffmpeg/gstffmpegtypes.c
new file mode 100644 (file)
index 0000000..d201e18
--- /dev/null
@@ -0,0 +1,129 @@
+/* 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.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <libav/avformat.h>
+
+#include <gst/gst.h>
+
+static GHashTable *global_types = NULL;
+
+extern GstCaps*        gst_ffmpegcodec_codec_context_to_caps (AVCodecContext *ctx, int id);
+
+static GstCaps*
+gst_ffmpegtypes_typefind (GstBuffer *buffer, gpointer priv)
+{
+  AVInputFormat *in_plugin;
+  AVInputFormat *highest = NULL;
+  gint max = 0;
+  gint res = 0;
+  
+  in_plugin = first_iformat;
+
+  while (in_plugin) {
+    if (in_plugin->read_probe) {
+      AVProbeData probe_data;
+
+      probe_data.filename = "";
+      probe_data.buf = GST_BUFFER_DATA (buffer);
+      probe_data.buf_size = GST_BUFFER_SIZE (buffer);
+
+      res = in_plugin->read_probe (&probe_data);
+      if (res > max) {
+       max = res;
+       highest = in_plugin;
+      }
+    }
+    in_plugin = in_plugin->next;
+  }
+  if (highest) {
+    GstCaps *caps;
+    caps = g_hash_table_lookup (global_types, highest->name);
+    return caps;
+  }
+       
+  return NULL;
+}
+
+#define ADD_TYPE(key,caps) g_hash_table_insert (global_types, (key), (caps))
+
+static void
+register_standard_formats (void)
+{
+  global_types = g_hash_table_new (g_str_hash, g_str_equal);
+
+  ADD_TYPE ("avi",     GST_CAPS_NEW ("ffmpeg_type_avi",  "video/avi", NULL));
+  ADD_TYPE ("mpeg",    GST_CAPS_NEW ("ffmpeg_type_mpeg", "video/mpeg", 
+                                       "systemstream", GST_PROPS_BOOLEAN (TRUE)));
+  ADD_TYPE ("mpegts",  GST_CAPS_NEW ("ffmpeg_type_mpegts", "video/x-mpegts", 
+                                       "systemstream", GST_PROPS_BOOLEAN (TRUE)));
+  ADD_TYPE ("rm",      GST_CAPS_NEW ("ffmpeg_type_rm",  "audio/x-pn-realaudio", NULL));
+  ADD_TYPE ("asf",     GST_CAPS_NEW ("ffmpeg_type_asf", "video/x-ms-asf", NULL));
+  ADD_TYPE ("avi",     GST_CAPS_NEW ("ffmpeg_type_avi", "video/avi", 
+                                       "format", GST_PROPS_STRING ("AVI")));
+  ADD_TYPE ("mov",     GST_CAPS_NEW ("ffmpeg_type_mov", "video/quicktime", NULL));
+  ADD_TYPE ("swf",     GST_CAPS_NEW ("ffmpeg_type_swf", "application/x-shockwave-flash", NULL));
+  ADD_TYPE ("au",      GST_CAPS_NEW ("ffmpeg_type_au", "audio/basic", NULL));
+  ADD_TYPE ("mov",     GST_CAPS_NEW ("ffmpeg_type_mov", "video/quicktime", NULL));
+}
+       
+gboolean
+gst_ffmpegtypes_register (GstPlugin *plugin)
+{
+  AVInputFormat *in_plugin;
+  GstTypeFactory *factory;
+  GstTypeDefinition *definition;
+  
+  in_plugin = first_iformat;
+
+  while (in_plugin) {
+    gchar *type_name;
+    gchar *p;
+
+    if (!in_plugin->read_probe)
+      goto next;
+    
+    /* construct the type */
+    type_name = g_strdup_printf("fftype_%s", in_plugin->name);
+
+    p = type_name;
+
+    while (*p) {
+      if (*p == '.') *p = '_';
+      p++;
+    }
+
+    definition = g_new0 (GstTypeDefinition, 1);
+    definition->name = type_name;
+    definition->mime = type_name;
+    definition->exts = g_strdup (in_plugin->extensions);
+    definition->typefindfunc = gst_ffmpegtypes_typefind;
+
+    factory = gst_type_factory_new (definition);
+
+    /* The very last thing is to register the elementfactory with the plugin. */
+    gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+next:
+    in_plugin = in_plugin->next;
+  }
+  register_standard_formats ();
+
+  return TRUE;
+}