From f5d5f2cf1a514975a7bde2adcefb1420242d180f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20Cr=C3=AAte?= Date: Mon, 18 Dec 2023 16:33:07 -0500 Subject: [PATCH] meta: Add API to register metas in two steps And also remove the specific registration APIs for serializable meta. Part-of: --- girs/Gst-1.0.gir | 153 ++++++++-------- .../gst-libs/gst/analytics/gstanalyticsmeta.c | 12 +- .../gst-libs/gst/audio/gstaudiometa.c | 18 +- .../gst-libs/gst/video/gstvideometa.c | 13 +- subprojects/gstreamer/gst/gstbuffer.c | 19 +- subprojects/gstreamer/gst/gstmeta.c | 167 ++++++++++++------ subprojects/gstreamer/gst/gstmeta.h | 12 +- 7 files changed, 218 insertions(+), 176 deletions(-) diff --git a/girs/Gst-1.0.gir b/girs/Gst-1.0.gir index 24483b2730..3de8bddb78 100644 --- a/girs/Gst-1.0.gir +++ b/girs/Gst-1.0.gir @@ -26040,48 +26040,6 @@ transform function. - - Same as gst_meta_register() but also set serialize/deserialize functions. - - - a #GstMetaInfo that can be used to access metadata. - - - - - the type of the #GstMeta API - - - - the name of the #GstMeta implementation - - - - the size of the #GstMeta structure - - - - a #GstMetaInitFunction - - - - a #GstMetaFreeFunction - - - - a #GstMetaTransformFunction - - - - a #GstMetaSerializeFunction - - - - a #GstMetaDeserializeFunction - - - - Clears the content of the meta. This will be called by the GstBufferPool @@ -26223,6 +26181,75 @@ pooled metas. + + Registers a new meta. + +Use the structure returned by gst_meta_info_new(), it consumes it and the +structure shouldnt be used after. The one returned by the function can be +kept. + + + the registered meta + + + + + a new #GstMetaInfo created by gst_meta_info_new() + + + + + + Creates a new structure that needs to be filled before being +registered. This structure should filled and then registered with +gst_meta_info_register(). + +Example: +```c +const GstMetaInfo * +gst_my_meta_get_info (void) +{ + static const GstMetaInfo *meta_info = NULL; + + if (g_once_init_enter ((GstMetaInfo **) & meta_info)) { + GstMetaInfo *info = gst_meta_info_new ( + gst_my_meta_api_get_type (), + "GstMyMeta", + sizeof (GstMyMeta)); + const GstMetaInfo *meta = NULL; + + info->init_func = my_meta_init; + info->free_func = my_meta_free; + info->transform_func = my_meta_transform; + info->serialize_func = my_meta_serialize; + info->deserialize_func = my_meta_deserialize; + meta = gst_meta_info_register (info); + g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) meta); + } + + return meta_info; +} +``` + + + a new #GstMetaInfo that needs to be filled + + + + + the type of the #GstMeta API + + + + the name of the #GstMeta implementation + + + + the size of the #GstMeta structure + + + + Function called when @meta is initialized in @buffer. @@ -52327,48 +52354,6 @@ transform function. - - Same as gst_meta_register() but also set serialize/deserialize functions. - - - a #GstMetaInfo that can be used to access metadata. - - - - - the type of the #GstMeta API - - - - the name of the #GstMeta implementation - - - - the size of the #GstMeta structure - - - - a #GstMetaInitFunction - - - - a #GstMetaFreeFunction - - - - a #GstMetaTransformFunction - - - - a #GstMetaSerializeFunction - - - - a #GstMetaDeserializeFunction - - - - Atomically modifies a pointer to point to a new mini-object. The reference count of @olddata is decreased and the reference count of diff --git a/subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c b/subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c index d3892fc581..e299a4ba77 100644 --- a/subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c +++ b/subprojects/gst-plugins-bad/gst-libs/gst/analytics/gstanalyticsmeta.c @@ -371,14 +371,14 @@ gst_analytics_relation_meta_get_info (void) { static const GstMetaInfo *info = NULL; if (g_once_init_enter ((GstMetaInfo **) & info)) { - GstMetaInfo *meta = (GstMetaInfo *) - gst_meta_register (GST_ANALYTICS_RELATION_META_API_TYPE, + GstMetaInfo *meta = gst_meta_info_new (GST_ANALYTICS_RELATION_META_API_TYPE, "GstAnalyticsRelationMeta", - sizeof (GstAnalyticsRelationMeta), - gst_analytics_relation_meta_init, - gst_analytics_relation_meta_free, - gst_analytics_relation_meta_transform); + sizeof (GstAnalyticsRelationMeta)); + meta->init_func = gst_analytics_relation_meta_init; + meta->free_func = gst_analytics_relation_meta_free; + meta->transform_func = gst_analytics_relation_meta_transform; meta->clear_func = gst_analytics_relation_meta_clear; + meta = (GstMetaInfo *) gst_meta_info_register (meta); g_once_init_leave ((GstMetaInfo **) & info, (GstMetaInfo *) meta); } return info; diff --git a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiometa.c b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiometa.c index 647eab446b..5e5437523d 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiometa.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/audio/gstaudiometa.c @@ -588,14 +588,16 @@ gst_audio_meta_get_info (void) static const GstMetaInfo *audio_meta_info = NULL; if (g_once_init_enter ((GstMetaInfo **) & audio_meta_info)) { - const GstMetaInfo *meta = - gst_meta_register_serializable (GST_AUDIO_META_API_TYPE, - "GstAudioMeta", sizeof (GstAudioMeta), - gst_audio_meta_init, - gst_audio_meta_free, - gst_audio_meta_transform, - gst_audio_meta_serialize, - gst_audio_meta_deserialize); + GstMetaInfo *info = gst_meta_info_new (GST_AUDIO_META_API_TYPE, + "GstAudioMeta", sizeof (GstAudioMeta)); + + info->init_func = gst_audio_meta_init; + info->free_func = gst_audio_meta_free; + info->transform_func = gst_audio_meta_transform; + info->serialize_func = gst_audio_meta_serialize; + info->deserialize_func = gst_audio_meta_deserialize; + const GstMetaInfo *meta = gst_meta_info_register (info); + g_once_init_leave ((GstMetaInfo **) & audio_meta_info, (GstMetaInfo *) meta); } diff --git a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c index d450c40bbe..f191820818 100644 --- a/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c +++ b/subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c @@ -252,11 +252,14 @@ gst_video_meta_get_info (void) static const GstMetaInfo *video_meta_info = NULL; if (g_once_init_enter ((GstMetaInfo **) & video_meta_info)) { - const GstMetaInfo *meta = - gst_meta_register_serializable (GST_VIDEO_META_API_TYPE, "GstVideoMeta", - sizeof (GstVideoMeta), (GstMetaInitFunction) gst_video_meta_init, - (GstMetaFreeFunction) NULL, gst_video_meta_transform, - video_meta_serialize, video_meta_deserialize); + GstMetaInfo *info = gst_meta_info_new (GST_VIDEO_META_API_TYPE, + "GstVideoMeta", + sizeof (GstVideoMeta)); + info->init_func = gst_video_meta_init; + info->transform_func = gst_video_meta_transform; + info->serialize_func = video_meta_serialize; + info->deserialize_func = video_meta_deserialize; + const GstMetaInfo *meta = gst_meta_info_register (info); g_once_init_leave ((GstMetaInfo **) & video_meta_info, (GstMetaInfo *) meta); } diff --git a/subprojects/gstreamer/gst/gstbuffer.c b/subprojects/gstreamer/gst/gstbuffer.c index ebe2d9b09c..52ce8e5f1d 100644 --- a/subprojects/gstreamer/gst/gstbuffer.c +++ b/subprojects/gstreamer/gst/gstbuffer.c @@ -2918,16 +2918,17 @@ gst_reference_timestamp_meta_get_info (void) static const GstMetaInfo *meta_info = NULL; if (g_once_init_enter ((GstMetaInfo **) & meta_info)) { - const GstMetaInfo *meta = - gst_meta_register_serializable - (gst_reference_timestamp_meta_api_get_type (), + const GstMetaInfo *meta = NULL; + GstMetaInfo *info = + gst_meta_info_new (gst_reference_timestamp_meta_api_get_type (), "GstReferenceTimestampMeta", - sizeof (GstReferenceTimestampMeta), - (GstMetaInitFunction) _gst_reference_timestamp_meta_init, - (GstMetaFreeFunction) _gst_reference_timestamp_meta_free, - _gst_reference_timestamp_meta_transform, - timestamp_meta_serialize, - timestamp_meta_deserialize); + sizeof (GstReferenceTimestampMeta)); + info->init_func = (GstMetaInitFunction) _gst_reference_timestamp_meta_init; + info->free_func = (GstMetaFreeFunction) _gst_reference_timestamp_meta_free; + info->transform_func = _gst_reference_timestamp_meta_transform; + info->serialize_func = timestamp_meta_serialize; + info->deserialize_func = timestamp_meta_deserialize; + meta = gst_meta_info_register (info); g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) meta); } diff --git a/subprojects/gstreamer/gst/gstmeta.c b/subprojects/gstreamer/gst/gstmeta.c index d113f32901..af0a73455d 100644 --- a/subprojects/gstreamer/gst/gstmeta.c +++ b/subprojects/gstreamer/gst/gstmeta.c @@ -301,8 +301,9 @@ gst_meta_register_custom (const gchar * name, const gchar ** tags, { gchar *api_name = g_strdup_printf ("%s-api", name); GType api; - GstMetaInfoImpl *info; - GstMetaInfo *ret = NULL; + GstMetaInfo *info; + GstMetaInfoImpl *impl; + const GstMetaInfo *ret = NULL; g_return_val_if_fail (tags != NULL, NULL); g_return_val_if_fail (name != NULL, NULL); @@ -312,20 +313,24 @@ gst_meta_register_custom (const gchar * name, const gchar ** tags, if (api == G_TYPE_INVALID) goto done; - info = (GstMetaInfoImpl *) gst_meta_register_serializable (api, name, - sizeof (GstCustomMeta), - custom_init_func, custom_free_func, custom_transform_func, - custom_serialize_func, custom_deserialize_func); - - if (!info) + info = gst_meta_info_new (api, name, sizeof (GstCustomMeta)); + if (info == NULL) goto done; - info->is_custom = TRUE; - info->custom_transform_func = transform_func; - info->custom_transform_user_data = user_data; - info->custom_transform_destroy_notify = destroy_data; + impl = (GstMetaInfoImpl *) info; - ret = (GstMetaInfo *) info; + info->init_func = custom_init_func; + info->free_func = custom_free_func; + info->transform_func = custom_transform_func; + info->serialize_func = custom_serialize_func; + info->deserialize_func = custom_deserialize_func; + + impl->is_custom = TRUE; + impl->custom_transform_func = transform_func; + impl->custom_transform_user_data = user_data; + impl->custom_transform_destroy_notify = destroy_data; + + ret = gst_meta_info_register (info); done: return ret; @@ -411,27 +416,14 @@ gst_meta_register_internal (GType api, const gchar * impl, gsize size, GstMetaDeserializeFunction deserialize_func) { GstMetaInfo *info; - GType type; - - 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 == G_TYPE_INVALID) + info = gst_meta_info_new (api, impl, size); + if (info == NULL) return NULL; - info = (GstMetaInfo *) g_new0 (GstMetaInfoImpl, 1); - info->api = api; - info->type = type; - info->size = size; info->init_func = init_func; info->free_func = free_func; info->transform_func = transform_func; @@ -439,16 +431,7 @@ gst_meta_register_internal (GType api, const gchar * impl, gsize size, info->deserialize_func = deserialize_func; ((GstMetaInfoImpl *) info)->is_custom = FALSE; - GST_CAT_DEBUG (GST_CAT_META, - "register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT, impl, - g_type_name (api), size); - - g_rw_lock_writer_lock (&lock); - g_hash_table_insert (metainfo, (gpointer) g_intern_string (impl), - (gpointer) info); - g_rw_lock_writer_unlock (&lock); - - return info; + return gst_meta_info_register (info); } /** @@ -478,33 +461,103 @@ gst_meta_register (GType api, const gchar * impl, gsize size, } /** - * gst_meta_register_serializable: (skip): - * @api: the type of the #GstMeta API + * gst_meta_info_new: + * @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 - * @transform_func: a #GstMetaTransformFunction - * @serialize_func: a #GstMetaSerializeFunction - * @deserialize_func: a #GstMetaDeserializeFunction * - * Same as gst_meta_register() but also set serialize/deserialize functions. + * Creates a new structure that needs to be filled before being + * registered. This structure should filled and then registered with + * gst_meta_info_register(). * - * Returns: (transfer none): a #GstMetaInfo that can be used to access metadata. + * Example: + * ```c + * const GstMetaInfo * + * gst_my_meta_get_info (void) + * { + * static const GstMetaInfo *meta_info = NULL; + * + * if (g_once_init_enter ((GstMetaInfo **) & meta_info)) { + * GstMetaInfo *info = gst_meta_info_new ( + * gst_my_meta_api_get_type (), + * "GstMyMeta", + * sizeof (GstMyMeta)); + * const GstMetaInfo *meta = NULL; + * + * info->init_func = my_meta_init; + * info->free_func = my_meta_free; + * info->transform_func = my_meta_transform; + * info->serialize_func = my_meta_serialize; + * info->deserialize_func = my_meta_deserialize; + * meta = gst_meta_info_register (info); + * g_once_init_leave ((GstMetaInfo **) & meta_info, (GstMetaInfo *) meta); + * } + * + * return meta_info; + * } + * ``` + * + * Returns: a new #GstMetaInfo that needs to be filled * * Since: 1.24 */ -const GstMetaInfo * -gst_meta_register_serializable (GType api, const gchar * impl, gsize size, - GstMetaInitFunction init_func, GstMetaFreeFunction free_func, - GstMetaTransformFunction transform_func, - GstMetaSerializeFunction serialize_func, - GstMetaDeserializeFunction deserialize_func) + +GstMetaInfo * +gst_meta_info_new (GType api, const gchar * impl, gsize size) { - g_return_val_if_fail (serialize_func != NULL, NULL); - g_return_val_if_fail (deserialize_func != NULL, NULL); - return gst_meta_register_internal (api, impl, size, init_func, free_func, - transform_func, serialize_func, deserialize_func); + GType type; + GstMetaInfo *info; + + g_return_val_if_fail (api != 0, NULL); + g_return_val_if_fail (impl != NULL, NULL); + g_return_val_if_fail (size != 0, NULL); + + /* 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); + + info = (GstMetaInfo *) g_new0 (GstMetaInfoImpl, 1); + info->api = api; + info->type = type; + info->size = size; + + return info; +} + +/** + * gst_meta_info_register: + * @info: (transfer full): a new #GstMetaInfo created by gst_meta_info_new() + * + * Registers a new meta. + * + * Use the structure returned by gst_meta_info_new(), it consumes it and the + * structure shouldnt be used after. The one returned by the function can be + * kept. + * + * Returns: (transfer none): the registered meta + * + * Since: 1.24 + */ + +const GstMetaInfo * +gst_meta_info_register (GstMetaInfo * info) +{ + if (info->type == G_TYPE_INVALID) { + g_free (info); + return NULL; + } + + GST_CAT_DEBUG (GST_CAT_META, + "register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT, + g_type_name (info->type), g_type_name (info->api), info->size); + + g_rw_lock_writer_lock (&lock); + g_hash_table_insert (metainfo, + (gpointer) g_intern_string (g_type_name (info->type)), (gpointer) info); + g_rw_lock_writer_unlock (&lock); + + return info; } /** diff --git a/subprojects/gstreamer/gst/gstmeta.h b/subprojects/gstreamer/gst/gstmeta.h index d949b71039..6d5c13a614 100644 --- a/subprojects/gstreamer/gst/gstmeta.h +++ b/subprojects/gstreamer/gst/gstmeta.h @@ -367,13 +367,11 @@ const GstMetaInfo * gst_meta_register (GType api, const gchar *impl, GstMetaTransformFunction transform_func); GST_API -const GstMetaInfo * gst_meta_register_serializable (GType api, const gchar *impl, - gsize size, - GstMetaInitFunction init_func, - GstMetaFreeFunction free_func, - GstMetaTransformFunction transform_func, - GstMetaSerializeFunction serialize_func, - GstMetaDeserializeFunction deserialize_func); +GstMetaInfo * gst_meta_info_new (GType api, + const gchar *impl, + gsize size); +GST_API +const GstMetaInfo * gst_meta_info_register (GstMetaInfo *info); GST_API const GstMetaInfo * gst_meta_register_custom (const gchar *name, const gchar **tags,