Index: gsttypefindhelper.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gsttypefindhelper.c,v
retrieving revision 1.12
diff -u -p -r1.12 gsttypefindhelper.c
--- gsttypefindhelper.c	12 Dec 2005 19:09:49 -0000	1.12
+++ gsttypefindhelper.c	27 Feb 2006 18:13:15 -0000
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *               2000,2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2000,2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2006      Tim-Philipp Müller <tim centricular net>
  *
  * gsttypefindhelper.c:
  *
@@ -181,3 +182,144 @@ gst_type_find_helper (GstPad * src, guin
 
   return result;
 }
+
+/* ********************** typefinding for buffers ************************* */
+
+typedef struct
+{
+  guint8     *data;
+  guint       size;
+  guint       best_probability;
+  GstCaps    *caps;
+  GstObject  *factory; /* for logging */
+  GstObject  *obj;     /* for logging */
+} GstTypeFindBufHelper;
+
+static guint8 *
+buf_helper_find_peek (gpointer data, gint64 off, guint size)
+{
+  GstTypeFindBufHelper *helper;
+
+  helper = (GstTypeFindBufHelper *) data;
+  GST_LOG_OBJECT (helper->obj, "'%s' called peek (%" G_GINT64_FORMAT ", %u)",
+      GST_PLUGIN_FEATURE_NAME (helper->factory), off, size);
+
+  if (size == 0)
+    return NULL;
+
+  if (off < 0) {
+    GST_LOG_OBJECT (helper->obj, "'%s' wanted to peek at end; not supported",
+      GST_PLUGIN_FEATURE_NAME (helper->factory));
+    return NULL;
+  }
+
+  if ((off + size) < helper->size)
+    return helper->data + off;
+
+  return NULL;
+}
+
+static void
+buf_helper_find_suggest (gpointer data, guint prob, const GstCaps * caps)
+{
+  GstTypeFindBufHelper *helper = (GstTypeFindBufHelper *) data;
+
+  GST_LOG_OBJECT (helper->obj,
+      "'%s' called called suggest (%u, %" GST_PTR_FORMAT ")",
+      GST_PLUGIN_FEATURE_NAME (helper->factory), prob, caps);
+
+  /* Note: not >= as we call typefinders in order of rank, highest first */
+  if (prob > helper->best_probability) {
+    GstCaps *copy = gst_caps_copy (caps);
+
+    gst_caps_replace (&helper->caps, copy);
+    gst_caps_unref (copy);
+    helper->best_probability = prob;
+  }
+}
+
+static gint
+type_find_factory_rank_cmp (gconstpointer fac1, gconstpointer fac2)
+{
+  if (GST_PLUGIN_FEATURE (fac1)->rank != GST_PLUGIN_FEATURE (fac2)->rank)
+    return GST_PLUGIN_FEATURE (fac2)->rank - GST_PLUGIN_FEATURE (fac1)->rank;
+
+  /* to make the order in which things happen more deterministic,
+   * sort by name when the ranks are the same. */
+  return strcmp (GST_PLUGIN_FEATURE_NAME (fac1), GST_PLUGIN_FEATURE_NAME (fac2));
+}
+
+/**
+ * gst_type_find_helper_for_buffer:
+ * @obj: object doing the typefinding, or NULL (used for logging)
+ * @buf: a #GstBuffer with data to typefind
+ * @prob: location to store the probability of the found caps, or #NULL
+ *
+ * Tries to find what type of data is contained in the given #GstBuffer, the
+ * assumption being that the buffer represents the beginning of the stream or
+ * file.
+ *
+ * All available typefinders will be called on the data in order of rank. If
+ * a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
+ * typefinding is stopped immediately and the found caps will be returned
+ * right away. Otherwise, all available typefind functions will the tried,
+ * and the caps with the highest probability will be returned, or #NULL if
+ * the content of the buffer could not be identified.
+ *
+ * Returns: The #GstCaps corresponding to the data, or #NULL if no type could
+ * be found. The caller should free the caps returned with gst_caps_unref().
+ */
+GstCaps *
+gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
+     GstTypeFindProbability * prob)
+{
+  GstTypeFindBufHelper helper;
+  GstTypeFind find;
+  GList *l, *type_list;
+
+  g_return_val_if_fail (buf != NULL, NULL);
+  g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
+  g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
+      GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
+
+  helper.data = GST_BUFFER_DATA (buf);
+  helper.size = GST_BUFFER_SIZE (buf);
+  helper.best_probability = 0;
+  helper.caps = NULL;
+  helper.obj = obj;
+
+  if (helper.data == NULL || helper.size == 0)
+    return NULL;
+
+  find.data = &helper;
+  find.peek = buf_helper_find_peek;
+  find.suggest = buf_helper_find_suggest;
+  find.get_length = NULL;
+
+  type_list = gst_type_find_factory_get_list ();
+
+  type_list = g_list_sort (type_list, type_find_factory_rank_cmp);
+
+  for (l = type_list; l != NULL; l = l->next) {
+    GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (l->data);
+
+    helper.factory = GST_OBJECT (factory);
+
+    gst_type_find_factory_call_function (factory, &find);
+    if (helper.best_probability >= GST_TYPE_FIND_MAXIMUM)
+      break;
+  }
+
+  gst_plugin_feature_list_free (type_list);
+
+  if (helper.best_probability == 0)
+    return NULL;
+
+  if (prob)
+    *prob = helper.best_probability;
+
+  GST_LOG_OBJECT (obj, "Returning %" GST_PTR_FORMAT " (probability = %u)",
+      helper.caps, (guint) helper.best_probability);
+
+  return helper.caps;
+}
Index: gsttypefindhelper.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/libs/gst/base/gsttypefindhelper.h,v
retrieving revision 1.2
diff -u -p -r1.2 gsttypefindhelper.h
--- gsttypefindhelper.h	15 Oct 2005 15:30:23 -0000	1.2
+++ gsttypefindhelper.h	27 Feb 2006 18:13:15 -0000
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *               2000,2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2000,2005 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2006      Tim-Philipp Müller <tim centricular net>
  *
  * gsttypefindhelper.h:
  *
@@ -29,6 +30,10 @@ G_BEGIN_DECLS
 
 GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
 
+GstCaps * gst_type_find_helper_for_buffer (GstObject              *obj,
+                                           GstBuffer              *buf,
+                                           GstTypeFindProbability *prob);
+
 G_END_DECLS
 
 #endif /* __GST_TYPEFINDHELPER_H__ */
