mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-07-02 20:55:55 +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
|
@ -241,9 +241,10 @@ gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
|
||||||
for (walk = src->priv; walk; walk = walk->next) {
|
for (walk = src->priv; walk; walk = walk->next) {
|
||||||
GstMeta *meta = &walk->meta;
|
GstMeta *meta = &walk->meta;
|
||||||
const GstMetaInfo *info = meta->info;
|
const GstMetaInfo *info = meta->info;
|
||||||
|
GstMetaTransformData data = { GST_META_TRANSFORM_COPY };
|
||||||
|
|
||||||
if (info->copy_func)
|
if (info->transform_func)
|
||||||
info->copy_func (dest, meta, src);
|
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) {
|
for (walk = buffer->priv; walk; walk = walk->next) {
|
||||||
GstMeta *meta = &walk->meta;
|
GstMeta *meta = &walk->meta;
|
||||||
const GstMetaInfo *info = meta->info;
|
const GstMetaInfo *info = meta->info;
|
||||||
|
GstMetaTransformSubbuffer subdata;
|
||||||
|
|
||||||
if (info->sub_func)
|
subdata.data.type = GST_META_TRANSFORM_TRIM;
|
||||||
info->sub_func (subbuffer, meta, buffer, offset, size);
|
subdata.offset = offset;
|
||||||
|
subdata.size = size;
|
||||||
|
|
||||||
|
if (info->transform_func)
|
||||||
|
info->transform_func (subbuffer, meta, buffer,
|
||||||
|
(GstMetaTransformData *) & subdata);
|
||||||
}
|
}
|
||||||
return subbuffer;
|
return subbuffer;
|
||||||
}
|
}
|
||||||
|
|
101
gst/gstmeta.c
101
gst/gstmeta.c
|
@ -54,7 +54,7 @@ _gst_meta_init (void)
|
||||||
const GstMetaInfo *
|
const GstMetaInfo *
|
||||||
gst_meta_register (const gchar * api, const gchar * impl, gsize size,
|
gst_meta_register (const gchar * api, const gchar * impl, gsize size,
|
||||||
GstMetaInitFunction init_func, GstMetaFreeFunction free_func,
|
GstMetaInitFunction init_func, GstMetaFreeFunction free_func,
|
||||||
GstMetaCopyFunction copy_func, GstMetaSubFunction sub_func,
|
GstMetaTransformFunction transform_func,
|
||||||
GstMetaSerializeFunction serialize_func,
|
GstMetaSerializeFunction serialize_func,
|
||||||
GstMetaDeserializeFunction deserialize_func)
|
GstMetaDeserializeFunction deserialize_func)
|
||||||
{
|
{
|
||||||
|
@ -70,8 +70,7 @@ gst_meta_register (const gchar * api, const gchar * impl, gsize size,
|
||||||
info->size = size;
|
info->size = size;
|
||||||
info->init_func = init_func;
|
info->init_func = init_func;
|
||||||
info->free_func = free_func;
|
info->free_func = free_func;
|
||||||
info->copy_func = copy_func;
|
info->transform_func = transform_func;
|
||||||
info->sub_func = sub_func;
|
|
||||||
info->serialize_func = serialize_func;
|
info->serialize_func = serialize_func;
|
||||||
info->deserialize_func = deserialize_func;
|
info->deserialize_func = deserialize_func;
|
||||||
|
|
||||||
|
@ -143,34 +142,60 @@ static gboolean
|
||||||
meta_memory_init (GstMetaMemoryImpl * meta, GstMetaMemoryParams * params,
|
meta_memory_init (GstMetaMemoryImpl * meta, GstMetaMemoryParams * params,
|
||||||
GstBuffer * buffer)
|
GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
GST_DEBUG ("init %p", buffer);
|
||||||
meta->memory.mmap_func = meta_memory_mmap;
|
meta->memory.mmap_func = meta_memory_mmap;
|
||||||
meta->memory.munmap_func = meta_memory_munmap;
|
meta->memory.munmap_func = meta_memory_munmap;
|
||||||
meta->params = *params;
|
meta->params = *params;
|
||||||
|
|
||||||
|
/* FIXME, backwards compatibility */
|
||||||
|
//GST_BUFFER_DATA (buffer) = params->data + params->offset;
|
||||||
|
//GST_BUFFER_SIZE (buffer) = params->size;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_memory_free (GstMetaMemoryImpl * meta, GstBuffer * buffer)
|
meta_memory_free (GstMetaMemoryImpl * meta, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
GST_DEBUG ("free buffer %p", buffer);
|
||||||
if (meta->params.free_func)
|
if (meta->params.free_func)
|
||||||
meta->params.free_func (meta->params.data);
|
meta->params.free_func (meta->params.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_memory_copy (GstBuffer * copy, GstMetaMemoryImpl * meta,
|
meta_memory_transform (GstBuffer * transbuf, GstMetaMemoryImpl * meta,
|
||||||
const GstBuffer * buffer)
|
GstBuffer * buffer, GstMetaTransformData * data)
|
||||||
{
|
{
|
||||||
gst_buffer_add_meta_memory (copy,
|
switch (data->type) {
|
||||||
g_memdup (meta->params.data, meta->params.size),
|
case GST_META_TRANSFORM_COPY:
|
||||||
g_free, meta->params.size, meta->params.offset);
|
{
|
||||||
}
|
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
|
GST_DEBUG ("trim %p to %p", buffer, transbuf);
|
||||||
meta_memory_sub (GstBuffer * subbuf, GstMetaMemoryImpl * meta,
|
gst_buffer_add_meta_memory (transbuf,
|
||||||
GstBuffer * buffer, guint offset, guint size)
|
meta->params.data, NULL, subdata->size,
|
||||||
{
|
meta->params.offset + subdata->offset);
|
||||||
gst_buffer_add_meta_memory (subbuf,
|
break;
|
||||||
meta->params.data, NULL, size, meta->params.offset + offset);
|
}
|
||||||
|
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 *
|
const GstMetaInfo *
|
||||||
|
@ -183,8 +208,7 @@ gst_meta_memory_get_info (void)
|
||||||
sizeof (GstMetaMemoryImpl),
|
sizeof (GstMetaMemoryImpl),
|
||||||
(GstMetaInitFunction) meta_memory_init,
|
(GstMetaInitFunction) meta_memory_init,
|
||||||
(GstMetaFreeFunction) meta_memory_free,
|
(GstMetaFreeFunction) meta_memory_free,
|
||||||
(GstMetaCopyFunction) meta_memory_copy,
|
(GstMetaTransformFunction) meta_memory_transform,
|
||||||
(GstMetaSubFunction) meta_memory_sub,
|
|
||||||
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
}
|
}
|
||||||
return meta_info;
|
return meta_info;
|
||||||
|
@ -195,12 +219,7 @@ gst_buffer_add_meta_memory (GstBuffer * buffer, gpointer data,
|
||||||
GFreeFunc free_func, gsize size, gsize offset)
|
GFreeFunc free_func, gsize size, gsize offset)
|
||||||
{
|
{
|
||||||
GstMeta *meta;
|
GstMeta *meta;
|
||||||
GstMetaMemoryParams params;
|
GstMetaMemoryParams params = { data, free_func, size, offset };
|
||||||
|
|
||||||
params.data = data;
|
|
||||||
params.free_func = free_func;
|
|
||||||
params.size = size;
|
|
||||||
params.offset = offset;
|
|
||||||
|
|
||||||
meta = gst_buffer_add_meta (buffer, GST_META_MEMORY_INFO, ¶ms);
|
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 */
|
/* Timing metadata */
|
||||||
static void
|
static void
|
||||||
meta_timing_copy (GstBuffer * copy, GstMetaTiming * meta, GstBuffer * buffer)
|
meta_timing_transform (GstBuffer * transbuf, GstMetaTiming * meta,
|
||||||
|
GstBuffer * buffer, GstMetaTransformData * data)
|
||||||
{
|
{
|
||||||
GstMetaTiming *timing;
|
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);
|
GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
|
||||||
timing->pts = meta->pts;
|
transbuf, meta, offset, size);
|
||||||
timing->dts = meta->dts;
|
|
||||||
timing->duration = meta->duration;
|
|
||||||
timing->clock_rate = meta->clock_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
timing = gst_buffer_add_meta_timing (transbuf);
|
||||||
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);
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
/* same offset, copy timestamps */
|
/* same offset, copy timestamps */
|
||||||
timing->pts = meta->pts;
|
timing->pts = meta->pts;
|
||||||
|
@ -261,8 +277,7 @@ gst_meta_timing_get_info (void)
|
||||||
sizeof (GstMetaTiming),
|
sizeof (GstMetaTiming),
|
||||||
(GstMetaInitFunction) NULL,
|
(GstMetaInitFunction) NULL,
|
||||||
(GstMetaFreeFunction) NULL,
|
(GstMetaFreeFunction) NULL,
|
||||||
(GstMetaCopyFunction) meta_timing_copy,
|
(GstMetaTransformFunction) meta_timing_transform,
|
||||||
(GstMetaSubFunction) meta_timing_sub,
|
|
||||||
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
(GstMetaSerializeFunction) NULL, (GstMetaDeserializeFunction) NULL);
|
||||||
}
|
}
|
||||||
return meta_info;
|
return meta_info;
|
||||||
|
|
|
@ -65,30 +65,69 @@ typedef gboolean (*GstMetaInitFunction) (GstMeta *meta, gpointer params, GstBuff
|
||||||
typedef void (*GstMetaFreeFunction) (GstMeta *meta, GstBuffer *buffer);
|
typedef void (*GstMetaFreeFunction) (GstMeta *meta, GstBuffer *buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMetaCopyFunction:
|
* GstMetaTransformType:
|
||||||
* @copy: a #GstBuffer
|
* @GST_META_TRANSFORM_NONE: invalid transform type
|
||||||
* @meta: a #GstMeta
|
* @GST_META_TRANSFORM_COPY: copy transform
|
||||||
* @buffer: a #GstBuffer
|
* @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
|
* Different default transform types.
|
||||||
* @copy.
|
|
||||||
*/
|
*/
|
||||||
typedef void (*GstMetaCopyFunction) (GstBuffer *copy, GstMeta *meta,
|
typedef enum {
|
||||||
const GstBuffer *buffer);
|
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:
|
* GstMetaTransformData:
|
||||||
* @subbuf: a #GstBuffer
|
* @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
|
* @meta: a #GstMeta
|
||||||
* @buffer: a #GstBuffer
|
* @buffer: a #GstBuffer
|
||||||
* @offset: subbuffer offset
|
* @data: transform specific data.
|
||||||
* @size: subbuffer size
|
|
||||||
*
|
*
|
||||||
* Function called for each @meta in @buffer as a result from creating a
|
* Function called for each @meta in @buffer as a result of performing a
|
||||||
* subbuffer @subbuf from @buffer at @offset and with @size. An
|
* transformation on @transbuf. Additional type specific transform data
|
||||||
* implementation could decide to copy and update the metadata on @subbuf.
|
* 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,
|
typedef void (*GstMetaTransformFunction) (GstBuffer *transbuf, GstMeta *meta,
|
||||||
GstBuffer *buffer, guint offset, guint size);
|
GstBuffer *buffer, GstMetaTransformData *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstMetaSerializeFunction:
|
* GstMetaSerializeFunction:
|
||||||
|
@ -125,8 +164,7 @@ struct _GstMetaInfo {
|
||||||
|
|
||||||
GstMetaInitFunction init_func;
|
GstMetaInitFunction init_func;
|
||||||
GstMetaFreeFunction free_func;
|
GstMetaFreeFunction free_func;
|
||||||
GstMetaCopyFunction copy_func;
|
GstMetaTransformFunction transform_func;
|
||||||
GstMetaSubFunction sub_func;
|
|
||||||
GstMetaSerializeFunction serialize_func;
|
GstMetaSerializeFunction serialize_func;
|
||||||
GstMetaDeserializeFunction deserialize_func;
|
GstMetaDeserializeFunction deserialize_func;
|
||||||
};
|
};
|
||||||
|
@ -137,8 +175,7 @@ const GstMetaInfo * gst_meta_register (const gchar *api, const gchar *im
|
||||||
gsize size,
|
gsize size,
|
||||||
GstMetaInitFunction init_func,
|
GstMetaInitFunction init_func,
|
||||||
GstMetaFreeFunction free_func,
|
GstMetaFreeFunction free_func,
|
||||||
GstMetaCopyFunction copy_func,
|
GstMetaTransformFunction transform_func,
|
||||||
GstMetaSubFunction sub_func,
|
|
||||||
GstMetaSerializeFunction serialize_func,
|
GstMetaSerializeFunction serialize_func,
|
||||||
GstMetaDeserializeFunction deserialize_func);
|
GstMetaDeserializeFunction deserialize_func);
|
||||||
const GstMetaInfo * gst_meta_get_info (const gchar * impl);
|
const GstMetaInfo * gst_meta_get_info (const gchar * impl);
|
||||||
|
|
|
@ -80,29 +80,26 @@ test_free_func (GstMetaTest * meta, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_copy_func (GstBuffer * copy, GstMetaTest * meta, GstBuffer * buffer)
|
test_transform_func (GstBuffer * transbuf, GstMetaTest * meta,
|
||||||
|
GstBuffer * buffer, GstMetaTransformData * data)
|
||||||
{
|
{
|
||||||
GstMetaTest *test;
|
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);
|
GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
|
||||||
test->pts = meta->pts;
|
transbuf, meta, offset, size);
|
||||||
test->dts = meta->dts;
|
|
||||||
test->duration = meta->duration;
|
|
||||||
test->clock_rate = meta->clock_rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
test = GST_META_TEST_ADD (transbuf);
|
||||||
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);
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
/* same offset, copy timestamps */
|
/* same offset, copy timestamps */
|
||||||
test->pts = meta->pts;
|
test->pts = meta->pts;
|
||||||
|
@ -132,8 +129,7 @@ gst_meta_test_get_info (void)
|
||||||
sizeof (GstMetaTest),
|
sizeof (GstMetaTest),
|
||||||
(GstMetaInitFunction) test_init_func,
|
(GstMetaInitFunction) test_init_func,
|
||||||
(GstMetaFreeFunction) test_free_func,
|
(GstMetaFreeFunction) test_free_func,
|
||||||
(GstMetaCopyFunction) test_copy_func,
|
(GstMetaTransformFunction) test_transform_func, NULL, NULL);
|
||||||
(GstMetaSubFunction) test_sub_func, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
return meta_test_info;
|
return meta_test_info;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue