mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 11:41:09 +00:00
memory: add gst_memory_init()
Add a method that memory implementations can call to initialize the standard GstMemory structure. Move the parent handling in the _free handler. Rearrange some internal function parameters so that the order is consistent. Add more memory examples
This commit is contained in:
parent
e30930af4f
commit
50cf7f6a08
6 changed files with 246 additions and 33 deletions
|
@ -127,47 +127,83 @@ static GstAllocator *_default_mem_impl;
|
|||
static GstMemory *
|
||||
_gst_memory_copy (GstMemory * mem)
|
||||
{
|
||||
GST_CAT_DEBUG (GST_CAT_MEMORY, "copy memory %p", mem);
|
||||
return gst_memory_copy (mem, 0, -1);
|
||||
}
|
||||
|
||||
static void
|
||||
_gst_memory_free (GstMemory * mem)
|
||||
{
|
||||
GST_CAT_DEBUG (GST_CAT_MEMORY, "free memory %p", mem);
|
||||
|
||||
if (mem->parent) {
|
||||
gst_memory_unlock (mem->parent, GST_LOCK_FLAG_EXCLUSIVE);
|
||||
gst_memory_unref (mem->parent);
|
||||
}
|
||||
|
||||
mem->allocator->info.mem_free (mem);
|
||||
}
|
||||
|
||||
/* initialize the fields */
|
||||
static void
|
||||
_default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
|
||||
GstMemory * parent, gsize slice_size, gpointer data,
|
||||
gsize maxsize, gsize offset, gsize size, gsize align,
|
||||
gpointer user_data, GDestroyNotify notify)
|
||||
/**
|
||||
* gst_memory_init: (skip)
|
||||
* @mem: a #GstMemory
|
||||
* @flags: #GstMemoryFlags
|
||||
* @allocator: the #GstAllocator
|
||||
* @parent: the parent of @mem
|
||||
* @maxsize: the total size of the memory
|
||||
* @align: the alignment of the memory
|
||||
* @offset: The offset in the memory
|
||||
* @size: the size of valid data in the memory
|
||||
|
||||
* Initializes a newly allocated @mem with the given parameters. This function
|
||||
* will call gst_mini_object_init() with the default memory parameters.
|
||||
*/
|
||||
void
|
||||
gst_memory_init (GstMemory * mem, GstMemoryFlags flags,
|
||||
GstAllocator * allocator, GstMemory * parent, gsize maxsize, gsize align,
|
||||
gsize offset, gsize size)
|
||||
{
|
||||
gst_mini_object_init (GST_MINI_OBJECT_CAST (mem),
|
||||
flags | GST_MINI_OBJECT_FLAG_LOCKABLE, GST_TYPE_MEMORY,
|
||||
(GstMiniObjectCopyFunction) _gst_memory_copy, NULL,
|
||||
(GstMiniObjectFreeFunction) _gst_memory_free);
|
||||
|
||||
mem->mem.allocator = _default_mem_impl;
|
||||
mem->mem.parent = parent ? gst_memory_ref (parent) : NULL;
|
||||
mem->mem.maxsize = maxsize;
|
||||
mem->mem.align = align;
|
||||
mem->mem.offset = offset;
|
||||
mem->mem.size = size;
|
||||
mem->slice_size = slice_size;
|
||||
mem->data = data;
|
||||
mem->user_data = user_data;
|
||||
mem->notify = notify;
|
||||
mem->allocator = allocator;
|
||||
if (parent) {
|
||||
gst_memory_lock (parent, GST_LOCK_FLAG_EXCLUSIVE);
|
||||
gst_memory_ref (parent);
|
||||
}
|
||||
mem->parent = parent;
|
||||
mem->maxsize = maxsize;
|
||||
mem->align = align;
|
||||
mem->offset = offset;
|
||||
mem->size = size;
|
||||
|
||||
GST_CAT_DEBUG (GST_CAT_MEMORY, "new memory %p, maxsize:%" G_GSIZE_FORMAT
|
||||
" offset:%" G_GSIZE_FORMAT " size:%" G_GSIZE_FORMAT, mem, maxsize,
|
||||
offset, size);
|
||||
}
|
||||
|
||||
/* initialize the fields */
|
||||
static inline void
|
||||
_default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
|
||||
GstMemory * parent, gsize slice_size, gpointer data,
|
||||
gsize maxsize, gsize align, gsize offset, gsize size,
|
||||
gpointer user_data, GDestroyNotify notify)
|
||||
{
|
||||
gst_memory_init (GST_MEMORY_CAST (mem),
|
||||
flags, _default_mem_impl, parent, maxsize, align, offset, size);
|
||||
|
||||
mem->slice_size = slice_size;
|
||||
mem->data = data;
|
||||
mem->user_data = user_data;
|
||||
mem->notify = notify;
|
||||
}
|
||||
|
||||
/* create a new memory block that manages the given memory */
|
||||
static GstMemoryDefault *
|
||||
static inline GstMemoryDefault *
|
||||
_default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data,
|
||||
gsize maxsize, gsize offset, gsize size, gsize align, gpointer user_data,
|
||||
gsize maxsize, gsize align, gsize offset, gsize size, gpointer user_data,
|
||||
GDestroyNotify notify)
|
||||
{
|
||||
GstMemoryDefault *mem;
|
||||
|
@ -177,7 +213,7 @@ _default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data,
|
|||
|
||||
mem = g_slice_alloc (slice_size);
|
||||
_default_mem_init (mem, flags, parent, slice_size,
|
||||
data, maxsize, offset, size, align, user_data, notify);
|
||||
data, maxsize, align, offset, size, user_data, notify);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
@ -219,7 +255,7 @@ _default_mem_new_block (GstMemoryFlags flags, gsize maxsize, gsize align,
|
|||
memset (data + offset + size, 0, padding);
|
||||
|
||||
_default_mem_init (mem, flags, NULL, slice_size, data, maxsize,
|
||||
offset, size, align, NULL, NULL);
|
||||
align, offset, size, NULL, NULL);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
@ -249,11 +285,6 @@ _default_mem_unmap (GstMemoryDefault * mem)
|
|||
static void
|
||||
_default_mem_free (GstMemoryDefault * mem)
|
||||
{
|
||||
GST_CAT_DEBUG (GST_CAT_MEMORY, "free memory %p", mem);
|
||||
|
||||
if (mem->mem.parent)
|
||||
gst_memory_unref (mem->mem.parent);
|
||||
|
||||
if (mem->notify)
|
||||
mem->notify (mem->user_data);
|
||||
|
||||
|
@ -292,10 +323,11 @@ _default_mem_share (GstMemoryDefault * mem, gssize offset, gsize size)
|
|||
if (size == -1)
|
||||
size = mem->mem.size - offset;
|
||||
|
||||
/* the shared memory is always readonly */
|
||||
sub =
|
||||
_default_mem_new (GST_MINI_OBJECT_FLAGS (parent), parent, mem->data,
|
||||
mem->mem.maxsize, mem->mem.offset + offset, size, mem->mem.align, NULL,
|
||||
NULL);
|
||||
_default_mem_new (GST_MINI_OBJECT_FLAGS (parent) |
|
||||
GST_MINI_OBJECT_FLAG_LOCK_READONLY, parent, mem->data, mem->mem.maxsize,
|
||||
mem->mem.align, mem->mem.offset + offset, size, NULL, NULL);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
@ -424,7 +456,7 @@ gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data,
|
|||
g_return_val_if_fail (offset + size <= maxsize, NULL);
|
||||
|
||||
mem =
|
||||
_default_mem_new (flags, NULL, data, maxsize, offset, size, 0, user_data,
|
||||
_default_mem_new (flags, NULL, data, maxsize, 0, offset, size, user_data,
|
||||
notify);
|
||||
|
||||
return (GstMemory *) mem;
|
||||
|
@ -586,7 +618,7 @@ lock_failed:
|
|||
error:
|
||||
{
|
||||
/* something went wrong, restore the orginal state again */
|
||||
GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: map failed", mem);
|
||||
GST_CAT_ERROR (GST_CAT_MEMORY, "mem %p: subclass map failed", mem);
|
||||
gst_memory_unlock (mem, flags);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
@ -414,10 +414,10 @@ GstAllocator * gst_allocator_find (const gchar *name);
|
|||
void gst_allocator_set_default (GstAllocator * allocator);
|
||||
|
||||
/* allocating memory blocks */
|
||||
void gst_allocation_params_init (GstAllocationParams *params);
|
||||
void gst_allocation_params_init (GstAllocationParams *params);
|
||||
GstAllocationParams *
|
||||
gst_allocation_params_copy (const GstAllocationParams *params) G_GNUC_MALLOC;
|
||||
void gst_allocation_params_free (GstAllocationParams *params);
|
||||
gst_allocation_params_copy (const GstAllocationParams *params) G_GNUC_MALLOC;
|
||||
void gst_allocation_params_free (GstAllocationParams *params);
|
||||
|
||||
GstMemory * gst_allocator_alloc (GstAllocator * allocator, gsize size,
|
||||
GstAllocationParams *params);
|
||||
|
@ -426,6 +426,11 @@ GstMemory * gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data, gsi
|
|||
gsize offset, gsize size, gpointer user_data,
|
||||
GDestroyNotify notify);
|
||||
|
||||
void gst_memory_init (GstMemory *mem, GstMemoryFlags flags,
|
||||
GstAllocator *allocator, GstMemory *parent,
|
||||
gsize maxsize, gsize align,
|
||||
gsize offset, gsize size);
|
||||
|
||||
/* refcounting */
|
||||
/**
|
||||
* gst_memory_ref:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
noinst_PROGRAMS = memory_test
|
||||
|
||||
memory_test_SOURCES = memory_test.c my-memory.c my-memory.h
|
||||
memory_test_LDADD = $(GST_OBJ_LIBS)
|
||||
memory_test_CFLAGS = $(GST_OBJ_CFLAGS)
|
||||
|
|
|
@ -5,10 +5,29 @@
|
|||
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "my-memory.h"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GstAllocator *alloc;
|
||||
GstMemory *mem;
|
||||
GstAllocationParams params;
|
||||
GstMapInfo info;
|
||||
|
||||
gst_init (&argc, &argv);
|
||||
|
||||
my_memory_init ();
|
||||
|
||||
alloc = gst_allocator_find ("MyMemory");
|
||||
|
||||
gst_allocation_params_init (¶ms);
|
||||
mem = gst_allocator_alloc (alloc, 1024, ¶ms);
|
||||
|
||||
gst_memory_map (mem, &info, GST_MAP_READ);
|
||||
gst_memory_unmap (mem, &info);
|
||||
|
||||
gst_memory_unref (mem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
133
tests/examples/memory/my-memory.c
Normal file
133
tests/examples/memory/my-memory.c
Normal file
|
@ -0,0 +1,133 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.be>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "my-memory.h"
|
||||
|
||||
static GstAllocator *_my_allocator;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GstMemory mem;
|
||||
|
||||
gpointer data;
|
||||
|
||||
} MyMemory;
|
||||
|
||||
|
||||
static GstMemory *
|
||||
_my_alloc_alloc (GstAllocator * allocator, gsize size,
|
||||
GstAllocationParams * params, gpointer user_data)
|
||||
{
|
||||
MyMemory *mem;
|
||||
gsize maxsize = size + params->prefix + params->padding;
|
||||
|
||||
GST_DEBUG ("alloc from allocator %p", allocator);
|
||||
|
||||
mem = g_slice_new (MyMemory);
|
||||
|
||||
gst_memory_init (GST_MEMORY_CAST (mem), params->flags, allocator, NULL,
|
||||
maxsize, params->align, params->prefix, size);
|
||||
|
||||
mem->data = NULL;
|
||||
|
||||
return (GstMemory *) mem;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
_my_mem_map (MyMemory * mem, gsize maxsize, GstMapFlags flags)
|
||||
{
|
||||
gpointer res;
|
||||
|
||||
while (TRUE) {
|
||||
if ((res = g_atomic_pointer_get (&mem->data)) != NULL)
|
||||
break;
|
||||
|
||||
res = g_malloc (maxsize);
|
||||
|
||||
if (g_atomic_pointer_compare_and_exchange (&mem->data, NULL, res))
|
||||
break;
|
||||
|
||||
g_free (res);
|
||||
}
|
||||
|
||||
GST_DEBUG ("%p: mapped %p", mem, res);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_my_mem_unmap (MyMemory * mem)
|
||||
{
|
||||
GST_DEBUG ("%p: unmapped", mem);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
_my_mem_free (MyMemory * mem)
|
||||
{
|
||||
g_free (mem->data);
|
||||
g_slice_free (MyMemory, mem);
|
||||
GST_DEBUG ("%p: freed", mem);
|
||||
}
|
||||
|
||||
static MyMemory *
|
||||
_my_mem_share (MyMemory * mem, gssize offset, gsize size)
|
||||
{
|
||||
MyMemory *sub;
|
||||
GstMemory *parent;
|
||||
|
||||
GST_DEBUG ("%p: share %" G_GSSIZE_FORMAT, G_GSIZE_FORMAT, mem, offset, size);
|
||||
|
||||
/* find the real parent */
|
||||
if ((parent = mem->mem.parent) == NULL)
|
||||
parent = (GstMemory *) mem;
|
||||
|
||||
if (size == -1)
|
||||
size = mem->mem.size - offset;
|
||||
|
||||
sub = g_slice_new (MyMemory);
|
||||
/* the shared memory is always readonly */
|
||||
gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) |
|
||||
GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent,
|
||||
mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size);
|
||||
|
||||
/* install pointer */
|
||||
sub->data = _my_mem_map (mem, mem->mem.maxsize, GST_MAP_READ);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
void
|
||||
my_memory_init (void)
|
||||
{
|
||||
static const GstMemoryInfo info = {
|
||||
"MyMemory",
|
||||
(GstAllocatorAllocFunction) _my_alloc_alloc,
|
||||
(GstMemoryMapFunction) _my_mem_map,
|
||||
(GstMemoryUnmapFunction) _my_mem_unmap,
|
||||
(GstMemoryFreeFunction) _my_mem_free,
|
||||
(GstMemoryCopyFunction) NULL,
|
||||
(GstMemoryShareFunction) _my_mem_share,
|
||||
(GstMemoryIsSpanFunction) NULL,
|
||||
};
|
||||
|
||||
_my_allocator = gst_allocator_new (&info, NULL, NULL);
|
||||
|
||||
gst_allocator_register ("MyMemory", gst_allocator_ref (_my_allocator));
|
||||
}
|
23
tests/examples/memory/my-memory.h
Normal file
23
tests/examples/memory/my-memory.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) 2012 Wim Taymans <wim.taymans@gmail.be>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <gst/gst.h>
|
||||
|
||||
void my_memory_init (void);
|
||||
|
Loading…
Reference in a new issue