diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt
index f9f051b672..688083bd1d 100644
--- a/docs/libs/gstreamer-libs-sections.txt
+++ b/docs/libs/gstreamer-libs-sections.txt
@@ -946,8 +946,10 @@ gst_push_src_get_type
gst/base/gsttypefindhelper.h
gst_type_find_helper
gst_type_find_helper_for_buffer
+gst_type_find_helper_for_buffer_with_extension
gst_type_find_helper_for_extension
gst_type_find_helper_for_data
+gst_type_find_helper_for_data_with_extension
GstTypeFindHelperGetRangeFunction
gst_type_find_helper_get_range
diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c
index 1723f3472e..32f7d9abd1 100644
--- a/libs/gst/base/gsttypefindhelper.c
+++ b/libs/gst/base/gsttypefindhelper.c
@@ -248,6 +248,57 @@ helper_find_get_length (gpointer data)
return helper->size;
}
+static GList *
+prioritize_extension (GstObject * obj, GList * type_list,
+ const gchar * extension)
+{
+ gint pos = 0;
+ GList *next, *l;
+
+ if (!extension)
+ return type_list;
+
+ /* move the typefinders for the extension first in the list. The idea is that
+ * when one of them returns MAX we don't need to search further as there is a
+ * very high chance we got the right type. */
+
+ GST_LOG_OBJECT (obj, "sorting typefind for extension %s to head", extension);
+
+ for (l = type_list; l; l = next) {
+ const gchar *const *ext;
+ GstTypeFindFactory *factory;
+
+ next = l->next;
+
+ factory = GST_TYPE_FIND_FACTORY (l->data);
+
+ ext = gst_type_find_factory_get_extensions (factory);
+ if (ext == NULL)
+ continue;
+
+ GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
+ GST_OBJECT_NAME (factory), extension);
+
+ while (*ext != NULL) {
+ if (strcmp (*ext, extension) == 0) {
+ /* found extension, move in front */
+ GST_LOG_OBJECT (obj, "moving typefind for extension %s to head",
+ extension);
+ /* remove entry from list */
+ type_list = g_list_delete_link (type_list, l);
+ /* insert at the position */
+ type_list = g_list_insert (type_list, factory, pos);
+ /* next element will be inserted after this one */
+ pos++;
+ break;
+ }
+ ++ext;
+ }
+ }
+
+ return type_list;
+}
+
/**
* gst_type_find_helper_get_range:
* @obj: A #GstObject that will be passed as first argument to @func
@@ -287,7 +338,6 @@ gst_type_find_helper_get_range (GstObject * obj, GstObject * parent,
GSList *walk;
GList *l, *type_list;
GstCaps *result = NULL;
- gint pos = 0;
g_return_val_if_fail (GST_IS_OBJECT (obj), NULL);
g_return_val_if_fail (func != NULL, NULL);
@@ -312,48 +362,7 @@ gst_type_find_helper_get_range (GstObject * obj, GstObject * parent,
}
type_list = gst_type_find_factory_get_list ();
-
- /* move the typefinders for the extension first in the list. The idea is that
- * when one of them returns MAX we don't need to search further as there is a
- * very high chance we got the right type. */
- if (extension) {
- GList *next;
-
- GST_LOG_OBJECT (obj, "sorting typefind for extension %s to head",
- extension);
-
- for (l = type_list; l; l = next) {
- const gchar *const *ext;
- GstTypeFindFactory *factory;
-
- next = l->next;
-
- factory = GST_TYPE_FIND_FACTORY (l->data);
-
- ext = gst_type_find_factory_get_extensions (factory);
- if (ext == NULL)
- continue;
-
- GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
- GST_OBJECT_NAME (factory), extension);
-
- while (*ext != NULL) {
- if (strcmp (*ext, extension) == 0) {
- /* found extension, move in front */
- GST_LOG_OBJECT (obj, "moving typefind for extension %s to head",
- extension);
- /* remove entry from list */
- type_list = g_list_delete_link (type_list, l);
- /* insert at the position */
- type_list = g_list_insert (type_list, factory, pos);
- /* next element will be inserted after this one */
- pos++;
- break;
- }
- ++ext;
- }
- }
- }
+ type_list = prioritize_extension (obj, type_list, extension);
for (l = type_list; l; l = l->next) {
helper.factory = GST_TYPE_FIND_FACTORY (l->data);
@@ -518,6 +527,48 @@ buf_helper_find_suggest (gpointer data, guint probability, GstCaps * caps)
GstCaps *
gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
GstTypeFindProbability * prob)
+{
+ return gst_type_find_helper_for_data_with_extension (obj, data, size, NULL,
+ prob);
+}
+
+/**
+ * gst_type_find_helper_for_data_with_extension:
+ * @obj: (allow-none): object doing the typefinding, or %NULL (used for logging)
+ * @data: (transfer none) (array length=size): * a pointer with data to typefind
+ * @size: the size of @data
+ * @extension: (allow-none): extension of the media, or %NULL
+ * @prob: (out) (allow-none): location to store the probability of the found
+ * caps, or %NULL
+ *
+ * Tries to find what type of data is contained in the given @data, the
+ * assumption being that the data 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 @data could not be identified.
+ *
+ * When @extension is not %NULL, this function will first try the typefind
+ * functions for the given extension, which might speed up the typefinding
+ * in many cases.
+ *
+ * Free-function: gst_caps_unref
+ *
+ * Returns: (transfer full) (nullable): 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().
+ *
+ * Since: 1.16
+ *
+ */
+GstCaps *
+gst_type_find_helper_for_data_with_extension (GstObject * obj,
+ const guint8 * data, gsize size, const gchar * extension,
+ GstTypeFindProbability * prob)
{
GstTypeFindBufHelper helper;
GstTypeFind find;
@@ -541,6 +592,7 @@ gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
find.get_length = NULL;
type_list = gst_type_find_factory_get_list ();
+ type_list = prioritize_extension (obj, type_list, extension);
for (l = type_list; l; l = l->next) {
helper.factory = GST_TYPE_FIND_FACTORY (l->data);
@@ -589,6 +641,45 @@ gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
GstCaps *
gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
GstTypeFindProbability * prob)
+{
+ return gst_type_find_helper_for_buffer_with_extension (obj, buf, NULL, prob);
+}
+
+/**
+ * gst_type_find_helper_for_buffer_with_extension:
+ * @obj: (allow-none): object doing the typefinding, or %NULL (used for logging)
+ * @buf: (in) (transfer none): a #GstBuffer with data to typefind
+ * @extension: (allow-none): extension of the media, or %NULL
+ * @prob: (out) (allow-none): 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.
+ *
+ * When @extension is not %NULL, this function will first try the typefind
+ * functions for the given extension, which might speed up the typefinding
+ * in many cases.
+ *
+ * Free-function: gst_caps_unref
+ *
+ * Returns: (transfer full) (nullable): 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().
+ *
+ * Since: 1.16
+ *
+ */
+GstCaps *
+gst_type_find_helper_for_buffer_with_extension (GstObject * obj,
+ GstBuffer * buf, const gchar * extension, GstTypeFindProbability * prob)
{
GstCaps *result;
GstMapInfo info;
@@ -600,7 +691,9 @@ gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
if (!gst_buffer_map (buf, &info, GST_MAP_READ))
return NULL;
- result = gst_type_find_helper_for_data (obj, info.data, info.size, prob);
+ result =
+ gst_type_find_helper_for_data_with_extension (obj, info.data, info.size,
+ extension, prob);
gst_buffer_unmap (buf, &info);
return result;
diff --git a/libs/gst/base/gsttypefindhelper.h b/libs/gst/base/gsttypefindhelper.h
index 6f032ca789..b722a13366 100644
--- a/libs/gst/base/gsttypefindhelper.h
+++ b/libs/gst/base/gsttypefindhelper.h
@@ -37,10 +37,25 @@ GstCaps * gst_type_find_helper_for_data (GstObject *obj,
const guint8 *data,
gsize size,
GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_data_with_extension (GstObject *obj,
+ const guint8 *data,
+ gsize size,
+ const gchar *extension,
+ GstTypeFindProbability *prob);
+
GST_BASE_API
GstCaps * gst_type_find_helper_for_buffer (GstObject *obj,
GstBuffer *buf,
GstTypeFindProbability *prob);
+
+GST_BASE_API
+GstCaps * gst_type_find_helper_for_buffer_with_extension (GstObject *obj,
+ GstBuffer *buf,
+ const gchar *extension,
+ GstTypeFindProbability *prob);
+
GST_BASE_API
GstCaps * gst_type_find_helper_for_extension (GstObject * obj,
const gchar * extension);
diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c
index 30f902be78..bd48152537 100644
--- a/plugins/elements/gsttypefindelement.c
+++ b/plugins/elements/gsttypefindelement.c
@@ -930,6 +930,7 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
gsize avail;
const guint8 *data;
gboolean have_min, have_max;
+ gchar *ext;
GST_OBJECT_LOCK (typefind);
if (typefind->force_caps) {
@@ -951,11 +952,13 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
if (!have_min)
goto not_enough_data;
+ ext = gst_type_find_get_extension (typefind, typefind->sink);
/* map all available data */
data = gst_adapter_map (typefind->adapter, avail);
- caps = gst_type_find_helper_for_data (GST_OBJECT (typefind),
- data, avail, &probability);
+ caps = gst_type_find_helper_for_data_with_extension (GST_OBJECT (typefind),
+ data, avail, ext, &probability);
gst_adapter_unmap (typefind->adapter);
+ g_free (ext);
if (caps == NULL && have_max)
goto no_type_found;
diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def
index ebc1d5418b..648c0bb016 100644
--- a/win32/common/libgstbase.def
+++ b/win32/common/libgstbase.def
@@ -353,6 +353,8 @@ EXPORTS
gst_queue_array_push_tail_struct
gst_type_find_helper
gst_type_find_helper_for_buffer
+ gst_type_find_helper_for_buffer_with_extension
gst_type_find_helper_for_data
+ gst_type_find_helper_for_data_with_extension
gst_type_find_helper_for_extension
gst_type_find_helper_get_range