Index: gst/typefind/gsttypefindfunctions.c
===================================================================
RCS file: /cvs/gstreamer/gst-plugins/gst/typefind/gsttypefindfunctions.c,v
retrieving revision 1.68.2.6
diff -u -r1.68.2.6 gsttypefindfunctions.c
--- gst/typefind/gsttypefindfunctions.c	31 Mar 2005 10:48:54 -0000	1.68.2.6
+++ gst/typefind/gsttypefindfunctions.c	1 Apr 2005 16:22:53 -0000
@@ -603,6 +603,58 @@
   }
 }
 
+/*** wavpack *****************************************************************/
+static GstStaticCaps wavpack_caps = GST_STATIC_CAPS ("audio/x-wavpack");
+
+#define WAVPACK_CAPS (gst_static_caps_get(&wavpack_caps))
+
+static void
+wavpack_type_find (GstTypeFind * tf, gpointer unused)
+{
+  guint8 *data = gst_type_find_peek (tf, 0, 32);
+
+  if (!data)
+    return;
+
+  if (data[0] == 'w' && data[1] == 'v' && data[2] == 'p' && data[3] == 'k') {
+    guint32 blocksize, sublen;
+    gint32 left;
+
+    blocksize = GST_READ_UINT32_LE (data + 4);
+    /* peek from offset 0, otherwise it won't work with apedemux */
+    data = gst_type_find_peek (tf, 0, 32 + blocksize);
+    if (!data)
+      return;
+    data += 32;
+    left = (gint32) blocksize;
+    while (left > 2) {
+      sublen = ((guint32) data[1]) << 1;
+      if (data[0] & 0x80) {
+        sublen |= (((guint32) data[2]) << 9) | (((guint32) data[3]) << 17);
+        sublen += 1 + 3;        /* id + length */
+      } else {
+        sublen += 1 + 1;        /* id + length */
+      }
+      if (sublen > blocksize)
+        return;
+      if ((data[0] & 0x20) == 0) {
+        switch (data[0] & 0x0f) {
+          case 0xa:            /* ID_WV_BITSTREAM  */
+          case 0xc:            /* ID_WVX_BITSTREAM */
+            gst_type_find_suggest (tf, GST_TYPE_FIND_LIKELY, WAVPACK_CAPS);
+            return;
+          case 0xb:            /* ID_WVC_BITSTREAM (correction data, do not identify as wavpack) */
+            return;
+          default:
+            break;
+        }
+      }
+      left -= sublen;
+      data += sublen;
+    }
+  }
+}
+
 /*** video/mpeg systemstream **************************************************/
 
 static GstStaticCaps mpeg_sys_caps = GST_STATIC_CAPS ("video/mpeg, "
@@ -1759,6 +1811,7 @@
   static gchar *q3gp_exts[] = { "3gp", NULL };
   static gchar *aac_exts[] = { "aac", NULL };
   static gchar *spc_exts[] = { "spc", NULL };
+  static gchar *wavpack_exts[] = { "wv", "wvp", NULL };
 
   GST_DEBUG_CATEGORY_INIT (type_find_debug, "typefindfunctions",
       GST_DEBUG_FG_GREEN | GST_DEBUG_BG_RED, "generic type find functions");
@@ -1907,6 +1960,8 @@
       aac_type_find, aac_exts, AAC_CAPS, NULL);
   TYPE_FIND_REGISTER_START_WITH (plugin, "audio/x-spc", GST_RANK_SECONDARY,
       spc_exts, "SNES-SPC700 Sound File Data", 27, GST_TYPE_FIND_MAXIMUM);
+  TYPE_FIND_REGISTER (plugin, "audio/x-wavpack", GST_RANK_SECONDARY,
+      wavpack_type_find, wavpack_exts, WAVPACK_CAPS, NULL);
 
   return TRUE;
 }
