meta: Move the clear operation to its own vfunc

Some transforms always assumed that the transformation was some kind
of copy. So adding a "clear" operation didn't work out in practice.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5830>
This commit is contained in:
Olivier Crête 2023-12-18 13:40:53 -05:00 committed by GStreamer Marge Bot
parent 73338aa1ae
commit 2a9c4e3270
5 changed files with 68 additions and 54 deletions

View file

@ -22164,16 +22164,6 @@ In hindsight, this tag should have been called "memory-layout".</doc>
<source-position filename="../subprojects/gstreamer/gst/gstmeta.h"/>
<type name="utf8" c:type="gchar*"/>
</constant>
<function-macro name="META_TRANSFORM_IS_CLEAR" c:identifier="GST_META_TRANSFORM_IS_CLEAR" version="1.24" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">Check if the transform type is clearing the content of the meta without
freeing it.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstmeta.h"/>
<parameters>
<parameter name="type">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">a transform type</doc>
</parameter>
</parameters>
</function-macro>
<function-macro name="META_TRANSFORM_IS_COPY" c:identifier="GST_META_TRANSFORM_IS_COPY" introspectable="0">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">Check if the transform type is a copy transform</doc>
<source-position filename="../subprojects/gstreamer/gst/gstmeta.h"/>
@ -26093,6 +26083,24 @@ transform function.</doc>
</parameters>
</function>
</record>
<callback name="MetaClearFunction" c:type="GstMetaClearFunction" version="1.24">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">Clears the content of the meta. This will be called by the GstBufferPool
when a pooled buffer is returned.</doc>
<source-position filename="../subprojects/gstreamer/gst/gstmeta.h"/>
<return-value transfer-ownership="none">
<type name="none" c:type="void"/>
</return-value>
<parameters>
<parameter name="buffer" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">a #GstBuffer</doc>
<type name="Buffer" c:type="GstBuffer*"/>
</parameter>
<parameter name="meta" transfer-ownership="none">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">a #GstMeta</doc>
<type name="Meta" c:type="GstMeta*"/>
</parameter>
</parameters>
</callback>
<callback name="MetaDeserializeFunction" c:type="GstMetaDeserializeFunction" version="1.24">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">Recreate a #GstMeta from serialized data returned by
#GstMetaSerializeFunction and add it to @buffer.</doc>
@ -26196,6 +26204,12 @@ meta.</doc>
meta.</doc>
<type name="MetaDeserializeFunction" c:type="GstMetaDeserializeFunction"/>
</field>
<field name="clear_func" version="1.24" writable="1">
<doc xml:space="preserve" filename="../subprojects/gstreamer/gst/gstmeta.h">Function for clearing the metadata, or %NULL if not supported by this
meta. This is called by the buffer pool when a buffer is returned for
pooled metas.</doc>
<type name="MetaClearFunction" c:type="GstMetaClearFunction"/>
</field>
<method name="is_custom" c:identifier="gst_meta_info_is_custom" version="1.20">
<source-position filename="../subprojects/gstreamer/gst/gstmeta.h"/>
<return-value transfer-ownership="none">

View file

@ -344,39 +344,41 @@ gst_analytics_relation_meta_transform (GstBuffer * transbuf,
return FALSE;
}
} else if (GST_META_TRANSFORM_IS_CLEAR (type)) {
GstAnalyticsRelationMeta *rmeta = (GstAnalyticsRelationMeta *) meta;
gsize adj_mat_data_size =
(sizeof (guint8) * rmeta->rel_order * rmeta->rel_order);
rmeta->next_id = 0;
rmeta->offset = 0;
rmeta->length = 0;
if (adj_mat_data_size) {
/* Only clear data and not lines addresses occupying begining of this
* array. */
memset (rmeta->adj_mat + rmeta->rel_order, 0, adj_mat_data_size);
}
return TRUE;
}
return FALSE;
}
static void
gst_analytics_relation_meta_clear (GstBuffer * buffer, GstMeta * meta)
{
GstAnalyticsRelationMeta *rmeta = (GstAnalyticsRelationMeta *) meta;
gsize adj_mat_data_size =
(sizeof (guint8) * rmeta->rel_order * rmeta->rel_order);
rmeta->next_id = 0;
rmeta->offset = 0;
rmeta->length = 0;
if (adj_mat_data_size) {
/* Only clear data and not lines addresses occupying begining of this
* array. */
memset (rmeta->adj_mat + rmeta->rel_order, 0, adj_mat_data_size);
}
}
const GstMetaInfo *
gst_analytics_relation_meta_get_info (void)
{
static const GstMetaInfo *info = NULL;
if (g_once_init_enter ((GstMetaInfo **) & info)) {
const GstMetaInfo *meta =
GstMetaInfo *meta = (GstMetaInfo *)
gst_meta_register (GST_ANALYTICS_RELATION_META_API_TYPE,
"GstAnalyticsRelationMeta",
sizeof (GstAnalyticsRelationMeta),
gst_analytics_relation_meta_init,
gst_analytics_relation_meta_free,
gst_analytics_relation_meta_transform);
meta->clear_func = gst_analytics_relation_meta_clear;
g_once_init_leave ((GstMetaInfo **) & info, (GstMetaInfo *) meta);
}
return info;

View file

@ -1221,10 +1221,8 @@ remove_meta_unpooled (GstBuffer * buffer, GstMeta ** meta, gpointer user_data)
const GstMetaInfo *info = (*meta)->info;
/* If we can clear it, don't free it */
if (info->transform_func) {
info->transform_func (NULL, *meta, buffer, _gst_meta_transform_clear,
NULL);
}
if (info->clear_func)
info->clear_func (buffer, *meta);
}
return TRUE;
}

View file

@ -56,7 +56,6 @@ static GHashTable *metainfo = NULL;
static GRWLock lock;
GQuark _gst_meta_transform_copy;
GQuark _gst_meta_transform_clear;
GQuark _gst_meta_tag_memory;
GQuark _gst_meta_tag_memory_reference;
@ -82,7 +81,6 @@ _priv_gst_meta_initialize (void)
metainfo = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_info);
_gst_meta_transform_copy = g_quark_from_static_string ("gst-copy");
_gst_meta_transform_clear = g_quark_from_static_string ("gst-clear");
_gst_meta_tag_memory = g_quark_from_static_string ("memory");
_gst_meta_tag_memory_reference =
g_quark_from_static_string ("memory-reference");
@ -430,7 +428,7 @@ gst_meta_register_internal (GType api, const gchar * impl, gsize size,
if (type == G_TYPE_INVALID)
return NULL;
info = (GstMetaInfo *) g_new (GstMetaInfoImpl, 1);
info = (GstMetaInfo *) g_new0 (GstMetaInfoImpl, 1);
info->api = api;
info->type = type;
info->size = size;

View file

@ -197,27 +197,6 @@ typedef struct {
gsize size;
} GstMetaTransformCopy;
/**
* gst_meta_transform_clear:
*
* GQuark for the "gst-clear" transform.
*
* Since: 1.24
*/
GST_API GQuark _gst_meta_transform_clear;
/**
* GST_META_TRANSFORM_IS_CLEAR:
* @type: a transform type
*
* Check if the transform type is clearing the content of the meta without
* freeing it.
*
* Since: 1.24
*/
#define GST_META_TRANSFORM_IS_CLEAR(type) ((type) == _gst_meta_transform_clear)
/**
* GstMetaTransformFunction:
* @transbuf: a #GstBuffer
@ -301,6 +280,18 @@ typedef gboolean (*GstMetaSerializeFunction) (const GstMeta *meta,
typedef GstMeta *(*GstMetaDeserializeFunction) (const GstMetaInfo *info,
GstBuffer *buffer, const guint8 *data, gsize size, guint8 version);
/**
* GstMetaClearFunction:
* @buffer: a #GstBuffer
* @meta: a #GstMeta
*
* Clears the content of the meta. This will be called by the GstBufferPool
* when a pooled buffer is returned.
*
* Since: 1.24
*/
typedef void (*GstMetaClearFunction) (GstBuffer *buffer, GstMeta *meta);
/**
* GstMetaInfo.serialize_func:
*
@ -319,6 +310,16 @@ typedef GstMeta *(*GstMetaDeserializeFunction) (const GstMetaInfo *info,
* Since: 1.24
*/
/**
* GstMetaInfo.clear_func:
*
* Function for clearing the metadata, or %NULL if not supported by this
* meta. This is called by the buffer pool when a buffer is returned for
* pooled metas.
*
* Since: 1.24
*/
/**
* GstMetaInfo:
* @api: tag identifying the metadata structure and api
@ -345,6 +346,7 @@ struct _GstMetaInfo {
GstMetaTransformFunction transform_func;
GstMetaSerializeFunction serialize_func;
GstMetaDeserializeFunction deserialize_func;
GstMetaClearFunction clear_func;
/* No padding needed, GstMetaInfo is always allocated by GStreamer and is
* not subclassable or stack-allocatable, so we can extend it as we please