2 * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
4 * gsttypefindfactory.c: typefinding subsystem
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
22 * SECTION:gsttypefindfactory
23 * @short_description: Information about registered typefind functions
25 * These functions allow querying informations about registered typefind
26 * functions. How to create and register these functions is described in
27 * the section <link linkend="gstreamer-Writing-typefind-functions">
28 * "Writing typefind functions"</link>.
31 * <title>how to write a simple typefinder</title>
40 * my_peek (gpointer data, gint64 offset, guint size)
42 * MyTypeFind *find = (MyTypeFind *) data;
43 * if (offset >= 0 && offset + size <= find->size) {
44 * return find->data + offset;
49 * my_suggest (gpointer data, guint probability, GstCaps *caps)
51 * MyTypeFind *find = (MyTypeFind *) data;
52 * if (probability > find->probability) {
53 * find->probability = probability;
54 * gst_caps_replace (&find->caps, caps);
58 * find_type (guint8 *data, guint size)
60 * GList *walk, *type_list;
61 * MyTypeFind find = {data, size, 0, NULL};
62 * GstTypeFind gst_find = {my_peek, my_suggest, &find, };
64 * walk = type_list = gst_type_find_factory_get_list ();
66 * GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
67 * walk = g_list_next (walk)
68 * gst_type_find_factory_call_function (factory, &gst_find);
70 * g_list_free (type_list);
76 * The above example shows how to write a very simple typefinder that identifies
77 * the given data. You can get quite a bit more complicated than that though.
80 #include "gst_private.h"
82 #include "gsttypefind.h"
83 #include "gsttypefindfactory.h"
84 #include "gstregistrypool.h"
86 GST_DEBUG_CATEGORY (gst_type_find_debug);
87 #define GST_CAT_DEFAULT gst_type_find_debug
89 static void gst_type_find_factory_class_init (gpointer g_class,
91 static void gst_type_find_factory_init (GTypeInstance * instance,
93 static void gst_type_find_factory_dispose (GObject * object);
95 static void gst_type_find_factory_unload_thyself (GstPluginFeature * feature);
97 static void gst_type_find_load_plugin (GstTypeFind * find, gpointer data);
99 static GstPluginFeatureClass *parent_class = NULL;
102 gst_type_find_factory_get_type (void)
104 static GType typefind_type = 0;
106 if (!typefind_type) {
107 static const GTypeInfo typefind_info = {
108 sizeof (GstTypeFindFactoryClass),
111 gst_type_find_factory_class_init,
114 sizeof (GstTypeFindFactory),
116 gst_type_find_factory_init,
120 typefind_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
121 "GstTypeFindFactory", &typefind_info, 0);
122 GST_DEBUG_CATEGORY_INIT (gst_type_find_debug, "GST_TYPEFIND",
123 GST_DEBUG_FG_GREEN, "typefinding subsystem");
126 return typefind_type;
129 gst_type_find_factory_class_init (gpointer g_class, gpointer class_data)
131 GstPluginFeatureClass *gstpluginfeature_class =
132 GST_PLUGIN_FEATURE_CLASS (g_class);
133 GObjectClass *object_class = G_OBJECT_CLASS (g_class);
135 parent_class = g_type_class_peek_parent (g_class);
137 object_class->dispose = gst_type_find_factory_dispose;
139 gstpluginfeature_class->unload_thyself =
140 GST_DEBUG_FUNCPTR (gst_type_find_factory_unload_thyself);
143 gst_type_find_factory_init (GTypeInstance * instance, gpointer g_class)
145 GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (instance);
147 factory->user_data = factory;
148 factory->function = gst_type_find_load_plugin;
151 gst_type_find_factory_dispose (GObject * object)
153 GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (object);
156 gst_caps_unref (factory->caps);
157 factory->caps = NULL;
159 if (factory->extensions) {
160 g_strfreev (factory->extensions);
161 factory->extensions = NULL;
165 gst_type_find_factory_unload_thyself (GstPluginFeature * feature)
167 GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
169 factory->function = gst_type_find_load_plugin;
170 factory->user_data = factory;
173 gst_type_find_load_plugin (GstTypeFind * find, gpointer data)
175 GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (data);
177 GST_DEBUG_OBJECT (factory, "need to load typefind function %s",
178 GST_PLUGIN_FEATURE_NAME (factory));
180 if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
181 if (factory->function == gst_type_find_load_plugin) {
182 /* looks like we didn't get a real typefind function */
183 g_warning ("could not load valid typefind function for feature '%s'\n",
184 GST_PLUGIN_FEATURE_NAME (factory));
186 g_assert (factory->function);
187 gst_type_find_factory_call_function (factory, find);
193 * gst_type_find_factory_get_list:
195 * Gets the list of all registered typefind factories. You must free the
196 * list using g_list_free.
198 * Returns: the list of all registered typefind factories
201 gst_type_find_factory_get_list (void)
203 return gst_registry_pool_feature_list (GST_TYPE_TYPE_FIND_FACTORY);
207 * gst_type_find_factory_get_caps:
208 * @factory: a factory
210 * Gets the caps associated with a typefind factory.
212 * Returns: the #GstCaps associated with this factory
215 gst_type_find_factory_get_caps (const GstTypeFindFactory * factory)
217 g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
219 return factory->caps;
223 * gst_type_find_factory_get_extensions:
224 * @factory: a factory
226 * Gets the extensions associated with a typefind factory. The returned
227 * array should not be changed. If you need to change stuff in it, you should
228 * copy it using g_stdupv(). This function may return NULL to indicate
231 * Returns: a NULL-terminated array of extensions associated with this factory
234 gst_type_find_factory_get_extensions (const GstTypeFindFactory * factory)
236 g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
238 return factory->extensions;
242 * gst_type_find_factory_call_function:
243 * @factory: a factory
244 * @find: a properly setup #GstTypeFind entry. The get_data and suggest_type
245 * members must be set.
247 * Calls the typefinding function associated with this factory.
250 gst_type_find_factory_call_function (const GstTypeFindFactory * factory,
253 g_return_if_fail (GST_IS_TYPE_FIND_FACTORY (factory));
254 g_return_if_fail (find != NULL);
255 g_return_if_fail (find->peek != NULL);
256 g_return_if_fail (find->suggest != NULL);
258 /* should never happen */
259 g_assert (factory->function != NULL);
261 factory->function (find, factory->user_data);