summaryrefslogtreecommitdiff
path: root/gst/gstregistrybinary.c
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2009-03-14 23:07:40 +0000
committerJan Schmidt <thaytan@noraisin.net>2009-10-06 19:51:42 +0100
commit51675e0c2a1bcf0263e45a74ab0da081469b3236 (patch)
treedb9ad1db6d6ef438c4bb2f5875c6be2b8ea26779 /gst/gstregistrybinary.c
parent1f4e47703348686bb2bf2b8c314eeff0e9066ff9 (diff)
registry: Add registry helper phase 1
Phase 1 of adding the registry scan helper
Diffstat (limited to 'gst/gstregistrybinary.c')
-rw-r--r--gst/gstregistrybinary.c854
1 files changed, 69 insertions, 785 deletions
diff --git a/gst/gstregistrybinary.c b/gst/gstregistrybinary.c
index 661685ea88..576ab0221f 100644
--- a/gst/gstregistrybinary.c
+++ b/gst/gstregistrybinary.c
@@ -61,6 +61,7 @@
#include <gst/gstenumtypes.h>
#include <gst/gstpadtemplate.h>
+#include <gst/gstregistrychunks.h>
#include <gst/gstregistrybinary.h>
#include <glib/gstdio.h> /* for g_stat(), g_mapped_file(), ... */
@@ -70,25 +71,7 @@
#define GST_CAT_DEFAULT GST_CAT_REGISTRY
-/* count string length, but return -1 if we hit the eof */
-static gint
-_strnlen (const gchar * str, gint maxlen)
-{
- gint len = 0;
-
- if (G_UNLIKELY (len == maxlen))
- return -1;
-
- while (*str++ != '\0') {
- len++;
- if (G_UNLIKELY (len == maxlen))
- return -1;
- }
- return len;
-}
-
/* reading macros */
-
#define unpack_element(inptr, outptr, element, endptr, error_label) G_STMT_START{ \
if (inptr + sizeof(element) >= endptr) \
goto error_label; \
@@ -96,22 +79,6 @@ _strnlen (const gchar * str, gint maxlen)
inptr += sizeof (element); \
}G_STMT_END
-#define unpack_const_string(inptr, outptr, endptr, error_label) G_STMT_START{\
- gint _len = _strnlen (inptr, (endptr-inptr)); \
- if (_len == -1) \
- goto error_label; \
- outptr = g_intern_string ((const gchar *)inptr); \
- inptr += _len + 1; \
-}G_STMT_END
-
-#define unpack_string(inptr, outptr, endptr, error_label) G_STMT_START{\
- gint _len = _strnlen (inptr, (endptr-inptr)); \
- if (_len == -1) \
- goto error_label; \
- outptr = g_memdup ((gconstpointer)inptr, _len + 1); \
- inptr += _len + 1; \
-}G_STMT_END
-
#define ALIGNMENT (sizeof (void *))
#define alignment(_address) (gsize)_address%ALIGNMENT
#define align(_ptr) _ptr += (( alignment(_ptr) == 0) ? 0 : ALIGNMENT-alignment(_ptr))
@@ -140,9 +107,8 @@ gst_registry_binary_cache_init (GstRegistry * registry, const char *location)
}
static int
-gst_registry_binary_cache_write (GstRegistry * registry,
- BinaryRegistryCache * cache, unsigned long offset,
- const void *data, int length)
+gst_registry_binary_cache_write (BinaryRegistryCache * cache,
+ unsigned long offset, const void *data, int length)
{
cache->len = MAX (offset + length, cache->len);
cache->mem = g_realloc (cache->mem, cache->len);
@@ -153,8 +119,7 @@ gst_registry_binary_cache_write (GstRegistry * registry,
}
static gboolean
-gst_registry_binary_cache_finish (GstRegistry * registry,
- BinaryRegistryCache * cache, gboolean success)
+gst_registry_binary_cache_finish (BinaryRegistryCache * cache, gboolean success)
{
gboolean ret = TRUE;
GError *error = NULL;
@@ -171,9 +136,21 @@ gst_registry_binary_cache_finish (GstRegistry * registry,
if (!g_file_set_contents (cache->location, (const gchar *) cache->mem,
cache->len, &error)) {
- GST_ERROR ("Failed to write to cache file: %s", error->message);
+ /* Probably the directory didn't exist; create it */
+ gchar *dir;
+ dir = g_path_get_dirname (cache->location);
+ g_mkdir_with_parents (dir, 0777);
+ g_free (dir);
+
g_error_free (error);
- ret = FALSE;
+ error = NULL;
+
+ if (!g_file_set_contents (cache->location, (const gchar *) cache->mem,
+ cache->len, &error)) {
+ GST_ERROR ("Failed to write to cache file: %s", error->message);
+ g_error_free (error);
+ ret = FALSE;
+ }
}
}
@@ -188,6 +165,7 @@ typedef struct BinaryRegistryCache
const char *location;
char *tmp_location;
unsigned long currentoffset;
+ int cache_fd;
} BinaryRegistryCache;
static BinaryRegistryCache *
@@ -197,8 +175,8 @@ gst_registry_binary_cache_init (GstRegistry * registry, const char *location)
cache->location = location;
cache->tmp_location = g_strconcat (location, ".tmpXXXXXX", NULL);
- registry->cache_file = g_mkstemp (cache->tmp_location);
- if (registry->cache_file == -1) {
+ cache->cache_fd = g_mkstemp (cache->tmp_location);
+ if (cache->cache_fd == -1) {
gchar *dir;
/* oops, I bet the directory doesn't exist */
@@ -209,9 +187,9 @@ gst_registry_binary_cache_init (GstRegistry * registry, const char *location)
/* the previous g_mkstemp call overwrote the XXXXXX placeholder ... */
g_free (cache->tmp_location);
cache->tmp_location = g_strconcat (location, ".tmpXXXXXX", NULL);
- registry->cache_file = g_mkstemp (cache->tmp_location);
+ cache->cache_fd = g_mkstemp (cache->tmp_location);
- if (registry->cache_file == -1) {
+ if (cache->cache_fd == -1) {
GST_DEBUG ("g_mkstemp() failed: %s", g_strerror (errno));
g_free (cache->tmp_location);
g_free (cache);
@@ -223,20 +201,19 @@ gst_registry_binary_cache_init (GstRegistry * registry, const char *location)
}
static int
-gst_registry_binary_cache_write (GstRegistry * registry,
- BinaryRegistryCache * cache, unsigned long offset,
- const void *data, int length)
+gst_registry_binary_cache_write (BinaryRegistryCache * cache,
+ unsigned long offset, const void *data, int length)
{
long written;
if (offset != cache->currentoffset) {
- if (lseek (registry->cache_file, offset, SEEK_SET) != 0) {
+ if (lseek (cache->cache_fd, offset, SEEK_SET) != 0) {
GST_ERROR ("Seeking to new offset failed");
return FALSE;
}
cache->currentoffset = offset;
}
- written = write (registry->cache_file, data, length);
+ written = write (cache->cache_fd, data, length);
if (written != length) {
GST_ERROR ("Failed to write to cache file");
}
@@ -246,20 +223,21 @@ gst_registry_binary_cache_write (GstRegistry * registry,
}
static gboolean
-gst_registry_binary_cache_finish (GstRegistry * registry,
- BinaryRegistryCache * cache, gboolean success)
+gst_registry_binary_cache_finish (BinaryRegistryCache * cache, gboolean success)
{
/* only fsync if we're actually going to use and rename the file below */
- if (success && fsync (registry->cache_file) < 0)
+ if (success && fsync (cache->cache_fd) < 0)
goto fsync_failed;
- if (close (registry->cache_file) < 0)
+ if (close (cache->cache_fd) < 0)
goto close_failed;
if (success) {
/* Only do the rename if we wrote the entire file successfully */
- if (g_rename (cache->tmp_location, cache->location) < 0)
+ if (g_rename (cache->tmp_location, cache->location) < 0) {
+ GST_ERROR ("g_rename() failed: %s", g_strerror (errno));
goto rename_failed;
+ }
}
g_free (cache->tmp_location);
@@ -301,17 +279,16 @@ rename_failed:
* Returns: %TRUE for success
*/
inline static gboolean
-gst_registry_binary_write_chunk (GstRegistry * registry,
- BinaryRegistryCache * cache, const void *mem,
- const gssize size, unsigned long *file_position, gboolean align)
+gst_registry_binary_write_chunk (BinaryRegistryCache * cache,
+ GstRegistryChunk * chunk, unsigned long *file_position)
{
gchar padder[ALIGNMENT] = { 0, };
int padsize = 0;
/* Padding to insert the struct that requiere word alignment */
- if ((align) && (alignment (*file_position) != 0)) {
+ if ((chunk->align) && (alignment (*file_position) != 0)) {
padsize = ALIGNMENT - alignment (*file_position);
- if (gst_registry_binary_cache_write (registry, cache, *file_position,
+ if (gst_registry_binary_cache_write (cache, *file_position,
padder, padsize) != padsize) {
GST_ERROR ("Failed to write binary registry padder");
return FALSE;
@@ -319,13 +296,13 @@ gst_registry_binary_write_chunk (GstRegistry * registry,
*file_position += padsize;
}
- if (gst_registry_binary_cache_write (registry, cache, *file_position,
- mem, size) != size) {
+ if (gst_registry_binary_cache_write (cache, *file_position,
+ chunk->data, chunk->size) != chunk->size) {
GST_ERROR ("Failed to write binary registry element");
return FALSE;
}
- *file_position += size;
+ *file_position += chunk->size;
return TRUE;
}
@@ -353,359 +330,6 @@ gst_registry_binary_initialize_magic (GstBinaryRegistryMagic * m)
return TRUE;
}
-
-/*
- * gst_registry_binary_save_const_string:
- *
- * Store a const string in a binary chunk.
- *
- * Returns: %TRUE for success
- */
-inline static gboolean
-gst_registry_binary_save_const_string (GList ** list, const gchar * str)
-{
- GstBinaryChunk *chunk;
-
- if (G_UNLIKELY (str == NULL)) {
- GST_ERROR ("unexpected NULL string in plugin or plugin feature data");
- str = "";
- }
-
- chunk = g_malloc (sizeof (GstBinaryChunk));
- chunk->data = (gpointer) str;
- chunk->size = strlen ((gchar *) chunk->data) + 1;
- chunk->flags = GST_BINARY_REGISTRY_FLAG_CONST;
- chunk->align = FALSE;
- *list = g_list_prepend (*list, chunk);
- return TRUE;
-}
-
-/*
- * gst_registry_binary_save_string:
- *
- * Store a string in a binary chunk.
- *
- * Returns: %TRUE for success
- */
-inline static gboolean
-gst_registry_binary_save_string (GList ** list, gchar * str)
-{
- GstBinaryChunk *chunk;
-
- chunk = g_malloc (sizeof (GstBinaryChunk));
- chunk->data = str;
- chunk->size = strlen ((gchar *) chunk->data) + 1;
- chunk->flags = GST_BINARY_REGISTRY_FLAG_NONE;
- chunk->align = FALSE;
- *list = g_list_prepend (*list, chunk);
- return TRUE;
-}
-
-
-/*
- * gst_registry_binary_save_data:
- *
- * Store some data in a binary chunk.
- *
- * Returns: the initialized chunk
- */
-inline static GstBinaryChunk *
-gst_registry_binary_make_data (gpointer data, gulong size)
-{
- GstBinaryChunk *chunk;
-
- chunk = g_malloc (sizeof (GstBinaryChunk));
- chunk->data = data;
- chunk->size = size;
- chunk->flags = GST_BINARY_REGISTRY_FLAG_NONE;
- chunk->align = TRUE;
- return chunk;
-}
-
-
-/*
- * gst_registry_binary_save_pad_template:
- *
- * Store pad_templates in binary chunks.
- *
- * Returns: %TRUE for success
- */
-static gboolean
-gst_registry_binary_save_pad_template (GList ** list,
- GstStaticPadTemplate * template)
-{
- GstBinaryPadTemplate *pt;
- GstBinaryChunk *chk;
-
- pt = g_malloc0 (sizeof (GstBinaryPadTemplate));
- chk = gst_registry_binary_make_data (pt, sizeof (GstBinaryPadTemplate));
-
- pt->presence = template->presence;
- pt->direction = template->direction;
-
- /* pack pad template strings */
- gst_registry_binary_save_const_string (list,
- (gchar *) (template->static_caps.string));
- gst_registry_binary_save_const_string (list, template->name_template);
-
- *list = g_list_prepend (*list, chk);
-
- return TRUE;
-}
-
-
-/*
- * gst_registry_binary_save_feature:
- *
- * Store features in binary chunks.
- *
- * Returns: %TRUE for success
- */
-static gboolean
-gst_registry_binary_save_feature (GList ** list, GstPluginFeature * feature)
-{
- const gchar *type_name = g_type_name (G_OBJECT_TYPE (feature));
- GstBinaryPluginFeature *pf = NULL;
- GstBinaryChunk *chk = NULL;
- GList *walk;
-
- if (!type_name) {
- GST_ERROR ("NULL feature type_name, aborting.");
- return FALSE;
- }
-
- if (GST_IS_ELEMENT_FACTORY (feature)) {
- GstBinaryElementFactory *ef;
- GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
-
- ef = g_malloc0 (sizeof (GstBinaryElementFactory));
- chk = gst_registry_binary_make_data (ef, sizeof (GstBinaryElementFactory));
- ef->npadtemplates = ef->ninterfaces = ef->nuriprotocols = 0;
- pf = (GstBinaryPluginFeature *) ef;
-
- /* save interfaces */
- for (walk = factory->interfaces; walk;
- walk = g_list_next (walk), ef->ninterfaces++) {
- gst_registry_binary_save_const_string (list, (gchar *) walk->data);
- }
- GST_DEBUG ("Saved %d Interfaces", ef->ninterfaces);
- /* save uritypes */
- if (GST_URI_TYPE_IS_VALID (factory->uri_type)) {
- if (factory->uri_protocols && *factory->uri_protocols) {
- GstBinaryChunk *subchk;
- gchar **protocol;
-
- subchk =
- gst_registry_binary_make_data (&factory->uri_type,
- sizeof (factory->uri_type));
- subchk->flags = GST_BINARY_REGISTRY_FLAG_CONST;
-
- protocol = factory->uri_protocols;
- while (*protocol) {
- gst_registry_binary_save_const_string (list, *protocol++);
- ef->nuriprotocols++;
- }
- *list = g_list_prepend (*list, subchk);
- GST_DEBUG ("Saved %d UriTypes", ef->nuriprotocols);
- } else {
- g_warning ("GStreamer feature '%s' is URI handler but does not provide"
- " any protocols it can handle", feature->name);
- }
- }
-
- /* save pad-templates */
- for (walk = factory->staticpadtemplates; walk;
- walk = g_list_next (walk), ef->npadtemplates++) {
- GstStaticPadTemplate *template = walk->data;
-
- if (!gst_registry_binary_save_pad_template (list, template)) {
- GST_ERROR ("Can't fill pad template, aborting.");
- goto fail;
- }
- }
-
- /* pack element factory strings */
- gst_registry_binary_save_const_string (list, factory->details.author);
- gst_registry_binary_save_const_string (list, factory->details.description);
- gst_registry_binary_save_const_string (list, factory->details.klass);
- gst_registry_binary_save_const_string (list, factory->details.longname);
- } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
- GstBinaryTypeFindFactory *tff;
- GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
-
- tff = g_malloc0 (sizeof (GstBinaryTypeFindFactory));
- chk =
- gst_registry_binary_make_data (tff, sizeof (GstBinaryTypeFindFactory));
- tff->nextensions = 0;
- pf = (GstBinaryPluginFeature *) tff;
-
- /* save extensions */
- if (factory->extensions) {
- while (factory->extensions[tff->nextensions]) {
- gst_registry_binary_save_const_string (list,
- factory->extensions[tff->nextensions++]);
- }
- }
- /* save caps */
- if (factory->caps) {
- GstCaps *copy = gst_caps_copy (factory->caps);
- gchar *str;
-
- /* we copy the caps here so we can simplify them
- * before saving. This is a lot faster when loading
- * them later on */
- gst_caps_do_simplify (copy);
- str = gst_caps_to_string (copy);
- gst_caps_unref (copy);
- gst_registry_binary_save_string (list, str);
- } else {
- gst_registry_binary_save_const_string (list, "");
- }
-
- } else if (GST_IS_INDEX_FACTORY (feature)) {
- GstIndexFactory *factory = GST_INDEX_FACTORY (feature);
-
- pf = g_malloc0 (sizeof (GstBinaryPluginFeature));
- chk = gst_registry_binary_make_data (pf, sizeof (GstBinaryPluginFeature));
- pf->rank = feature->rank;
-
- /* pack element factory strings */
- gst_registry_binary_save_const_string (list, factory->longdesc);
- } else {
- GST_WARNING ("unhandled feature type '%s'", type_name);
- }
-
- if (pf) {
- pf->rank = feature->rank;
- *list = g_list_prepend (*list, chk);
-
- /* pack plugin feature strings */
- gst_registry_binary_save_const_string (list, feature->name);
- gst_registry_binary_save_const_string (list, (gchar *) type_name);
-
- return TRUE;
- }
-
- /* Errors */
-fail:
- g_free (chk);
- g_free (pf);
- return FALSE;
-}
-
-static gboolean
-gst_registry_binary_save_plugin_dep (GList ** list, GstPluginDep * dep)
-{
- GstBinaryDep *ed;
- GstBinaryChunk *chk;
- gchar **s;
-
- ed = g_new0 (GstBinaryDep, 1);
- chk = gst_registry_binary_make_data (ed, sizeof (GstBinaryDep));
-
- ed->flags = dep->flags;
- ed->n_env_vars = 0;
- ed->n_paths = 0;
- ed->n_names = 0;
-
- ed->env_hash = dep->env_hash;
- ed->stat_hash = dep->stat_hash;
-
- for (s = dep->env_vars; s != NULL && *s != NULL; ++s, ++ed->n_env_vars)
- gst_registry_binary_save_string (list, g_strdup (*s));
-
- for (s = dep->paths; s != NULL && *s != NULL; ++s, ++ed->n_paths)
- gst_registry_binary_save_string (list, g_strdup (*s));
-
- for (s = dep->names; s != NULL && *s != NULL; ++s, ++ed->n_names)
- gst_registry_binary_save_string (list, g_strdup (*s));
-
- *list = g_list_prepend (*list, chk);
-
- GST_LOG ("Saved external plugin dependency");
- return TRUE;
-}
-
-/*
- * gst_registry_binary_save_plugin:
- *
- * Adapt a GstPlugin to our GstBinaryPluginElement structure, and write it to
- * the registry file.
- */
-static gboolean
-gst_registry_binary_save_plugin (GList ** list, GstRegistry * registry,
- GstPlugin * plugin)
-{
- GstBinaryPluginElement *pe;
- GstBinaryChunk *chk;
- GList *plugin_features = NULL;
- GList *walk;
-
- pe = g_malloc0 (sizeof (GstBinaryPluginElement));
- chk = gst_registry_binary_make_data (pe, sizeof (GstBinaryPluginElement));
-
- pe->file_size = plugin->file_size;
- pe->file_mtime = plugin->file_mtime;
- pe->n_deps = 0;
- pe->nfeatures = 0;
-
- /* pack external deps */
- for (walk = plugin->priv->deps; walk != NULL; walk = walk->next) {
- if (!gst_registry_binary_save_plugin_dep (list, walk->data)) {
- GST_ERROR ("Could not save external plugin dependency, aborting.");
- goto fail;
- }
- ++pe->n_deps;
- }
-
- /* pack plugin features */
- plugin_features =
- gst_registry_get_feature_list_by_plugin (registry, plugin->desc.name);
- for (walk = plugin_features; walk; walk = g_list_next (walk), pe->nfeatures++) {
- GstPluginFeature *feature = GST_PLUGIN_FEATURE (walk->data);
-
- if (!gst_registry_binary_save_feature (list, feature)) {
- GST_ERROR ("Can't fill plugin feature, aborting.");
- goto fail;
- }
- }
- GST_DEBUG ("Save plugin '%s' with %d feature(s)", plugin->desc.name,
- pe->nfeatures);
-
- gst_plugin_feature_list_free (plugin_features);
-
- /* pack cache data */
- if (plugin->priv->cache_data) {
- gchar *cache_str = gst_structure_to_string (plugin->priv->cache_data);
- gst_registry_binary_save_string (list, cache_str);
- } else {
- gst_registry_binary_save_const_string (list, "");
- }
-
- /* pack plugin element strings */
- gst_registry_binary_save_const_string (list, plugin->desc.origin);
- gst_registry_binary_save_const_string (list, plugin->desc.package);
- gst_registry_binary_save_const_string (list, plugin->desc.source);
- gst_registry_binary_save_const_string (list, plugin->desc.license);
- gst_registry_binary_save_const_string (list, plugin->desc.version);
- gst_registry_binary_save_const_string (list, plugin->filename);
- gst_registry_binary_save_const_string (list, plugin->desc.description);
- gst_registry_binary_save_const_string (list, plugin->desc.name);
-
- *list = g_list_prepend (*list, chk);
-
- GST_DEBUG ("Found %d features in plugin \"%s\"", pe->nfeatures,
- plugin->desc.name);
- return TRUE;
-
- /* Errors */
-fail:
- gst_plugin_feature_list_free (plugin_features);
- g_free (chk);
- g_free (pe);
- return FALSE;
-}
-
/**
* gst_registry_binary_write_cache:
* @registry: a #GstRegistry
@@ -747,7 +371,7 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
continue;
}
- if (!gst_registry_binary_save_plugin (&to_write, registry, plugin)) {
+ if (!_priv_gst_registry_chunks_save_plugin (&to_write, registry, plugin)) {
GST_ERROR ("Can't write binary plugin information for \"%s\"",
plugin->filename);
}
@@ -760,7 +384,7 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
goto fail_free_list;
/* write magic */
- if (gst_registry_binary_cache_write (registry, cache, file_position,
+ if (gst_registry_binary_cache_write (cache, file_position,
&magic, sizeof (GstBinaryRegistryMagic)) !=
sizeof (GstBinaryRegistryMagic)) {
GST_ERROR ("Failed to write binary registry magic");
@@ -770,20 +394,20 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
/* write out data chunks */
for (walk = to_write; walk; walk = g_list_next (walk)) {
- GstBinaryChunk *cur = walk->data;
+ GstRegistryChunk *cur = walk->data;
+ gboolean res;
- if (!gst_registry_binary_write_chunk (registry, cache, cur->data, cur->size,
- &file_position, cur->align)) {
- goto fail_free_list;
- }
- if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST))
+ res = gst_registry_binary_write_chunk (cache, cur, &file_position);
+ if (!(cur->flags & GST_REGISTRY_CHUNK_FLAG_CONST))
g_free (cur->data);
g_free (cur);
walk->data = NULL;
+ if (!res)
+ goto fail_free_list;
}
g_list_free (to_write);
- if (!gst_registry_binary_cache_finish (registry, cache, TRUE))
+ if (!gst_registry_binary_cache_finish (cache, TRUE))
return FALSE;
return TRUE;
@@ -792,10 +416,10 @@ gst_registry_binary_write_cache (GstRegistry * registry, const char *location)
fail_free_list:
{
for (walk = to_write; walk; walk = g_list_next (walk)) {
- GstBinaryChunk *cur = walk->data;
+ GstRegistryChunk *cur = walk->data;
if (cur) {
- if (!(cur->flags & GST_BINARY_REGISTRY_FLAG_CONST))
+ if (!(cur->flags & GST_REGISTRY_CHUNK_FLAG_CONST))
g_free (cur->data);
g_free (cur);
}
@@ -803,7 +427,7 @@ fail_free_list:
g_list_free (to_write);
if (cache)
- (void) gst_registry_binary_cache_finish (registry, cache, FALSE);
+ (void) gst_registry_binary_cache_finish (cache, FALSE);
/* fall through */
}
fail:
@@ -857,354 +481,6 @@ fail:
return -1;
}
-
-/*
- * gst_registry_binary_load_pad_template:
- *
- * Make a new GstStaticPadTemplate from current GstBinaryPadTemplate structure
- *
- * Returns: new GstStaticPadTemplate
- */
-static gboolean
-gst_registry_binary_load_pad_template (GstElementFactory * factory, gchar ** in,
- gchar * end)
-{
- GstBinaryPadTemplate *pt;
- GstStaticPadTemplate *template = NULL;
-
- align (*in);
- GST_DEBUG ("Reading/casting for GstBinaryPadTemplate at address %p", *in);
- unpack_element (*in, pt, GstBinaryPadTemplate, end, fail);
-
- template = g_new0 (GstStaticPadTemplate, 1);
- template->presence = pt->presence;
- template->direction = pt->direction;
-
- /* unpack pad template strings */
- unpack_const_string (*in, template->name_template, end, fail);
- unpack_string (*in, template->static_caps.string, end, fail);
-
- __gst_element_factory_add_static_pad_template (factory, template);
- GST_DEBUG ("Added pad_template %s", template->name_template);
-
- return TRUE;
-
-fail:
- GST_INFO ("Reading pad template failed");
- g_free (template);
- return FALSE;
-}
-
-
-/*
- * gst_registry_binary_load_feature:
- *
- * Make a new GstPluginFeature from current binary plugin feature structure
- *
- * Returns: new GstPluginFeature
- */
-static gboolean
-gst_registry_binary_load_feature (GstRegistry * registry, gchar ** in,
- gchar * end, const gchar * plugin_name)
-{
- GstBinaryPluginFeature *pf = NULL;
- GstPluginFeature *feature = NULL;
- gchar *type_name = NULL, *str;
- GType type;
- guint i;
-
- /* unpack plugin feature strings */
- unpack_string (*in, type_name, end, fail);
-
- if (G_UNLIKELY (!type_name)) {
- GST_ERROR ("No feature type name");
- return FALSE;
- }
-
- GST_DEBUG ("Plugin '%s' feature typename : '%s'", plugin_name, type_name);
-
- if (G_UNLIKELY (!(type = g_type_from_name (type_name)))) {
- GST_ERROR ("Unknown type from typename '%s' for plugin '%s'", type_name,
- plugin_name);
- g_free (type_name);
- return FALSE;
- }
- if (G_UNLIKELY ((feature = g_object_new (type, NULL)) == NULL)) {
- GST_ERROR ("Can't create feature from type");
- g_free (type_name);
- return FALSE;
- }
-
- if (G_UNLIKELY (!GST_IS_PLUGIN_FEATURE (feature))) {
- GST_ERROR ("typename : '%s' is not a plugin feature", type_name);
- goto fail;
- }
-
- /* unpack more plugin feature strings */
- unpack_string (*in, feature->name, end, fail);
-
- if (GST_IS_ELEMENT_FACTORY (feature)) {
- GstBinaryElementFactory *ef;
- guint n;
- GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (feature);
-
- align (*in);
- GST_LOG ("Reading/casting for GstBinaryElementFactory at address %p", *in);
- unpack_element (*in, ef, GstBinaryElementFactory, end, fail);
- pf = (GstBinaryPluginFeature *) ef;
-
- /* unpack element factory strings */
- unpack_string (*in, factory->details.longname, end, fail);
- unpack_string (*in, factory->details.klass, end, fail);
- unpack_string (*in, factory->details.description, end, fail);
- unpack_string (*in, factory->details.author, end, fail);
- n = ef->npadtemplates;
- GST_DEBUG ("Element factory : '%s' with npadtemplates=%d",
- factory->details.longname, n);
-
- /* load pad templates */
- for (i = 0; i < n; i++) {
- if (G_UNLIKELY (!gst_registry_binary_load_pad_template (factory, in,
- end))) {
- GST_ERROR ("Error while loading binary pad template");
- goto fail;
- }
- }
-
- /* load uritypes */
- if (G_UNLIKELY ((n = ef->nuriprotocols))) {
- GST_DEBUG ("Reading %d UriTypes at address %p", n, *in);
-
- align (*in);
- factory->uri_type = *((guint *) * in);
- *in += sizeof (factory->uri_type);
- /*unpack_element(*in, &factory->uri_type, factory->uri_type, end, fail); */
-
- factory->uri_protocols = g_new0 (gchar *, n + 1);
- for (i = 0; i < n; i++) {
- unpack_string (*in, str, end, fail);
- factory->uri_protocols[i] = str;
- }
- }
-
- /* load interfaces */
- if (G_UNLIKELY ((n = ef->ninterfaces))) {
- GST_DEBUG ("Reading %d Interfaces at address %p", n, *in);
- for (i = 0; i < n; i++) {
- unpack_string (*in, str, end, fail);
- __gst_element_factory_add_interface (factory, str);
- g_free (str);
- }
- }
- } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
- GstBinaryTypeFindFactory *tff;
- GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
-
- align (*in);
- GST_DEBUG ("Reading/casting for GstBinaryPluginFeature at address %p", *in);
- unpack_element (*in, tff, GstBinaryTypeFindFactory, end, fail);
- pf = (GstBinaryPluginFeature *) tff;
-
- /* load caps */
- unpack_string (*in, str, end, fail);
- factory->caps = (str && *str) ? gst_caps_from_string (str) : NULL;
- g_free (str);
- /* load extensions */
- if (tff->nextensions) {
- GST_DEBUG ("Reading %d Typefind extensions at address %p",
- tff->nextensions, *in);
- factory->extensions = g_new0 (gchar *, tff->nextensions + 1);
- for (i = 0; i < tff->nextensions; i++) {
- unpack_string (*in, str, end, fail);
- factory->extensions[i] = str;
- }
- }
- } else if (GST_IS_INDEX_FACTORY (feature)) {
- GstIndexFactory *factory = GST_INDEX_FACTORY (feature);
-
- align (*in);
- GST_DEBUG ("Reading/casting for GstBinaryPluginFeature at address %p", *in);
- unpack_element (*in, pf, GstBinaryPluginFeature, end, fail);
-
- /* unpack index factory strings */
- unpack_string (*in, factory->longdesc, end, fail);
- } else {
- GST_WARNING ("unhandled factory type : %s", G_OBJECT_TYPE_NAME (feature));
- goto fail;
- }
-
- feature->rank = pf->rank;
-
- /* should already be the interned string, but better make sure */
- feature->plugin_name = g_intern_string (plugin_name);
-
- gst_registry_add_feature (registry, feature);
- GST_DEBUG ("Added feature %s", feature->name);
-
- g_free (type_name);
- return TRUE;
-
- /* Errors */
-fail:
- GST_INFO ("Reading plugin feature failed");
- g_free (type_name);
- if (feature) {
- if (GST_IS_OBJECT (feature))
- gst_object_unref (feature);
- else
- g_object_unref (feature);
- }
- return FALSE;
-}
-
-static gchar **
-gst_registry_binary_load_plugin_dep_strv (gchar ** in, gchar * end, guint n)
-{
- gchar **arr;
-
- if (n == 0)
- return NULL;
-
- arr = g_new0 (gchar *, n + 1);
- while (n > 0) {
- unpack_string (*in, arr[n - 1], end, fail);
- --n;
- }
- return arr;
-fail:
- GST_INFO ("Reading plugin dependency strings failed");
- return NULL;
-}
-
-static gboolean
-gst_registry_binary_load_plugin_dep (GstPlugin * plugin, gchar ** in,
- gchar * end)
-{
- GstPluginDep *dep;
- GstBinaryDep *d;
- gchar **s;
-
- align (*in);
- GST_LOG_OBJECT (plugin, "Unpacking GstBinaryDep from %p", *in);
- unpack_element (*in, d, GstBinaryDep, end, fail);
-
- dep = g_new0 (GstPluginDep, 1);
-
- dep->env_hash = d->env_hash;
- dep->stat_hash = d->stat_hash;
-
- dep->flags = d->flags;
-
- dep->names = gst_registry_binary_load_plugin_dep_strv (in, end, d->n_names);
- dep->paths = gst_registry_binary_load_plugin_dep_strv (in, end, d->n_paths);
- dep->env_vars =
- gst_registry_binary_load_plugin_dep_strv (in, end, d->n_env_vars);
-
- plugin->priv->deps = g_list_append (plugin->priv->deps, dep);
-
- GST_DEBUG_OBJECT (plugin, "Loaded external plugin dependency from registry: "
- "env_hash: %08x, stat_hash: %08x", dep->env_hash, dep->stat_hash);
- for (s = dep->env_vars; s != NULL && *s != NULL; ++s)
- GST_LOG_OBJECT (plugin, " evar: %s", *s);
- for (s = dep->paths; s != NULL && *s != NULL; ++s)
- GST_LOG_OBJECT (plugin, " path: %s", *s);
- for (s = dep->names; s != NULL && *s != NULL; ++s)
- GST_LOG_OBJECT (plugin, " name: %s", *s);
-
- return TRUE;
-fail:
- GST_INFO ("Reading plugin dependency failed");
- return FALSE;
-}
-
-/*
- * gst_registry_binary_load_plugin:
- *
- * Make a new GstPlugin from current GstBinaryPluginElement structure
- * and save it to the GstRegistry. Return an offset to the next
- * GstBinaryPluginElement structure.
- */
-static gboolean
-gst_registry_binary_load_plugin (GstRegistry * registry, gchar ** in,
- gchar * end)
-{
- GstBinaryPluginElement *pe;
- GstPlugin *plugin = NULL;
- gchar *cache_str = NULL;
- guint i, n;
-
- align (*in);
- GST_LOG ("Reading/casting for GstBinaryPluginElement at address %p", *in);
- unpack_element (*in, pe, GstBinaryPluginElement, end, fail);
-
- plugin = g_object_new (GST_TYPE_PLUGIN, NULL);
-
- /* TODO: also set GST_PLUGIN_FLAG_CONST */
- plugin->flags |= GST_PLUGIN_FLAG_CACHED;
- plugin->file_mtime = pe->file_mtime;
- plugin->file_size = pe->file_size;
-
- /* unpack plugin element strings */
- unpack_const_string (*in, plugin->desc.name, end, fail);
- unpack_string (*in, plugin->desc.description, end, fail);
- unpack_string (*in, plugin->filename, end, fail);
- unpack_const_string (*in, plugin->desc.version, end, fail);
- unpack_const_string (*in, plugin->desc.license, end, fail);
- unpack_const_string (*in, plugin->desc.source, end, fail);
- unpack_const_string (*in, plugin->desc.package, end, fail);
- unpack_const_string (*in, plugin->desc.origin, end, fail);
- GST_LOG ("read strings for name='%s'", plugin->desc.name);
- GST_LOG (" desc.description='%s'", plugin->desc.description);
- GST_LOG (" filename='%s'", plugin->filename);
- GST_LOG (" desc.version='%s'", plugin->desc.version);
- GST_LOG (" desc.license='%s'", plugin->desc.license);
- GST_LOG (" desc.source='%s'", plugin->desc.source);
- GST_LOG (" desc.package='%s'", plugin->desc.package);
- GST_LOG (" desc.origin='%s'", plugin->desc.origin);
-
- /* unpack cache data */
- unpack_string (*in, cache_str, end, fail);
- if (*cache_str) {
- plugin->priv->cache_data = gst_structure_from_string (cache_str, NULL);
- }
- g_free (cache_str);
-
- plugin->basename = g_path_get_basename (plugin->filename);
-
- /* Takes ownership of plugin */
- gst_registry_add_plugin (registry, plugin);
- n = pe->nfeatures;
- GST_DEBUG ("Added plugin '%s' plugin with %d features from binary registry",
- plugin->desc.name, n);
-
- /* Load plugin features */
- for (i = 0; i < n; i++) {
- if (G_UNLIKELY (!gst_registry_binary_load_feature (registry, in, end,
- plugin->desc.name))) {
- GST_ERROR ("Error while loading binary feature");
- gst_registry_remove_plugin (registry, plugin);
- goto fail;
- }
- }
-
- /* Load external plugin dependencies */
- for (i = 0; i < pe->n_deps; ++i) {
- if (G_UNLIKELY (!gst_registry_binary_load_plugin_dep (plugin, in, end))) {
- GST_ERROR_OBJECT (plugin, "Could not read external plugin dependency");
- gst_registry_remove_plugin (registry, plugin);
- goto fail;
- }
- }
-
- return TRUE;
-
- /* Errors */
-fail:
- GST_INFO ("Reading plugin failed");
- return FALSE;
-}
-
-
/**
* gst_registry_binary_read_cache:
* @registry: a #GstRegistry
@@ -1243,6 +519,14 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
GST_INFO ("Unable to mmap file %s : %s", location, err->message);
g_error_free (err);
err = NULL;
+ }
+
+ if (contents == NULL) {
+ /* Error mmap-ing the cache, try a plain memory read */
+ if (mapped) {
+ g_mapped_file_free (mapped);
+ mapped = NULL;
+ }
g_file_get_contents (location, &contents, &size, &err);
if (err != NULL) {
@@ -1258,8 +542,6 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
GST_ERROR ("Can't load file %s : %s", location, g_strerror (errno));
goto Error;
}
- /* check length for header */
- size = g_mapped_file_get_length (mapped);
}
/* in is a cursor pointer, we initialize it with the begin of registry and is updated on each read */
@@ -1282,20 +564,20 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
}
/* check if there are plugins in the file */
- if (G_UNLIKELY (!(((gsize) in + sizeof (GstBinaryPluginElement)) <
+ if (G_UNLIKELY (!(((gsize) in + sizeof (GstRegistryChunkPluginElement)) <
(gsize) contents + size))) {
GST_INFO ("No binary plugins structure to read");
/* empty file, this is not an error */
} else {
gchar *end = contents + size;
- /* read as long as we still have space for a GstBinaryPluginElement */
+ /* read as long as we still have space for a GstRegistryChunkPluginElement */
for (;
- ((gsize) in + sizeof (GstBinaryPluginElement)) <
+ ((gsize) in + sizeof (GstRegistryChunkPluginElement)) <
(gsize) contents + size;) {
GST_DEBUG ("reading binary registry %" G_GSIZE_FORMAT "(%x)/%"
G_GSIZE_FORMAT, (gsize) in - (gsize) contents,
(guint) ((gsize) in - (gsize) contents), size);
- if (!gst_registry_binary_load_plugin (registry, &in, end)) {
+ if (!_priv_gst_registry_chunks_load_plugin (registry, &in, end, NULL)) {
GST_ERROR ("Problem while reading binary registry %s", location);
goto Error;
}
@@ -1313,6 +595,9 @@ gst_registry_binary_read_cache (GstRegistry * registry, const char *location)
/* TODO: once we re-use the pointers to registry contents, return here */
Error:
+ if (err)
+ g_error_free (err);
+
#ifndef GST_DISABLE_GST_DEBUG
g_timer_destroy (timer);
#endif
@@ -1324,9 +609,8 @@ Error:
return res;
}
-
-/* FIXME 0.11: these are here for backwards compatibility */
-
+/* FIXME 0.11: these symbols are here for backwards compatibility and should
+ * be removed or made private */
gboolean
gst_registry_xml_read_cache (GstRegistry * registry, const char *location)
{