Git init
[framework/multimedia/gstreamer0.10.git] / gst / gsttypefindfactory.c
1 /* GStreamer
2  * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
3  *
4  * gsttypefindfactory.c: 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 /**
23  * SECTION:gsttypefindfactory
24  * @short_description: Information about registered typefind functions
25  *
26  * These functions allow querying informations about registered typefind
27  * functions. How to create and register these functions is described in
28  * the section <link linkend="gstreamer-Writing-typefind-functions">
29  * "Writing typefind functions"</link>.
30  *
31  * <example>
32  *   <title>how to write a simple typefinder</title>
33  *   <programlisting>
34  *   typedef struct {
35  *     guint8 *data;
36  *     guint size;
37  *     guint probability;
38  *     GstCaps *data;
39  *   } MyTypeFind;
40  *   static void
41  *   my_peek (gpointer data, gint64 offset, guint size)
42  *   {
43  *     MyTypeFind *find = (MyTypeFind *) data;
44  *     if (offset &gt;= 0 &amp;&amp; offset + size &lt;= find->size) {
45  *       return find->data + offset;
46  *     }
47  *     return NULL;
48  *   }
49  *   static void
50  *   my_suggest (gpointer data, guint probability, GstCaps *caps)
51  *   {
52  *     MyTypeFind *find = (MyTypeFind *) data;
53  *     if (probability &gt; find->probability) {
54  *       find->probability = probability;
55  *       gst_caps_replace (&amp;find->caps, caps);
56  *     }
57  *   }
58  *   static GstCaps *
59  *   find_type (guint8 *data, guint size)
60  *   {
61  *     GList *walk, *type_list;
62  *     MyTypeFind find = {data, size, 0, NULL};
63  *     GstTypeFind gst_find = {my_peek, my_suggest, &amp;find, };
64  *     walk = type_list = gst_type_find_factory_get_list ();
65  *     while (walk) {
66  *       GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
67  *       walk = g_list_next (walk)
68  *       gst_type_find_factory_call_function (factory, &amp;gst_find);
69  *     }
70  *     g_list_free (type_list);
71  *     return find.caps;
72  *   };
73  *   </programlisting>
74  * </example>
75  *
76  * The above example shows how to write a very simple typefinder that
77  * identifies the given data. You can get quite a bit more complicated than
78  * that though.
79  *
80  * Last reviewed on 2005-11-09 (0.9.4)
81  */
82
83 #include "gst_private.h"
84 #include "gstinfo.h"
85 #include "gsttypefind.h"
86 #include "gsttypefindfactory.h"
87 #include "gstregistry.h"
88
89 GST_DEBUG_CATEGORY (type_find_debug);
90 #define GST_CAT_DEFAULT type_find_debug
91
92 static void gst_type_find_factory_dispose (GObject * object);
93
94 static GstPluginFeatureClass *parent_class = NULL;
95
96 #define _do_init \
97 { \
98   GST_DEBUG_CATEGORY_INIT (type_find_debug, "GST_TYPEFIND", \
99       GST_DEBUG_FG_GREEN, "typefinding subsystem"); \
100 }
101
102 G_DEFINE_TYPE_WITH_CODE (GstTypeFindFactory, gst_type_find_factory,
103     GST_TYPE_PLUGIN_FEATURE, _do_init);
104
105 static void
106 gst_type_find_factory_class_init (GstTypeFindFactoryClass * klass)
107 {
108   GObjectClass *object_class = G_OBJECT_CLASS (klass);
109
110   parent_class = g_type_class_peek_parent (klass);
111
112   object_class->dispose = gst_type_find_factory_dispose;
113 }
114
115 static void
116 gst_type_find_factory_init (GstTypeFindFactory * factory)
117 {
118   factory->user_data = factory;
119   factory->user_data_notify = NULL;
120 }
121
122 static void
123 gst_type_find_factory_dispose (GObject * object)
124 {
125   GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (object);
126
127   if (factory->caps) {
128     gst_caps_unref (factory->caps);
129     factory->caps = NULL;
130   }
131   if (factory->extensions) {
132     g_strfreev (factory->extensions);
133     factory->extensions = NULL;
134   }
135   if (factory->user_data_notify && factory->user_data) {
136     factory->user_data_notify (factory->user_data);
137     factory->user_data = NULL;
138   }
139
140   G_OBJECT_CLASS (parent_class)->dispose (object);
141 }
142
143 /**
144  * gst_type_find_factory_get_list:
145  *
146  * Gets the list of all registered typefind factories. You must free the
147  * list using gst_plugin_feature_list_free().
148  *
149  * The returned factories are sorted by highest rank first, and then by
150  * factory name. (behaviour change since 0.10.26)
151  *
152  * Free-function: gst_plugin_feature_list_free
153  *
154  * Returns: (transfer full) (element-type Gst.TypeFindFactory): the list of all
155  *     registered #GstTypeFindFactory.
156  */
157 GList *
158 gst_type_find_factory_get_list (void)
159 {
160   return gst_registry_get_feature_list (gst_registry_get_default (),
161       GST_TYPE_TYPE_FIND_FACTORY);
162 }
163
164 /**
165  * gst_type_find_factory_get_caps:
166  * @factory: A #GstTypeFindFactory
167  *
168  * Gets the #GstCaps associated with a typefind factory.
169  *
170  * Returns: (transfer none): the #GstCaps associated with this factory
171  */
172 GstCaps *
173 gst_type_find_factory_get_caps (GstTypeFindFactory * factory)
174 {
175   g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
176
177   return factory->caps;
178 }
179
180 /**
181  * gst_type_find_factory_get_extensions:
182  * @factory: A #GstTypeFindFactory
183  *
184  * Gets the extensions associated with a #GstTypeFindFactory. The returned
185  * array should not be changed. If you need to change stuff in it, you should
186  * copy it using g_strdupv().  This function may return NULL to indicate
187  * a 0-length list.
188  *
189  * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): a
190  *     NULL-terminated array of extensions associated with this factory
191  */
192 gchar **
193 gst_type_find_factory_get_extensions (GstTypeFindFactory * factory)
194 {
195   g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
196
197   return factory->extensions;
198 }
199
200 /**
201  * gst_type_find_factory_call_function:
202  * @factory: A #GstTypeFindFactory
203  * @find: (transfer none): a properly setup #GstTypeFind entry. The get_data
204  *     and suggest_type members must be set.
205  *
206  * Calls the #GstTypeFindFunction associated with this factory.
207  */
208 void
209 gst_type_find_factory_call_function (GstTypeFindFactory * factory,
210     GstTypeFind * find)
211 {
212   GstTypeFindFactory *new_factory;
213
214   g_return_if_fail (GST_IS_TYPE_FIND_FACTORY (factory));
215   g_return_if_fail (find != NULL);
216   g_return_if_fail (find->peek != NULL);
217   g_return_if_fail (find->suggest != NULL);
218
219   new_factory =
220       GST_TYPE_FIND_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
221           (factory)));
222   if (new_factory) {
223     if (new_factory->function)
224       new_factory->function (find, new_factory->user_data);
225     gst_object_unref (new_factory);
226   }
227 }