diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index d5c796be1e..596123d557 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -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 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 diff --git a/gst/gstelement.c b/gst/gstelement.c index 3d7daff779..1ffc6423fa 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -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 diff --git a/gst/gstelement.h b/gst/gstelement.h index 6795f552d8..12ed0dfa86 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -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 diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index d19d5841a7..14ca75490a 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -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 diff --git a/gst/gstelementfactory.h b/gst/gstelementfactory.h index 1a71d73046..4d06edb7fc 100644 --- a/gst/gstelementfactory.h +++ b/gst/gstelementfactory.h @@ -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); diff --git a/gst/gstregistrychunks.c b/gst/gstregistrychunks.c index 3a7b96031e..6867e23079 100644 --- a/gst/gstregistrychunks.c +++ b/gst/gstregistrychunks.c @@ -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); diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index 8f37f43311..b8c242a17d 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -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"); } diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index 594964c86c..ba11cd74c3 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -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