meta: split registration of API and implementation
authorWim Taymans <wim.taymans@collabora.co.uk>
Wed, 29 Feb 2012 16:20:23 +0000 (17:20 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Wed, 29 Feb 2012 16:37:09 +0000 (17:37 +0100)
Split out the registration of the metadata API and its implementation. Make a
GType for each metadata API. This allows us to store extra information with the
API type such as the tags.
Change the buffer API so that we can get the metadata using the API GType.
Change the query API so that we use the metadata API GType in the allocation
query instead of a string.
Update netaddress and unit tests

gst/gstbuffer.c
gst/gstbuffer.h
gst/gstmeta.c
gst/gstmeta.h
gst/gstquery.c
gst/gstquery.h
libs/gst/net/gstnetaddressmeta.c
libs/gst/net/gstnetaddressmeta.h
tests/check/gst/gstmeta.c
win32/common/libgstnet.def
win32/common/libgstreamer.def

index b3d4efd..1b1db7e 100644 (file)
@@ -1474,28 +1474,26 @@ gst_buffer_span (GstBuffer * buf1, gsize offset, GstBuffer * buf2, gsize size)
 /**
  * gst_buffer_get_meta:
  * @buffer: a #GstBuffer
- * @info: a #GstMetaInfo
+ * @api: the #GType of an API
  *
- * Get the metadata for the api in @info on buffer. When there is no such
+ * Get the metadata for @api on buffer. When there is no such
  * metadata, NULL is returned.
  *
- * Note that the result metadata might not be of the implementation @info.
- *
- * Returns: the metadata for the api in @info on @buffer.
+ * Returns: the metadata for @api on @buffer.
  */
 GstMeta *
-gst_buffer_get_meta (GstBuffer * buffer, const GstMetaInfo * info)
+gst_buffer_get_meta (GstBuffer * buffer, GType api)
 {
   GstMetaItem *item;
   GstMeta *result = NULL;
 
   g_return_val_if_fail (buffer != NULL, NULL);
-  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (api != 0, NULL);
 
   /* find GstMeta of the requested API */
   for (item = GST_BUFFER_META (buffer); item; item = item->next) {
     GstMeta *meta = &item->meta;
-    if (meta->info->api == info->api) {
+    if (meta->info->api == api) {
       result = meta;
       break;
     }
index 87ff090..57052d5 100644 (file)
@@ -506,7 +506,7 @@ GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, gsize offset,
 typedef gboolean (*GstBufferForeachMetaFunc)    (GstBuffer *buffer, GstMeta **meta,
                                                  gpointer user_data);
 
-GstMeta *       gst_buffer_get_meta             (GstBuffer *buffer, const GstMetaInfo *info);
+GstMeta *       gst_buffer_get_meta             (GstBuffer *buffer, GType api);
 GstMeta *       gst_buffer_add_meta             (GstBuffer *buffer, const GstMetaInfo *info,
                                                  gpointer params);
 gboolean        gst_buffer_remove_meta          (GstBuffer *buffer, GstMeta *meta);
index db69933..7865030 100644 (file)
@@ -47,8 +47,56 @@ _priv_gst_meta_initialize (void)
 }
 
 /**
+ * gst_meta_api_type_register:
+ * @api: an API to register
+ * @tags: 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);
+
+  type = g_pointer_type_register_static (api);
+
+  if (type != 0) {
+    gint i;
+
+    for (i = 0; tags[i]; i++)
+      g_type_set_qdata (type, g_quark_from_string (tags[i]),
+          GINT_TO_POINTER (TRUE));
+  }
+  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_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
@@ -66,33 +114,24 @@ _priv_gst_meta_initialize (void)
  */
 
 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,
-    GstMetaTransformFunction transform_func, const gchar ** tags)
+    GstMetaTransformFunction transform_func)
 {
   GstMetaInfo *info;
-  guint len, i;
-  GQuark *qtags;
 
-  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);
-  g_return_val_if_fail (tags != NULL, NULL);
 
   info = g_slice_new (GstMetaInfo);
-  info->api = g_quark_from_string (api);
+  info->api = api;
   info->type = g_pointer_type_register_static (impl);
   info->size = size;
   info->init_func = init_func;
   info->free_func = free_func;
   info->transform_func = transform_func;
 
-  len = g_strv_length ((gchar **) tags);
-  qtags = g_new0 (GQuark, len);
-  for (i = 0; i < len; i++)
-    qtags[i] = g_quark_from_static_string (tags[i]);
-  info->tags = qtags;
-
   GST_DEBUG ("register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT,
       api, impl, size);
 
@@ -126,27 +165,3 @@ gst_meta_get_info (const gchar * impl)
 
   return info;
 }
-
-/*
- * gst_meta_info_has_tag:
- * @info: a #GstMetaInfo
- * @tag: a #GQuark
- *
- * Check if @info contains @tag.
- *
- * Returns: %TRUE when @info contains @tag.
- */
-gboolean
-gst_meta_info_has_tag (const GstMetaInfo * info, GQuark tag)
-{
-  gint i;
-
-  g_return_val_if_fail (info != NULL, FALSE);
-  g_return_val_if_fail (tag != 0, FALSE);
-
-  for (i = 0; info->tags[i]; i++)
-    if (info->tags[i] == tag)
-      return TRUE;
-
-  return FALSE;
-}
index 9d820c2..5503534 100644 (file)
@@ -170,7 +170,7 @@ typedef gboolean (*GstMetaTransformFunction) (GstBuffer *transbuf,
  * structure.
  */
 struct _GstMetaInfo {
-  GQuark                     api;
+  GType                      api;
   GType                      type;
   gsize                      size;
 
@@ -178,21 +178,21 @@ struct _GstMetaInfo {
   GstMetaFreeFunction        free_func;
   GstMetaTransformFunction   transform_func;
 
-  const GQuark              *tags;
-
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
 };
 
-const GstMetaInfo *  gst_meta_register        (const gchar *api, const gchar *impl,
-                                               gsize size,
-                                               GstMetaInitFunction        init_func,
-                                               GstMetaFreeFunction        free_func,
-                                               GstMetaTransformFunction   transform_func,
-                                               const gchar **tags);
-const GstMetaInfo *  gst_meta_get_info        (const gchar * impl);
+GType                gst_meta_api_type_register (const gchar *api,
+                                                 const gchar **tags);
+gboolean             gst_meta_api_type_has_tag  (GType api, GQuark tag);
+
+const GstMetaInfo *  gst_meta_register          (GType api, const gchar *impl,
+                                                 gsize size,
+                                                 GstMetaInitFunction      init_func,
+                                                 GstMetaFreeFunction      free_func,
+                                                 GstMetaTransformFunction transform_func);
+const GstMetaInfo *  gst_meta_get_info          (const gchar * impl);
 
-gboolean             gst_meta_info_has_tag    (const GstMetaInfo *info, GQuark tag);
 
 G_END_DECLS
 
index f076361..a3d4dae 100644 (file)
@@ -1713,20 +1713,18 @@ gst_query_parse_allocation_params (GstQuery * query, guint * size,
  * Add @api as aone of the supported metadata API to @query.
  */
 void
-gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
+gst_query_add_allocation_meta (GstQuery * query, GType api)
 {
   GArray *array;
   GstStructure *structure;
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
-  g_return_if_fail (api != NULL);
+  g_return_if_fail (api != 0);
   g_return_if_fail (gst_query_is_writable (query));
 
   structure = GST_QUERY_STRUCTURE (query);
-  array =
-      ensure_array (structure, GST_QUARK (META), sizeof (const gchar *), NULL);
+  array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
 
-  api = g_intern_string (api);
   g_array_append_val (array, api);
 }
 
@@ -1748,8 +1746,7 @@ gst_query_get_n_allocation_metas (GstQuery * query)
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
 
   structure = GST_QUERY_STRUCTURE (query);
-  array =
-      ensure_array (structure, GST_QUARK (META), sizeof (const gchar *), NULL);
+  array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
 
   return array->len;
 }
@@ -1762,23 +1759,22 @@ gst_query_get_n_allocation_metas (GstQuery * query)
  * Parse an available query and get the metadata API
  * at @index of the metadata API array.
  *
- * Returns: a #gchar of the metadata API at @index.
+ * Returns: a #GType of the metadata API at @index.
  */
-const gchar *
+GType
 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
 {
   GArray *array;
-  const gchar *ret = NULL;
+  GType ret = 0;
   GstStructure *structure;
 
-  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
 
   structure = GST_QUERY_STRUCTURE (query);
-  array =
-      ensure_array (structure, GST_QUARK (META), sizeof (const gchar *), NULL);
+  array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
 
   if (index < array->len)
-    ret = g_array_index (array, const gchar *, index);
+    ret = g_array_index (array, GType, index);
 
   return ret;
 }
@@ -1793,22 +1789,21 @@ gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
  * Returns: TRUE when @api is in the list of metadata.
  */
 gboolean
-gst_query_has_allocation_meta (GstQuery * query, const gchar * api)
+gst_query_has_allocation_meta (GstQuery * query, GType api)
 {
   GArray *array;
   GstStructure *structure;
   guint i, len;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
-  g_return_val_if_fail (api != NULL, FALSE);
+  g_return_val_if_fail (api != 0, FALSE);
 
   structure = GST_QUERY_STRUCTURE (query);
-  array =
-      ensure_array (structure, GST_QUARK (META), sizeof (const gchar *), NULL);
+  array = ensure_array (structure, GST_QUARK (META), sizeof (GType), NULL);
 
   len = array->len;
   for (i = 0; i < len; i++) {
-    if (strcmp (api, g_array_index (array, const gchar *, i)) == 0)
+    if (g_array_index (array, GType, i) == api)
       return TRUE;
   }
   return FALSE;
index 1f16212..38ef3fe 100644 (file)
@@ -372,10 +372,10 @@ void            gst_query_parse_allocation_params (GstQuery *query, guint *size,
                                                    guint *max_buffers, guint *prefix, guint *alignment,
                                                    GstBufferPool **pool);
 
-void            gst_query_add_allocation_meta       (GstQuery *query, const gchar *api);
+void            gst_query_add_allocation_meta       (GstQuery *query, GType api);
 guint           gst_query_get_n_allocation_metas    (GstQuery *query);
-const gchar *   gst_query_parse_nth_allocation_meta (GstQuery *query, guint index);
-gboolean        gst_query_has_allocation_meta       (GstQuery *query, const gchar *api);
+GType           gst_query_parse_nth_allocation_meta (GstQuery *query, guint index);
+gboolean        gst_query_has_allocation_meta       (GstQuery *query, GType api);
 
 void            gst_query_add_allocation_memory       (GstQuery *query, GstAllocator *allocator);
 guint           gst_query_get_n_allocation_memories   (GstQuery *query);
index 12028de..af869ae 100644 (file)
@@ -64,17 +64,30 @@ net_address_meta_free (GstMeta * meta, GstBuffer * buffer)
   nmeta->addr = NULL;
 }
 
+GType
+gst_net_address_meta_api_get_type (void)
+{
+  static volatile GType type;
+  static const gchar *tags[] = { "origin", NULL };
+
+  if (g_once_init_enter (&type)) {
+    GType _type = gst_meta_api_type_register ("GstNetAddressMetaAPI", tags);
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
+
 const GstMetaInfo *
 gst_net_address_meta_get_info (void)
 {
   static const GstMetaInfo *meta_info = NULL;
-  static const gchar *tags[] = { "origin", NULL };
 
   if (meta_info == NULL) {
-    meta_info = gst_meta_register ("GstNetAddressMeta", "GstNetAddressMeta",
+    meta_info = gst_meta_register (GST_NET_ADDRESS_META_API_TYPE,
+        "GstNetAddressMeta",
         sizeof (GstNetAddressMeta),
         net_address_meta_init,
-        net_address_meta_free, net_address_meta_transform, tags);
+        net_address_meta_free, net_address_meta_transform);
   }
   return meta_info;
 }
index c40cf48..0173d87 100644 (file)
@@ -38,11 +38,16 @@ struct _GstNetAddressMeta {
   GSocketAddress *addr;
 };
 
+GType gst_net_address_meta_api_get_type (void);
+#define GST_NET_ADDRESS_META_API_TYPE (gst_net_address_meta_api_get_type())
+
+#define gst_buffer_get_net_address_meta(b) \
+  ((GstNetAddressMeta*)gst_buffer_get_meta((b),GST_NET_ADDRESS_META_API_TYPE))
+
+/* implementation */
 const GstMetaInfo *gst_net_address_meta_get_info (void);
 #define GST_NET_ADDRESS_META_INFO (gst_net_address_meta_get_info())
 
-#define gst_buffer_get_net_address_meta(b) \
-  ((GstNetAddressMeta*)gst_buffer_get_meta((b),GST_NET_ADDRESS_META_INFO))
 GstNetAddressMeta * gst_buffer_add_net_address_meta (GstBuffer      *buffer,
                                                      GSocketAddress *addr);
 
index 392b123..b3ea3d7 100644 (file)
@@ -43,10 +43,13 @@ typedef struct
   GstClockTime clock_rate;
 } GstMetaTest;
 
+static GType gst_meta_test_api_get_type (void);
+#define GST_META_TEST_API_TYPE (gst_meta_test_api_get_type())
+
 static const GstMetaInfo *gst_meta_test_get_info (void);
 #define GST_META_TEST_INFO (gst_meta_test_get_info())
 
-#define GST_META_TEST_GET(buf) ((GstMetaTest *)gst_buffer_get_meta(buf,GST_META_TEST_INFO))
+#define GST_META_TEST_GET(buf) ((GstMetaTest *)gst_buffer_get_meta(buf,GST_META_TEST_API_TYPE))
 #define GST_META_TEST_ADD(buf) ((GstMetaTest *)gst_buffer_add_meta(buf,GST_META_TEST_INFO,NULL))
 
 #if 0
@@ -114,16 +117,29 @@ test_transform_func (GstBuffer * transbuf, GstMeta * meta,
   return TRUE;
 }
 
+static GType
+gst_meta_test_api_get_type (void)
+{
+  static volatile GType type;
+  static const gchar *tags[] = { "timing", NULL };
+
+  if (g_once_init_enter (&type)) {
+    GType _type = gst_meta_api_type_register ("GstMetaTestAPI", tags);
+    g_once_init_leave (&type, _type);
+  }
+  return type;
+}
+
 static const GstMetaInfo *
 gst_meta_test_get_info (void)
 {
   static const GstMetaInfo *meta_test_info = NULL;
-  static const gchar *tags[] = { "timing", NULL };
 
   if (meta_test_info == NULL) {
-    meta_test_info = gst_meta_register ("GstMetaTest", "GstMetaTest",
+    meta_test_info = gst_meta_register (GST_META_TEST_API_TYPE,
+        "GstMetaTest",
         sizeof (GstMetaTest),
-        test_init_func, test_free_func, test_transform_func, tags);
+        test_init_func, test_free_func, test_transform_func);
   }
   return meta_test_info;
 }
index 14685a2..42c28ba 100644 (file)
@@ -1,5 +1,6 @@
 EXPORTS
        gst_buffer_add_net_address_meta
+       gst_net_address_meta_api_get_type
        gst_net_address_meta_get_info
        gst_net_client_clock_get_type
        gst_net_client_clock_new
index ce0c515..4bafc0f 100644 (file)
@@ -584,9 +584,10 @@ EXPORTS
        gst_message_type_get_name
        gst_message_type_get_type
        gst_message_type_to_quark
+       gst_meta_api_type_has_tag
+       gst_meta_api_type_register
        gst_meta_flags_get_type
        gst_meta_get_info
-       gst_meta_info_has_tag
        gst_meta_register
        gst_mini_object_copy
        gst_mini_object_flags_get_type