libs/gst/base/gsttypefindhelper.*: New API: gst_type_find_helper_for_buffer() (#332723).

Original commit message from CVS:
* libs/gst/base/gsttypefindhelper.c: (buf_helper_find_peek),
(buf_helper_find_suggest), (type_find_factory_rank_cmp),
(gst_type_find_helper_for_buffer):
* libs/gst/base/gsttypefindhelper.h:
New API: gst_type_find_helper_for_buffer() (#332723).
This commit is contained in:
Tim-Philipp Müller 2006-02-27 18:43:26 +00:00
parent 323c4ca50e
commit 991aa71ffb
3 changed files with 158 additions and 2 deletions

View file

@ -1,3 +1,11 @@
2006-02-27 Tim-Philipp Müller <tim at centricular dot net>
* libs/gst/base/gsttypefindhelper.c: (buf_helper_find_peek),
(buf_helper_find_suggest), (type_find_factory_rank_cmp),
(gst_type_find_helper_for_buffer):
* libs/gst/base/gsttypefindhelper.h:
New API: gst_type_find_helper_for_buffer() (#332723).
2006-02-27 Michael Smith <msmith@fluendo.com>
* configure.ac:

View file

@ -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,145 @@ gst_type_find_helper (GstPad * src, guint64 size)
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;
}

View file

@ -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__ */