meta: separate add and get methods

Make separate api for getting and adding metadata. This allows us to pass extra
parameters to the init functions when creating metadata, which is needed for
specific API implementations.
Add beginnings of memory metadata.
This commit is contained in:
Wim Taymans 2011-02-27 19:40:45 +01:00
parent 0969106993
commit 58060d7528
5 changed files with 94 additions and 35 deletions

View file

@ -776,52 +776,79 @@ gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
* gst_buffer_get_meta:
* @buffer: a #GstBuffer
* @info: a #GstMetaInfo
* @create: create when needed
*
* Get the metadata for the api in @info on buffer. When there is no such
* metadata and @create is TRUE, a new metadata form @info is created and added
* to @buffer.
* metadata, NULL is returned.
*
* Note that the result metadata might not be of the implementation @info when
* it was already on the buffer.
* Note that the result metadata might not be of the implementation @info.
*
* Returns: the metadata for @info on @buffer.
* Returns: the metadata for the api in @info on @buffer.
*/
GstMeta *
gst_buffer_get_meta (GstBuffer * buffer, const GstMetaInfo * info,
gboolean create)
gst_buffer_get_meta (GstBuffer * buffer, const GstMetaInfo * info)
{
GstMetaItem *walk;
GstMeta *result = NULL;
GstMetaItem *item;
GstMeta *result = NULL;
g_return_val_if_fail (buffer != NULL, NULL);
g_return_val_if_fail (info != NULL, NULL);
/* find GstMeta of the requested API */
for (walk = buffer->priv; walk; walk = walk->next) {
GstMeta *meta = &walk->meta;
for (item = buffer->priv; item; item = item->next) {
GstMeta *meta = &item->meta;
if (meta->info->api == info->api) {
result = meta;
break;
}
}
return result;
}
if (result == NULL && create) {
/* create a new slice */
GST_DEBUG ("alloc metadata of size %" G_GSIZE_FORMAT, info->size);
item = g_slice_alloc (ITEM_SIZE (info));
result = &item->meta;
result->info = info;
/* call the init_func when needed */
if (info->init_func)
info->init_func (result, buffer);
/* and add to the list of metadata */
item->next = buffer->priv;
buffer->priv = item;
}
/**
* gst_buffer_add_meta:
* @buffer: a #GstBuffer
* @info: a #GstMetaInfo
* @params: params for @info
*
* Add metadata for @info to @buffer using the parameters in @params.
*
* Returns: the metadata for the api in @info on @buffer.
*/
GstMeta *
gst_buffer_add_meta (GstBuffer * buffer, const GstMetaInfo * info,
gpointer params)
{
GstMetaItem *item;
GstMeta *result = NULL;
gsize size;
g_return_val_if_fail (buffer != NULL, NULL);
g_return_val_if_fail (info != NULL, NULL);
/* create a new slice */
GST_DEBUG ("alloc metadata of size %" G_GSIZE_FORMAT, info->size);
size = ITEM_SIZE (info);
item = g_slice_alloc (size);
result = &item->meta;
result->info = info;
/* call the init_func when needed */
if (info->init_func)
if (!info->init_func (result, params, buffer))
goto init_failed;
/* and add to the list of metadata */
item->next = buffer->priv;
buffer->priv = item;
return result;
init_failed:
{
g_slice_free1 (size, item);
return NULL;
}
}
/**

View file

@ -470,8 +470,9 @@ GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset
/* metadata */
#include <gst/gstmeta.h>
GstMeta * gst_buffer_get_meta (GstBuffer *buffer, const GstMetaInfo *info,
gboolean create);
GstMeta * gst_buffer_get_meta (GstBuffer *buffer, const GstMetaInfo *info);
GstMeta * gst_buffer_add_meta (GstBuffer *buffer, const GstMetaInfo *info,
gpointer params);
gboolean gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta);
GstMeta * gst_buffer_iterate_meta (GstBuffer *buffer, gpointer *state);

View file

@ -53,7 +53,7 @@ struct _GstMeta {
*
* Function called when @meta is initialized in @buffer.
*/
typedef void (*GstMetaInitFunction) (GstMeta *meta, GstBuffer *buffer);
typedef gboolean (*GstMetaInitFunction) (GstMeta *meta, gpointer params, GstBuffer *buffer);
/**
* GstMetaFreeFunction:
@ -143,6 +143,34 @@ const GstMetaInfo * gst_meta_register (const gchar *api, const gchar *im
GstMetaDeserializeFunction deserialize_func);
const GstMetaInfo * gst_meta_get_info (const gchar * impl);
/* default metadata */
typedef struct _GstMetaMemory GstMetaMemory;
typedef enum {
GST_META_MAP_NONE,
GST_META_MAP_READ,
GST_META_MAP_WRITE
} GstMetaMapFlags;
typedef gpointer (*GstMetaMapFunc) (GstMetaMemory *meta, guint offset, guint *size,
GstMetaMapFlags flags);
typedef gboolean (*GstMetaUnmapFunc) (GstMetaMemory *meta, gpointer data, guint size);
struct _GstMetaMemory
{
GstMeta meta;
GstMetaMapFunc mmap_func;
GstMetaUnmapFunc munmap_func;
};
#define gst_meta_memory_map(m,o,s,f) ((m)->mmap_func(m, o, s, f))
#define gst_meta_memory_unmap(m,d,s) ((m)->munmap_func(m, d, s))
const GstMetaInfo *gst_meta_memory_get_info(void);
#define GST_META_MEMORY_INFO (gst_meta_memory_get_info())
G_END_DECLS
#endif /* __GST_META_H__ */

View file

@ -45,7 +45,8 @@ typedef struct
static const GstMetaInfo *gst_test_meta_get_info (void);
#define GST_TEST_META_GET(buf,create) ((GstTestMeta *)gst_buffer_get_meta(buf,gst_test_meta_get_info(),create));
#define GST_TEST_META_GET(buf) ((GstTestMeta *)gst_buffer_get_meta(buf,gst_test_meta_get_info()))
#define GST_TEST_META_ADD(buf) ((GstTestMeta *)gst_buffer_add_meta(buf,gst_test_meta_get_info(),NULL))
#if 0
/* unused currently. This is a user function to fill the metadata with default
@ -84,7 +85,7 @@ test_copy_func (GstBuffer * copy, GstTestMeta * meta, GstBuffer * buffer)
GST_DEBUG ("copy called from buffer %p to %p, meta %p", buffer, copy, meta);
test = GST_TEST_META_GET (copy, TRUE);
test = GST_TEST_META_ADD (copy);
test->pts = meta->pts;
test->dts = meta->dts;
test->duration = meta->duration;
@ -100,7 +101,7 @@ test_sub_func (GstBuffer * sub, GstTestMeta * meta, GstBuffer * buffer,
GST_DEBUG ("sub called from buffer %p to %p, meta %p, %u-%u", buffer, sub,
meta, offset, size);
test = GST_TEST_META_GET (sub, TRUE);
test = GST_TEST_META_ADD (sub);
if (offset == 0) {
/* same offset, copy timestamps */
test->pts = meta->pts;
@ -145,7 +146,7 @@ GST_START_TEST (test_metadata)
memset (GST_BUFFER_DATA (buffer), 0, 4);
/* add some metadata */
meta = GST_TEST_META_GET (buffer, TRUE);
meta = GST_TEST_META_ADD (buffer);
fail_if (meta == NULL);
/* fill some values */
meta->pts = 1000;
@ -156,7 +157,7 @@ GST_START_TEST (test_metadata)
/* copy of the buffer */
copy = gst_buffer_copy (buffer);
/* get metadata of the buffer */
meta = GST_TEST_META_GET (copy, FALSE);
meta = GST_TEST_META_GET (copy);
fail_if (meta == NULL);
fail_if (meta->pts != 1000);
fail_if (meta->dts != 2000);
@ -167,7 +168,7 @@ GST_START_TEST (test_metadata)
/* make subbuffer */
subbuf = gst_buffer_create_sub (buffer, 0, 1);
/* get metadata of the buffer */
meta = GST_TEST_META_GET (subbuf, FALSE);
meta = GST_TEST_META_GET (subbuf);
fail_if (meta == NULL);
fail_if (meta->pts != 1000);
fail_if (meta->dts != 2000);
@ -178,7 +179,7 @@ GST_START_TEST (test_metadata)
/* make another subbuffer */
subbuf = gst_buffer_create_sub (buffer, 1, 3);
/* get metadata of the buffer */
meta = GST_TEST_META_GET (subbuf, FALSE);
meta = GST_TEST_META_GET (subbuf);
fail_if (meta == NULL);
fail_if (meta->pts != -1);
fail_if (meta->dts != -1);

View file

@ -89,6 +89,7 @@ EXPORTS
gst_bin_recalculate_latency
gst_bin_remove
gst_bin_remove_many
gst_buffer_add_meta
gst_buffer_copy_flags_get_type
gst_buffer_copy_metadata
gst_buffer_create_sub
@ -571,6 +572,7 @@ EXPORTS
gst_message_type_get_type
gst_message_type_to_quark
gst_meta_get_info
gst_meta_map_flags_get_type
gst_meta_register
gst_mini_object_copy
gst_mini_object_flags_get_type