Commit 920ef127 authored by Wim Taymans's avatar Wim Taymans

element: rework GstElementDetails

Clean up the GstElement structure
Replace GstElementDetails with metadata
parent a0ed044d
......@@ -198,7 +198,7 @@ noinst_HEADERS = \
glib-compat-private.h \
gst-i18n-lib.h \
gst-i18n-app.h \
gstelementdetails.h \
gstelementmetadata.h \
gstpluginloader.h \
gstquark.h \
gstregistrybinary.h \
......
......@@ -40,6 +40,7 @@
#include <gst/gstdatetime.h>
#include <gst/gstdebugutils.h>
#include <gst/gstelement.h>
#include <gst/gstelementmetadata.h>
#include <gst/gsterror.h>
#include <gst/gstevent.h>
#include <gst/gstghostpad.h>
......
......@@ -311,7 +311,7 @@ gst_bin_base_init (gpointer g_class)
{
GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
gst_element_class_set_details_simple (gstelement_class, "Generic bin",
gst_element_class_set_metadata (gstelement_class, "Generic bin",
"Generic/Bin",
"Simple container object",
"Erik Walthinsen <omega@cse.ogi.edu>,"
......
......@@ -34,6 +34,17 @@
G_BEGIN_DECLS
/* added to ease the transition to 0.11 */
#define gst_element_class_set_details_simple gst_element_class_set_metadata
#define gst_element_factory_get_longname(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_LONGNAME)
#define gst_element_factory_get_klass(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_KLASS)
#define gst_element_factory_get_description(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_DESCRIPTION)
#define gst_element_factory_get_author(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_AUTHOR)
#define gst_element_factory_get_documentation_uri(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_DOC_URI)
#define gst_element_factory_get_icon_name(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_ICON_NAME)
#ifndef GST_DISABLE_DEPRECATED
#endif /* not GST_DISABLE_DEPRECATED */
......
......@@ -82,7 +82,7 @@
#include <gobject/gvaluecollector.h>
#include "gstelement.h"
#include "gstelementdetails.h"
#include "gstelementmetadata.h"
#include "gstenumtypes.h"
#include "gstbus.h"
#include "gstmarshal.h"
......@@ -233,7 +233,7 @@ gst_element_base_class_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
/* FIXME 0.11: Copy the element details and instead of clearing the
/* FIXME 0.11: Instead of clearing the
* pad template list copy the list and increase the refcount of
* the pad templates by one.
*
......@@ -242,8 +242,7 @@ gst_element_base_class_init (gpointer g_class)
* of doing things.
* See http://bugzilla.gnome.org/show_bug.cgi?id=491501
*/
memset (&element_class->details, 0, sizeof (GstElementDetails));
element_class->meta_data = NULL;
element_class->metadata = gst_structure_empty_new ("metadata");
element_class->padtemplates = NULL;
/* set the factory, see gst_element_register() */
......@@ -261,11 +260,8 @@ 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;
}
gst_structure_free (klass->metadata);
}
static void
......@@ -1158,60 +1154,29 @@ 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
* @name: name of an icon
* gst_element_class_add_metadata:
* @klass: class to set metadata for
* @key: the key to set
* @value: the value to set
*
* 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
* Set @key with @value as metadata in @klass.
*/
void
gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
gst_element_class_add_metadata (GstElementClass * klass,
const gchar * key, const gchar * value)
{
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (key != NULL);
g_return_if_fail (value != NULL);
gst_element_class_add_meta_data (klass, "icon-name", name);
gst_structure_set ((GstStructure *) klass->metadata,
key, G_TYPE_STRING, value, NULL);
}
/**
* gst_element_class_set_details_simple:
* @klass: class to set details for
* gst_element_class_set_metadata:
* @klass: class to set metadata for
* @longname: The long English name of the element. E.g. "File Sink"
* @classification: String describing the type of element, as an unordered list
* separated with slashes ('/'). See draft-klass.txt of the design docs
......@@ -1219,29 +1184,23 @@ gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
* @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
* multiple author details. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
* multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
*
* Sets the detailed information for a #GstElementClass. Simpler version of
* gst_element_class_set_details() that generates less linker overhead.
* Sets the detailed information for a #GstElementClass.
* <note>This function is for use in _base_init functions only.</note>
*
* The detail parameter strings are copied into the #GstElementDetails for
* the element class.
*
* Since: 0.10.14
*/
void
gst_element_class_set_details_simple (GstElementClass * klass,
gst_element_class_set_metadata (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_structure_set ((GstStructure *) klass->metadata,
GST_ELEMENT_METADATA_LONGNAME, G_TYPE_STRING, longname,
GST_ELEMENT_METADATA_KLASS, G_TYPE_STRING, classification,
GST_ELEMENT_METADATA_DESCRIPTION, G_TYPE_STRING, description,
GST_ELEMENT_METADATA_AUTHOR, G_TYPE_STRING, author, NULL);
}
/**
......
......@@ -131,7 +131,7 @@ typedef enum {
*
* Since: 0.10.13
*/
#define GST_STATE_TARGET(elem) (GST_ELEMENT_CAST(elem)->abidata.ABI.target_state)
#define GST_STATE_TARGET(elem) (GST_ELEMENT_CAST(elem)->target_state)
/**
* GST_STATE_RETURN:
......@@ -391,7 +391,7 @@ typedef enum
*
* Since: 0.10.24
*/
#define GST_ELEMENT_START_TIME(elem) (GST_ELEMENT_CAST(elem)->abidata.ABI.start_time)
#define GST_ELEMENT_START_TIME(elem) (GST_ELEMENT_CAST(elem)->start_time)
/**
* GST_ELEMENT_ERROR:
......@@ -513,6 +513,7 @@ G_STMT_START { \
* @state_cond: Used to signal completion of a state change
* @state_cookie: Used to detect concurrent execution of
* gst_element_set_state() and gst_element_get_state()
* @target_state: the target state of an element as set by the application
* @current_state: the current state of an element
* @next_state: the next state of an element, can be #GST_STATE_VOID_PENDING if
* the element is in the correct state.
......@@ -526,6 +527,7 @@ G_STMT_START { \
* @base_time: the time of the clock right before the element is set to
* PLAYING. Subtracting @base_time from the current clock time in the PLAYING
* state will yield the running_time against the clock.
* @start_time: the running_time of the last PAUSED state
* @numpads: number of pads of the element, includes both source and sink pads.
* @pads: list of pads
* @numsrcpads: number of source pads of the element.
......@@ -546,6 +548,7 @@ struct _GstElement
/* element state */
GCond *state_cond;
guint32 state_cookie;
GstState target_state;
GstState current_state;
GstState next_state;
GstState pending_state;
......@@ -556,6 +559,7 @@ struct _GstElement
/* allocated clock */
GstClock *clock;
GstClockTimeDiff base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */
GstClockTime start_time;
/* element pads, these lists can only be iterated while holding
* the LOCK or checking the cookie after each LOCK. */
......@@ -568,22 +572,13 @@ struct _GstElement
guint32 pads_cookie;
/*< private >*/
union {
struct {
/* state set by application */
GstState target_state;
/* running time of the last PAUSED state */
GstClockTime start_time;
} ABI;
/* adding + 0 to mark ABI change to be undone later */
gpointer _gst_reserved[GST_PADDING + 0];
} abidata;
gpointer _gst_reserved[GST_PADDING];
};
/**
* GstElementClass:
* @parent_class: the parent class structure
* @details: #GstElementDetails for elements of this class
* @metadata: metadata for elements of this class
* @elementfactory: the #GstElementFactory that creates these elements
* @padtemplates: a #GList of #GstPadTemplate
* @numpadtemplates: the number of padtemplates
......@@ -610,9 +605,8 @@ struct _GstElementClass
GstObjectClass parent_class;
/*< public >*/
/* the element details */
/* FIXME-0.11: deprecate this in favour of meta_data */
GstElementDetails details;
/* the element metadata */
gpointer metadata;
/* factory that the element was created from */
GstElementFactory *elementfactory;
......@@ -659,10 +653,8 @@ struct _GstElementClass
gboolean (*query) (GstElement *element, GstQuery *query);
/*< private >*/
/* FIXME-0.11: move up and replace details */
gpointer meta_data;
gpointer _gst_reserved[GST_PADDING-1];
gpointer _gst_reserved[GST_PADDING];
};
/* element class pad templates */
......@@ -671,13 +663,14 @@ GstPadTemplate* gst_element_class_get_pad_template (GstElementClass
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);
void gst_element_class_set_details_simple (GstElementClass *klass,
void gst_element_class_set_metadata (GstElementClass *klass,
const gchar *longname,
const gchar *classification,
const gchar *description,
const gchar *author);
void gst_element_class_add_metadata (GstElementClass * klass,
const gchar * key, const gchar * value);
/* element instance */
GType gst_element_get_type (void);
......
......@@ -60,7 +60,7 @@
#include "gst_private.h"
#include "gstelement.h"
#include "gstelementdetails.h"
#include "gstelementmetadata.h"
#include "gstinfo.h"
#include "gsturi.h"
#include "gstregistry.h"
......@@ -150,10 +150,9 @@ 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->metadata) {
gst_structure_free ((GstStructure *) factory->metadata);
factory->metadata = NULL;
}
if (factory->type) {
factory->type = G_TYPE_INVALID;
......@@ -247,17 +246,16 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
/* provide info needed during class structure setup */
g_type_set_qdata (type, _gst_elementclass_factory, factory);
klass = GST_ELEMENT_CLASS (g_type_class_ref (type));
#if 0
/* FIXME */
if ((klass->details.longname == NULL) ||
(klass->details.klass == NULL) || (klass->details.author == NULL))
goto detailserror;
#endif
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;
}
factory->metadata = gst_structure_copy ((GstStructure *) klass->metadata);
for (item = klass->padtemplates; item; item = item->next) {
GstPadTemplate *templ = item->data;
GstStaticPadTemplate *newt;
......@@ -324,6 +322,7 @@ urierror:
return FALSE;
}
#if 0
detailserror:
{
GST_WARNING_OBJECT (factory,
......@@ -331,6 +330,7 @@ detailserror:
gst_element_factory_cleanup (factory);
return FALSE;
}
#endif
}
/**
......@@ -498,113 +498,11 @@ gst_element_factory_get_element_type (GstElementFactory * factory)
return factory->type;
}
/**
* gst_element_factory_get_longname:
* @factory: a #GstElementFactory
*
* Gets the longname for this factory
*
* Returns: the longname
*/
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;
}
/**
* gst_element_factory_get_klass:
* @factory: a #GstElementFactory
*
* Gets the class for this factory.
*
* Returns: the class
*/
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;
}
/**
* gst_element_factory_get_description:
* @factory: a #GstElementFactory
*
* Gets the description for this factory.
*
* Returns: the description
*/
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;
}
/**
* gst_element_factory_get_author:
* @factory: a #GstElementFactory
*
* Gets the author for this factory.
*
* Returns: the author
*/
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;
}
static G_CONST_RETURN gchar *
gst_element_factory_get_meta_data (GstElementFactory * factory,
gst_element_factory_get_metadata (GstElementFactory * factory,
const gchar * key)
{
if (!factory->meta_data)
return NULL;
/* 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");
return gst_structure_get_string ((GstStructure *) factory->metadata, key);
}
/**
......@@ -749,7 +647,8 @@ gst_element_factory_list_is_type (GstElementFactory * factory,
gboolean res = FALSE;
const gchar *klass;
klass = gst_element_factory_get_klass (factory);
klass =
gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
/* Filter by element type first, as soon as it matches
* one type, we skip all other tests */
......
......@@ -36,68 +36,6 @@ typedef struct _GstElementFactoryClass GstElementFactoryClass;
G_BEGIN_DECLS
/* FIXME 0.11: Move GstElementDetails into a private header and use it internally
* in GstElementFactory, GstElementClass and the registry
*/
typedef struct _GstElementDetails GstElementDetails;
/**
* GstElementDetails:
* @longname: long, english name
* @klass: 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
* @description: what the element is about
* @author: who wrote this thing?
*
* This struct defines the public information about a #GstElement. It contains
* meta-data about the element that is mostly for the benefit of editors.
*
* The @klass member can be used by applications to filter elements based
* on functionality.
*/
/* FIXME: need translatable stuff in here (how handle in registry)?
* can't we use _N("long name") in element implementations and use _(longname)
* in gst_element_factory_get_longname()
*/
struct _GstElementDetails
{
/*< public > */
gchar *longname;
gchar *klass;
gchar *description;
gchar *author;
/*< private >*/
gpointer _gst_reserved[GST_PADDING];
};
/**
* GST_ELEMENT_DETAILS:
* @longname: long, english name
* @klass: 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
* @description: what the element is about
* @author: who wrote this element
*
* Macro to initialize #GstElementDetails.
*/
#define GST_ELEMENT_DETAILS(longname,klass,description,author) \
{ longname, klass, description, author, {NULL} }
/**
* GST_IS_ELEMENT_DETAILS:
* @details: the #GstElementDetails to check
*
* Tests if element details are initialized.
*/
/* FIXME: what about adding '&& (*__gst_reserved==NULL)' */
#define GST_IS_ELEMENT_DETAILS(details) ( \
(details) && ((details)->longname != NULL) && ((details)->klass != NULL) \
&& ((details)->description != NULL) && ((details)->author != NULL))
#define GST_TYPE_ELEMENT_FACTORY (gst_element_factory_get_type())
#define GST_ELEMENT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENT_FACTORY,\
GstElementFactory))
......@@ -117,8 +55,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;
gpointer metadata;
GList * staticpadtemplates; /* GstStaticPadTemplate list */
guint numpadtemplates;
......@@ -130,9 +67,7 @@ struct _GstElementFactory {
GList * interfaces; /* interface type names this element implements */
/*< private >*/
/* FIXME-0.11: move up and replace details */
gpointer meta_data;
gpointer _gst_reserved[GST_PADDING - 1];
gpointer _gst_reserved[GST_PADDING];
};
struct _GstElementFactoryClass {
......@@ -146,16 +81,15 @@ GType gst_element_factory_get_type (void);
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_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);
G_CONST_RETURN gchar * gst_element_factory_get_documentation_uri (GstElementFactory *factory);
G_CONST_RETURN gchar * gst_element_factory_get_icon_name (GstElementFactory *factory);
G_CONST_RETURN gchar * gst_element_factory_get_metadata (GstElementFactory *factoryi, const gchar *key);
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);
gchar ** gst_element_factory_get_uri_protocols (GstElementFactory *factory);
gboolean gst_element_factory_has_interface (GstElementFactory *factory,
const gchar *interfacename);
......
......@@ -2,7 +2,7 @@
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000,2004 Wim Taymans <wim@fluendo.com>
*
* gstelement.h: Header for GstElement
* gstelementmetadata.h: Metadata for GstElement classes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
......@@ -20,50 +20,58 @@
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_ELEMENT_DETAILS_H__
#define __GST_ELEMENT_DETAILS_H__
#ifndef __GST_ELEMENT_METADATA_H__
#define __GST_ELEMENT_METADATA_H__
G_BEGIN_DECLS
static inline void
__gst_element_details_clear (GstElementDetails * dp)
{
g_free (dp->longname);
g_free (dp->klass);
g_free (dp->description);
g_free (dp->author);
memset (dp, 0, sizeof (GstElementDetails));
}
#define VALIDATE_SET(__dest, __src, __entry) \
G_STMT_START { \
if (g_utf8_validate (__src->__entry, -1, NULL)) { \
__dest->__entry = g_strdup (__src->__entry); \