From 991aa71ffb9e1c04bab7df82ea19116cf3e62311 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 27 Feb 2006 18:43:26 +0000 Subject: [PATCH] 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). --- ChangeLog | 8 +++ libs/gst/base/gsttypefindhelper.c | 145 +++++++++++++++++++++++++++++++++++++- libs/gst/base/gsttypefindhelper.h | 7 +- 3 files changed, 158 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index eb5e05a..5d01e0e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2006-02-27 Tim-Philipp Müller + + * 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 * configure.ac: diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c index b802a74..747190c 100644 --- a/libs/gst/base/gsttypefindhelper.c +++ b/libs/gst/base/gsttypefindhelper.c @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen - * 2000,2005 Wim Taymans + * Copyright (C) 2000,2005 Wim Taymans + * Copyright (C) 2006 Tim-Philipp Müller * * 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; +} diff --git a/libs/gst/base/gsttypefindhelper.h b/libs/gst/base/gsttypefindhelper.h index 994b239..7439f9b 100644 --- a/libs/gst/base/gsttypefindhelper.h +++ b/libs/gst/base/gsttypefindhelper.h @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen - * 2000,2005 Wim Taymans + * Copyright (C) 2000,2005 Wim Taymans + * Copyright (C) 2006 Tim-Philipp Müller * * 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__ */ -- 2.7.4