summaryrefslogtreecommitdiffstats
path: root/meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c')
-rw-r--r--meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c487
1 files changed, 487 insertions, 0 deletions
diff --git a/meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c b/meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c
new file mode 100644
index 0000000000..c1f3e71af6
--- /dev/null
+++ b/meta/recipes-multimedia/gstreamer/gstreamer-0.10.29/gstregistrybinary.c
@@ -0,0 +1,487 @@
1/* GStreamer
2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 * 2005 David A. Schleef <ds@schleef.org>
5 *
6 * gstregistryxml.c: GstRegistry object, support routines
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it ulnder the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
22 */
23
24
25#include <gst/gstregistrybinary.h>
26
27/*
28** Simple handy function to write a memory location to the registry cache file
29*/
30inline static gboolean
31gst_registry_binary_write(GstRegistry *registry, const void *mem, const ssize_t size)
32{
33 if (write(registry->cache_file, mem, size) != size)
34 {
35 GST_ERROR("Failed to write binary registry element: ptr=%p size=%u error=%s\n",
36 mem, size, strerror(errno));
37 return FALSE;
38 }
39 return TRUE;
40}
41
42/*
43** Save features GstBinary style
44*/
45static gboolean
46gst_registry_binary_fill_feature(GList **list, GstPluginFeature *orig, GstBinaryPluginFeature *dest, const char *name)
47{
48 GstBinaryChunck *chk;
49
50 if ((chk = calloc(1, sizeof (GstBinaryChunck))) == NULL)
51 return FALSE;
52
53 chk->data = dest;
54 chk->size = sizeof (GstBinaryPluginFeature);
55
56 *list = g_list_append(*list, chk);
57
58 dest->rank = orig->rank;
59 if (!strncpy(dest->typename, name, GST_BINARY_REGISTRY_TYPENAME_TYPENAME_LEN) ||
60 !strncpy(dest->name, orig->name, GST_BINARY_REGISTRY_TYPENAME_NAME_LEN))
61 {
62 GST_ERROR("Failed to write binary registry feature");
63 goto fail;
64 }
65
66 if (GST_IS_ELEMENT_FACTORY(orig))
67 {
68 GstElementFactory *factory = GST_ELEMENT_FACTORY(orig);
69
70 if (!strncpy(dest->longname, factory->details.longname, GST_BINARY_REGISTRY_TYPENAME_LONGNAME_LEN) ||
71 !strncpy(dest->class, factory->details.klass, GST_BINARY_REGISTRY_TYPENAME_CLASS_LEN) ||
72 !strncpy(dest->description, factory->details.description, GST_BINARY_REGISTRY_TYPENAME_DESCRIPTION_LEN) ||
73 !strncpy(dest->author, factory->details.author, GST_BINARY_REGISTRY_TYPENAME_AUTHOR_LEN))
74 {
75 GST_ERROR("Failed to write binary registry feature");
76 goto fail;
77 }
78 }
79
80 dest->npadtemplates = dest->ninterfaces = dest->nuritypes = 0;
81 return TRUE;
82
83 fail:
84 free(chk);
85 return FALSE;
86}
87
88
89/*
90** Initialize the GstBinaryRegistryMagic, setting both our magic number and gstreamer major/minor version
91*/
92inline static gboolean
93gst_registry_binary_initialize_magic(GstBinaryRegistryMagic *m)
94{
95 if (!strncpy(m->magic, GST_MAGIC_BINARY_REGISTRY_STR, GST_MAGIC_BINARY_REGISTRY_LEN) ||
96 !strncpy(m->version, GST_MAJORMINOR, GST_BINARY_REGISTRY_VERSION_LEN))
97 {
98 GST_ERROR("Failed to write magic to the registry magic structure");
99 return FALSE;
100 }
101 return TRUE;
102}
103
104/*
105** Check GstBinaryRegistryMagic validity.
106** Return a pointer pointing right after the magic structure
107*/
108static gchar *
109gst_registry_binary_check_magic(gchar *in)
110{
111 GstBinaryRegistryMagic *m = (GstBinaryRegistryMagic *) in;
112
113 if (m == NULL || m->magic == NULL || m->version == NULL)
114 {
115 GST_ERROR("Binary registry magic structure is broken");
116 return NULL;
117 }
118 if (strncmp(m->magic, GST_MAGIC_BINARY_REGISTRY_STR, GST_MAGIC_BINARY_REGISTRY_LEN) != 0)
119 {
120 GST_ERROR("Binary registry magic is different : %02x%02x%02x%02x != %02x%02x%02x%02x",
121 GST_MAGIC_BINARY_REGISTRY_STR[0] & 0xff, GST_MAGIC_BINARY_REGISTRY_STR[1] & 0xff,
122 GST_MAGIC_BINARY_REGISTRY_STR[2] & 0xff, GST_MAGIC_BINARY_REGISTRY_STR[3] & 0xff,
123 m->magic[0] & 0xff, m->magic[1] & 0xff, m->magic[2] & 0xff, m->magic[3] & 0xff);
124 return NULL;
125 }
126 if (strncmp(m->version, GST_MAJORMINOR, GST_BINARY_REGISTRY_VERSION_LEN))
127 {
128 GST_ERROR("Binary registry magic version is different : %s != %s",
129 GST_MAJORMINOR, m->version);
130 return NULL;
131 }
132 return (in + sizeof (GstBinaryRegistryMagic));
133}
134
135/*
136** Adapt a GstPlugin to our GstBinaryPluginElement structure, and write it to the
137** registry file.
138*/
139static gboolean
140gst_registry_binary_save_plugin(GList **list, GstRegistry *registry, GstPlugin *plugin)
141{
142 GstBinaryPluginElement *e;
143 GstBinaryChunck *chk;
144 GList *walk;
145
146 if ((e = calloc(1, sizeof (GstBinaryPluginElement))) == NULL ||
147 (chk = calloc(1, sizeof (GstBinaryChunck))) == NULL)
148 return FALSE;
149
150 chk->data = e;
151 chk->size = sizeof (GstBinaryPluginElement);
152 *list = g_list_append(*list, chk);
153
154 if (!strncpy(e->name, plugin->desc.name, GST_BINARY_REGISTRY_NAME_LEN) ||
155 !strncpy(e->description, plugin->desc.description, GST_BINARY_REGISTRY_DESCRIPTION_LEN) ||
156 !strncpy(e->filename, plugin->filename, _POSIX_PATH_MAX) ||
157 !strncpy(e->version, plugin->desc.version, GST_BINARY_REGISTRY_VERSION_LEN) ||
158 !strncpy(e->license, plugin->desc.license, GST_BINARY_REGISTRY_LICENSE_LEN) ||
159 !strncpy(e->source, plugin->desc.source, GST_BINARY_REGISTRY_SOURCE_LEN) ||
160 !strncpy(e->package, plugin->desc.package, GST_BINARY_REGISTRY_PACKAGE_LEN) ||
161 !strncpy(e->origin, plugin->desc.origin, GST_BINARY_REGISTRY_ORIGIN_LEN))
162 {
163 GST_DEBUG("Can't adapt GstPlugin to GstBinaryPluginElement");
164 goto fail;
165 }
166
167 e->size = plugin->file_size;
168 e->m32p = plugin->file_mtime;
169
170 GList *ft_list = gst_registry_get_feature_list_by_plugin(registry, plugin->desc.name);
171
172 for (walk = ft_list; walk; walk = g_list_next(walk), e->nfeatures++)
173 {
174 GstPluginFeature *curfeat = GST_PLUGIN_FEATURE (walk->data);
175 GstBinaryPluginFeature *newfeat;
176 const char *feat_name = g_type_name(G_OBJECT_TYPE(curfeat));
177
178 if ((newfeat = calloc(1, sizeof (GstBinaryPluginFeature))) == NULL)
179 goto fail;
180
181 if (!feat_name || !gst_registry_binary_fill_feature(list, curfeat, newfeat, feat_name))
182 {
183 GST_ERROR("Can't fill plugin feature, aborting.");
184 goto fail;
185 }
186 }
187
188 GST_DEBUG("Found %d features in plugin \"%s\"\n", e->nfeatures, e->name);
189 return TRUE;
190
191 fail:
192 free(chk);
193 free(e);
194 return FALSE;
195}
196
197/*
198** Write the cache to file. Part of the code was taken from gstregistryxml.c
199*/
200gboolean
201gst_registry_binary_write_cache(GstRegistry *registry, const char *location)
202{
203 GList *walk;
204 char *tmp_location;
205 GstBinaryRegistryMagic *magic;
206 GstBinaryChunck *magic_chunck;
207 GList *to_write = NULL;
208
209 GST_INFO("Writing binary registry cache");
210
211 g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
212 tmp_location = g_strconcat (location, ".tmpXXXXXX", NULL);
213 registry->cache_file = g_mkstemp (tmp_location);
214 if (registry->cache_file == -1)
215 {
216 char *dir;
217
218 /* oops, I bet the directory doesn't exist */
219 dir = g_path_get_dirname (location);
220 g_mkdir_with_parents (dir, 0777);
221 g_free (dir);
222
223 registry->cache_file = g_mkstemp (tmp_location);
224 }
225
226 if (registry->cache_file == -1)
227 goto fail;
228
229 if ((magic = calloc(1, sizeof (GstBinaryRegistryMagic))) == NULL ||
230 !gst_registry_binary_initialize_magic(magic))
231 goto fail;
232
233 if ((magic_chunck = calloc(1, sizeof (GstBinaryChunck))) == NULL)
234 goto fail;
235
236 magic_chunck->data = magic;
237 magic_chunck->size = sizeof (GstBinaryRegistryMagic);
238 to_write = g_list_append(to_write, magic_chunck);
239
240 /* Iterate trough the list of plugins in the GstRegistry and adapt them to our structures */
241 for (walk = g_list_last(registry->plugins); walk; walk = g_list_previous(walk))
242 {
243 GstPlugin *plugin = GST_PLUGIN(walk->data);
244
245 if (!plugin->filename)
246 continue;
247
248 if (plugin->flags & GST_PLUGIN_FLAG_CACHED)
249 {
250 int ret;
251 struct stat statbuf;
252
253 ret = g_stat (plugin->filename, &statbuf);
254 if ((ret = g_stat (plugin->filename, &statbuf)) < 0 ||
255 plugin->file_mtime != statbuf.st_mtime ||
256 plugin->file_size != statbuf.st_size)
257 continue;
258 }
259
260 if (!gst_registry_binary_save_plugin(&to_write, registry, plugin))
261 {
262 GST_ERROR("Can't write binary plugin information for \"%s\"", plugin->filename);
263 continue; /* Try anyway */
264 }
265 }
266
267 for (walk = g_list_first(to_write); walk; walk = g_list_next(walk))
268 {
269 GstBinaryChunck *cur = walk->data;
270
271 if (!gst_registry_binary_write(registry, cur->data, cur->size))
272 {
273 free(cur->data);
274 free(cur);
275 g_list_free(to_write);
276 goto fail;
277 }
278 free(cur->data);
279 free(cur);
280 }
281 g_list_free(to_write);
282
283 if (close(registry->cache_file) < 0)
284 {
285 GST_DEBUG("Can't close registry file : %s", strerror(errno));
286 goto fail;
287 }
288
289 if (g_file_test (tmp_location, G_FILE_TEST_EXISTS)) {
290#ifdef WIN32
291 remove (location);
292#endif
293 rename (tmp_location, location);
294 }
295
296 g_free (tmp_location);
297 return TRUE;
298
299 fail:
300 g_free(tmp_location);
301 return FALSE;
302}
303
304static GstPluginFeature*
305gst_registry_binary_load_feature(GstBinaryPluginFeature *in)
306{
307 GstPluginFeature *feature;
308 GType type;
309
310 if (!in->typename || !*(in->typename))
311 return NULL;
312
313 /* GST_INFO("Plugin feature typename : %s", in->typename);*/
314
315 if (!(type = g_type_from_name(in->typename)))
316 {
317 GST_ERROR("Unknown type from typename");
318 return NULL;
319 }
320 feature = g_object_new (type, NULL);
321
322 if (!feature) {
323 GST_ERROR("Can't create feature from type");
324 return NULL;
325 }
326
327 if (!GST_IS_PLUGIN_FEATURE (feature)) {
328 /* don't really know what it is */
329 if (GST_IS_OBJECT (feature))
330 gst_object_unref (feature);
331 else
332 g_object_unref (feature);
333 return NULL;
334 }
335
336 feature->name = g_strdup(in->name);
337 feature->rank = in->rank;
338
339 if (GST_IS_ELEMENT_FACTORY(feature))
340 {
341 GstElementFactory *factory = GST_ELEMENT_FACTORY(feature);
342
343 factory->details.longname = g_strdup(in->longname);
344 factory->details.klass = g_strdup(in->class);
345 factory->details.description = g_strdup(in->description);
346 factory->details.author = g_strdup(in->author);
347
348 /* GST_INFO("Element factory : %s", factory->details.longname); */
349 }
350
351 GST_DEBUG("Added feature %p with name %s", feature, feature->name);
352 return feature;
353}
354
355/*
356** Make a new plugin from current GstBinaryPluginElement structure
357** and save it to the GstRegistry. Return an offset to the next
358** GstBinaryPluginElement structure.
359*/
360static unsigned long
361gst_registry_binary_get_binary_plugin(GstRegistry *registry, gchar *in)
362{
363 GstBinaryPluginElement *p = (GstBinaryPluginElement *) in;
364 GstPlugin *plugin = NULL;
365 GList *plugin_features = NULL;
366 GstBinaryPluginFeature *feat;
367 unsigned int i;
368 unsigned long offset;
369
370 plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
371
372 plugin->flags |= GST_PLUGIN_FLAG_CACHED;
373
374 plugin->desc.name = g_strdup(p->name);
375 plugin->desc.description= g_strdup(p->description);
376 plugin->filename = g_strdup(p->filename);
377 plugin->desc.version = g_strdup(p->version);
378 plugin->desc.license = g_strdup(p->license);
379 plugin->desc.source = g_strdup(p->source);
380 plugin->desc.package = g_strdup(p->package);
381 plugin->desc.origin = g_strdup(p->origin);
382 plugin->file_mtime = p->m32p;
383 plugin->file_size = p->size;
384 plugin->basename = g_path_get_basename (plugin->filename);
385
386 if (plugin->file_mtime < 0 || plugin->file_size < 0)
387 {
388 GST_ERROR("Plugin time or file size is not valid !");
389 g_free(plugin);
390 return -1;
391 }
392
393 if (p->nfeatures < 0)
394 {
395 GST_ERROR("The number of feature structure is not valid !");
396 gst_object_unref(plugin);
397 return -1;
398 }
399
400 for (feat = (GstBinaryPluginFeature *) (in + sizeof (GstBinaryPluginElement)), i = 0;
401 i < p->nfeatures; i++, feat++)
402 {
403 GstPluginFeature *gstfeat;
404
405 if ((gstfeat = gst_registry_binary_load_feature(feat)) == NULL)
406 {
407 g_list_free(plugin_features);
408 g_free(plugin);
409 GST_ERROR("Error while loading binary feature");
410 return -1;
411 }
412 gstfeat->plugin_name = g_strdup(plugin->desc.name);
413 plugin_features = g_list_prepend(plugin_features, gstfeat);
414 }
415
416 GST_DEBUG("Added plugin \"%s\" to global registry from binary registry", plugin->desc.name);
417 GList *g;
418
419 gst_registry_add_plugin (registry, plugin);
420 for (g = plugin_features; g; g = g_list_next (g))
421 gst_registry_add_feature (registry, GST_PLUGIN_FEATURE (g->data));
422 /* g_list_free(plugin_features); */
423
424 offset = sizeof (GstBinaryPluginElement) + p->nfeatures * sizeof (GstBinaryPluginFeature);
425 return offset;
426}
427
428
429/*
430** Read the cache and adapt it to fill GstRegistry
431*/
432gboolean
433gst_registry_binary_read_cache(GstRegistry *registry, const char *location)
434{
435 GMappedFile *mapped = NULL;
436 GTimer *timer = NULL;
437 gchar *contents = NULL;
438 gdouble seconds;
439 unsigned long offset, inc;
440 gsize size;
441
442 /* make sure these types exist */
443 GST_TYPE_ELEMENT_FACTORY;
444 GST_TYPE_TYPE_FIND_FACTORY;
445 GST_TYPE_INDEX_FACTORY;
446
447 timer = g_timer_new ();
448
449 if ((mapped = g_mapped_file_new(location, FALSE, NULL)) == NULL ||
450 (contents = g_mapped_file_get_contents(mapped)) == NULL)
451 {
452 GST_ERROR("Can't load file : %s", strerror(errno));
453 return FALSE;
454 }
455 if ((contents = gst_registry_binary_check_magic(contents)) == NULL)
456 {
457 GST_ERROR("Binary registry type not recognized (invalid magic)");
458 g_mapped_file_free(mapped);
459 return FALSE;
460 }
461
462 if ((size = g_mapped_file_get_length(mapped)) < sizeof (GstBinaryPluginElement))
463 {
464 GST_INFO("No binary plugins structure to read");
465 return TRUE; /* This is not really an error */
466 }
467
468 for (offset = inc = 0; (offset + sizeof (GstBinaryPluginElement)) < size &&
469 (inc = gst_registry_binary_get_binary_plugin(registry, contents + offset)) > 0;
470 offset += inc)
471 ; /* May want in the future to do something here */
472 if (inc < 0)
473 {
474 GST_DEBUG("Problem while reading binary registry");
475 return FALSE;
476 }
477
478 g_timer_stop (timer);
479 seconds = g_timer_elapsed (timer, NULL);
480 g_timer_destroy (timer);
481
482 GST_INFO ("loaded %s in %f seconds", location, seconds);
483
484 if (mapped)
485 g_mapped_file_free (mapped);
486 return TRUE;
487}