element-details: allow for arbitrary element details

Add a GstStructure to GstElementClass and GstElementFactory. Add setters/getter.
Handle it in the registry code. Print items in gst-inspect.
Fixes #396774.

API: gst_element_class_set_meta_data(), gst_element_factory_get_meta_data_detail()
This commit is contained in:
Stefan Kost 2010-08-10 14:05:22 +03:00
parent 9fb04bdfc0
commit 65356fbb7a
8 changed files with 166 additions and 2 deletions

View file

@ -510,6 +510,8 @@ 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_documentation_uri
gst_element_class_set_icon_name
<SUBSECTION element-pads>
gst_element_add_pad
@ -639,6 +641,8 @@ gst_element_factory_get_longname
gst_element_factory_get_klass
gst_element_factory_get_description
gst_element_factory_get_author
gst_element_factory_get_documentation_uri
gst_element_factory_get_icon_name
gst_element_factory_get_num_pad_templates
gst_element_factory_get_uri_type
gst_element_factory_get_uri_protocols

View file

@ -268,6 +268,7 @@ gst_element_base_class_init (gpointer g_class)
* See http://bugzilla.gnome.org/show_bug.cgi?id=491501
*/
memset (&element_class->details, 0, sizeof (GstElementDetails));
element_class->meta_data = NULL;
element_class->padtemplates = NULL;
/* set the factory, see gst_element_register() */
@ -286,6 +287,10 @@ gst_element_base_class_finalize (gpointer g_class)
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;
}
}
static void
@ -1214,6 +1219,58 @@ gst_element_class_add_pad_template (GstElementClass * klass,
klass->numpadtemplates++;
}
static void
gst_element_class_add_meta_data (GstElementClass * klass,
const gchar * key, const gchar * value)
{
if (!klass->meta_data) {
/* FIXME: use a quark for "metadata" */
klass->meta_data = gst_structure_empty_new ("metadata");
}
gst_structure_set ((GstStructure *) klass->meta_data,
key, G_TYPE_STRING, value, NULL);
}
/**
* gst_element_class_set_documentation_uri:
* @klass: class to set details for
* @uri: uri of element documentation
*
* Set uri pointing to user documentation. Applications can use this to show
* help for e.g. effects to users.
*
* Since: 0.10.31
*/
void
gst_element_class_set_documentation_uri (GstElementClass * klass,
const gchar * uri)
{
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
gst_element_class_add_meta_data (klass, "doc-uri", uri);
}
/**
* gst_element_class_set_icon_name:
* @klass: class to set details for
* @uri: name of an icon
*
* Elements that bridge to certain other products can include an icon of that
* used product. Application can show the icon in menus/selectors to help
* identifying specific elements.
*
* Since: 0.10.31
*/
void
gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
{
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
gst_element_class_add_meta_data (klass, "icon-name", name);
}
/* FIXME-0.11: deprecate and remove gst_element_class_set_details*() */
/**
* gst_element_class_set_details:
* @klass: class to set details for

View file

@ -609,6 +609,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 */
@ -656,13 +657,20 @@ struct _GstElementClass
gboolean (*query) (GstElement *element, GstQuery *query);
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
/* FIXME-0.11: move up and replace details */
gpointer 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 class meta data */
void gst_element_class_set_documentation_uri (GstElementClass * klass, const gchar *uri);
void gst_element_class_set_icon_name (GstElementClass * klass, const gchar *name);
#ifndef GST_DISABLE_DEPRECATED
void gst_element_class_set_details (GstElementClass *klass, const GstElementDetails *details);
#endif

View file

@ -154,6 +154,10 @@ gst_element_factory_cleanup (GstElementFactory * factory)
GList *item;
__gst_element_details_clear (&factory->details);
if (factory->meta_data) {
gst_structure_free ((GstStructure *) factory->meta_data);
factory->meta_data = NULL;
}
if (factory->type) {
factory->type = G_TYPE_INVALID;
}
@ -255,6 +259,11 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
factory->type = type;
__gst_element_details_copy (&factory->details, &klass->details);
if (klass->meta_data) {
factory->meta_data = gst_structure_copy ((GstStructure *) klass->meta_data);
} else {
factory->meta_data = NULL;
}
for (item = klass->padtemplates; item; item = item->next) {
GstPadTemplate *templ = item->data;
GstStaticPadTemplate *newt;
@ -555,6 +564,48 @@ gst_element_factory_get_author (GstElementFactory * factory)
return factory->details.author;
}
static G_CONST_RETURN gchar *
gst_element_factory_get_meta_data (GstElementFactory * factory,
const gchar * key)
{
/* FIXME: do we want to support other types? */
return gst_structure_get_string ((GstStructure *) factory->meta_data, key);
}
/**
* gst_element_factory_get_documentation_uri:
* @factory: a #GstElementFactory
*
* Gets documentation uri for this factory if set.
*
* Since: 0.10.31
*
* Returns: the documentation uri
*/
G_CONST_RETURN gchar *
gst_element_factory_get_documentation_uri (GstElementFactory * factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
return gst_element_factory_get_meta_data (factory, "doc-uri");
}
/**
* gst_element_factory_get_documentation_uri:
* @factory: a #GstElementFactory
*
* Gets icon name for this factory if set.
*
* Since: 0.10.31
*
* Returns: the icon name
*/
G_CONST_RETURN gchar *
gst_element_factory_get_icon_name (GstElementFactory * factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
return gst_element_factory_get_meta_data (factory, "icon-name");
}
/**
* gst_element_factory_get_num_pad_templates:
* @factory: a #GstElementFactory

View file

@ -117,6 +117,7 @@ struct _GstElementFactory {
GType type; /* unique GType of element or 0 if not loaded */
/* FIXME-0.11: deprecate this in favour of meta_data */
GstElementDetails details;
GList * staticpadtemplates;
@ -128,7 +129,10 @@ struct _GstElementFactory {
GList * interfaces; /* interfaces this element implements */
gpointer _gst_reserved[GST_PADDING];
/*< private >*/
/* FIXME-0.11: move up and replace details */
gpointer meta_data;
gpointer _gst_reserved[GST_PADDING - 1];
};
struct _GstElementFactoryClass {
@ -146,6 +150,8 @@ G_CONST_RETURN gchar * gst_element_factory_get_longname (GstElementFacto
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);
G_CONST_RETURN gchar * gst_element_factory_get_documentation_uri (GstElementFactory *factory);
G_CONST_RETURN gchar * gst_element_factory_get_icon_name (GstElementFactory *factory);
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);

View file

@ -289,6 +289,12 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
gst_registry_chunks_save_const_string (list, factory->details.description);
gst_registry_chunks_save_const_string (list, factory->details.klass);
gst_registry_chunks_save_const_string (list, factory->details.longname);
if (factory->meta_data) {
gst_registry_chunks_save_string (list,
gst_structure_to_string (factory->meta_data));
} else {
gst_registry_chunks_save_const_string (list, "");
}
} else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
GstRegistryChunkTypeFindFactory *tff;
GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
@ -567,6 +573,8 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
GstRegistryChunkElementFactory *ef;
guint n;
GstElementFactory *factory = GST_ELEMENT_FACTORY_CAST (feature);
gchar *str;
const gchar *meta_data_str;
align (*in);
GST_LOG ("Reading/casting for GstRegistryChunkElementFactory at address %p",
@ -575,6 +583,16 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
pf = (GstRegistryChunkPluginFeature *) ef;
/* unpack element factory strings */
unpack_string_nocopy (*in, meta_data_str, end, fail);
if (meta_data_str && *meta_data_str) {
factory->meta_data = gst_structure_from_string (meta_data_str, NULL);
if (!factory->meta_data) {
GST_ERROR
("Error when trying to deserialize structure for metadata '%s'",
str);
goto fail;
}
}
unpack_string (*in, factory->details.longname, end, fail);
unpack_string (*in, factory->details.klass, end, fail);
unpack_string (*in, factory->details.description, end, fail);

View file

@ -198,6 +198,20 @@ get_rank_name (char *s, gint rank)
return s;
}
static gboolean
print_factory_details_meta_data (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\t%s\n", key, val);
g_free (val);
g_free (key);
return TRUE;
}
static void
print_factory_details_info (GstElementFactory * factory)
{
@ -211,6 +225,8 @@ print_factory_details_info (GstElementFactory * factory)
n_print (" Rank:\t\t%s (%d)\n",
get_rank_name (s, GST_PLUGIN_FEATURE (factory)->rank),
GST_PLUGIN_FEATURE (factory)->rank);
gst_structure_foreach ((GstStructure *) factory->meta_data,
print_factory_details_meta_data, NULL);
n_print ("\n");
}

View file

@ -286,6 +286,8 @@ EXPORTS
gst_element_class_install_std_props
gst_element_class_set_details
gst_element_class_set_details_simple
gst_element_class_set_documentation_uri
gst_element_class_set_icon_name
gst_element_continue_state
gst_element_create_all_pads
gst_element_factory_can_sink_caps
@ -294,7 +296,9 @@ EXPORTS
gst_element_factory_find
gst_element_factory_get_author
gst_element_factory_get_description
gst_element_factory_get_documentation_uri
gst_element_factory_get_element_type
gst_element_factory_get_icon_name
gst_element_factory_get_klass
gst_element_factory_get_longname
gst_element_factory_get_num_pad_templates