mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 11:10:37 +00:00
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:
parent
fd0fd97200
commit
fa0d993372
4 changed files with 143 additions and 88 deletions
|
@ -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;
|
||||
}
|
||||
|
|
101
gst/gstmeta.c
101
gst/gstmeta.c
|
@ -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, ¶ms);
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue