static gboolean do_plugin_load (GstPluginLoader * l, const gchar * filename, guint tag) { GstPlugin *newplugin; GList *chunks = NULL; GST_DEBUG ("Plugin scanner loading file %s. tag %u", filename, tag); #if 0 /* Test code - crash based on filename */ if (strstr (filename, "coreelements") == NULL) { g_printerr ("Crashing on file %s\n", filename); g_printerr ("%d", *(gint *) (NULL)); } #endif newplugin = gst_plugin_load_file ((gchar *) filename, NULL); if (newplugin) { guint hdr_pos; guint offset; /* Now serialise the plugin details and send */ if (!_priv_gst_registry_chunks_save_plugin (&chunks, gst_registry_get_default (), newplugin)) goto fail; /* Store where the header is, write an empty one, then write * all the payload chunks, then fix up the header size */ hdr_pos = l->tx_buf_write; offset = HEADER_SIZE; put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0); if (chunks) { GList *walk; for (walk = chunks; walk; walk = g_list_next (walk)) { GstRegistryChunk *cur = walk->data; put_chunk (l, cur, &offset); _priv_gst_registry_chunk_free (cur); } g_list_free (chunks); /* Store the size of the written payload */ GST_WRITE_UINT32_BE (l->tx_buf + hdr_pos + 4, offset - HEADER_SIZE); } #if 0 /* Test code - corrupt the tx buffer based on filename */ if (strstr (filename, "sink") != NULL) { int fd, res; g_printerr ("Corrupting tx buf on file %s\n", filename); fd = open ("/dev/urandom", O_RDONLY); res = read (fd, l->tx_buf, l->tx_buf_size); close (fd); } #endif gst_object_unref (newplugin); } else { put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0); } return TRUE; fail: put_packet (l, PACKET_PLUGIN_DETAILS, tag, NULL, 0); if (chunks) { GList *walk; for (walk = chunks; walk; walk = g_list_next (walk)) { GstRegistryChunk *cur = walk->data; _priv_gst_registry_chunk_free (cur); } g_list_free (chunks); } return FALSE; }
/** * gst_registry_binary_write_cache: * @registry: a #GstRegistry * @location: a filename * * Write the @registry to a cache to file at given @location. * * Returns: %TRUE on success. */ gboolean priv_gst_registry_binary_write_cache (GstRegistry * registry, GList * plugins, const char *location) { GList *walk; GstBinaryRegistryMagic magic; GList *to_write = NULL; unsigned long file_position = 0; BinaryRegistryCache *cache; GST_INFO ("Building binary registry cache image"); g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE); if (!gst_registry_binary_initialize_magic (&magic)) goto fail; /* iterate trough the list of plugins and fit them into binary structures */ for (walk = plugins; walk != NULL; walk = walk->next) { GstPlugin *plugin = GST_PLUGIN (walk->data); if (!plugin->filename) continue; if (GST_OBJECT_FLAG_IS_SET (plugin, GST_PLUGIN_FLAG_CACHED)) { GStatBuf statbuf; if (g_stat (plugin->filename, &statbuf) < 0 || plugin->file_mtime != statbuf.st_mtime || plugin->file_size != statbuf.st_size) continue; } if (!_priv_gst_registry_chunks_save_plugin (&to_write, registry, plugin)) { GST_ERROR ("Can't write binary plugin information for \"%s\"", plugin->filename); } } _priv_gst_registry_chunks_save_global_header (&to_write, registry, priv_gst_plugin_loading_get_whitelist_hash ()); GST_INFO ("Writing binary registry cache"); cache = gst_registry_binary_cache_init (registry, location); if (!cache) goto fail_free_list; /* write magic */ if (gst_registry_binary_cache_write (cache, file_position, &magic, sizeof (GstBinaryRegistryMagic)) != sizeof (GstBinaryRegistryMagic)) { GST_ERROR ("Failed to write binary registry magic"); goto fail_free_list; } file_position += sizeof (GstBinaryRegistryMagic); /* write out data chunks */ for (walk = to_write; walk; walk = g_list_next (walk)) { GstRegistryChunk *cur = walk->data; gboolean res; res = gst_registry_binary_write_chunk (cache, cur, &file_position); _priv_gst_registry_chunk_free (cur); walk->data = NULL; if (!res) goto fail_free_list; } g_list_free (to_write); if (!gst_registry_binary_cache_finish (cache, TRUE)) return FALSE; return TRUE; /* Errors */ fail_free_list: { for (walk = to_write; walk; walk = g_list_next (walk)) { GstRegistryChunk *cur = walk->data; if (cur) _priv_gst_registry_chunk_free (cur); } g_list_free (to_write); if (cache) (void) gst_registry_binary_cache_finish (cache, FALSE); /* fall through */ } fail: { return FALSE; } }