Commit c6a1bed1 authored by Wim Taymans's avatar Wim Taymans

memory: more work on refcount and writability

Rename _is_writable() with _is_exclusive because the writability does not depend
on the amount of references to the memory object anymore.
Add accessor macros for the memory flags.
Rename the GstBuffer _peek_memory() method to _get_memory() and return a
reference to the memory now that we can do this without affecting writability
of the memory object. Make it possible to also make this function merge the
buffer memory.
Add methods to replace memory in a buffer. Make some convience macros for the
buffer memory functions.
Fix unit tests.
parent 88fdeb3e
......@@ -172,17 +172,46 @@ _span_memory (GstBuffer * buffer, gsize offset, gsize size, gboolean writable)
return span;
}
static GstMemory *
_get_merged_memory (GstBuffer * buffer)
{
guint len;
GstMemory *mem;
len = GST_BUFFER_MEM_LEN (buffer);
if (G_UNLIKELY (len == 0)) {
/* no memory */
mem = NULL;
} else if (G_LIKELY (len == 1)) {
/* we can take the first one */
mem = GST_BUFFER_MEM_PTR (buffer, 0);
gst_memory_ref (mem);
} else {
/* we need to span memory */
mem = _span_memory (buffer, 0, -1, FALSE);
}
return mem;
}
static void
_replace_memory (GstBuffer * buffer, GstMemory * mem)
_replace_all_memory (GstBuffer * buffer, GstMemory * mem)
{
gsize len, i;
len = GST_BUFFER_MEM_LEN (buffer);
/* unref old buffers */
if (G_LIKELY (len == 1 && GST_BUFFER_MEM_PTR (buffer, 0) == mem)) {
gst_memory_unref (mem);
return;
}
GST_LOG ("buffer %p replace with memory %p", buffer, mem);
/* unref old memory */
for (i = 0; i < len; i++)
gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
/* replace with single spanned buffer */
/* replace with single memory */
GST_BUFFER_MEM_PTR (buffer, 0) = mem;
GST_BUFFER_MEM_LEN (buffer) = 1;
}
......@@ -199,7 +228,7 @@ _memory_add (GstBuffer * buffer, guint idx, GstMemory * mem)
* could try to only merge the two smallest buffers to avoid memcpy, etc. */
GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "memory array overflow in buffer %p",
buffer);
_replace_memory (buffer, _span_memory (buffer, 0, -1, FALSE));
_replace_all_memory (buffer, _span_memory (buffer, 0, -1, FALSE));
/* we now have 1 single spanned buffer */
len = 1;
}
......@@ -321,7 +350,7 @@ gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
}
}
if (flags & GST_BUFFER_COPY_MERGE) {
_replace_memory (dest, _span_memory (dest, 0, size, FALSE));
_replace_all_memory (dest, _span_memory (dest, 0, size, FALSE));
}
}
......@@ -584,7 +613,7 @@ gst_buffer_new_wrapped_full (gpointer data, GFreeFunc free_func, gsize offset,
GstBuffer *newbuf;
newbuf = gst_buffer_new ();
gst_buffer_take_memory (newbuf, -1,
gst_buffer_append_memory (newbuf,
gst_memory_new_wrapped (free_func ? 0 : GST_MEMORY_FLAG_READONLY,
data, free_func, offset + size, offset, size));
......@@ -647,67 +676,79 @@ gst_buffer_take_memory (GstBuffer * buffer, gint idx, GstMemory * mem)
}
static GstMemory *
_get_memory (GstBuffer * buffer, guint idx, gboolean write)
_get_mapped (GstBuffer * buffer, guint idx, GstMapInfo * info,
GstMapFlags flags)
{
GstMemory *mem;
GstMemory *mem, *mapped;
mem = GST_BUFFER_MEM_PTR (buffer, idx);
if (G_UNLIKELY (write && !gst_memory_is_writable (mem))) {
GstMemory *copy;
GST_CAT_LOG (GST_CAT_BUFFER,
"making writable copy of memory %p in buffer %p", mem, buffer);
/* replace with a writable copy */
copy = gst_memory_copy (mem, 0, -1);
GST_BUFFER_MEM_PTR (buffer, idx) = copy;
mapped = gst_memory_make_mapped (mem, info, flags);
if (!mapped)
return NULL;
if (mapped != mem) {
GST_BUFFER_MEM_PTR (buffer, idx) = mapped;
gst_memory_unref (mem);
mem = copy;
mem = mapped;
}
return mem;
}
/**
* gst_buffer_peek_memory:
* gst_buffer_get_memory:
* @buffer: a #GstBuffer.
* @idx: an index
* @flags: #GstMapFlags
*
* Get the memory block in @buffer at @idx for memory access in @flags.
* This function does not return a refcount to the memory block. The memory
* block stays valid for as long as the caller has a valid reference to @buffer
* and as long as no operations that modify the memory blocks are called, such
* as gst_buffer_remove_memory_range(), gst_buffer_take_memory() and gst_buffer_resize().
*
* @buffer should be writable when @flags contains #GST_MAP_WRITE. If the memory
* at @idx is not writable, a new writable copy will be installed in @buffer and
* returned.
* Get the memory block in @buffer at @idx. If @idx is -1, all memory is merged
* into one large #GstMemory object that is then returned.
*
* Returns: a #GstMemory at @idx.
* Returns: (transfer full): a #GstMemory at @idx. Use gst_memory_unref () after usage.
*/
GstMemory *
gst_buffer_peek_memory (GstBuffer * buffer, guint idx, GstMapFlags flags)
gst_buffer_get_memory (GstBuffer * buffer, gint idx)
{
GstMemory *mem;
gboolean write;
write = (flags & GST_MAP_WRITE) != 0;
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
g_return_val_if_fail (idx < GST_BUFFER_MEM_LEN (buffer), NULL);
g_return_val_if_fail (idx == -1 ||
(idx >= 0 && idx <= GST_BUFFER_MEM_LEN (buffer)), NULL);
/* check if we can write when asked for write access */
if (G_UNLIKELY (write && !gst_buffer_is_writable (buffer)))
goto not_writable;
if (idx == -1) {
mem = _get_merged_memory (buffer);
} else if ((mem = GST_BUFFER_MEM_PTR (buffer, idx))) {
gst_memory_ref (mem);
}
return mem;
}
mem = _get_memory (buffer, idx, write);
/**
* gst_buffer_replace_memory:
* @buffer: a #GstBuffer.
* @idx: an index
* @mem: (transfer full): a #GstMemory
*
* Replaces the memory block in @buffer at @idx with @mem. If @idx is -1, all
* memory will be removed and replaced with @mem.
*
* @buffer should be writable.
*/
void
gst_buffer_replace_memory (GstBuffer * buffer, gint idx, GstMemory * mem)
{
g_return_if_fail (GST_IS_BUFFER (buffer));
g_return_if_fail (gst_buffer_is_writable (buffer));
g_return_if_fail (idx == -1 ||
(idx >= 0 && idx < GST_BUFFER_MEM_LEN (buffer)));
return mem;
if (idx == -1) {
_replace_all_memory (buffer, mem);
} else {
GstMemory *old;
/* ERRORS */
not_writable:
{
g_return_val_if_fail (gst_buffer_is_writable (buffer), NULL);
return NULL;
if ((old = GST_BUFFER_MEM_PTR (buffer, idx)))
gst_memory_unref (old);
GST_BUFFER_MEM_PTR (buffer, idx) = mem;
}
}
......@@ -722,7 +763,7 @@ not_writable:
* @length can be -1, in which case all memory starting from @idx is removed.
*/
void
gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length)
gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, gint length)
{
guint len, i, end;
......@@ -730,10 +771,10 @@ gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length)
g_return_if_fail (gst_buffer_is_writable (buffer));
len = GST_BUFFER_MEM_LEN (buffer);
if (length == -1) {
g_return_if_fail (idx < len);
g_return_if_fail ((length == -1 && idx < len) || length + idx < len);
if (length == -1)
length = len - idx;
}
end = idx + length;
for (i = idx; i < end; i++)
......@@ -746,42 +787,6 @@ gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length)
GST_BUFFER_MEM_LEN (buffer) = len - length;
}
/**
* gst_buffer_get_merged_memory:
* @buffer: a #GstBuffer.
*
* Return a #GstMemory object that contains all the memory in @buffer. If there
* was only one memory in @buffer, it will be returned directly, otherwise all
* memory objects will be merged into one object that will be returned.
*
* Returns: a #GstMemory with the merged memory in @buffer. This function can
* return %NULL if there is no memory in @buffer. Use gst_memory_unref() after
* usage.
*/
static GstMemory *
gst_buffer_get_merged_memory (GstBuffer * buffer)
{
guint len;
GstMemory *mem;
g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
len = GST_BUFFER_MEM_LEN (buffer);
if (G_UNLIKELY (len == 0)) {
/* no memory */
mem = NULL;
} else if (G_LIKELY (len == 1)) {
/* we can take the first one */
mem = GST_BUFFER_MEM_PTR (buffer, 0);
gst_memory_ref (mem);
} else {
/* we need to span memory */
mem = _span_memory (buffer, 0, -1, FALSE);
}
return mem;
}
/**
* gst_buffer_get_sizes:
* @buffer: a #GstBuffer.
......@@ -904,8 +909,7 @@ gst_buffer_resize (GstBuffer * buffer, gssize offset, gssize size)
left = MIN (bsize - offset, size);
if (offset != 0 || left != bsize) {
/* we need to clip something */
if (gst_memory_is_writable (mem)) {
if (gst_memory_is_exclusive (mem)) {
gst_memory_resize (mem, offset, left);
} else {
GstMemory *tmp;
......@@ -963,7 +967,7 @@ gst_buffer_map (GstBuffer * buffer, GstMapInfo * info, GstMapFlags flags)
if (G_UNLIKELY (write && !writable))
goto not_writable;
mem = gst_buffer_get_merged_memory (buffer);
mem = _get_merged_memory (buffer);
if (G_UNLIKELY (mem == NULL))
goto no_memory;
......@@ -973,11 +977,13 @@ gst_buffer_map (GstBuffer * buffer, GstMapInfo * info, GstMapFlags flags)
goto cannot_map;
/* if the buffer is writable, replace the memory */
if (writable)
_replace_memory (buffer, gst_memory_ref (mem));
else if (GST_BUFFER_MEM_LEN (buffer) > 1) {
GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
"temporary mapping for memory %p in buffer %p", mem, buffer);
if (writable) {
_replace_all_memory (buffer, gst_memory_ref (mem));
} else {
if (GST_BUFFER_MEM_LEN (buffer) > 1) {
GST_CAT_DEBUG (GST_CAT_PERFORMANCE,
"temporary mapping for memory %p in buffer %p", mem, buffer);
}
}
return TRUE;
......@@ -1056,9 +1062,7 @@ gst_buffer_fill (GstBuffer * buffer, gsize offset, gconstpointer src,
gsize tocopy;
GstMemory *mem;
mem = _get_memory (buffer, i, TRUE);
gst_memory_map (mem, &info, GST_MAP_WRITE);
mem = _get_mapped (buffer, i, &info, GST_MAP_WRITE);
if (info.size > offset) {
/* we have enough */
tocopy = MIN (info.size - offset, left);
......@@ -1104,9 +1108,7 @@ gst_buffer_extract (GstBuffer * buffer, gsize offset, gpointer dest, gsize size)
gsize tocopy;
GstMemory *mem;
mem = GST_BUFFER_MEM_PTR (buffer, i);
gst_memory_map (mem, &info, GST_MAP_READ);
mem = _get_mapped (buffer, i, &info, GST_MAP_READ);
if (info.size > offset) {
/* we have enough */
tocopy = MIN (info.size - offset, left);
......@@ -1152,9 +1154,7 @@ gst_buffer_memcmp (GstBuffer * buffer, gsize offset, gconstpointer mem,
gsize tocmp;
GstMemory *mem;
mem = GST_BUFFER_MEM_PTR (buffer, i);
gst_memory_map (mem, &info, GST_MAP_READ);
mem = _get_mapped (buffer, i, &info, GST_MAP_READ);
if (info.size > offset) {
/* we have enough */
tocmp = MIN (info.size - offset, size);
......@@ -1199,9 +1199,7 @@ gst_buffer_memset (GstBuffer * buffer, gsize offset, guint8 val, gsize size)
gsize toset;
GstMemory *mem;
mem = _get_memory (buffer, i, TRUE);
gst_memory_map (mem, &info, GST_MAP_WRITE);
mem = _get_mapped (buffer, i, &info, GST_MAP_WRITE);
if (info.size > offset) {
/* we have enough */
toset = MIN (info.size - offset, left);
......
......@@ -265,9 +265,13 @@ GstBuffer * gst_buffer_new_wrapped (gpointer data, gsize size);
/* memory blocks */
guint gst_buffer_n_memory (GstBuffer *buffer);
void gst_buffer_take_memory (GstBuffer *buffer, gint idx, GstMemory *mem);
GstMemory * gst_buffer_peek_memory (GstBuffer *buffer, guint idx, GstMapFlags flags);
void gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, guint length);
void gst_buffer_replace_memory (GstBuffer *buffer, gint idx, GstMemory *mem);
GstMemory * gst_buffer_get_memory (GstBuffer *buffer, gint idx);
void gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, gint length);
#define gst_buffer_append_memory(b,m) gst_buffer_take_memory ((b), -1, (m))
#define gst_buffer_replace_all_memory(b,m) gst_buffer_replace_memory ((b), -1, (m))
#define gst_buffer_get_merged_memory(b) gst_buffer_get_memory ((b), -1)
/**
* gst_buffer_remove_memory:
* @b: a #GstBuffer.
......@@ -275,7 +279,8 @@ void gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, guint
*
* Remove the memory block in @b at @i.
*/
#define gst_buffer_remove_memory(b,i) gst_buffer_remove_memory_range ((b), (i), 1)
#define gst_buffer_remove_memory(b,i) gst_buffer_remove_memory_range ((b), (i), 1)
#define gst_buffer_remove_all_memory(b) gst_buffer_remove_memory_range ((b), 0, -1)
gsize gst_buffer_fill (GstBuffer *buffer, gsize offset,
gconstpointer src, gsize size);
......
......@@ -135,7 +135,7 @@ _default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
mem->mem.flags = flags;
mem->mem.refcount = 1;
mem->mem.parent = parent ? gst_memory_ref (parent) : NULL;
mem->mem.state = (flags & GST_MEMORY_FLAG_READONLY ? 0x5 : 0);
mem->mem.state = (flags & GST_MEMORY_FLAG_READONLY ? 0x1 : 0);
mem->mem.maxsize = maxsize;
mem->mem.offset = offset;
mem->mem.size = size;
......@@ -431,6 +431,7 @@ gst_memory_unref (GstMemory * mem)
mem->refcount - 1);
if (g_atomic_int_dec_and_test (&mem->refcount)) {
g_return_if_fail (g_atomic_int_get (&mem->state) < 4);
#ifndef GST_DISABLE_TRACE
_gst_alloc_trace_free (_gst_memory_trace, mem);
#endif
......@@ -438,6 +439,21 @@ gst_memory_unref (GstMemory * mem)
}
}
/**
* gst_memory_is_exclusive:
* @mem: a #GstMemory
*
* Check if the current ref to @mem is exclusive, this means that no other
* references exist other than @mem.
*/
gboolean
gst_memory_is_exclusive (GstMemory * mem)
{
g_return_val_if_fail (mem != NULL, FALSE);
return (g_atomic_int_get (&mem->refcount) == 1);
}
/**
* gst_memory_get_sizes:
* @mem: a #GstMemory
......@@ -474,7 +490,6 @@ void
gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
{
g_return_if_fail (mem != NULL);
g_return_if_fail (gst_memory_is_writable (mem));
g_return_if_fail (offset >= 0 || mem->offset >= -offset);
g_return_if_fail (size + mem->offset + offset <= mem->maxsize);
......@@ -482,24 +497,6 @@ gst_memory_resize (GstMemory * mem, gssize offset, gsize size)
mem->size = size;
}
/**
* gst_memory_is_writable:
* @mem: a #GstMemory
*
* Check if @mem is writable.
*
* Returns: %TRUE is @mem is writable.
*/
gboolean
gst_memory_is_writable (GstMemory * mem)
{
g_return_val_if_fail (mem != NULL, FALSE);
return (mem->refcount == 1) &&
((mem->parent == NULL) || (mem->parent->refcount == 1)) &&
((mem->flags & GST_MEMORY_FLAG_READONLY) == 0);
}
static gboolean
gst_memory_lock (GstMemory * mem, GstMapFlags flags)
{
......@@ -610,8 +607,8 @@ cannot_map:
* - the memory backed by @mem is not accessible with the given @flags.
* - the memory was already mapped with a different mapping.
*
* @info and its contents remains valid for as long as @mem is alive and until
* gst_memory_unmap() is called.
* @info and its contents remain valid for as long as @mem is valid and
* until gst_memory_unmap() is called.
*
* For each gst_memory_map() call, a corresponding gst_memory_unmap() call
* should be done.
......@@ -722,6 +719,8 @@ gst_memory_share (GstMemory * mem, gssize offset, gssize size)
GstMemory *shared;
g_return_val_if_fail (mem != NULL, NULL);
g_return_val_if_fail (!GST_MEMORY_FLAG_IS_SET (mem, GST_MEMORY_FLAG_NO_SHARE),
NULL);
shared = mem->allocator->info.mem_share (mem, offset, size);
......
......@@ -41,6 +41,8 @@ typedef struct _GstAllocator GstAllocator;
GST_EXPORT gsize gst_memory_alignment;
#define GST_MEMORY_CAST(mem) ((GstMemory *)(mem))
/**
* GstMemoryFlags:
* @GST_MEMORY_FLAG_READONLY: memory is readonly. It is not allowed to map the
......@@ -58,6 +60,30 @@ typedef enum {
GST_MEMORY_FLAG_LAST = (1 << 16)
} GstMemoryFlags;
/**
* GST_MEMORY_FLAGS:
* @mem: a #GstMemory.
*
* A flags word containing #GstMemoryFlags flags set on @mem
*/
#define GST_MEMORY_FLAGS(mem) (GST_MEMORY_CAST (mem)->flags)
/**
* GST_MEMORY_FLAG_IS_SET:
* @mem: a #GstMemory.
* @flag: the #GstMemoryFlags to check.
*
* Gives the status of a specific flag on a @mem.
*/
#define GST_MEMORY_FLAG_IS_SET(mem,flag) !!(GST_MEMORY_FLAGS (mem) & (flag))
/**
* GST_MEMORY_IS_READONLY:
* @mem: a #GstMemory.
*
* Check if @mem is readonly.
*/
#define GST_MEMORY_IS_READONLY(mem) GST_MEMORY_FLAG_IS_SET(mem,GST_MEMORY_FLAG_READONLY)
/**
* GstMemory:
* @allocator: pointer to the #GstAllocator
......@@ -278,30 +304,30 @@ void gst_allocator_set_default (GstAllocator * allocator);
GstMemory * gst_allocator_alloc (GstAllocator * allocator,
gsize maxsize, gsize align);
GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, GFreeFunc free_func,
gsize maxsize, gsize offset, gsize size);
GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, GFreeFunc free_func,
gsize maxsize, gsize offset, gsize size);
/* refcounting */
GstMemory * gst_memory_ref (GstMemory *mem);
void gst_memory_unref (GstMemory *mem);
GstMemory * gst_memory_ref (GstMemory *mem);
void gst_memory_unref (GstMemory *mem);
gboolean gst_memory_is_exclusive (GstMemory *mem);
/* getting/setting memory properties */
gsize gst_memory_get_sizes (GstMemory *mem, gsize *offset, gsize *maxsize);
void gst_memory_resize (GstMemory *mem, gssize offset, gsize size);
gsize gst_memory_get_sizes (GstMemory *mem, gsize *offset, gsize *maxsize);
void gst_memory_resize (GstMemory *mem, gssize offset, gsize size);
/* retrieving data */
gboolean gst_memory_is_writable (GstMemory *mem);
GstMemory * gst_memory_make_mapped (GstMemory *mem, GstMapInfo *info, GstMapFlags flags);
gboolean gst_memory_map (GstMemory *mem, GstMapInfo *info, GstMapFlags flags);
void gst_memory_unmap (GstMemory *mem, GstMapInfo *info);
GstMemory * gst_memory_make_mapped (GstMemory *mem, GstMapInfo *info, GstMapFlags flags);
gboolean gst_memory_map (GstMemory *mem, GstMapInfo *info, GstMapFlags flags);
void gst_memory_unmap (GstMemory *mem, GstMapInfo *info);
/* copy and subregions */
GstMemory * gst_memory_copy (GstMemory *mem, gssize offset, gssize size);
GstMemory * gst_memory_share (GstMemory *mem, gssize offset, gssize size);
GstMemory * gst_memory_copy (GstMemory *mem, gssize offset, gssize size);
GstMemory * gst_memory_share (GstMemory *mem, gssize offset, gssize size);
/* span memory */
gboolean gst_memory_is_span (GstMemory *mem1, GstMemory *mem2, gsize *offset);
gboolean gst_memory_is_span (GstMemory *mem1, GstMemory *mem2, gsize *offset);
G_END_DECLS
......
......@@ -450,8 +450,9 @@ GST_START_TEST (test_size)
fail_unless (offset == 0);
fail_unless (maxalloc >= 100);
mem = gst_buffer_peek_memory (buf, 0, GST_MAP_WRITE);
mem = gst_buffer_get_memory (buf, 0);
gst_memory_resize (mem, 10, 70);
gst_memory_unref (mem);
size = gst_buffer_get_sizes (buf, &offset, &maxsize);
fail_unless (size == 70);
......
......@@ -133,7 +133,7 @@ create_read_only_memory (void)
/* assign some read-only data to the new memory */
mem = gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
(gpointer) ro_memory, NULL, sizeof (ro_memory), 0, sizeof (ro_memory));
fail_if (gst_memory_is_writable (mem));
fail_unless (GST_MEMORY_IS_READONLY (mem));
return mem;
}
......@@ -147,11 +147,10 @@ GST_START_TEST (test_writable)
mem = create_read_only_memory ();
fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
fail_if (gst_memory_is_writable (mem));
mem2 = gst_memory_copy (mem, 0, -1);
fail_if (gst_memory_is_writable (mem));
fail_unless (gst_memory_is_writable (mem2));
fail_unless (GST_MEMORY_IS_READONLY (mem));
fail_if (GST_MEMORY_IS_READONLY (mem2));
fail_unless (gst_memory_map (mem2, &info, GST_MAP_WRITE));
info.data[4] = 'a';
......@@ -180,7 +179,7 @@ GST_START_TEST (test_submemory_writable)
mem = create_read_only_memory ();
sub_mem = gst_memory_share (mem, 0, 8);
fail_if (gst_memory_is_writable (sub_mem));
fail_unless (GST_MEMORY_IS_READONLY (sub_mem));
fail_if (gst_memory_map (mem, &info, GST_MAP_WRITE));
fail_if (gst_memory_map (sub_mem, &info, GST_MAP_WRITE));
......
......@@ -90,6 +90,7 @@ EXPORTS
gst_buffer_fill
gst_buffer_flags_get_type
gst_buffer_foreach_meta
gst_buffer_get_memory
gst_buffer_get_meta
gst_buffer_get_sizes
gst_buffer_get_type
......@@ -113,7 +114,6 @@ EXPORTS
gst_buffer_new_allocate
gst_buffer_new_wrapped
gst_buffer_new_wrapped_full
gst_buffer_peek_memory
gst_buffer_pool_acquire_buffer
gst_buffer_pool_config_add_option
gst_buffer_pool_config_get
......@@ -133,6 +133,7 @@ EXPORTS
gst_buffer_pool_set_config
gst_buffer_remove_memory_range
gst_buffer_remove_meta
gst_buffer_replace_memory
gst_buffer_resize
gst_buffer_span
gst_buffer_take_memory
......@@ -507,8 +508,8 @@ EXPORTS
gst_memory_flags_get_type
gst_memory_get_sizes
gst_memory_get_type
gst_memory_is_exclusive
gst_memory_is_span
gst_memory_is_writable
gst_memory_make_mapped
gst_memory_map
gst_memory_new_wrapped
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment