X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;ds=sidebyside;f=gst%2Fgstmeta.c;h=4bcaa7aa512ba83d06b20936c5fa5cd846ac6542;hb=ce43de86902c4e9c8ed4e9682602664cb9bce2ee;hp=62131ad552b6147b1fbb0120381b43eeff052a8f;hpb=af4d5c7fd6f0619c7528e8aac8e42f193c059093;p=platform%2Fupstream%2Fgstreamer.git diff --git a/gst/gstmeta.c b/gst/gstmeta.c index 62131ad..4bcaa7a 100644 --- a/gst/gstmeta.c +++ b/gst/gstmeta.c @@ -15,15 +15,34 @@ * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. */ /** * SECTION:gstmeta + * @title: GstMeta * @short_description: Buffer metadata * - * Last reviewed on December 17th, 2009 (0.10.26) + * The #GstMeta structure should be included as the first member of a #GstBuffer + * metadata structure. The structure defines the API of the metadata and should + * be accessible to all elements using the metadata. + * + * A metadata API is registered with gst_meta_api_type_register() which takes a + * name for the metadata API and some tags associated with the metadata. + * With gst_meta_api_type_has_tag() one can check if a certain metadata API + * contains a given tag. + * + * Multiple implementations of a metadata API can be registered. + * To implement a metadata API, gst_meta_register() should be used. This + * function takes all parameters needed to create, free and transform metadata + * along with the size of the metadata. The function returns a #GstMetaInfo + * structure that contains the information for the implementation of the API. + * + * A specific implementation can be retrieved by name with gst_meta_get_info(). + * + * See #GstBuffer for how the metadata can be added, retrieved and removed from + * buffers. */ #include "gst_private.h" @@ -33,58 +52,154 @@ #include "gstutils.h" static GHashTable *metainfo = NULL; -static GStaticRWLock lock = G_STATIC_RW_LOCK_INIT; +static GRWLock lock; + +GQuark _gst_meta_transform_copy; +GQuark _gst_meta_tag_memory; void _priv_gst_meta_initialize (void) { + g_rw_lock_init (&lock); metainfo = g_hash_table_new (g_str_hash, g_str_equal); + + _gst_meta_transform_copy = g_quark_from_static_string ("gst-copy"); + _gst_meta_tag_memory = g_quark_from_static_string ("memory"); +} + +/** + * gst_meta_api_type_register: + * @api: an API to register + * @tags: (array zero-terminated=1): tags for @api + * + * Register and return a GType for the @api and associate it with + * @tags. + * + * Returns: a unique GType for @api. + */ +GType +gst_meta_api_type_register (const gchar * api, const gchar ** tags) +{ + GType type; + + g_return_val_if_fail (api != NULL, 0); + g_return_val_if_fail (tags != NULL, 0); + + GST_CAT_DEBUG (GST_CAT_META, "register API \"%s\"", api); + type = g_pointer_type_register_static (api); + + if (type != 0) { + gint i; + + for (i = 0; tags[i]; i++) { + GST_CAT_DEBUG (GST_CAT_META, " adding tag \"%s\"", tags[i]); + g_type_set_qdata (type, g_quark_from_string (tags[i]), + GINT_TO_POINTER (TRUE)); + } + } + + g_type_set_qdata (type, g_quark_from_string ("tags"), + g_strdupv ((gchar **) tags)); + + return type; +} + +/** + * gst_meta_api_type_has_tag: + * @api: an API + * @tag: the tag to check + * + * Check if @api was registered with @tag. + * + * Returns: %TRUE if @api was registered with @tag. + */ +gboolean +gst_meta_api_type_has_tag (GType api, GQuark tag) +{ + g_return_val_if_fail (api != 0, FALSE); + g_return_val_if_fail (tag != 0, FALSE); + + return g_type_get_qdata (api, tag) != NULL; +} + +/** + * gst_meta_api_type_get_tags: + * @api: an API + * + * Returns: (transfer none) (array zero-terminated=1) (element-type utf8): an array of tags as strings. + * + * Since: 1.2 + */ +const gchar *const * +gst_meta_api_type_get_tags (GType api) +{ + const gchar **tags; + g_return_val_if_fail (api != 0, FALSE); + + tags = g_type_get_qdata (api, g_quark_from_string ("tags")); + + if (!tags[0]) + return NULL; + + return (const gchar * const *) tags; } /** * gst_meta_register: - * @api: the name of the #GstMeta API + * @api: the type of the #GstMeta API * @impl: the name of the #GstMeta implementation * @size: the size of the #GstMeta structure - * @init_func: a #GstMetaInitFunction - * @free_func: a #GstMetaFreeFunction - * @copy_func: a #GstMetaCopyFunction - * @transform_func: a #GstMetaTransformFunction + * @init_func: (scope async): a #GstMetaInitFunction + * @free_func: (scope async): a #GstMetaFreeFunction + * @transform_func: (scope async): a #GstMetaTransformFunction * * Register a new #GstMeta implementation. * * The same @info can be retrieved later with gst_meta_get_info() by using * @impl as the key. * - * Returns: (transfer none): a #GstMetaInfo that can be used to access metadata. + * Returns: (transfer none) (nullable): a #GstMetaInfo that can be used to + * access metadata. */ const GstMetaInfo * -gst_meta_register (const gchar * api, const gchar * impl, gsize size, +gst_meta_register (GType api, const gchar * impl, gsize size, GstMetaInitFunction init_func, GstMetaFreeFunction free_func, - GstMetaCopyFunction copy_func, GstMetaTransformFunction transform_func) + GstMetaTransformFunction transform_func) { GstMetaInfo *info; + GType type; - g_return_val_if_fail (api != NULL, NULL); + g_return_val_if_fail (api != 0, NULL); g_return_val_if_fail (impl != NULL, NULL); g_return_val_if_fail (size != 0, NULL); + if (init_func == NULL) + g_critical ("Registering meta implementation '%s' without init function", + impl); + + /* first try to register the implementation name. It's possible + * that this fails because it was already registered. Don't warn, + * glib did this for us already. */ + type = g_pointer_type_register_static (impl); + if (type == 0) + return NULL; + info = g_slice_new (GstMetaInfo); - info->api = g_quark_from_string (api); - info->type = g_pointer_type_register_static (impl); + info->api = api; + info->type = type; info->size = size; info->init_func = init_func; info->free_func = free_func; - info->copy_func = copy_func; info->transform_func = transform_func; - GST_DEBUG ("register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT, - api, impl, size); + GST_CAT_DEBUG (GST_CAT_META, + "register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT, impl, + g_type_name (api), size); - g_static_rw_lock_writer_lock (&lock); + g_rw_lock_writer_lock (&lock); g_hash_table_insert (metainfo, (gpointer) impl, (gpointer) info); - g_static_rw_lock_writer_unlock (&lock); + g_rw_lock_writer_unlock (&lock); return info; } @@ -96,8 +211,8 @@ gst_meta_register (const gchar * api, const gchar * impl, gsize size, * Lookup a previously registered meta info structure by its implementation name * @impl. * - * Returns: (transfer none): a #GstMetaInfo with @impl, or #NULL when no such - * metainfo exists. + * Returns: (transfer none) (nullable): a #GstMetaInfo with @impl, or + * %NULL when no such metainfo exists. */ const GstMetaInfo * gst_meta_get_info (const gchar * impl) @@ -106,9 +221,57 @@ gst_meta_get_info (const gchar * impl) g_return_val_if_fail (impl != NULL, NULL); - g_static_rw_lock_reader_lock (&lock); + g_rw_lock_reader_lock (&lock); info = g_hash_table_lookup (metainfo, impl); - g_static_rw_lock_reader_unlock (&lock); + g_rw_lock_reader_unlock (&lock); return info; } + +/** + * gst_meta_get_seqnum: + * @meta: a #GstMeta + * + * Gets seqnum for this meta. + * + * Since: 1.16 + */ +guint64 +gst_meta_get_seqnum (const GstMeta * meta) +{ + GstMetaItem *meta_item; + guint8 *p; + + g_return_val_if_fail (meta != NULL, 0); + + p = (guint8 *) meta; + p -= G_STRUCT_OFFSET (GstMetaItem, meta); + meta_item = (GstMetaItem *) p; + return meta_item->seq_num; +} + +/** + * gst_meta_compare_seqnum: + * @meta1: a #GstMeta + * @meta2: a #GstMeta + * + * Meta sequence number compare function. Can be used as #GCompareFunc + * or a #GCompareDataFunc. + * + * Returns: a negative number if @meta1 comes before @meta2, 0 if both metas + * have an equal sequence number, or a positive integer if @meta1 comes + * after @meta2. + * + * Since: 1.16 + */ +gint +gst_meta_compare_seqnum (const GstMeta * meta1, const GstMeta * meta2) +{ + guint64 seqnum1 = gst_meta_get_seqnum (meta1); + guint64 seqnum2 = gst_meta_get_seqnum (meta2); + + if (seqnum1 == seqnum2) + return 0; + + return (seqnum1 < seqnum2) ? -1 : 1; +}