meta: implement transform function

Replace subbuffer and copy vmethods by a more generic transform function that
can then be parametrised by transform specific data. This should allow us to
implement make-writable and more future transform functions.
This commit is contained in:
Wim Taymans 2011-03-08 16:58:49 +00:00
parent fd0fd97200
commit fa0d993372
4 changed files with 143 additions and 88 deletions

View file

@ -241,9 +241,10 @@ gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
for (walk = src->priv; walk; walk = walk->next) {
GstMeta *meta = &walk->meta;
const GstMetaInfo *info = meta->info;
GstMetaTransformData data = { GST_META_TRANSFORM_COPY };
if (info->copy_func)
info->copy_func (dest, meta, src);
if (info->transform_func)
info->transform_func (dest, meta, (GstBuffer *) src, &data);
}
}
@ -679,9 +680,15 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
for (walk = buffer->priv; walk; walk = walk->next) {
GstMeta *meta = &walk->meta;
const GstMetaInfo *info = meta->info;
GstMetaTransformSubbuffer subdata;
if (info->sub_func)
info->sub_func (subbuffer, meta, buffer, offset, size);
subdata.data.type = GST_META_TRANSFORM_TRIM;
subdata.offset = offset;
subdata.size = size;
if (info->transform_func)
info->transform_func (subbuffer, meta, buffer,
(GstMetaTransformData *) & subdata);
}
return subbuffer;
}

View file

@ -54,7 +54,7 @@ _gst_meta_init (void)
const GstMetaInfo *
gst_meta_register (const gchar * api, const gchar * impl, gsize size,
GstMetaInitFunction init_func, GstMetaFreeFunction free_func,
GstMetaCopyFunction copy_func, GstMetaSubFunction sub_func,
GstMetaTransformFunction transform_func,
GstMetaSerializeFunction serialize_func,
GstMetaDeserializeFunction deserialize_func)
{
@ -70,8 +70,7 @@ gst_meta_register (const gchar * api, const gchar * impl, gsize size,
info->size = size;
info->init_func = init_func;
info->free_func = free_func;
info->copy_func = copy_func;
info->sub_func = sub_func;
info->transform_func = transform_func;
info->serialize_func = serialize_func;
info->deserialize_func = deserialize_func;
@ -143,34 +142,60 @@ static gboolean
meta_memory_init (GstMetaMemoryImpl * meta, GstMetaMemoryParams * params,
GstBuffer * buffer)
{
GST_DEBUG ("init %p", buffer);
meta->memory.mmap_func = meta_memory_mmap;
meta->memory.munmap_func = meta_memory_munmap;
meta->params = *params;
/* FIXME, backwards compatibility */
//GST_BUFFER_DATA (buffer) = params->data + params->offset;
//GST_BUFFER_SIZE (buffer) = params->size;
return TRUE;
}
static void
meta_memory_free (GstMetaMemoryImpl * meta, GstBuffer * buffer)
{
GST_DEBUG ("free buffer %p", buffer);
if (meta->params.free_func)
meta->params.free_func (meta->params.data);
}
static void
meta_memory_copy (GstBuffer * copy, GstMetaMemoryImpl * meta,
const GstBuffer * buffer)
meta_memory_transform (GstBuffer * transbuf, GstMetaMemoryImpl * meta,
GstBuffer * buffer, GstMetaTransformData * data)
{
gst_buffer_add_meta_memory (copy,
g_memdup (meta->params.data, meta->params.size),
g_free, meta->params.size, meta->params.offset);
}
switch (data->type) {
case GST_META_TRANSFORM_COPY:
{
GST_DEBUG ("copy %p to %p", buffer, transbuf);
gst_buffer_add_meta_memory (transbuf,
g_memdup (meta->params.data, meta->params.size),
g_free, meta->params.size, meta->params.offset);
break;
}
case GST_META_TRANSFORM_TRIM:
{
GstMetaTransformSubbuffer *subdata = (GstMetaTransformSubbuffer *) data;
static void
meta_memory_sub (GstBuffer * subbuf, GstMetaMemoryImpl * meta,
GstBuffer * buffer, guint offset, guint size)
{
gst_buffer_add_meta_memory (subbuf,
meta->params.data, NULL, size, meta->params.offset + offset);
GST_DEBUG ("trim %p to %p", buffer, transbuf);
gst_buffer_add_meta_memory (transbuf,
meta->params.data, NULL, subdata->size,
meta->params.offset + subdata->offset);
break;
}
case GST_META_TRANSFORM_MAKE_WRITABLE:
{
GST_DEBUG ("make writable %p to %p", buffer, transbuf);
gst_buffer_add_meta_memory (transbuf,
meta->params.data, NULL, meta->params.size, meta->params.offset);
break;
}
default:
/* don't copy by default */
break;
}
}
const GstMetaInfo *
@ -183,8 +208,7 @@ gst_meta_memory_get_info (void)
sizeof (GstMetaMemoryImpl),
(GstMetaInitFunction) meta_memory_init,
(GstMetaFreeFunction) meta_memory_free,
(GstMetaCopyFunction) meta_memory_copy,
(GstMetaSubFunction) meta_memory_sub,
(GstMetaTransformFunction) meta_memory_transform,
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
}
return meta_info;
@ -195,12 +219,7 @@ gst_buffer_add_meta_memory (GstBuffer * buffer, gpointer data,
GFreeFunc free_func, gsize size, gsize offset)
{
GstMeta *meta;
GstMetaMemoryParams params;
params.data = data;
params.free_func = free_func;
params.size = size;
params.offset = offset;
GstMetaMemoryParams params = { data, free_func, size, offset };
meta = gst_buffer_add_meta (buffer, GST_META_MEMORY_INFO, &params);
@ -209,29 +228,26 @@ gst_buffer_add_meta_memory (GstBuffer * buffer, gpointer data,
/* Timing metadata */
static void
meta_timing_copy (GstBuffer * copy, GstMetaTiming * meta, GstBuffer * buffer)
meta_timing_transform (GstBuffer * transbuf, GstMetaTiming * meta,
GstBuffer * buffer, GstMetaTransformData * data)
{
GstMetaTiming *timing;
guint offset;
guint size;
GST_DEBUG ("copy called from buffer %p to %p, meta %p", buffer, copy, meta);
if (data->type == GST_META_TRANSFORM_TRIM) {
GstMetaTransformSubbuffer *subdata = (GstMetaTransformSubbuffer *) data;
offset = subdata->offset;
size = subdata->size;
} else {
offset = 0;
size = GST_BUFFER_SIZE (buffer);
}
timing = gst_buffer_add_meta_timing (copy);
timing->pts = meta->pts;
timing->dts = meta->dts;
timing->duration = meta->duration;
timing->clock_rate = meta->clock_rate;
}
GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
transbuf, meta, offset, size);
static void
meta_timing_sub (GstBuffer * sub, GstMetaTiming * meta, GstBuffer * buffer,
guint offset, guint size)
{
GstMetaTiming *timing;
GST_DEBUG ("sub called from buffer %p to %p, meta %p, %u-%u", buffer, sub,
meta, offset, size);
timing = gst_buffer_add_meta_timing (sub);
timing = gst_buffer_add_meta_timing (transbuf);
if (offset == 0) {
/* same offset, copy timestamps */
timing->pts = meta->pts;
@ -261,8 +277,7 @@ gst_meta_timing_get_info (void)
sizeof (GstMetaTiming),
(GstMetaInitFunction) NULL,
(GstMetaFreeFunction) NULL,
(GstMetaCopyFunction) meta_timing_copy,
(GstMetaSubFunction) meta_timing_sub,
(GstMetaTransformFunction) meta_timing_transform,
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
}
return meta_info;

View file

@ -65,30 +65,69 @@ typedef gboolean (*GstMetaInitFunction) (GstMeta *meta, gpointer params, GstBuff
typedef void (*GstMetaFreeFunction) (GstMeta *meta, GstBuffer *buffer);
/**
* GstMetaCopyFunction:
* @copy: a #GstBuffer
* @meta: a #GstMeta
* @buffer: a #GstBuffer
* GstMetaTransformType:
* @GST_META_TRANSFORM_NONE: invalid transform type
* @GST_META_TRANSFORM_COPY: copy transform
* @GST_META_TRANSFORM_MAKE_WRITABLE: make writable type
* @GST_META_TRANSFORM_TRIM: trim buffer
* @GST_META_TRANSFORM_CUSTOM: start of custom transform types
*
* Function called when a copy of @buffer is made and @meta should be copied to
* @copy.
* Different default transform types.
*/
typedef void (*GstMetaCopyFunction) (GstBuffer *copy, GstMeta *meta,
const GstBuffer *buffer);
typedef enum {
GST_META_TRANSFORM_NONE = 0,
GST_META_TRANSFORM_COPY,
GST_META_TRANSFORM_MAKE_WRITABLE,
GST_META_TRANSFORM_TRIM,
GST_META_TRANSFORM_CUSTOM = 256
} GstMetaTransformType;
/**
* GstMetaSubFunction:
* @subbuf: a #GstBuffer
* GstMetaTransformData:
* @type: a #GstMetaTransformType
*
* Common structure that should be put as the first field in the type specific
* structure for the #GstMetaTransformFunction. It contains the type of the
* transform that should be performed.
*/
typedef struct {
GstMetaTransformType type;
} GstMetaTransformData;
/**
* GstMetaTransformSubbuffer:
* @data: parent #GstMetaTransformData
* @offset: the offset of the subbuffer
* @size: the new size of the subbuffer
*
* The subbuffer specific extra info.
*/
typedef struct {
GstMetaTransformData data;
gsize offset;
gsize size;
} GstMetaTransformSubbuffer;
/**
* GstMetaTransformFunction:
* @transbuf: a #GstBuffer
* @meta: a #GstMeta
* @buffer: a #GstBuffer
* @offset: subbuffer offset
* @size: subbuffer size
* @data: transform specific data.
*
* Function called for each @meta in @buffer as a result from creating a
* subbuffer @subbuf from @buffer at @offset and with @size. An
* implementation could decide to copy and update the metadata on @subbuf.
* Function called for each @meta in @buffer as a result of performing a
* transformation on @transbuf. Additional type specific transform data
* is passed to the function.
*
* Implementations should check the type of the transform @data and parse
* additional type specific field that should be used to perform the transform.
*
* If @data is NULL, the metadata should be shallow copied. This is done when
* gst_buffer_make_metadata_writable() is called.
*/
typedef void (*GstMetaSubFunction) (GstBuffer *subbuf, GstMeta *meta,
GstBuffer *buffer, guint offset, guint size);
typedef void (*GstMetaTransformFunction) (GstBuffer *transbuf, GstMeta *meta,
GstBuffer *buffer, GstMetaTransformData *data);
/**
* GstMetaSerializeFunction:
@ -125,8 +164,7 @@ struct _GstMetaInfo {
GstMetaInitFunction init_func;
GstMetaFreeFunction free_func;
GstMetaCopyFunction copy_func;
GstMetaSubFunction sub_func;
GstMetaTransformFunction transform_func;
GstMetaSerializeFunction serialize_func;
GstMetaDeserializeFunction deserialize_func;
};
@ -137,8 +175,7 @@ const GstMetaInfo * gst_meta_register (const gchar *api, const gchar *im
gsize size,
GstMetaInitFunction init_func,
GstMetaFreeFunction free_func,
GstMetaCopyFunction copy_func,
GstMetaSubFunction sub_func,
GstMetaTransformFunction transform_func,
GstMetaSerializeFunction serialize_func,
GstMetaDeserializeFunction deserialize_func);
const GstMetaInfo * gst_meta_get_info (const gchar * impl);

View file

@ -80,29 +80,26 @@ test_free_func (GstMetaTest * meta, GstBuffer * buffer)
}
static void
test_copy_func (GstBuffer * copy, GstMetaTest * meta, GstBuffer * buffer)
test_transform_func (GstBuffer * transbuf, GstMetaTest * meta,
GstBuffer * buffer, GstMetaTransformData * data)
{
GstMetaTest *test;
guint offset;
guint size;
GST_DEBUG ("copy called from buffer %p to %p, meta %p", buffer, copy, meta);
if (data->type == GST_META_TRANSFORM_TRIM) {
GstMetaTransformSubbuffer *subdata = (GstMetaTransformSubbuffer *) data;
offset = subdata->offset;
size = subdata->size;
} else {
offset = 0;
size = GST_BUFFER_SIZE (buffer);
}
test = GST_META_TEST_ADD (copy);
test->pts = meta->pts;
test->dts = meta->dts;
test->duration = meta->duration;
test->clock_rate = meta->clock_rate;
}
GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
transbuf, meta, offset, size);
static void
test_sub_func (GstBuffer * sub, GstMetaTest * meta, GstBuffer * buffer,
guint offset, guint size)
{
GstMetaTest *test;
GST_DEBUG ("sub called from buffer %p to %p, meta %p, %u-%u", buffer, sub,
meta, offset, size);
test = GST_META_TEST_ADD (sub);
test = GST_META_TEST_ADD (transbuf);
if (offset == 0) {
/* same offset, copy timestamps */
test->pts = meta->pts;
@ -132,8 +129,7 @@ gst_meta_test_get_info (void)
sizeof (GstMetaTest),
(GstMetaInitFunction) test_init_func,
(GstMetaFreeFunction) test_free_func,
(GstMetaCopyFunction) test_copy_func,
(GstMetaSubFunction) test_sub_func, NULL, NULL);
(GstMetaTransformFunction) test_transform_func, NULL, NULL);
}
return meta_test_info;
}