docs: convert NULL, TRUE, and FALSE to %NULL, %TRUE, and %FALSE
[platform/upstream/gstreamer.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., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, 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  * The following example shows how to write a very simple typefinder that
32  * identifies the given data. You can get quite a bit more complicated than
33  * that though.
34  * |[
35  *   typedef struct {
36  *     guint8 *data;
37  *     guint size;
38  *     guint probability;
39  *     GstCaps *data;
40  *   } MyTypeFind;
41  *   static void
42  *   my_peek (gpointer data, gint64 offset, guint size)
43  *   {
44  *     MyTypeFind *find = (MyTypeFind *) data;
45  *     if (offset &gt;= 0 &amp;&amp; offset + size &lt;= find->size) {
46  *       return find->data + offset;
47  *     }
48  *     return NULL;
49  *   }
50  *   static void
51  *   my_suggest (gpointer data, guint probability, GstCaps *caps)
52  *   {
53  *     MyTypeFind *find = (MyTypeFind *) data;
54  *     if (probability &gt; find->probability) {
55  *       find->probability = probability;
56  *       gst_caps_replace (&amp;find->caps, caps);
57  *     }
58  *   }
59  *   static GstCaps *
60  *   find_type (guint8 *data, guint size)
61  *   {
62  *     GList *walk, *type_list;
63  *     MyTypeFind find = {data, size, 0, NULL};
64  *     GstTypeFind gst_find = {my_peek, my_suggest, &amp;find, };
65  *     walk = type_list = gst_type_find_factory_get_list ();
66  *     while (walk) {
67  *       GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
68  *       walk = g_list_next (walk)
69  *       gst_type_find_factory_call_function (factory, &amp;gst_find);
70  *     }
71  *     g_list_free (type_list);
72  *     return find.caps;
73  *   };
74  * ]|
75  */
76
77 #include "gst_private.h"
78 #include "gstinfo.h"
79 #include "gsttypefind.h"
80 #include "gsttypefindfactory.h"
81 #include "gstregistry.h"
82
83 GST_DEBUG_CATEGORY (type_find_debug);
84 #define GST_CAT_DEFAULT type_find_debug
85
86 static void gst_type_find_factory_dispose (GObject * object);
87
88 #define _do_init \
89 { \
90   GST_DEBUG_CATEGORY_INIT (type_find_debug, "GST_TYPEFIND", \
91       GST_DEBUG_FG_GREEN, "typefinding subsystem"); \
92 }
93
94 #define gst_type_find_factory_parent_class parent_class
95 G_DEFINE_TYPE_WITH_CODE (GstTypeFindFactory, gst_type_find_factory,
96     GST_TYPE_PLUGIN_FEATURE, _do_init);
97
98 static void
99 gst_type_find_factory_class_init (GstTypeFindFactoryClass * klass)
100 {
101   GObjectClass *object_class = G_OBJECT_CLASS (klass);
102
103   object_class->dispose = gst_type_find_factory_dispose;
104 }
105
106 static void
107 gst_type_find_factory_init (GstTypeFindFactory * factory)
108 {
109   factory->user_data = factory;
110   factory->user_data_notify = NULL;
111 }
112
113 static void
114 gst_type_find_factory_dispose (GObject * object)
115 {
116   GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (object);
117
118   if (factory->caps) {
119     gst_caps_unref (factory->caps);
120     factory->caps = NULL;
121   }
122   if (factory->extensions) {
123     g_strfreev (factory->extensions);
124     factory->extensions = NULL;
125   }
126   if (factory->user_data_notify && factory->user_data) {
127     factory->user_data_notify (factory->user_data);
128     factory->user_data = NULL;
129   }
130
131   G_OBJECT_CLASS (parent_class)->dispose (object);
132 }
133
134 /**
135  * gst_type_find_factory_get_list:
136  *
137  * Gets the list of all registered typefind factories. You must free the
138  * list using gst_plugin_feature_list_free().
139  *
140  * The returned factories are sorted by highest rank first, and then by
141  * factory name.
142  *
143  * Free-function: gst_plugin_feature_list_free
144  *
145  * Returns: (transfer full) (element-type Gst.TypeFindFactory): the list of all
146  *     registered #GstTypeFindFactory.
147  */
148 GList *
149 gst_type_find_factory_get_list (void)
150 {
151   return gst_registry_get_feature_list (gst_registry_get (),
152       GST_TYPE_TYPE_FIND_FACTORY);
153 }
154
155 /**
156  * gst_type_find_factory_get_caps:
157  * @factory: A #GstTypeFindFactory
158  *
159  * Gets the #GstCaps associated with a typefind factory.
160  *
161  * Returns: (transfer none): the #GstCaps associated with this factory
162  */
163 GstCaps *
164 gst_type_find_factory_get_caps (GstTypeFindFactory * factory)
165 {
166   g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
167
168   return factory->caps;
169 }
170
171 /**
172  * gst_type_find_factory_get_extensions:
173  * @factory: A #GstTypeFindFactory
174  *
175  * Gets the extensions associated with a #GstTypeFindFactory. The returned
176  * array should not be changed. If you need to change stuff in it, you should
177  * copy it using g_strdupv().  This function may return %NULL to indicate
178  * a 0-length list.
179  *
180  * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): a
181  *     %NULL-terminated array of extensions associated with this factory
182  */
183 const gchar *const *
184 gst_type_find_factory_get_extensions (GstTypeFindFactory * factory)
185 {
186   g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), NULL);
187
188   return (const gchar * const *) factory->extensions;
189 }
190
191 /**
192  * gst_type_find_factory_call_function:
193  * @factory: A #GstTypeFindFactory
194  * @find: (transfer none): a properly setup #GstTypeFind entry. The get_data
195  *     and suggest_type members must be set.
196  *
197  * Calls the #GstTypeFindFunction associated with this factory.
198  */
199 void
200 gst_type_find_factory_call_function (GstTypeFindFactory * factory,
201     GstTypeFind * find)
202 {
203   GstTypeFindFactory *new_factory;
204
205   g_return_if_fail (GST_IS_TYPE_FIND_FACTORY (factory));
206   g_return_if_fail (find != NULL);
207   g_return_if_fail (find->peek != NULL);
208   g_return_if_fail (find->suggest != NULL);
209
210   new_factory =
211       GST_TYPE_FIND_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE
212           (factory)));
213   if (new_factory) {
214     if (new_factory->function)
215       new_factory->function (find, new_factory->user_data);
216     gst_object_unref (new_factory);
217   }
218 }
219
220 /**
221  * gst_type_find_factory_has_function:
222  * @factory: A #GstTypeFindFactory
223  *
224  * Check whether the factory has a typefind function. Typefind factories
225  * without typefind functions are a last-effort fallback mechanism to
226  * e.g. assume a certain media type based on the file extension.
227  *
228  * Returns: %TRUE if the factory has a typefind functions set, otherwise %FALSE
229  */
230 gboolean
231 gst_type_find_factory_has_function (GstTypeFindFactory * factory)
232 {
233   g_return_val_if_fail (GST_IS_TYPE_FIND_FACTORY (factory), FALSE);
234
235   return (factory->function != NULL);
236 }