mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
buffermeta: add beginnings of buffer metadata
Add first implementation of arbitrary buffer metadata. We use a simple linked linked of slice allocated metadata chunks. Future implementations could use something more performant. Add get, remove, iterate methods to handle the metadata.
This commit is contained in:
parent
a27da6a919
commit
8468dadc77
10 changed files with 651 additions and 3 deletions
|
@ -209,6 +209,24 @@ gst_buffer_span
|
|||
gst_buffer_join
|
||||
gst_buffer_merge
|
||||
|
||||
GstBufferMeta
|
||||
|
||||
gst_buffer_get_meta
|
||||
gst_buffer_remove_meta
|
||||
gst_buffer_iterate_meta
|
||||
|
||||
GstBufferMetaInfo
|
||||
|
||||
GstMetaInitFunction
|
||||
GstMetaFreeFunction
|
||||
GstMetaCopyFunction
|
||||
GstMetaSubFunction
|
||||
GstMetaSerializeFunction
|
||||
GstMetaDeserializeFunction
|
||||
|
||||
gst_buffer_meta_get_info
|
||||
gst_buffer_meta_register_info
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GstBufferClass
|
||||
GST_BUFFER
|
||||
|
|
|
@ -51,6 +51,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
|
|||
gstbin.c \
|
||||
gstbuffer.c \
|
||||
gstbufferlist.c \
|
||||
gstbuffermeta.c \
|
||||
gstbus.c \
|
||||
gstcaps.c \
|
||||
gstchildproxy.c \
|
||||
|
@ -142,6 +143,7 @@ gst_headers = \
|
|||
gstbin.h \
|
||||
gstbuffer.h \
|
||||
gstbufferlist.h \
|
||||
gstbuffermeta.h \
|
||||
gstbus.h \
|
||||
gstcaps.h \
|
||||
gstchildproxy.h \
|
||||
|
|
|
@ -668,6 +668,7 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
|
|||
_gst_format_initialize ();
|
||||
_gst_query_initialize ();
|
||||
_gst_caps_initialize ();
|
||||
_gst_buffer_meta_init ();
|
||||
|
||||
g_type_class_ref (gst_object_get_type ());
|
||||
g_type_class_ref (gst_pad_get_type ());
|
||||
|
|
168
gst/gstbuffer.c
168
gst/gstbuffer.c
|
@ -130,6 +130,16 @@
|
|||
|
||||
GType _gst_buffer_type = 0;
|
||||
|
||||
typedef struct _GstBufferMetaItem GstBufferMetaItem;
|
||||
|
||||
struct _GstBufferMetaItem
|
||||
{
|
||||
GstBufferMetaItem *next;
|
||||
GstBufferMeta meta;
|
||||
};
|
||||
|
||||
#define ITEM_SIZE(info) ((info)->size + sizeof (GstBufferMetaItem))
|
||||
|
||||
/* buffer alignment in bytes
|
||||
* an alignment of 8 would be the same as malloc() guarantees
|
||||
*/
|
||||
|
@ -189,6 +199,8 @@ void
|
|||
gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
|
||||
GstBufferCopyFlags flags)
|
||||
{
|
||||
GstBufferMetaItem *walk;
|
||||
|
||||
g_return_if_fail (dest != NULL);
|
||||
g_return_if_fail (src != NULL);
|
||||
|
||||
|
@ -224,6 +236,14 @@ gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
|
|||
if (flags & GST_BUFFER_COPY_CAPS) {
|
||||
gst_caps_replace (&GST_BUFFER_CAPS (dest), GST_BUFFER_CAPS (src));
|
||||
}
|
||||
|
||||
for (walk = src->priv; walk; walk = walk->next) {
|
||||
GstBufferMeta *meta = &walk->meta;
|
||||
const GstBufferMetaInfo *info = meta->info;
|
||||
|
||||
if (info->copy_func)
|
||||
info->copy_func (dest, meta, src);
|
||||
}
|
||||
}
|
||||
|
||||
static GstBuffer *
|
||||
|
@ -269,6 +289,8 @@ _gst_buffer_copy (GstBuffer * buffer)
|
|||
static void
|
||||
_gst_buffer_free (GstBuffer * buffer)
|
||||
{
|
||||
GList *walk;
|
||||
|
||||
g_return_if_fail (buffer != NULL);
|
||||
|
||||
GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
|
||||
|
@ -282,6 +304,18 @@ _gst_buffer_free (GstBuffer * buffer)
|
|||
if (buffer->parent)
|
||||
gst_buffer_unref (buffer->parent);
|
||||
|
||||
/* free metadata */
|
||||
for (walk = buffer->priv; walk; walk = walk->next) {
|
||||
GstBufferMeta *meta = &walk->meta;
|
||||
const GstBufferMetaInfo *info = meta->info;
|
||||
|
||||
/* call free_func if any */
|
||||
if (info->free_func)
|
||||
info->free_func (meta, buffer);
|
||||
/* and free the slice */
|
||||
g_slice_free1 (ITEM_SIZE (info), meta);
|
||||
}
|
||||
|
||||
g_slice_free1 (GST_MINI_OBJECT_SIZE (buffer), buffer);
|
||||
}
|
||||
|
||||
|
@ -558,6 +592,7 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
|
|||
GstBuffer *subbuffer;
|
||||
GstBuffer *parent;
|
||||
gboolean complete;
|
||||
GstBufferMetaItem *walk;
|
||||
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
|
||||
|
@ -620,6 +655,14 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
|
|||
GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_CAPS (subbuffer) = NULL;
|
||||
}
|
||||
/* call subbuffer functions for metadata */
|
||||
for (walk = buffer->priv; walk; walk = walk->next) {
|
||||
GstBufferMeta *meta = &walk->meta;
|
||||
const GstBufferMetaInfo *info = meta->info;
|
||||
|
||||
if (info->sub_func)
|
||||
info->sub_func (subbuffer, meta, buffer, offset, size);
|
||||
}
|
||||
return subbuffer;
|
||||
}
|
||||
|
||||
|
@ -727,3 +770,128 @@ gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
|
|||
|
||||
return newbuf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gst_buffer_get_meta:
|
||||
* @buffer: a #GstBuffer
|
||||
* @info: a #GstBufferMetaInfo
|
||||
*
|
||||
* Retrieve the metadata for @info on @buffer.
|
||||
*
|
||||
* If there is no metadata for @info on @buffer, this function will return
|
||||
* %NULL unless the @create flags is set to %TRUE, in which case a new
|
||||
* metadata for @info will be created.
|
||||
*
|
||||
* Returns: the metadata for @info on @buffer or %NULL when there is no such
|
||||
* metadata on @buffer and @create is %FALSE.
|
||||
*/
|
||||
GstBufferMeta *
|
||||
gst_buffer_get_meta (GstBuffer * buffer, const GstBufferMetaInfo * info,
|
||||
gboolean create)
|
||||
{
|
||||
GstBufferMetaItem *walk;
|
||||
GstBufferMeta *result = NULL;
|
||||
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
|
||||
/* loop over the metadata items until we find the one with the
|
||||
* requested info. FIXME, naive implementation using a list */
|
||||
for (walk = buffer->priv; walk; walk = walk->next) {
|
||||
GstBufferMeta *meta = &walk->meta;
|
||||
if (meta->info == info) {
|
||||
result = meta;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* not found, check if we need to create */
|
||||
if (!result && create) {
|
||||
/* create a new slice */
|
||||
GST_DEBUG ("alloc metadata of size %" G_GSIZE_FORMAT, info->size);
|
||||
walk = g_slice_alloc (ITEM_SIZE (info));
|
||||
result = &walk->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 */
|
||||
walk->next = buffer->priv;
|
||||
buffer->priv = walk;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_remove_meta:
|
||||
* @buffer: a #GstBuffer
|
||||
* @info: a #GstBufferMetaInfo
|
||||
*
|
||||
* Remove the metadata for @info on @buffer.
|
||||
*
|
||||
* Returns: %TRUE if the metadata existed and was removed, %FALSE if no such
|
||||
* metadata was on @buffer.
|
||||
*/
|
||||
gboolean
|
||||
gst_buffer_remove_meta (GstBuffer * buffer, const GstBufferMetaInfo * info)
|
||||
{
|
||||
GstBufferMetaItem *walk, *prev;
|
||||
|
||||
g_return_val_if_fail (buffer != NULL, FALSE);
|
||||
g_return_val_if_fail (info != NULL, FALSE);
|
||||
|
||||
/* find the metadata and delete */
|
||||
prev = buffer->priv;
|
||||
for (walk = prev; walk; walk = walk->next) {
|
||||
GstBufferMeta *meta = &walk->meta;
|
||||
if (meta->info == info) {
|
||||
/* remove from list */
|
||||
if (buffer->priv == walk)
|
||||
buffer->priv = walk->next;
|
||||
else
|
||||
prev->next = walk->next;
|
||||
/* call free_func if any */
|
||||
if (info->free_func)
|
||||
info->free_func (meta, buffer);
|
||||
/* and free the slice */
|
||||
g_slice_free1 (ITEM_SIZE (info), meta);
|
||||
break;
|
||||
}
|
||||
prev = walk;
|
||||
}
|
||||
return walk != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_iterate_meta:
|
||||
* @buffer: a #GstBuffer
|
||||
* @state: an opaque state pointer
|
||||
*
|
||||
* Retrieve the next #GstBufferMeta after @current. If @state points
|
||||
* to %NULL, the first metadata is returned.
|
||||
*
|
||||
* @state will be updated with an opage state pointer
|
||||
*
|
||||
* Returns: The next #GstBufferMeta or %NULL when there are no more items.
|
||||
*/
|
||||
GstBufferMeta *
|
||||
gst_buffer_iterate_meta (GstBuffer * buffer, gpointer * state)
|
||||
{
|
||||
GstBufferMetaItem **meta;
|
||||
|
||||
g_return_val_if_fail (buffer != NULL, NULL);
|
||||
g_return_val_if_fail (state != NULL, NULL);
|
||||
|
||||
meta = (GstBufferMetaItem **) state;
|
||||
if (*meta == NULL)
|
||||
/* state NULL, move to first item */
|
||||
*meta = buffer->priv;
|
||||
else
|
||||
/* state !NULL, move to next item in list */
|
||||
*meta = (*meta)->next;
|
||||
|
||||
if (*meta)
|
||||
return &(*meta)->meta;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -284,11 +284,9 @@ struct _GstBuffer {
|
|||
/* ABI Added */
|
||||
GFreeFunc free_func;
|
||||
GstBuffer *parent;
|
||||
gpointer priv;
|
||||
|
||||
gpointer owner_priv;
|
||||
|
||||
/*< private >*/
|
||||
gpointer _gst_reserved[GST_PADDING];
|
||||
};
|
||||
|
||||
/* allocation */
|
||||
|
@ -471,6 +469,15 @@ GstBuffer* gst_buffer_create_sub (GstBuffer *parent, guint offset
|
|||
gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2);
|
||||
GstBuffer* gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
|
||||
|
||||
/* metadata */
|
||||
#include <gst/gstbuffermeta.h>
|
||||
|
||||
GstBufferMeta * gst_buffer_get_meta (GstBuffer *buffer, const GstBufferMetaInfo *info,
|
||||
gboolean create);
|
||||
gboolean gst_buffer_remove_meta (GstBuffer *buffer, const GstBufferMetaInfo *info);
|
||||
|
||||
GstBufferMeta * gst_buffer_iterate_meta (GstBuffer *buffer, gpointer *state);
|
||||
|
||||
/**
|
||||
* gst_value_set_buffer:
|
||||
* @v: a #GValue to receive the data
|
||||
|
|
91
gst/gstbuffermeta.c
Normal file
91
gst/gstbuffermeta.c
Normal file
|
@ -0,0 +1,91 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2009 Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* gstbuffermeta.c: Buffer metadata operations
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
* SECTION:gstbuffermeta
|
||||
* @short_description: Buffer metadata
|
||||
*
|
||||
* Last reviewed on December 17th, 2009 (0.10.26)
|
||||
*/
|
||||
#include "gst_private.h"
|
||||
|
||||
#include "gstbuffermeta.h"
|
||||
#include "gstbuffer.h"
|
||||
#include "gstinfo.h"
|
||||
#include "gstutils.h"
|
||||
|
||||
static GHashTable *metainfo = NULL;
|
||||
static GStaticRWLock lock = G_STATIC_RW_LOCK_INIT;
|
||||
|
||||
void
|
||||
_gst_buffer_meta_init (void)
|
||||
{
|
||||
metainfo = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_meta_register_info:
|
||||
* @info: a #GstBufferMetaInfo
|
||||
*
|
||||
* Register a #GstBufferMetaInfo. The same @info can be retrieved later with
|
||||
* gst_buffer_meta_get_info() by using the name as the key.
|
||||
*
|
||||
* Returns: a #GstBufferMetaInfo that can be used to access buffer metadata.
|
||||
*/
|
||||
const GstBufferMetaInfo *
|
||||
gst_buffer_meta_register_info (const GstBufferMetaInfo * info)
|
||||
{
|
||||
g_return_val_if_fail (info != NULL, NULL);
|
||||
g_return_val_if_fail (info->name != NULL, NULL);
|
||||
g_return_val_if_fail (info->size != 0, NULL);
|
||||
|
||||
GST_DEBUG ("register \"%s\" of size %" G_GSIZE_FORMAT, info->name,
|
||||
info->size);
|
||||
|
||||
g_static_rw_lock_writer_lock (&lock);
|
||||
g_hash_table_insert (metainfo, (gpointer) info->name, (gpointer) info);
|
||||
g_static_rw_lock_writer_unlock (&lock);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_buffer_meta_get_info:
|
||||
* @name: the name
|
||||
*
|
||||
* Lookup a previously registered meta info structure by its @name.
|
||||
*
|
||||
* Returns: a #GstBufferMetaInfo with @name or #NULL when no such metainfo
|
||||
* exists.
|
||||
*/
|
||||
const GstBufferMetaInfo *
|
||||
gst_buffer_meta_get_info (const gchar * name)
|
||||
{
|
||||
GstBufferMetaInfo *info;
|
||||
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
g_static_rw_lock_reader_lock (&lock);
|
||||
info = g_hash_table_lookup (metainfo, name);
|
||||
g_static_rw_lock_reader_unlock (&lock);
|
||||
|
||||
return info;
|
||||
}
|
139
gst/gstbuffermeta.h
Normal file
139
gst/gstbuffermeta.h
Normal file
|
@ -0,0 +1,139 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2009 Wim Taymans <wim.taymans@gmail.be>
|
||||
*
|
||||
* gstbuffermeta.h: Header for Buffer Metadata structures
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __GST_BUFFER_META_H__
|
||||
#define __GST_BUFFER_META_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GstBufferMeta GstBufferMeta;
|
||||
typedef struct _GstBufferMetaInfo GstBufferMetaInfo;
|
||||
|
||||
/**
|
||||
* GstBufferMeta:
|
||||
* @info: pointer to the #GstBufferMetaInfo
|
||||
*
|
||||
* Base structure for buffer metadata. Custom metadata will put this structure
|
||||
* as the first member of their structure.
|
||||
*/
|
||||
struct _GstBufferMeta {
|
||||
const GstBufferMetaInfo *info;
|
||||
};
|
||||
|
||||
/**
|
||||
* GST_BUFFER_META_TRACE_NAME:
|
||||
*
|
||||
* The name used for tracing memory allocations.
|
||||
*/
|
||||
#define GST_BUFFER_META_TRACE_NAME "GstBufferMeta"
|
||||
|
||||
/**
|
||||
* GstMetaInitFunction:
|
||||
* @meta: a #GstMeta
|
||||
* @buffer: a #GstBuffer
|
||||
*
|
||||
* Function called when @meta is initialized in @buffer.
|
||||
*/
|
||||
typedef void (*GstMetaInitFunction) (GstBufferMeta *meta, GstBuffer *buffer);
|
||||
|
||||
/**
|
||||
* GstMetaFreeFunction:
|
||||
* @meta: a #GstMeta
|
||||
* @buffer: a #GstBuffer
|
||||
*
|
||||
* Function called when @meta is freed in @buffer.
|
||||
*/
|
||||
typedef void (*GstMetaFreeFunction) (GstBufferMeta *meta, GstBuffer *buffer);
|
||||
|
||||
/**
|
||||
* GstMetaCopyFunction:
|
||||
* @copy: a #GstBuffer
|
||||
* @meta: a #GstMeta
|
||||
* @buffer: a #GstBuffer
|
||||
*
|
||||
* Function called when a copy of @buffer is made and @meta should be copied to
|
||||
* @copy.
|
||||
*/
|
||||
typedef void (*GstMetaCopyFunction) (GstBuffer *copy, GstBufferMeta *meta,
|
||||
const GstBuffer *buffer);
|
||||
/**
|
||||
* GstMetaSubFunction:
|
||||
* @subbuf: a #GstBuffer
|
||||
* @meta: a #GstMeta
|
||||
* @buffer: a #GstBuffer
|
||||
* @offset: subbuffer offset
|
||||
* @size: subbuffer size
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
typedef void (*GstMetaSubFunction) (GstBuffer *subbuf, GstBufferMeta *meta,
|
||||
GstBuffer *buffer, guint offset, guint size);
|
||||
|
||||
/**
|
||||
* GstMetaSerializeFunction:
|
||||
* @meta: a #GstMeta
|
||||
*/
|
||||
typedef gchar * (*GstMetaSerializeFunction) (GstBufferMeta *meta);
|
||||
|
||||
/**
|
||||
* GstMetaDeserializeFunction:
|
||||
* @meta: a #GstMeta
|
||||
*/
|
||||
typedef gboolean (*GstMetaDeserializeFunction) (GstBufferMeta *meta,
|
||||
const gchar *s);
|
||||
|
||||
/**
|
||||
* GstBufferMetaInfo:
|
||||
* @name: tag indentifying the metadata
|
||||
* @size: size of the metadata
|
||||
* @init_func: function for initializing the metadata
|
||||
* @free_func: function for freeing the metadata
|
||||
* @copy_func: function for copying the metadata
|
||||
* @sub_func: function for when a subbuffer is taken
|
||||
* @serialize_func: function for serializing
|
||||
* @deserialize_func: function for deserializing
|
||||
*
|
||||
* The #GstBufferMetaInfo provides infomation about a specific metadata
|
||||
* structure.
|
||||
*/
|
||||
struct _GstBufferMetaInfo {
|
||||
const gchar *name;
|
||||
gsize size;
|
||||
|
||||
GstMetaInitFunction init_func;
|
||||
GstMetaFreeFunction free_func;
|
||||
GstMetaCopyFunction copy_func;
|
||||
GstMetaSubFunction sub_func;
|
||||
GstMetaSerializeFunction serialize_func;
|
||||
GstMetaDeserializeFunction deserialize_func;
|
||||
};
|
||||
|
||||
void _gst_buffer_meta_init (void);
|
||||
|
||||
const GstBufferMetaInfo * gst_buffer_meta_register_info (const GstBufferMetaInfo *info);
|
||||
const GstBufferMetaInfo * gst_buffer_meta_get_info (const gchar * name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GST_BUFFER_META_H__ */
|
|
@ -100,6 +100,7 @@ check_PROGRAMS = \
|
|||
$(ABI_CHECKS) \
|
||||
gst/gstbuffer \
|
||||
gst/gstbufferlist \
|
||||
gst/gstbuffermeta \
|
||||
gst/gstbus \
|
||||
gst/gstcaps \
|
||||
$(CXX_CHECKS) \
|
||||
|
|
211
tests/check/gst/gstbuffermeta.c
Normal file
211
tests/check/gst/gstbuffermeta.c
Normal file
|
@ -0,0 +1,211 @@
|
|||
/* GStreamer
|
||||
*
|
||||
* unit test for GstBufferMeta
|
||||
*
|
||||
* Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_VALGRIND_H
|
||||
# include <valgrind/valgrind.h>
|
||||
#else
|
||||
# define RUNNING_ON_VALGRIND FALSE
|
||||
#endif
|
||||
|
||||
#include <gst/check/gstcheck.h>
|
||||
|
||||
static const GstBufferMetaInfo *test_meta_info = NULL;
|
||||
|
||||
/* test metadata for PTS/DTS and duration */
|
||||
typedef struct
|
||||
{
|
||||
GstBufferMeta meta;
|
||||
|
||||
GstClockTime pts;
|
||||
GstClockTime dts;
|
||||
GstClockTime duration;
|
||||
GstClockTime clock_rate;
|
||||
} GstTestMeta;
|
||||
|
||||
static const GstBufferMetaInfo *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));
|
||||
|
||||
#if 0
|
||||
/* unused currently. This is a user function to fill the metadata with default
|
||||
* values. We don't call this from the init function because the user is mostly
|
||||
* likely going to override the values immediately after */
|
||||
static void
|
||||
gst_test_meta_init (GstTestMeta * meta)
|
||||
{
|
||||
meta->pts = GST_CLOCK_TIME_NONE;
|
||||
meta->dts = GST_CLOCK_TIME_NONE;
|
||||
meta->duration = GST_CLOCK_TIME_NONE;
|
||||
meta->clock_rate = GST_SECOND;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_init_func (GstTestMeta * meta, GstBuffer * buffer)
|
||||
{
|
||||
GST_DEBUG ("init called on buffer %p, meta %p", buffer, meta);
|
||||
/* nothing to init really, the init function is mostly for allocating
|
||||
* additional memory or doing special setup as part of adding the metadata to
|
||||
* the buffer*/
|
||||
}
|
||||
|
||||
static void
|
||||
test_free_func (GstTestMeta * meta, GstBuffer * buffer)
|
||||
{
|
||||
GST_DEBUG ("free called on buffer %p, meta %p", buffer, meta);
|
||||
/* nothing to free really */
|
||||
}
|
||||
|
||||
static void
|
||||
test_copy_func (GstBuffer * copy, GstTestMeta * meta, GstBuffer * buffer)
|
||||
{
|
||||
GstTestMeta *test;
|
||||
|
||||
GST_DEBUG ("copy called from buffer %p to %p, meta %p", buffer, copy, meta);
|
||||
|
||||
test = GST_TEST_META_GET (copy, TRUE);
|
||||
test->pts = meta->pts;
|
||||
test->dts = meta->dts;
|
||||
test->duration = meta->duration;
|
||||
test->clock_rate = meta->clock_rate;
|
||||
}
|
||||
|
||||
static void
|
||||
test_sub_func (GstBuffer * sub, GstTestMeta * meta, GstBuffer * buffer,
|
||||
guint offset, guint size)
|
||||
{
|
||||
GstTestMeta *test;
|
||||
|
||||
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);
|
||||
if (offset == 0) {
|
||||
/* same offset, copy timestamps */
|
||||
test->pts = meta->pts;
|
||||
test->dts = meta->dts;
|
||||
if (size == GST_BUFFER_SIZE (buffer)) {
|
||||
/* same size, copy duration */
|
||||
test->duration = meta->duration;
|
||||
} else {
|
||||
/* else clear */
|
||||
test->duration = GST_CLOCK_TIME_NONE;
|
||||
}
|
||||
}
|
||||
test->clock_rate = meta->clock_rate;
|
||||
}
|
||||
|
||||
static void
|
||||
register_metadata (void)
|
||||
{
|
||||
if (test_meta_info == NULL) {
|
||||
static const GstBufferMetaInfo info = {
|
||||
"GstTestMeta",
|
||||
sizeof (GstTestMeta),
|
||||
(GstMetaInitFunction) test_init_func,
|
||||
(GstMetaFreeFunction) test_free_func,
|
||||
(GstMetaCopyFunction) test_copy_func,
|
||||
(GstMetaSubFunction) test_sub_func,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
test_meta_info = gst_buffer_meta_register_info (&info);
|
||||
}
|
||||
return test_meta_info;
|
||||
}
|
||||
|
||||
GST_START_TEST (test_metadata)
|
||||
{
|
||||
GstBuffer *buffer, *copy, *subbuf;
|
||||
GstTestMeta *meta;
|
||||
|
||||
register_metadata ();
|
||||
|
||||
buffer = gst_buffer_new_and_alloc (4);
|
||||
memset (GST_BUFFER_DATA (buffer), 0, 4);
|
||||
|
||||
/* add some metadata */
|
||||
meta = GST_TEST_META_GET (buffer, TRUE);
|
||||
fail_if (meta == NULL);
|
||||
/* fill some values */
|
||||
meta->pts = 1000;
|
||||
meta->dts = 2000;
|
||||
meta->duration = 1000;
|
||||
meta->clock_rate = 1000;
|
||||
|
||||
/* copy of the buffer */
|
||||
copy = gst_buffer_copy (buffer);
|
||||
/* get metadata of the buffer */
|
||||
meta = GST_TEST_META_GET (copy, FALSE);
|
||||
fail_if (meta == NULL);
|
||||
fail_if (meta->pts != 1000);
|
||||
fail_if (meta->dts != 2000);
|
||||
fail_if (meta->duration != 1000);
|
||||
fail_if (meta->clock_rate != 1000);
|
||||
gst_buffer_unref (copy);
|
||||
|
||||
/* make subbuffer */
|
||||
subbuf = gst_buffer_create_sub (buffer, 0, 1);
|
||||
/* get metadata of the buffer */
|
||||
meta = GST_TEST_META_GET (subbuf, FALSE);
|
||||
fail_if (meta == NULL);
|
||||
fail_if (meta->pts != 1000);
|
||||
fail_if (meta->dts != 2000);
|
||||
fail_if (meta->duration != -1);
|
||||
fail_if (meta->clock_rate != 1000);
|
||||
gst_buffer_unref (subbuf);
|
||||
|
||||
/* make another subbuffer */
|
||||
subbuf = gst_buffer_create_sub (buffer, 1, 3);
|
||||
/* get metadata of the buffer */
|
||||
meta = GST_TEST_META_GET (subbuf, FALSE);
|
||||
fail_if (meta == NULL);
|
||||
fail_if (meta->pts != -1);
|
||||
fail_if (meta->dts != -1);
|
||||
fail_if (meta->duration != -1);
|
||||
fail_if (meta->clock_rate != 1000);
|
||||
gst_buffer_unref (subbuf);
|
||||
|
||||
/* clean up */
|
||||
gst_buffer_unref (buffer);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
|
||||
static Suite *
|
||||
gst_buffermeta_suite (void)
|
||||
{
|
||||
Suite *s = suite_create ("GstBufferMeta");
|
||||
TCase *tc_chain = tcase_create ("general");
|
||||
|
||||
suite_add_tcase (s, tc_chain);
|
||||
tcase_add_test (tc_chain, test_metadata);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
GST_CHECK_MAIN (gst_buffermeta);
|
|
@ -38,6 +38,7 @@ EXPORTS
|
|||
_gst_buffer_list_type DATA
|
||||
_gst_buffer_type DATA
|
||||
_gst_caps_type DATA
|
||||
_gst_buffer_meta_init
|
||||
_gst_debug_bin_to_dot_file
|
||||
_gst_debug_bin_to_dot_file_with_ts
|
||||
_gst_debug_category_new
|
||||
|
@ -94,8 +95,14 @@ EXPORTS
|
|||
gst_buffer_create_sub
|
||||
gst_buffer_flag_get_type
|
||||
gst_buffer_get_caps
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
gst_buffer_get_meta
|
||||
gst_buffer_get_type
|
||||
>>>>>>> buffermeta: implement arbitrary buffer metadata
|
||||
gst_buffer_is_metadata_writable
|
||||
gst_buffer_is_span_fast
|
||||
gst_buffer_iterate_meta
|
||||
gst_buffer_join
|
||||
gst_buffer_list_foreach
|
||||
gst_buffer_list_get
|
||||
|
@ -117,8 +124,11 @@ EXPORTS
|
|||
gst_buffer_list_new
|
||||
gst_buffer_make_metadata_writable
|
||||
gst_buffer_merge
|
||||
gst_buffer_meta_get_info
|
||||
gst_buffer_meta_register_info
|
||||
gst_buffer_new
|
||||
gst_buffer_new_and_alloc
|
||||
gst_buffer_remove_meta
|
||||
gst_buffer_set_caps
|
||||
gst_buffer_span
|
||||
gst_buffer_try_new_and_alloc
|
||||
|
|
Loading…
Reference in a new issue