source: trunk/third/gstreamer/gst/gsttypefind.c @ 21005

Revision 21005, 9.8 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r21004, which included commits to RCS files with non-trunk default branches.
Line 
1/* GStreamer
2 * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
3 *
4 * gsttypefind.h: typefinding subsystem
5 *
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.
10 *
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.
15 *
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.
20 */
21
22#include "gst_private.h"
23#include "gstinfo.h"
24#include "gsttypefind.h"
25#include "gstregistrypool.h"
26
27GST_DEBUG_CATEGORY_STATIC (gst_type_find_debug);
28#define GST_CAT_DEFAULT gst_type_find_debug
29
30static void gst_type_find_factory_class_init (gpointer g_class,
31    gpointer class_data);
32static void gst_type_find_factory_init (GTypeInstance * instance,
33    gpointer g_class);
34static void gst_type_find_factory_dispose (GObject * object);
35
36static void gst_type_find_factory_unload_thyself (GstPluginFeature * feature);
37
38static void gst_type_find_load_plugin (GstTypeFind * find, gpointer data);
39
40static GstPluginFeatureClass *parent_class = NULL;
41
42GType
43gst_type_find_factory_get_type (void)
44{
45  static GType typefind_type = 0;
46
47  if (!typefind_type) {
48    static const GTypeInfo typefind_info = {
49      sizeof (GstTypeFindFactoryClass),
50      NULL,
51      NULL,
52      gst_type_find_factory_class_init,
53      NULL,
54      NULL,
55      sizeof (GstTypeFindFactory),
56      0,
57      gst_type_find_factory_init,
58      NULL
59    };
60
61    typefind_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
62        "GstTypeFindFactory", &typefind_info, 0);
63    GST_DEBUG_CATEGORY_INIT (gst_type_find_debug, "GST_TYPEFIND",
64        GST_DEBUG_FG_GREEN, "typefinding subsystem");
65  }
66
67  return typefind_type;
68}
69static void
70gst_type_find_factory_class_init (gpointer g_class, gpointer class_data)
71{
72  GstPluginFeatureClass *gstpluginfeature_class =
73      GST_PLUGIN_FEATURE_CLASS (g_class);
74  GObjectClass *object_class = G_OBJECT_CLASS (g_class);
75
76  parent_class = g_type_class_peek_parent (g_class);
77
78  object_class->dispose = gst_type_find_factory_dispose;
79
80  gstpluginfeature_class->unload_thyself =
81      GST_DEBUG_FUNCPTR (gst_type_find_factory_unload_thyself);
82}
83static void
84gst_type_find_factory_init (GTypeInstance * instance, gpointer g_class)
85{
86  GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (instance);
87
88  factory->user_data = factory;
89  factory->function = gst_type_find_load_plugin;
90}
91static void
92gst_type_find_factory_dispose (GObject * object)
93{
94  GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (object);
95
96  if (factory->caps) {
97    gst_caps_free (factory->caps);
98    factory->caps = NULL;
99  }
100  if (factory->extensions) {
101    g_strfreev (factory->extensions);
102    factory->extensions = NULL;
103  }
104}
105static void
106gst_type_find_factory_unload_thyself (GstPluginFeature * feature)
107{
108  GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
109
110  factory->function = gst_type_find_load_plugin;
111  factory->user_data = factory;
112}
113static void
114gst_type_find_load_plugin (GstTypeFind * find, gpointer data)
115{
116  GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (data);
117
118  GST_DEBUG_OBJECT (factory, "need to load typefind function %s",
119      GST_PLUGIN_FEATURE_NAME (factory));
120
121  if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
122    if (factory->function == gst_type_find_load_plugin) {
123      /* looks like we didn't get a real typefind function */
124      g_warning ("could not load valid typefind function for feature '%s'\n",
125          GST_PLUGIN_FEATURE_NAME (factory));
126    } else {
127      g_assert (factory->function);
128      gst_type_find_factory_call_function (factory, find);
129    }
130  }
131}
132
133/**
134 * gst_type_find_factory_get_list:
135 *
136 * Gets the list of all registered typefind factories. You must free the
137 * list using g_list_free.
138 *
139 * Returns: the list of all registered typefind factories
140 */
141GList *
142gst_type_find_factory_get_list (void)
143{
144  return gst_registry_pool_feature_list (GST_TYPE_TYPE_FIND_FACTORY);
145}
146
147/**
148 * gst_type_find_factory_get_caps:
149 * @factory: a factory
150 *
151 * Gets the caps associated with a typefind factory.
152 *
153 * Returns: the #GstCaps associated with this factory
154 */
155const GstCaps *
156gst_type_find_factory_get_caps (const GstTypeFindFactory * factory)
157{
158  g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
159
160  return factory->caps;
161}
162
163/**
164 * gst_type_find_factory_get_extensions:
165 * @factory: a factory
166 *
167 * Gets the extensions associated with a typefind factory. The returned
168 * array should not be changed. If you need to change stuff in it, you should
169 * copy it using g_stdupv().  This function may return NULL to indicate
170 * a 0-length list.
171 *
172 * Returns: a NULL-terminated array of extensions associated with this factory
173 */
174gchar **
175gst_type_find_factory_get_extensions (const GstTypeFindFactory * factory)
176{
177  g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
178
179  return factory->extensions;
180}
181
182/**
183 * gst_type_find_factory_call_function:
184 * @factory: a factory
185 * @find: a properly setup #GstTypeFind entry. The get_data and suggest_type
186 *        members must be set.
187 *
188 * Calls the typefinding function associated with this factory.
189 */
190void
191gst_type_find_factory_call_function (const GstTypeFindFactory * factory,
192    GstTypeFind * find)
193{
194  g_return_if_fail (GST_IS_TYPE_FIND_FACTORY (factory));
195  g_return_if_fail (find != NULL);
196  g_return_if_fail (find->peek != NULL);
197  g_return_if_fail (find->suggest != NULL);
198
199  /* should never happen */
200  g_assert (factory->function != NULL);
201
202  factory->function (find, factory->user_data);
203}
204
205/**
206 * gst_type_find_register:
207 * @plugin: the GstPlugin to register with
208 * @name: the name for registering
209 * @rank: rank (or importance) of this typefind function
210 * @func: the function to use for typefinding
211 * @extensions: optional extensions that could belong to this type
212 * @possible_caps: optionally the caps that could be returned when typefinding succeeds
213 * @data: optional user data. This user data must be available until the plugin
214 *        is unloaded.
215 *
216 * Registers a new typefind function to be used for typefinding. After
217 * registering this function will be available for typefinding.
218 * This function is typically called during an element's plugin initialization.
219 *
220 * Returns: TRUE on success, FALSE otherwise
221 */
222gboolean
223gst_type_find_register (GstPlugin * plugin, const gchar * name, guint rank,
224    GstTypeFindFunction func, gchar ** extensions,
225    const GstCaps * possible_caps, gpointer data)
226{
227  GstTypeFindFactory *factory;
228
229  g_return_val_if_fail (plugin != NULL, FALSE);
230  g_return_val_if_fail (name != NULL, FALSE);
231  g_return_val_if_fail (func != NULL, FALSE);
232
233  GST_INFO ("registering typefind function for %s", name);
234  factory =
235      GST_TYPE_FIND_FACTORY (gst_registry_pool_find_feature (name,
236          GST_TYPE_TYPE_FIND_FACTORY));
237  if (!factory) {
238    factory = g_object_new (GST_TYPE_TYPE_FIND_FACTORY, NULL);
239    GST_DEBUG_OBJECT (factory, "using new typefind factory for %s", name);
240    g_assert (GST_IS_TYPE_FIND_FACTORY (factory));
241    gst_plugin_feature_set_name (GST_PLUGIN_FEATURE (factory), name);
242    gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
243  } else {
244    GST_DEBUG_OBJECT (factory, "using old typefind factory for %s", name);
245  }
246
247  gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
248  if (factory->extensions)
249    g_strfreev (factory->extensions);
250
251  factory->extensions = g_strdupv (extensions);
252  gst_caps_replace (&factory->caps, gst_caps_copy (possible_caps));
253  factory->function = func;
254  factory->user_data = data;
255
256  return TRUE;
257}
258
259/*** typefind function interface **********************************************/
260
261/**
262 * gst_type_find_peek:
263 * @find: the find object the function was called with
264 * @offset: the offset
265 * @size: the number of bytes to return
266 *
267 * Returns size bytes of the stream to identify beginning at offset. If offset
268 * is a positive number, the offset is relative to the beginning of the stream,
269 * if offset is a negative number the offset is relative to the end of the
270 * stream. The returned memory is valid until the typefinding function returns
271 * and must not be freed.
272 * If NULL is returned, that data is not available.
273 *
274 * Returns: the requested data or NULL if that data is not available.
275 */
276guint8 *
277gst_type_find_peek (GstTypeFind * find, gint64 offset, guint size)
278{
279  g_return_val_if_fail (find->peek != NULL, NULL);
280
281  return find->peek (find->data, offset, size);
282}
283
284/**
285 * gst_type_find_suggest:
286 * @find: the find object the function was called with
287 * @probability: the probability in percent that the suggestion is right
288 * @caps: the fixed caps to suggest
289 *
290 * If a typefind function calls this function it suggests the caps with the
291 * given probability. A typefind function may supply different suggestions
292 * in one call.
293 * It is up to the caller of the typefind function to interpret these values.
294 */
295void
296gst_type_find_suggest (GstTypeFind * find, guint probability,
297    const GstCaps * caps)
298{
299  g_return_if_fail (find->suggest != NULL);
300  g_return_if_fail (probability <= 100);
301  g_return_if_fail (caps != NULL);
302  g_return_if_fail (gst_caps_is_fixed (caps));
303
304  find->suggest (find->data, probability, caps);
305}
306
307/**
308 * gst_type_find_get_length:
309 * @find: the find object the function was called with
310 *
311 * Get the length of the data stream.
312 *
313 * Returns: the length of the data stream or 0 if it is not available.
314 */
315guint64
316gst_type_find_get_length (GstTypeFind * find)
317{
318  if (find->get_length == NULL)
319    return 0;
320
321  return find->get_length (find->data);
322}
Note: See TracBrowser for help on using the repository browser.