mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-09-27 14:31:01 +00:00
242 lines
7.2 KiB
C
242 lines
7.2 KiB
C
/* GStreamer
|
|
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
|
|
*
|
|
* gsttypefindfactory.c: typefinding subsystem
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public
|
|
* License along with this library; if not, write to the
|
|
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
* Boston, MA 02111-1307, USA.
|
|
*/
|
|
|
|
/**
|
|
* SECTION:gsttypefindfactory
|
|
* @short_description: Information about registered typefind functions
|
|
*
|
|
* These functions allow querying informations about registered typefind
|
|
* functions. How to create and register these functions is described in
|
|
* the section <link linkend="gstreamer-Writing-typefind-functions">
|
|
* "Writing typefind functions"</link>.
|
|
*
|
|
* <example>
|
|
* <title>how to write a simple typefinder</title>
|
|
* <programlisting>
|
|
* typedef struct {
|
|
* guint8 *data;
|
|
* guint size;
|
|
* guint probability;
|
|
* GstCaps *data;
|
|
* } MyTypeFind;
|
|
* static void
|
|
* my_peek (gpointer data, gint64 offset, guint size)
|
|
* {
|
|
* MyTypeFind *find = (MyTypeFind *) data;
|
|
* if (offset >= 0 && offset + size <= find->size) {
|
|
* return find->data + offset;
|
|
* }
|
|
* return NULL;
|
|
* }
|
|
* static void
|
|
* my_suggest (gpointer data, guint probability, GstCaps *caps)
|
|
* {
|
|
* MyTypeFind *find = (MyTypeFind *) data;
|
|
* if (probability > find->probability) {
|
|
* find->probability = probability;
|
|
* gst_caps_replace (&find->caps, caps);
|
|
* }
|
|
* }
|
|
* static GstCaps *
|
|
* find_type (guint8 *data, guint size)
|
|
* {
|
|
* GList *walk, *type_list;
|
|
* MyTypeFind find = {data, size, 0, NULL};
|
|
* GstTypeFind gst_find = {my_peek, my_suggest, &find, };
|
|
* walk = type_list = gst_type_find_factory_get_list ();
|
|
* while (walk) {
|
|
* GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
|
|
* walk = g_list_next (walk)
|
|
* gst_type_find_factory_call_function (factory, &gst_find);
|
|
* }
|
|
* g_list_free (type_list);
|
|
* return find.caps;
|
|
* };
|
|
* </programlisting>
|
|
* </example>
|
|
*
|
|
* The above example shows how to write a very simple typefinder that
|
|
* identifies the given data. You can get quite a bit more complicated than
|
|
* that though.
|
|
*
|
|
* Last reviewed on 2005-11-09 (0.9.4)
|
|
*/
|
|
|
|
#include "gst_private.h"
|
|
#include "gstinfo.h"
|
|
#include "gsttypefind.h"
|
|
#include "gsttypefindfactory.h"
|
|
#include "gstregistry.h"
|
|
|
|
GST_DEBUG_CATEGORY (type_find_debug);
|
|
#define GST_CAT_DEFAULT type_find_debug
|
|
|
|
static void gst_type_find_factory_dispose (GObject * object);
|
|
|
|
#define _do_init \
|
|
{ \
|
|
GST_DEBUG_CATEGORY_INIT (type_find_debug, "GST_TYPEFIND", \
|
|
GST_DEBUG_FG_GREEN, "typefinding subsystem"); \
|
|
}
|
|
|
|
#define gst_type_find_factory_parent_class parent_class
|
|
G_DEFINE_TYPE_WITH_CODE (GstTypeFindFactory, gst_type_find_factory,
|
|
GST_TYPE_PLUGIN_FEATURE, _do_init);
|
|
|
|
static void
|
|
gst_type_find_factory_class_init (GstTypeFindFactoryClass * klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->dispose = gst_type_find_factory_dispose;
|
|
}
|
|
|
|
static void
|
|
gst_type_find_factory_init (GstTypeFindFactory * factory)
|
|
{
|
|
factory->user_data = factory;
|
|
factory->user_data_notify = NULL;
|
|
}
|
|
|
|
static void
|
|
gst_type_find_factory_dispose (GObject * object)
|
|
{
|
|
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (object);
|
|
|
|
if (factory->caps) {
|
|
gst_caps_unref (factory->caps);
|
|
factory->caps = NULL;
|
|
}
|
|
if (factory->extensions) {
|
|
g_strfreev (factory->extensions);
|
|
factory->extensions = NULL;
|
|
}
|
|
if (factory->user_data_notify && factory->user_data) {
|
|
factory->user_data_notify (factory->user_data);
|
|
factory->user_data = NULL;
|
|
}
|
|
|
|
G_OBJECT_CLASS (parent_class)->dispose (object);
|
|
}
|
|
|
|
/**
|
|
* gst_type_find_factory_get_list:
|
|
*
|
|
* Gets the list of all registered typefind factories. You must free the
|
|
* list using gst_plugin_feature_list_free().
|
|
*
|
|
* The returned factories are sorted by highest rank first, and then by
|
|
* factory name.
|
|
*
|
|
* Free-function: gst_plugin_feature_list_free
|
|
*
|
|
* Returns: (transfer full) (element-type Gst.TypeFindFactory): the list of all
|
|
* registered #GstTypeFindFactory.
|
|
*/
|
|
GList *
|
|
gst_type_find_factory_get_list (void)
|
|
{
|
|
return gst_registry_get_feature_list (gst_registry_get (),
|
|
GST_TYPE_TYPE_FIND_FACTORY);
|
|
}
|
|
|
|
/**
|
|
* gst_type_find_factory_get_caps:
|
|
* @factory: A #GstTypeFindFactory
|
|
*
|
|
* Gets the #GstCaps associated with a typefind factory.
|
|
*
|
|
* Returns: (transfer none): the #GstCaps associated with this factory
|
|
*/
|
|
GstCaps *
|
|
gst_type_find_factory_get_caps (GstTypeFindFactory * factory)
|
|
{
|
|
g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
|
|
|
|
return factory->caps;
|
|
}
|
|
|
|
/**
|
|
* gst_type_find_factory_get_extensions:
|
|
* @factory: A #GstTypeFindFactory
|
|
*
|
|
* Gets the extensions associated with a #GstTypeFindFactory. The returned
|
|
* array should not be changed. If you need to change stuff in it, you should
|
|
* copy it using g_strdupv(). This function may return NULL to indicate
|
|
* a 0-length list.
|
|
*
|
|
* Returns: (transfer none) (array zero-terminated=1) (element-type utf8): a
|
|
* NULL-terminated array of extensions associated with this factory
|
|
*/
|
|
const gchar *const *
|
|
gst_type_find_factory_get_extensions (GstTypeFindFactory * factory)
|
|
{
|
|
g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
|
|
|
|
return (const gchar * const *) factory->extensions;
|
|
}
|
|
|
|
/**
|
|
* gst_type_find_factory_call_function:
|
|
* @factory: A #GstTypeFindFactory
|
|
* @find: (transfer none): a properly setup #GstTypeFind entry. The get_data
|
|
* and suggest_type members must be set.
|
|
*
|
|
* Calls the #GstTypeFindFunction associated with this factory.
|
|
*/
|
|
void
|
|
gst_type_find_factory_call_function (GstTypeFindFactory * factory,
|
|
GstTypeFind * find)
|
|
{
|
|
GstTypeFindFactory *new_factory;
|
|
|
|
g_return_if_fail (GST_IS_TYPE_FIND_FACTORY (factory));
|
|
g_return_if_fail (find != NULL);
|
|
g_return_if_fail (find->peek != NULL);
|
|
g_return_if_fail (find->suggest != NULL);
|
|
|
|
new_factory =
|
|
GST_TYPE_FIND_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
|
|
(factory)));
|
|
if (new_factory) {
|
|
if (new_factory->function)
|
|
new_factory->function (find, new_factory->user_data);
|
|
gst_object_unref (new_factory);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* gst_type_find_factory_has_function:
|
|
* @factory: A #GstTypeFindFactory
|
|
*
|
|
* Check whether the factory has a typefind function. Typefind factories
|
|
* without typefind functions are a last-effort fallback mechanism to
|
|
* e.g. assume a certain media type based on the file extension.
|
|
*
|
|
* Returns: TRUE if the factory has a typefind functions set, otherwise FALSE
|
|
*/
|
|
gboolean
|
|
gst_type_find_factory_has_function (GstTypeFindFactory * factory)
|
|
{
|
|
g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), FALSE);
|
|
|
|
return (factory->function != NULL);
|
|
}
|