mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 09:10:36 +00:00
[574/906] memory: implement transperent upload/download for data
(not async yet)
This commit is contained in:
parent
3ee54d3135
commit
84ec07072d
2 changed files with 182 additions and 20 deletions
|
@ -26,9 +26,8 @@
|
||||||
|
|
||||||
#include "gstglmemory.h"
|
#include "gstglmemory.h"
|
||||||
|
|
||||||
/*GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY);
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY);
|
||||||
#define GST_CAT_DEFUALT GST_CAT_GL_MEMORY
|
#define GST_CAT_DEFUALT GST_CAT_GL_MEMORY
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_MEMORY);*/
|
|
||||||
|
|
||||||
static GstAllocator *_gl_allocator;
|
static GstAllocator *_gl_allocator;
|
||||||
|
|
||||||
|
@ -40,23 +39,38 @@ typedef struct
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
|
_gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
|
||||||
GstGLDisplay * display, GstVideoFormat v_format, gsize width, gsize height)
|
GstGLDisplay * display, GstVideoFormat v_format, gsize width, gsize height,
|
||||||
|
gpointer user_data, GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
|
gsize maxsize;
|
||||||
|
GstVideoInfo info;
|
||||||
|
|
||||||
|
gst_video_info_set_format (&info, v_format, width, height);
|
||||||
|
|
||||||
|
maxsize = info.size;
|
||||||
|
|
||||||
gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE,
|
gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE,
|
||||||
allocator, parent, 0, 0, 0, 0);
|
allocator, parent, maxsize, 0, 0, maxsize);
|
||||||
|
|
||||||
mem->display = g_object_ref (display);
|
mem->display = g_object_ref (display);
|
||||||
mem->gl_format = GL_RGBA;
|
mem->gl_format = GL_RGBA;
|
||||||
mem->v_format = v_format;
|
mem->v_format = v_format;
|
||||||
mem->width = width;
|
mem->width = width;
|
||||||
mem->height = height;
|
mem->height = height;
|
||||||
|
mem->notify = notify;
|
||||||
|
mem->user_data = user_data;
|
||||||
|
mem->wrapped = FALSE;
|
||||||
|
mem->upload = gst_gl_display_find_upload (display, v_format, width, height);
|
||||||
|
mem->download =
|
||||||
|
gst_gl_display_find_download (display, v_format, width, height);
|
||||||
|
|
||||||
GST_DEBUG ("new GL memory");
|
GST_DEBUG ("new GL texture memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstGLMemory *
|
static GstGLMemory *
|
||||||
_gl_mem_new (GstAllocator * allocator, GstMemory * parent,
|
_gl_mem_new (GstAllocator * allocator, GstMemory * parent,
|
||||||
GstGLDisplay * display, GstVideoFormat v_format, gsize width, gsize height)
|
GstGLDisplay * display, GstVideoFormat v_format, gsize width, gsize height,
|
||||||
|
gpointer user_data, GDestroyNotify notify)
|
||||||
{
|
{
|
||||||
GstGLMemory *mem;
|
GstGLMemory *mem;
|
||||||
GLuint tex_id;
|
GLuint tex_id;
|
||||||
|
@ -69,7 +83,8 @@ _gl_mem_new (GstAllocator * allocator, GstMemory * parent,
|
||||||
GST_TRACE ("created texture %u", tex_id);
|
GST_TRACE ("created texture %u", tex_id);
|
||||||
|
|
||||||
mem = g_slice_alloc (sizeof (GstGLMemory));
|
mem = g_slice_alloc (sizeof (GstGLMemory));
|
||||||
_gl_mem_init (mem, allocator, parent, display, v_format, width, height);
|
_gl_mem_init (mem, allocator, parent, display, v_format, width, height,
|
||||||
|
user_data, notify);
|
||||||
|
|
||||||
mem->tex_id = tex_id;
|
mem->tex_id = tex_id;
|
||||||
|
|
||||||
|
@ -79,13 +94,59 @@ _gl_mem_new (GstAllocator * allocator, GstMemory * parent,
|
||||||
gpointer
|
gpointer
|
||||||
_gl_mem_map (GstGLMemory * gl_mem, gsize maxsize, GstMapFlags flags)
|
_gl_mem_map (GstGLMemory * gl_mem, gsize maxsize, GstMapFlags flags)
|
||||||
{
|
{
|
||||||
/* should we perform a {up,down}load? */
|
gpointer data;
|
||||||
return NULL;
|
|
||||||
|
g_return_val_if_fail (maxsize == gl_mem->mem.maxsize, NULL);
|
||||||
|
|
||||||
|
if ((flags & GST_MAP_GL) == GST_MAP_GL) {
|
||||||
|
if ((flags & GST_MAP_READ) == GST_MAP_READ) {
|
||||||
|
if (GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
|
||||||
|
if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem,
|
||||||
|
GST_GL_MEMORY_FLAG_UPLOAD_INITTED)) {
|
||||||
|
gst_gl_upload_init_format (gl_mem->upload, gl_mem->v_format,
|
||||||
|
gl_mem->width, gl_mem->height);
|
||||||
|
GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_UPLOAD_INITTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_gl_upload_perform_with_memory (gl_mem->upload, gl_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data = &gl_mem->tex_id;
|
||||||
|
} else { /* not GL */
|
||||||
|
if ((flags & GST_MAP_READ) == GST_MAP_READ) {
|
||||||
|
if (GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD)) {
|
||||||
|
if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem,
|
||||||
|
GST_GL_MEMORY_FLAG_DOWNLOAD_INITTED)) {
|
||||||
|
gst_gl_download_init_format (gl_mem->download, gl_mem->v_format,
|
||||||
|
gl_mem->width, gl_mem->height);
|
||||||
|
GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_DOWNLOAD_INITTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_gl_download_perform_with_memory (gl_mem->download, gl_mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data = gl_mem->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_mem->map_flags = flags;
|
||||||
|
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gl_mem_unmap (GstGLMemory * gl_mem)
|
_gl_mem_unmap (GstGLMemory * gl_mem)
|
||||||
{
|
{
|
||||||
|
if ((gl_mem->map_flags & GST_MAP_WRITE) == GST_MAP_WRITE) {
|
||||||
|
if ((gl_mem->map_flags & GST_MAP_GL) == GST_MAP_GL) {
|
||||||
|
GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
|
||||||
|
} else {
|
||||||
|
GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_mem->map_flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -219,22 +280,21 @@ _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
|
||||||
|
|
||||||
dest = g_slice_alloc (sizeof (GstGLMemory));
|
dest = g_slice_alloc (sizeof (GstGLMemory));
|
||||||
_gl_mem_init (dest, src->mem.allocator, NULL, src->display, src->v_format,
|
_gl_mem_init (dest, src->mem.allocator, NULL, src->display, src->v_format,
|
||||||
src->width, src->height);
|
src->width, src->height, NULL, NULL);
|
||||||
|
|
||||||
if (!copy_params.tex_id)
|
if (!copy_params.tex_id)
|
||||||
GST_WARNING ("Could not copy GL Memory");
|
GST_WARNING ("Could not copy GL Memory");
|
||||||
|
|
||||||
dest->tex_id = copy_params.tex_id;
|
dest->tex_id = copy_params.tex_id;
|
||||||
|
dest->data = g_malloc (src->mem.maxsize);
|
||||||
|
if (dest->data == NULL) {
|
||||||
|
gst_memory_unref ((GstMemory *) dest);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return (GstMemory *) dest;
|
return (GstMemory *) dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstGLMemory *
|
|
||||||
gst_gl_memory_copy (GstGLMemory * src)
|
|
||||||
{
|
|
||||||
return (GstGLMemory *) _gl_mem_copy (src, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
GstMemory *
|
GstMemory *
|
||||||
_gl_mem_share (GstGLMemory * mem, gssize offset, gssize size)
|
_gl_mem_share (GstGLMemory * mem, gssize offset, gssize size)
|
||||||
{
|
{
|
||||||
|
@ -262,10 +322,19 @@ _gl_mem_free (GstAllocator * allocator, GstMemory * mem)
|
||||||
{
|
{
|
||||||
GstGLMemory *gl_mem = (GstGLMemory *) mem;
|
GstGLMemory *gl_mem = (GstGLMemory *) mem;
|
||||||
|
|
||||||
gst_gl_display_del_texture (gl_mem->display, &gl_mem->tex_id);
|
if (gl_mem->tex_id)
|
||||||
|
gst_gl_display_del_texture (gl_mem->display, &gl_mem->tex_id);
|
||||||
|
|
||||||
g_object_unref (gl_mem->display);
|
g_object_unref (gl_mem->display);
|
||||||
|
|
||||||
|
if (gl_mem->notify)
|
||||||
|
gl_mem->notify (gl_mem->user_data);
|
||||||
|
|
||||||
|
if (gl_mem->data && !gl_mem->wrapped) {
|
||||||
|
g_free (gl_mem->data);
|
||||||
|
gl_mem->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
g_slice_free (GstGLMemory, gl_mem);
|
g_slice_free (GstGLMemory, gl_mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,8 +352,49 @@ GstMemory *
|
||||||
gst_gl_memory_alloc (GstGLDisplay * display, GstVideoFormat format,
|
gst_gl_memory_alloc (GstGLDisplay * display, GstVideoFormat format,
|
||||||
gsize width, gsize height)
|
gsize width, gsize height)
|
||||||
{
|
{
|
||||||
return (GstMemory *) _gl_mem_new (_gl_allocator, NULL, display, format, width,
|
GstGLMemory *mem;
|
||||||
height);
|
|
||||||
|
mem = _gl_mem_new (_gl_allocator, NULL, display, format, width, height,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
mem->data = g_malloc (mem->mem.maxsize);
|
||||||
|
if (mem->data == NULL) {
|
||||||
|
gst_memory_unref ((GstMemory *) mem);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (GstMemory *) mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_gl_memory_wrapped
|
||||||
|
* @display:a #GstGLDisplay
|
||||||
|
* @format: the format for the texture
|
||||||
|
* @width: width of the texture
|
||||||
|
* @height: height of the texture
|
||||||
|
* @data: the data to wrap
|
||||||
|
* @user_data: data called with for @notify
|
||||||
|
* @notify: function called with @user_data when @data needs to be freed
|
||||||
|
*
|
||||||
|
* Returns: a GstMemory object with a GL texture specified by @format, @width and @height
|
||||||
|
* from @display and contents specified by @data
|
||||||
|
*/
|
||||||
|
GstGLMemory *
|
||||||
|
gst_gl_memory_wrapped (GstGLDisplay * display, GstVideoFormat format,
|
||||||
|
guint width, guint height, gpointer data,
|
||||||
|
gpointer user_data, GDestroyNotify notify)
|
||||||
|
{
|
||||||
|
GstGLMemory *mem;
|
||||||
|
|
||||||
|
mem = _gl_mem_new (_gl_allocator, NULL, display, format, width, height,
|
||||||
|
user_data, notify);
|
||||||
|
|
||||||
|
mem->data = data;
|
||||||
|
mem->wrapped = TRUE;
|
||||||
|
|
||||||
|
GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
|
||||||
|
|
||||||
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
G_DEFINE_TYPE (GstGLAllocator, gst_gl_allocator, GST_TYPE_ALLOCATOR);
|
G_DEFINE_TYPE (GstGLAllocator, gst_gl_allocator, GST_TYPE_ALLOCATOR);
|
||||||
|
@ -325,6 +435,8 @@ gst_gl_memory_init (void)
|
||||||
static volatile gsize _init = 0;
|
static volatile gsize _init = 0;
|
||||||
|
|
||||||
if (g_once_init_enter (&_init)) {
|
if (g_once_init_enter (&_init)) {
|
||||||
|
GST_DEBUG_CATEGORY_INIT (GST_CAT_GL_MEMORY, "glmemory", 0, "OpenGL Memory");
|
||||||
|
|
||||||
_gl_allocator = g_object_new (gst_gl_allocator_get_type (), NULL);
|
_gl_allocator = g_object_new (gst_gl_allocator_get_type (), NULL);
|
||||||
|
|
||||||
gst_allocator_register (GST_GL_MEMORY_ALLOCATOR,
|
gst_allocator_register (GST_GL_MEMORY_ALLOCATOR,
|
||||||
|
@ -333,8 +445,14 @@ gst_gl_memory_init (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* gst_is_gl_memory:
|
||||||
|
* @mem:a #GstMemory
|
||||||
|
*
|
||||||
|
* Returns: whether the memory in @mem is a #GstGLMemory
|
||||||
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_is_gl_memory (GstMemory * mem)
|
gst_is_gl_memory (GstMemory * mem)
|
||||||
{
|
{
|
||||||
return mem->allocator == _gl_allocator;
|
return mem != NULL && mem->allocator == _gl_allocator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,14 @@
|
||||||
#include <gst/gstallocator.h>
|
#include <gst/gstallocator.h>
|
||||||
|
|
||||||
#include "gstgldisplay.h"
|
#include "gstgldisplay.h"
|
||||||
|
#include "gstgldownload.h"
|
||||||
|
#include "gstglupload.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GstGLUpload GstGLUpload;
|
||||||
|
typedef struct _GstGLDownload GstGLDownload;
|
||||||
|
|
||||||
#define GST_TYPE_GL_ALLOCATOR (gst_gl_allocator_get_type())
|
#define GST_TYPE_GL_ALLOCATOR (gst_gl_allocator_get_type())
|
||||||
GType gst_gl_allocator_get_type(void);
|
GType gst_gl_allocator_get_type(void);
|
||||||
|
|
||||||
|
@ -43,6 +48,25 @@ typedef struct _GstGLMemory GstGLMemory;
|
||||||
typedef struct _GstGLAllocator GstGLAllocator;
|
typedef struct _GstGLAllocator GstGLAllocator;
|
||||||
typedef struct _GstGLAllocatorClass GstGLAllocatorClass;
|
typedef struct _GstGLAllocatorClass GstGLAllocatorClass;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
GST_GL_MEMORY_FLAG_DOWNLOAD_INITTED = (GST_MEMORY_FLAG_LAST << 0),
|
||||||
|
GST_GL_MEMORY_FLAG_UPLOAD_INITTED = (GST_MEMORY_FLAG_LAST << 1),
|
||||||
|
GST_GL_MEMORY_FLAG_NEED_DOWNLOAD = (GST_MEMORY_FLAG_LAST << 2),
|
||||||
|
GST_GL_MEMORY_FLAG_NEED_UPLOAD = (GST_MEMORY_FLAG_LAST << 3)
|
||||||
|
} GstGLMemoryFlags;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GST_MAP_GL:
|
||||||
|
*
|
||||||
|
* Flag indicating that we should map the GL object instead of to system memory.
|
||||||
|
*
|
||||||
|
* Combining #GST_MAP_GL with #GST_MAP_WRITE has the same semantics as though
|
||||||
|
* you are writing to OpenGL. Conversely, combining #GST_MAP_GL with
|
||||||
|
* #GST_MAP_READ has the same semantics as though you are reading from OpenGL.
|
||||||
|
*/
|
||||||
|
#define GST_MAP_GL GST_MAP_FLAG_LAST << 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstGLMemory:
|
* GstGLMemory:
|
||||||
* @mem: the parent object
|
* @mem: the parent object
|
||||||
|
@ -64,15 +88,35 @@ struct _GstGLMemory
|
||||||
GLenum gl_format;
|
GLenum gl_format;
|
||||||
GLuint width;
|
GLuint width;
|
||||||
GLuint height;
|
GLuint height;
|
||||||
|
|
||||||
|
GstGLDownload *download;
|
||||||
|
GLenum render_target;
|
||||||
|
GstGLUpload *upload;
|
||||||
|
|
||||||
|
GstMapFlags map_flags;
|
||||||
|
gpointer data;
|
||||||
|
|
||||||
|
gboolean wrapped;
|
||||||
|
GDestroyNotify notify;
|
||||||
|
gpointer user_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GST_GL_MEMORY_ALLOCATOR "GLMemory"
|
#define GST_GL_MEMORY_ALLOCATOR "GLMemory"
|
||||||
|
|
||||||
|
#define GST_GL_MEMORY_FLAGS(mem) GST_MEMORY_FLAGS(mem)
|
||||||
|
#define GST_GL_MEMORY_FLAG_IS_SET(mem,flag) GST_MEMORY_FLAG_IS_SET(mem,flag)
|
||||||
|
#define GST_GL_MEMORY_FLAG_SET(mem,flag) GST_MINI_OBJECT_FLAG_SET(mem,flag)
|
||||||
|
#define GST_GL_MEMORY_FLAG_UNSET(mem,flag) GST_MEMORY_FLAG_UNSET(mem,flag)
|
||||||
|
|
||||||
void gst_gl_memory_init (void);
|
void gst_gl_memory_init (void);
|
||||||
|
|
||||||
GstMemory * gst_gl_memory_alloc (GstGLDisplay * display, GstVideoFormat format,
|
GstMemory * gst_gl_memory_alloc (GstGLDisplay * display, GstVideoFormat format,
|
||||||
gsize width, gsize height);
|
gsize width, gsize height);
|
||||||
|
|
||||||
|
GstGLMemory * gst_gl_memory_wrapped (GstGLDisplay * display, GstVideoFormat format,
|
||||||
|
guint width, guint height, gpointer data,
|
||||||
|
gpointer user_data, GDestroyNotify notify);
|
||||||
|
|
||||||
gboolean gst_is_gl_memory (GstMemory * mem);
|
gboolean gst_is_gl_memory (GstMemory * mem);
|
||||||
|
|
||||||
struct _GstGLAllocator
|
struct _GstGLAllocator
|
||||||
|
|
Loading…
Reference in a new issue