2007-10-18  Stefan Kost  <ensonic@users.sf.net>

	* docs/gst/gstreamer-sections.txt:
	* gst/gstelement.c:
	* gst/gstelement.h:
	* gst/gstelementfactory.c:
	* gst/gstelementfactory.h:
	* gst/gstpluginfeature.c:
	* gst/gstpluginfeature.h:
	* gst/gstregistrybinary.c:
	* gst/gstregistryxml.c:
	* tools/gst-inspect.c:
	* tools/gst-xmlinspect.c:

Index: docs/gst/gstreamer-sections.txt
===================================================================
RCS file: /cvs/gstreamer/gstreamer/docs/gst/gstreamer-sections.txt,v
retrieving revision 1.311
diff -u -p -u -3 -r1.311 gstreamer-sections.txt
--- docs/gst/gstreamer-sections.txt	17 Oct 2007 12:58:22 -0000	1.311
+++ docs/gst/gstreamer-sections.txt	18 Oct 2007 11:09:47 -0000
@@ -450,6 +450,7 @@ gst_element_class_get_pad_template_list
 gst_element_class_install_std_props
 gst_element_class_set_details
 gst_element_class_set_details_simple
+gst_element_class_set_meta_data
 
 <SUBSECTION element-pads>
 gst_element_add_pad
@@ -572,6 +573,7 @@ gst_element_register
 gst_element_factory_find
 gst_element_factory_get_element_type
 gst_element_factory_get_longname
+gst_element_factory_get_meta_data_detail
 gst_element_factory_get_klass
 gst_element_factory_get_description
 gst_element_factory_get_author
Index: gst/gstelement.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.c,v
retrieving revision 1.463
diff -u -p -u -3 -r1.463 gstelement.c
--- gst/gstelement.c	3 Oct 2007 15:27:24 -0000	1.463
+++ gst/gstelement.c	18 Oct 2007 11:12:42 -0000
@@ -240,6 +240,7 @@ gst_element_base_class_init (gpointer g_
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
 
   memset (&element_class->details, 0, sizeof (GstElementDetails));
+  element_class->meta_data = NULL;
   element_class->padtemplates = NULL;
 }
 
@@ -250,7 +251,13 @@ gst_element_base_class_finalize (gpointe
 
   g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
   g_list_free (klass->padtemplates);
-  __gst_element_details_clear (&klass->details);
+  if(klass->meta_data) {
+    gst_structure_free (klass->meta_data);
+    klass->meta_data = NULL;
+  }
+  else {
+    __gst_element_details_clear (&klass->details);
+  }
 }
 
 static void
@@ -1121,6 +1128,78 @@ gst_element_class_add_pad_template (GstE
   klass->numpadtemplates++;
 }
 
+#define VALIDATE_SET(__dest, __src, __entry)                                     \
+G_STMT_START {                                                                   \
+  const gchar *__str = gst_structure_get_string (__src, G_STRINGIFY ( __entry)); \
+  if (g_utf8_validate (__str, -1, NULL)) {                                       \
+    (__dest)->__entry = (gchar *)__str;                                          \
+  } else {                                                                       \
+    g_warning ("Invalid UTF-8 in " G_STRINGIFY (__entry) ": %s", __str);         \
+    (__dest)->__entry = "[ERROR: invalid UTF-8]";                                \
+  }                                                                              \
+} G_STMT_END
+
+
+/**
+ * gst_element_class_set_meta_data:
+ * @klass: the element class
+ * @fieldname: name of first field to set
+ * @...: additional arguments
+ *
+ * Sets the meta data for a #GstElementClass.
+ * <note>This function is for use in _base_init functions only.</note>
+ *
+ * These items are the mandatory ones:<ul>
+ * <li>longname: The long English name of the element. E.g. "File Sink"
+ * </li>
+ * <li>classification: String describing the type of element, as an unordered list
+ * separated with slashes ('/'). See draft-klass.txt of the design docs
+ * for more details and common types. E.g: "Sink/File"
+ * </li>
+ * <li>description: Sentence describing the purpose of the element. 
+ * E.g: "Write stream to a file"
+ * </li>
+ * <li>author: Name and contact details of the author(s). Use ', ' to separate 
+ * multiple authors. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
+ * </li>
+ * </ul>
+ *
+ * Since: 0.10.16
+ */
+/* FIXME:
+ * - what if someone calls _set_meta_data() and later _set_details_simple()
+ *   - free the structure in _set_details_simple() ?
+ *   - reject (the data should be set just once)
+ */
+void
+gst_element_class_set_meta_data (GstElementClass * klass, const char *fieldname, ...)
+{
+  va_list var_args;
+
+  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
+
+  if(klass->meta_data) {
+    //GST_WARNING("clear metadata in class %p to %p", klass, klass->meta_data);
+    gst_structure_free (klass->meta_data);
+    klass->meta_data = NULL;
+  }
+  else {
+    __gst_element_details_clear (&klass->details);
+  }
+
+  va_start (var_args, fieldname);
+  klass->meta_data = gst_structure_new_valist ("metadata", fieldname, var_args);
+  va_end (var_args);
+  //GST_WARNING("set metadata for class %p to %p", klass, klass->meta_data);
+
+  /* backwards compatibillity */
+  VALIDATE_SET (&klass->details, klass->meta_data, longname);
+  VALIDATE_SET (&klass->details, klass->meta_data, klass);
+  VALIDATE_SET (&klass->details, klass->meta_data, description);
+  VALIDATE_SET (&klass->details, klass->meta_data, author);
+
+}
+
 /**
  * gst_element_class_set_details:
  * @klass: class to set details for
@@ -1130,7 +1209,10 @@ gst_element_class_add_pad_template (GstE
  * <note>This function is for use in _base_init functions only.</note>
  *
  * The @details are copied.
+ *
+ * Deprecated: use gst_element_class_set_meta_data()
  */
+#ifndef GST_REMOVE_DEPRECATED
 void
 gst_element_class_set_details (GstElementClass * klass,
     const GstElementDetails * details)
@@ -1138,8 +1220,15 @@ gst_element_class_set_details (GstElemen
   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
 
-  __gst_element_details_copy (&klass->details, details);
+  gst_element_class_set_meta_data (klass,
+    "longname", G_TYPE_STRING, details->longname,
+    "klass", G_TYPE_STRING, details->klass,
+    "description", G_TYPE_STRING, details->description,
+    "author", G_TYPE_STRING, details->author,
+    NULL);
+  //__gst_element_details_copy (&klass->details, details);
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_class_set_details_simple:
@@ -1150,7 +1239,7 @@ gst_element_class_set_details (GstElemen
  * for more details and common types. E.g: "Sink/File"
  * @description: Sentence describing the purpose of the element. 
  * E.g: "Write stream to a file"
- * @author: Name and contact details of the author(s). Use \n to separate 
+ * @author: Name and contact details of the author(s). Use ', ' to separate 
  * multiple author details. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
  *
  * Sets the detailed information for a #GstElementClass. Simpler version of 
@@ -1161,20 +1250,31 @@ gst_element_class_set_details (GstElemen
  * the element class.
  *
  * Since: 0.10.14
+ *
+ * Deprecated: use gst_element_class_set_meta_data()
  */
+#ifndef GST_REMOVE_DEPRECATED
 void
 gst_element_class_set_details_simple (GstElementClass * klass,
     const gchar * longname, const gchar * classification,
     const gchar * description, const gchar * author)
 {
+  /*
   const GstElementDetails details =
       GST_ELEMENT_DETAILS ((gchar *) longname, (gchar *) classification,
       (gchar *) description, (gchar *) author);
-
+  */
   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
 
-  __gst_element_details_copy (&klass->details, &details);
+  gst_element_class_set_meta_data (klass,
+    "longname", G_TYPE_STRING, longname,
+    "klass", G_TYPE_STRING, classification,
+    "description", G_TYPE_STRING, description,
+    "author", G_TYPE_STRING, author,
+    NULL);
+  //__gst_element_details_copy (&klass->details, &details);
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_class_get_pad_template_list:
@@ -2704,7 +2804,7 @@ gst_element_dispose (GObject * object)
     goto not_null;
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
-      "removing %d pads", g_list_length (element->pads));
+    "removing %d pads", g_list_length (element->pads));
   /* first we break all our links with the outside */
   while (element->pads && element->pads->data) {
     /* don't call _remove_pad with NULL */
@@ -2958,8 +3058,7 @@ gst_element_get_bus (GstElement * elemen
     gst_object_ref (result);
   GST_OBJECT_UNLOCK (element);
 
-  GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
-      result);
+  GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT, result);
 
   return result;
 }
Index: gst/gstelement.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstelement.h,v
retrieving revision 1.242
diff -u -p -u -3 -r1.242 gstelement.h
--- gst/gstelement.h	2 Aug 2007 11:51:17 -0000	1.242
+++ gst/gstelement.h	18 Oct 2007 11:13:43 -0000
@@ -478,6 +478,7 @@ struct _GstElementClass
 
   /*< public >*/
   /* the element details */
+  /* FIXME: 0.11 deprecate this in favour of meta_data */
   GstElementDetails	 details;
 
   /* factory that the element was created from */
@@ -525,19 +526,28 @@ struct _GstElementClass
   gboolean		(*query)		(GstElement *element, GstQuery *query);
 
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  /* FIXME: 0.11 move up and replace details */
+  GstStructure		 *meta_data;
+
+  gpointer _gst_reserved[GST_PADDING-1];
 };
 
 /* element class pad templates */
 void			gst_element_class_add_pad_template	(GstElementClass *klass, GstPadTemplate *templ);
 GstPadTemplate*		gst_element_class_get_pad_template	(GstElementClass *element_class, const gchar *name);
 GList*                  gst_element_class_get_pad_template_list	(GstElementClass *element_class);
+
+/* element meta data */
+void			gst_element_class_set_meta_data		(GstElementClass * klass, const char *fieldname, ...);
+//#ifndef GST_DISABLE_DEPRECATED
 void			gst_element_class_set_details		(GstElementClass *klass, const GstElementDetails *details);
 void			gst_element_class_set_details_simple	(GstElementClass *klass,
 			                                    	 const gchar     *longname,
 			                                    	 const gchar     *classification,
 			                                    	 const gchar     *description,
-			                                         const gchar     *author);
+			                                    	 const gchar     *author);
+			                                    	 
+//#endif /* GST_DISABLE_DEPRECATED */
 
 /* element instance */
 GType			gst_element_get_type		(void);
Index: gst/gstelementfactory.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstelementfactory.c,v
retrieving revision 1.136
diff -u -p -u -3 -r1.136 gstelementfactory.c
--- gst/gstelementfactory.c	13 Oct 2007 17:20:09 -0000	1.136
+++ gst/gstelementfactory.c	18 Oct 2007 11:16:18 -0000
@@ -188,7 +188,7 @@ G_STMT_START {                          
   }                                                                     \
 } G_STMT_END
 
-void
+static void
 __gst_element_details_set (GstElementDetails * dest,
     const GstElementDetails * src)
 {
@@ -211,7 +211,11 @@ gst_element_factory_cleanup (GstElementF
 {
   GList *item;
 
-  __gst_element_details_clear (&factory->details);
+  //__gst_element_details_clear (&factory->details);
+  if (factory->meta_data) {
+    gst_structure_free (factory->meta_data);
+    factory->meta_data = NULL;
+  }
   if (factory->type) {
     g_type_class_unref (g_type_class_peek (factory->type));
     factory->type = 0;
@@ -283,12 +287,20 @@ gst_element_register (GstPlugin * plugin
       g_type_name (type));
 
   klass = GST_ELEMENT_CLASS (g_type_class_ref (type));
+  /* FIXME: what about description? */
+  if (!klass->meta_data || !gst_structure_get_name(klass->meta_data) ||
+    !gst_structure_has_field_typed(klass->meta_data,"klass",G_TYPE_STRING) ||
+    !gst_structure_has_field_typed(klass->meta_data,"author",G_TYPE_STRING))
+  /*
   if ((klass->details.longname == NULL) ||
       (klass->details.klass == NULL) || (klass->details.author == NULL))
+  */
     goto detailserror;
 
   factory->type = type;
-  __gst_element_details_copy (&factory->details, &klass->details);
+  factory->meta_data = gst_structure_copy(klass->meta_data);
+  //__gst_element_details_copy (&factory->details, &klass->details);
+
   for (item = klass->padtemplates; item; item = item->next) {
     GstPadTemplate *templ = item->data;
     GstStaticPadTemplate *newt;
@@ -325,6 +337,9 @@ gst_element_register (GstPlugin * plugin
   }
   g_free (interfaces);
 
+  /* FIXME: why not just ref this
+   * g_object_add_weak_pointer(plugin, GST_PLUGIN_FEATURE (factory)->plugin_name);
+   */
   if (plugin && plugin->desc.name) {
     GST_PLUGIN_FEATURE (factory)->plugin_name = plugin->desc.name;
   } else {
@@ -515,20 +530,45 @@ gst_element_factory_get_element_type (Gs
 }
 
 /**
+ * gst_element_factory_get_meta_data_detail:
+ * @factory: a #GstElementFactory
+ * @detail: a detail name, such as "klass", "description" or "author".
+ *
+ * Gets the meta data detail for this factory
+ *
+ * Since: 0.10.16
+ *
+ * Returns: the meta data item
+ */
+G_CONST_RETURN gchar *
+gst_element_factory_get_meta_data_detail (GstElementFactory * factory, const gchar *detail)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
+  g_return_val_if_fail (detail, NULL);
+
+  return gst_structure_get_string (factory->meta_data, detail);
+}
+
+/**
  * gst_element_factory_get_longname:
  * @factory: a #GstElementFactory
  *
  * Gets the longname for this factory
  *
+ * Deprecated: use gst_element_factory_get_meta_data_detail(factory, &quot;longname&quot;);
+ *
  * Returns: the longname
  */
+#ifndef GST_REMOVE_DEPRECATED
 G_CONST_RETURN gchar *
 gst_element_factory_get_longname (GstElementFactory * factory)
 {
   g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
 
-  return factory->details.longname;
+  return gst_element_factory_get_meta_data_detail (factory, "longname");
+  //return factory->details.longname;
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_factory_get_klass:
@@ -536,15 +576,20 @@ gst_element_factory_get_longname (GstEle
  *
  * Gets the class for this factory.
  *
+ * Deprecated: use gst_element_factory_get_meta_data_detail(factory, &quot;klass&quot;);
+ *
  * Returns: the class
  */
+#ifndef GST_REMOVE_DEPRECATED
 G_CONST_RETURN gchar *
 gst_element_factory_get_klass (GstElementFactory * factory)
 {
   g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
 
-  return factory->details.klass;
+  return gst_element_factory_get_meta_data_detail (factory, "klass");
+  //return factory->details.klass;
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_factory_get_description:
@@ -552,15 +597,20 @@ gst_element_factory_get_klass (GstElemen
  *
  * Gets the description for this factory.
  *
+ * Deprecated: use gst_element_factory_get_meta_data_detail(factory, &quot;description&quot;);
+ *
  * Returns: the description
  */
+#ifndef GST_REMOVE_DEPRECATED
 G_CONST_RETURN gchar *
 gst_element_factory_get_description (GstElementFactory * factory)
 {
   g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
 
-  return factory->details.description;
+  return gst_element_factory_get_meta_data_detail (factory, "description");
+  //return factory->details.description;
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_factory_get_author:
@@ -568,15 +618,20 @@ gst_element_factory_get_description (Gst
  *
  * Gets the author for this factory.
  *
+ * Deprecated: use gst_element_factory_get_meta_data_detail(factory, &quot;author&quot;);
+ *
  * Returns: the author
  */
+#ifndef GST_REMOVE_DEPRECATED
 G_CONST_RETURN gchar *
 gst_element_factory_get_author (GstElementFactory * factory)
 {
   g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
 
-  return factory->details.author;
+  return gst_element_factory_get_meta_data_detail (factory, "author");
+  //return factory->details.author;
 }
+#endif /* GST_REMOVE_DEPRECATED */
 
 /**
  * gst_element_factory_get_num_pad_templates:
Index: gst/gstelementfactory.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstelementfactory.h,v
retrieving revision 1.11
diff -u -p -u -3 -r1.11 gstelementfactory.h
--- gst/gstelementfactory.h	25 Jul 2007 18:37:12 -0000	1.11
+++ gst/gstelementfactory.h	18 Oct 2007 11:17:54 -0000
@@ -113,7 +113,11 @@ struct _GstElementFactory {
 
   GType			type;			/* unique GType of element or 0 if not loaded */
 
-  GstElementDetails	details;
+  /* the element details */
+  //GstElementDetails	details;
+  GstStructure		*meta_data;
+  gpointer _gst_details_reserved[GST_PADDING+3];
+  
 
   GList *		staticpadtemplates;
   guint			numpadtemplates;
@@ -138,10 +142,13 @@ GType 			gst_element_factory_get_type 		
 GstElementFactory *	gst_element_factory_find		(const gchar *name);
 
 GType			gst_element_factory_get_element_type	(GstElementFactory *factory);
+G_CONST_RETURN gchar *	gst_element_factory_get_meta_data_detail	(GstElementFactory *factory, const gchar *detail);
+//#ifndef GST_DISABLE_DEPRECATED
 G_CONST_RETURN gchar *	gst_element_factory_get_longname	(GstElementFactory *factory);
 G_CONST_RETURN gchar *	gst_element_factory_get_klass		(GstElementFactory *factory);
 G_CONST_RETURN gchar *	gst_element_factory_get_description  	(GstElementFactory *factory);
 G_CONST_RETURN gchar *	gst_element_factory_get_author		(GstElementFactory *factory);
+//#endif /* GST_DISABLE_DEPRECATED */
 guint			gst_element_factory_get_num_pad_templates (GstElementFactory *factory);
 G_CONST_RETURN GList *	gst_element_factory_get_static_pad_templates (GstElementFactory *factory);
 gint			gst_element_factory_get_uri_type	(GstElementFactory *factory);
Index: gst/gstpluginfeature.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstpluginfeature.c,v
retrieving revision 1.51
diff -u -p -u -3 -r1.51 gstpluginfeature.c
--- gst/gstpluginfeature.c	13 Oct 2007 17:20:09 -0000	1.51
+++ gst/gstpluginfeature.c	18 Oct 2007 11:19:06 -0000
@@ -159,6 +159,7 @@ gboolean
 gst_plugin_feature_type_name_filter (GstPluginFeature * feature,
     GstTypeNameData * data)
 {
+  /* FIXME: use g_quark_from_string for the feature names */
   return ((data->type == 0 || data->type == G_OBJECT_TYPE (feature)) &&
       (data->name == NULL
           || !strcmp (data->name, GST_PLUGIN_FEATURE_NAME (feature))));
Index: gst/gstpluginfeature.h
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstpluginfeature.h,v
retrieving revision 1.27
diff -u -p -u -3 -r1.27 gstpluginfeature.h
--- gst/gstpluginfeature.h	13 Oct 2007 17:20:09 -0000	1.27
+++ gst/gstpluginfeature.h	18 Oct 2007 11:19:53 -0000
@@ -79,9 +79,9 @@ struct _GstPluginFeature {
   GstObject      object;
 
   /*< private >*/
-  gboolean       loaded;
-  gchar         *name;
-  guint          rank;
+  gboolean        loaded;
+  gchar         *name;    /* points to gstobject->name */
+  guint   	 rank;
 
   const gchar   *plugin_name;
 
Index: gst/gstregistrybinary.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstregistrybinary.c,v
retrieving revision 1.16
diff -u -p -u -3 -r1.16 gstregistrybinary.c
--- gst/gstregistrybinary.c	13 Oct 2007 17:20:09 -0000	1.16
+++ gst/gstregistrybinary.c	18 Oct 2007 11:21:26 -0000
@@ -23,7 +23,7 @@
 
 /* FIXME:
  * - Add random key to libgstreamer during build and only accept registry,
- *   if key matches (or is the version check enough)
+ *   if key matches or extend version string (currently just 0.10)
  * - keep registry binary blob and reference strings
  *   - don't free/unmmap contents when leaving gst_registry_binary_read_cache()
  *     - free at gst_deinit() / _priv_gst_registry_cleanup() ?
@@ -80,9 +80,13 @@
   _outptr = g_intern_string ((const gchar *)_inptr); \
   _inptr += strlen(_outptr) + 1
 
-#define unpack_string(_inptr, _outptr)  \
-  _outptr = g_strdup ((gchar *)_inptr); \
-  _inptr += strlen(_outptr) + 1
+#define unpack_string(_inptr, _outptr) \
+  if (*(gchar *)_inptr) \
+    _outptr = g_strdup ((gchar *)_inptr); \
+  else \
+    _outptr = NULL; \
+  _inptr += strlen(_inptr) + 1
+
 
 #if !GST_HAVE_UNALIGNED_ACCESS
 #  define alignment32(_address)  (size_t)_address%4
@@ -141,7 +145,7 @@ gst_registry_binary_initialize_magic (Gs
 {
   if (!strncpy (m->magic, GST_MAGIC_BINARY_REGISTRY_STR,
           GST_MAGIC_BINARY_REGISTRY_LEN)
-      || !strncpy (m->version, GST_MAJORMINOR, GST_MAGIC_BINARY_VERSION_LEN)) {
+      || !strncpy (m->version, PACKAGE_VERSION, GST_MAGIC_BINARY_VERSION_LEN)) {
     GST_ERROR ("Failed to write magic to the registry magic structure");
     return FALSE;
   }
@@ -160,10 +164,19 @@ inline static gboolean
 gst_registry_binary_save_const_string (GList ** list, const gchar * str)
 {
   GstBinaryChunk *chunk;
+  
+  GST_LOG ("  saving const str : '%s'",str);
 
   chunk = g_malloc (sizeof (GstBinaryChunk));
-  chunk->data = (gpointer) str;
-  chunk->size = strlen ((gchar *) chunk->data) + 1;
+  if (str) {
+    chunk->data = (gpointer) str;
+    chunk->size = strlen ((gchar *) chunk->data) + 1;
+  }
+  else {
+    /* we cannot skip it totally, as the reader needs to see the empty string */
+    chunk->data = "";
+    chunk->size = 1;
+  }
   chunk->flags = GST_BINARY_REGISTRY_FLAG_CONST;
   chunk->align = FALSE;
   *list = g_list_prepend (*list, chunk);
@@ -182,6 +195,8 @@ gst_registry_binary_save_string (GList *
 {
   GstBinaryChunk *chunk;
 
+  GST_LOG ("  saving str : '%s'",str);
+  
   chunk = g_malloc (sizeof (GstBinaryChunk));
   chunk->data = str;
   chunk->size = strlen ((gchar *) chunk->data) + 1;
@@ -267,6 +282,7 @@ gst_registry_binary_save_feature (GList 
   if (GST_IS_ELEMENT_FACTORY (feature)) {
     GstBinaryElementFactory *ef;
     GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
+    gchar *str;
 
     ef = g_malloc (sizeof (GstBinaryElementFactory));
     chk = gst_registry_binary_make_data (ef, sizeof (GstBinaryElementFactory));
@@ -315,10 +331,15 @@ gst_registry_binary_save_feature (GList 
     }
 
     /* pack element factory strings */
+    str = gst_structure_to_string(factory->meta_data);
+    gst_registry_binary_save_string (list, str);
+    GST_INFO ("Serialize structure for metadata '%s'",str);
+    /*
     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);
@@ -415,20 +436,30 @@ gst_registry_binary_save_plugin (GList *
       goto fail;
     }
   }
-  GST_DEBUG ("Save plugin '%s' with %d features", plugin->desc.name,
+  GST_DEBUG ("Save plugin '%s' with %d feature(s)", plugin->desc.name,
       pe->nfeatures);
 
   gst_plugin_feature_list_free (plugin_features);
+  
+  GST_LOG ("Now saving metadata");
 
   /* pack plugin element strings */
   gst_registry_binary_save_const_string (list, plugin->desc.origin);
+  GST_LOG ("desc.origin ok");
   gst_registry_binary_save_const_string (list, plugin->desc.package);
+  GST_LOG ("desc.package ok");
   gst_registry_binary_save_const_string (list, plugin->desc.source);
+  GST_LOG ("desc.source ok");
   gst_registry_binary_save_const_string (list, plugin->desc.license);
+  GST_LOG ("desc.license ok");
   gst_registry_binary_save_const_string (list, plugin->desc.version);
+  GST_LOG ("desc.version ok");
   gst_registry_binary_save_const_string (list, plugin->filename);
+  GST_LOG ("filename ok");
   gst_registry_binary_save_const_string (list, plugin->desc.description);
+  GST_LOG ("desc.description ok");
   gst_registry_binary_save_const_string (list, plugin->desc.name);
+  GST_LOG ("desc.name ok");
 
   *list = g_list_prepend (*list, chk);
 
@@ -599,7 +630,7 @@ gst_registry_binary_check_magic (gchar *
         m->magic[1] & 0xff, m->magic[2] & 0xff, m->magic[3] & 0xff);
     return FALSE;
   }
-  if (strncmp (m->version, GST_MAJORMINOR, GST_MAGIC_BINARY_VERSION_LEN)) {
+  if (strncmp (m->version, PACKAGE_VERSION, GST_MAGIC_BINARY_VERSION_LEN)) {
     GST_WARNING ("Binary registry magic version is different : %s != %s",
         GST_MAJORMINOR, m->version);
     return FALSE;
@@ -688,17 +719,30 @@ gst_registry_binary_load_feature (GstReg
     GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
 
     align32 (*in);
-    GST_LOG ("Reading/casting for GstBinaryElementFactory at address %p", *in);
+    GST_LOG ("Reading/casting for GstBinaryElementFactory '%s' at address %p",
+      feature->name, *in);
     unpack_element (*in, ef, GstBinaryElementFactory);
     pf = (GstBinaryPluginFeature *) ef;
 
     /* unpack element factory strings */
+    unpack_string (*in, str);
+    factory->meta_data = gst_structure_from_string (str, NULL);
+    if(!factory->meta_data) {
+      GST_ERROR ("Error when trying to deserialize structure for metadata '%s'",str);
+      g_free (str);
+      goto fail;
+    }
+    g_free (str);
+    /*
     unpack_string (*in, factory->details.longname);
     unpack_string (*in, factory->details.klass);
     unpack_string (*in, factory->details.description);
     unpack_string (*in, factory->details.author);
+    */
     GST_DEBUG ("Element factory : '%s' with npadtemplates=%d",
-        factory->details.longname, ef->npadtemplates);
+        //factory->details.longname,
+        gst_structure_get_name (factory->meta_data),
+        ef->npadtemplates);
 
     /* load pad templates */
     for (i = 0; i < ef->npadtemplates; i++) {
@@ -735,7 +779,8 @@ gst_registry_binary_load_feature (GstReg
     GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
 
     align32 (*in);
-    GST_DEBUG ("Reading/casting for GstBinaryPluginFeature at address %p", *in);
+    GST_DEBUG ("Reading/casting for GstBinaryTypeFindFactory '%s' at address %p",
+      feature->name, *in);
     unpack_element (*in, tff, GstBinaryTypeFindFactory);
     pf = (GstBinaryPluginFeature *) tff;
 
@@ -749,6 +794,7 @@ gst_registry_binary_load_feature (GstReg
           tff->nextensions, *in);
       factory->extensions = g_new0 (gchar *, tff->nextensions + 1);
       for (i = 0; i < tff->nextensions; i++) {
+        GST_DEBUG ("  extension '%s'", *in);
         unpack_string (*in, str);
         factory->extensions[i] = str;
       }
@@ -759,7 +805,8 @@ gst_registry_binary_load_feature (GstReg
     GstIndexFactory *factory = GST_INDEX_FACTORY (feature);
 
     align32 (*in);
-    GST_DEBUG ("Reading/casting for GstBinaryPluginFeature at address %p", *in);
+    GST_DEBUG ("Reading/casting for GstBinaryPluginFeature '%s' at address %p",
+      feature->name, *in);
     unpack_element (*in, pf, GstBinaryPluginFeature);
 
     /* unpack index factory strings */
@@ -833,7 +880,14 @@ gst_registry_binary_load_plugin (GstRegi
   unpack_const_string (*in, plugin->desc.source);
   unpack_const_string (*in, plugin->desc.package);
   unpack_const_string (*in, plugin->desc.origin);
-  GST_LOG ("read strings for '%s'", plugin->desc.name);
+  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);
 
   plugin->basename = g_path_get_basename (plugin->filename);
   gst_registry_add_plugin (registry, plugin);
Index: gst/gstregistryxml.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/gst/gstregistryxml.c,v
retrieving revision 1.38
diff -u -p -u -3 -r1.38 gstregistryxml.c
--- gst/gstregistryxml.c	13 Oct 2007 17:20:09 -0000	1.38
+++ gst/gstregistryxml.c	18 Oct 2007 11:23:03 -0000
@@ -304,17 +304,23 @@ load_feature (xmlTextReaderPtr reader)
       if (GST_IS_ELEMENT_FACTORY (feature)) {
         GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (feature);
 
-        if (g_str_equal (tag, "longname")) {
-          int ret;
+        if (g_str_equal (tag, "metadata")) {
+          gchar *s = NULL;
 
-          ret = read_string (reader, &factory->details.longname, TRUE);
-          GST_LOG ("longname ret=%d, name=%s", ret, factory->details.longname);
+          if (read_string (reader, &s, FALSE)) {
+            factory->meta_data = gst_structure_from_string (s, NULL);
+            g_free (s);
+          }
+        /*
+        if (g_str_equal (tag, "longname")) {
+          read_string (reader, &factory->details.longname, TRUE);
         } else if (g_str_equal (tag, "class")) {
           read_string (reader, &factory->details.klass, TRUE);
         } else if (g_str_equal (tag, "description")) {
           read_string (reader, &factory->details.description, TRUE);
         } else if (g_str_equal (tag, "author")) {
           read_string (reader, &factory->details.author, TRUE);
+        */
         } else if (g_str_equal (tag, "uri_type")) {
           gchar *s = NULL;
 
@@ -627,7 +633,7 @@ gst_registry_xml_save_caps (GstRegistry 
 {
   /* we copy the caps here so we can simplify them before saving. This is a lot
    * faster when loading them later on */
-  char *s;
+  gchar *s;
   GstCaps *copy = gst_caps_copy (caps);
   gboolean ret;
 
@@ -697,7 +703,16 @@ gst_registry_xml_save_feature (GstRegist
   if (GST_IS_ELEMENT_FACTORY (feature)) {
     GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
     GList *walk;
+    gchar *s;
+    gboolean ret;
 
+    s = gst_structure_to_string(factory->meta_data);
+    ret = gst_registry_save_escaped (registry, "  ", "metadata", s);
+    g_free (s);
+    if(!ret)
+      return FALSE;
+    
+    /*
     if (!gst_registry_save_escaped (registry, "  ", "longname",
             factory->details.longname))
       return FALSE;
@@ -710,7 +725,7 @@ gst_registry_xml_save_feature (GstRegist
     if (!gst_registry_save_escaped (registry, "  ", "author",
             factory->details.author))
       return FALSE;
-
+    */
     walk = factory->staticpadtemplates;
 
     while (walk) {
Index: tools/gst-inspect.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/tools/gst-inspect.c,v
retrieving revision 1.130
diff -u -p -u -3 -r1.130 gst-inspect.c
--- tools/gst-inspect.c	15 Oct 2007 14:33:16 -0000	1.130
+++ tools/gst-inspect.c	18 Oct 2007 11:23:30 -0000
@@ -196,14 +196,31 @@ get_rank_name (gint rank)
   }
 }
 
+static gboolean
+print_factory_details_info_fields (GQuark field_id, const GValue *value,
+  gpointer user_data)
+{
+  gchar *val = g_strdup_value_contents (value);
+  gchar *key = g_strdup (g_quark_to_string (field_id));
+
+  key[0] = g_ascii_toupper (key[0]);
+  n_print ("  %s:\t%s\n", key, val);
+  g_free (val);
+  g_free (key);
+  return TRUE;
+}
+
 static void
 print_factory_details_info (GstElementFactory * factory)
 {
   n_print ("Factory Details:\n");
-  n_print ("  Long name:\t%s\n", factory->details.longname);
-  n_print ("  Class:\t%s\n", factory->details.klass);
-  n_print ("  Description:\t%s\n", factory->details.description);
-  n_print ("  Author(s):\t%s\n", factory->details.author);
+  gst_structure_foreach (factory->meta_data, print_factory_details_info_fields, NULL);
+  /*
+  n_print ("  Long name:\t%s\n", gst_element_factory_get_longname (factory));
+  n_print ("  Class:\t%s\n", gst_element_factory_get_meta_data_detail (factory, "klass"));
+  n_print ("  Description:\t%s\n", gst_element_factory_get_meta_data_detail (factory, "description"));
+  n_print ("  Author(s):\t%s\n", gst_element_factory_get_meta_data_detail (factory, "author"));
+  */
   n_print ("  Rank:\t\t%s (%d)\n",
       get_rank_name (GST_PLUGIN_FEATURE (factory)->rank),
       GST_PLUGIN_FEATURE (factory)->rank);
@@ -471,7 +488,8 @@ print_element_properties_info (GstElemen
             if (_name)
               g_print (_name);
             g_print ("%-23.23s    (%d): %-16s - %s", "",
-                values[j].value, values[j].value_nick, values[j].value_name);
+                values[j].value, values[j].value_nick,
+                values[j].value_name);
             j++;
           }
           /* g_type_class_unref (ec); */
@@ -505,7 +523,8 @@ print_element_properties_info (GstElemen
             if (_name)
               g_print (_name);
             g_print ("%-23.23s    (0x%08x): %-16s - %s", "",
-                values[j].value, values[j].value_nick, values[j].value_name);
+                values[j].value, values[j].value_nick,
+                values[j].value_name);
             j++;
           }
 
@@ -828,7 +847,8 @@ print_signal_info (GstElement * element)
         if (_name)
           g_print (_name);
         g_print (",\n%sgpointer user_data);\n", indent);
-      } else
+      }
+      else
         g_print (");\n");
 
       g_free (indent);
@@ -1010,15 +1030,15 @@ print_plugin_features (GstPlugin * plugi
         guint i = 0;
 
         g_print ("%s: %s: ", plugin->desc.name,
-            gst_plugin_feature_get_name (feature));
+          gst_plugin_feature_get_name (feature));
         while (factory->extensions[i]) {
           g_print ("%s%s", i > 0 ? ", " : "", factory->extensions[i]);
           i++;
         }
         g_print ("\n");
       } else
-        g_print ("%s: %s: no extensions\n", plugin->desc.name,
-            gst_plugin_feature_get_name (feature));
+      g_print ("%s: %s: no extensions\n", plugin->desc.name,
+          gst_plugin_feature_get_name (feature));
 
       num_types++;
     } else {
Index: tools/gst-xmlinspect.c
===================================================================
RCS file: /cvs/gstreamer/gstreamer/tools/gst-xmlinspect.c,v
retrieving revision 1.42
diff -u -p -u -3 -r1.42 gst-xmlinspect.c
--- tools/gst-xmlinspect.c	15 Oct 2007 07:11:04 -0000	1.42
+++ tools/gst-xmlinspect.c	18 Oct 2007 11:23:48 -0000
@@ -426,6 +426,7 @@ print_element_info (GstElementFactory * 
   GstPad *pad;
   GstStaticPadTemplate *padtemplate;
   gint maxlevel = 0;
+  gchar *s;
 
   element = gst_element_factory_create (factory, "element");
   if (!element) {
@@ -438,12 +439,18 @@ print_element_info (GstElementFactory * 
   gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
   gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
 
+  s = gst_structure_to_string(factory->meta_data);
+  PUT_ESCAPED (1, "details", s);
+  g_free (s);
+
+  /*
   PUT_START_TAG (1, "details");
   PUT_ESCAPED (2, "long-name", factory->details.longname);
   PUT_ESCAPED (2, "class", factory->details.klass);
   PUT_ESCAPED (2, "description", factory->details.description);
   PUT_ESCAPED (2, "authors", factory->details.author);
   PUT_END_TAG (1, "details");
+  */
 
   output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel);
 
@@ -634,7 +641,7 @@ print_element_list (void)
 
         factory = GST_ELEMENT_FACTORY (feature);
         g_print ("%s:  %s: %s\n", plugin->desc.name,
-            GST_PLUGIN_FEATURE_NAME (factory),
+            GST_PLUGIN_FEATURE_NAME (factory), 
             gst_element_factory_get_longname (factory));
       }
 #ifndef GST_DISABLE_INDEX
