2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gsttype.c: Media-type management functions
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
24 * probably should set up a hash table for the type id's, since currently
25 * it's a rather pathetic linear search. Eventually there may be dozens
26 * of id's, but in reality there are only so many instances of lookup, so
27 * I'm not overly worried yet...
30 #include "gst_private.h"
32 #include "gstbytestream.h"
34 #include "gstregistrypool.h"
35 #include "gstobject.h"
39 /* global list of registered types */
40 static GList *_gst_types;
41 static guint16 _gst_maxtype;
43 static void gst_type_factory_class_init (GstTypeFactoryClass *klass);
44 static void gst_type_factory_init (GstTypeFactory *factory);
46 static void gst_type_factory_unload_thyself (GstPluginFeature *feature);
48 static GstPluginFeatureClass *parent_class = NULL;
49 /* static guint gst_type_factory_signals[LAST_SIGNAL] = { 0 }; */
52 gst_type_factory_get_type (void)
54 static GType typefactory_type = 0;
56 if (!typefactory_type) {
57 static const GTypeInfo typefactory_info = {
58 sizeof (GstTypeFactoryClass),
61 (GClassInitFunc) gst_type_factory_class_init,
64 sizeof(GstTypeFactory),
66 (GInstanceInitFunc) gst_type_factory_init,
69 typefactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
70 "GstTypeFactory", &typefactory_info, 0);
72 return typefactory_type;
76 gst_type_factory_class_init (GstTypeFactoryClass *klass)
78 GObjectClass *gobject_class;
79 GstObjectClass *gstobject_class;
80 GstPluginFeatureClass *gstpluginfeature_class;
82 gobject_class = (GObjectClass*)klass;
83 gstobject_class = (GstObjectClass*)klass;
84 gstpluginfeature_class = (GstPluginFeatureClass*) klass;
86 parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
88 gstpluginfeature_class->unload_thyself = GST_DEBUG_FUNCPTR (gst_type_factory_unload_thyself);
91 _gst_maxtype = 1; /* type 0 is undefined */
96 gst_type_factory_init (GstTypeFactory *factory)
101 * gst_type_factory_new:
102 * @definition: the definition to use
104 * Creata a new typefactory from the given definition.
106 * Returns: the new typefactory
109 gst_type_factory_new (GstTypeDefinition *definition)
111 GstTypeFactory *factory;
113 g_return_val_if_fail (definition != NULL, NULL);
114 g_return_val_if_fail (definition->name != NULL, NULL);
115 g_return_val_if_fail (definition->mime != NULL, NULL);
117 factory = gst_type_factory_find (definition->name);
120 factory = GST_TYPE_FACTORY (g_object_new (GST_TYPE_TYPE_FACTORY, NULL));
124 GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (definition->name);
125 factory->mime = g_strdup (definition->mime);
126 factory->exts = g_strdup (definition->exts);
127 factory->typefindfunc = definition->typefindfunc;
134 * @factory: the type factory to register
136 * Register a new type factory to the system.
138 * Returns: the new type id
141 gst_type_register (GstTypeFactory *factory)
146 g_return_val_if_fail (factory != NULL, 0);
148 /* GST_CAT_INFO (GST_CAT_TYPES,"type register %s", factory->mime); */
149 id = gst_type_find_by_mime (factory->mime);
152 type = g_new0 (GstType, 1);
154 type->id = _gst_maxtype++;
155 type->mime = factory->mime;
156 type->exts = factory->exts;
157 type->factories = NULL;
158 _gst_types = g_list_prepend (_gst_types, type);
163 type = gst_type_find_by_id (id);
164 /* now we want to try to merge the types and return the original */
166 /* FIXME: do extension merging here, not that easy */
168 /* if there is no existing typefind function, try to use new one */
170 GST_CAT_DEBUG (GST_CAT_TYPES,"gsttype: %s(%p) gave new mime type '%s', id %d",
171 GST_OBJECT_NAME (factory), factory, type->mime, type->id);
172 type->factories = g_slist_prepend (type->factories, factory);
178 gst_type_find_by_mime_func (const gchar *mime)
182 gint typelen,mimelen;
183 gchar *search, *found;
185 g_return_val_if_fail (mime != NULL, 0);
188 /* GST_CAT_DEBUG (GST_CAT_TYPES,"searching for '%s'",mime); */
189 mimelen = strlen (mime);
191 type = (GstType *)walk->data;
193 /* GST_CAT_DEBUG (GST_CAT_TYPES,"checking against '%s'",search); */
194 typelen = strlen (search);
195 while ((search - type->mime) < typelen) {
196 found = strstr (search, mime);
197 /* if the requested mime is in the list */
199 if ((*(found + mimelen) == ' ') ||
200 (*(found + mimelen) == ',') ||
201 (*(found + mimelen) == '\0')) {
204 search = found + mimelen;
209 walk = g_list_next (walk);
216 * gst_type_find_by_mime:
217 * @mime: the mime type to find
219 * Find the type id of a given mime type.
221 * Returns: the type id
224 gst_type_find_by_mime (const gchar *mime)
226 return gst_type_find_by_mime_func (mime);
230 * gst_type_find_by_ext:
231 * @ext: the extension to find
233 * Find the type id of a given extention.
235 * Returns: the type id
238 gst_type_find_by_ext (const gchar *ext)
241 g_warning ("gsttype: find_by_ext not implemented");
246 * gst_type_find_by_id:
247 * @id: the type id to lookup
249 * Find the type of a given type id.
254 gst_type_find_by_id (guint16 id)
256 GList *walk = _gst_types;
260 type = (GstType *)walk->data;
263 walk = g_list_next (walk);
272 * Return a list of all registered types.
274 * Returns: a list of GstTypes
277 gst_type_get_list (void)
283 * gst_type_factory_find:
284 * @name: the name of the typefactory to find
286 * Return the TypeFactory with the given name.
288 * Returns: a GstTypeFactory with the given name;
291 gst_type_factory_find (const gchar *name)
293 GstPluginFeature *feature;
295 g_return_val_if_fail (name != NULL, NULL);
297 feature = gst_registry_pool_find_feature (name, GST_TYPE_TYPE_FACTORY);
299 return GST_TYPE_FACTORY (feature);
305 gst_type_factory_unload_thyself (GstPluginFeature *feature)
307 GstTypeFactory *factory;
309 g_return_if_fail (GST_IS_TYPE_FACTORY (feature));
311 factory = GST_TYPE_FACTORY (feature);
313 if (factory->typefindfunc)
314 factory->typefindfunc = gst_type_type_find_dummy;
318 gst_type_type_find_dummy (GstByteStream *bs, gpointer priv)
321 GstTypeFactory *factory = (GstTypeFactory *)priv;
323 GST_CAT_DEBUG (GST_CAT_TYPES,"gsttype: need to load typefind function for %s", factory->mime);
325 if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
326 if (factory->typefindfunc == gst_type_type_find_dummy) {
327 /* looks like we didn't get a real typefind function */
328 g_warning ("could not load valid typefind function for %s\n", factory->mime);
330 else if (factory->typefindfunc) {
331 res = factory->typefindfunc (bs, priv);