glmemory: implement on top of glbasebuffer
authorMatthew Waters <matthew@centricular.com>
Wed, 10 Jun 2015 06:36:15 +0000 (16:36 +1000)
committerMatthew Waters <matthew@centricular.com>
Fri, 12 Jun 2015 06:59:20 +0000 (16:59 +1000)
Provides convenient access to PBO usage.

Currently texture updates are coupled tightly to data transfers.

docs/libs/gst-plugins-bad-libs-sections.txt
gst-libs/gst/gl/gstglbasebuffer.c
gst-libs/gst/gl/gstglbasebuffer.h
gst-libs/gst/gl/gstgldisplay.c
gst-libs/gst/gl/gstgldownload.c
gst-libs/gst/gl/gstglmemory.c
gst-libs/gst/gl/gstglmemory.h
gst-libs/gst/gl/gstglupload.c
gst-libs/gst/gl/gstgluploadmeta.c
tests/check/Makefile.am
tests/check/libs/gstglmemory.c

index 4d45c8b..a1e346e 100644 (file)
@@ -1034,13 +1034,7 @@ GST_GL_FRAMEBUFFER_GET_CLASS
 <FILE>gstglmemory</FILE>
 GstGLAllocator
 GstGLAllocatorClass
-GST_MAP_GL
 GST_GL_MEMORY_ALLOCATOR
-GstGLMemoryFlags
-GST_GL_MEMORY_FLAGS
-GST_GL_MEMORY_FLAG_IS_SET
-GST_GL_MEMORY_FLAG_SET
-GST_GL_MEMORY_FLAG_UNSET
 <TITLE>GstGLMemory</TITLE>
 GstGLMemory
 gst_gl_memory_init
index aaab67d..827c64e 100644 (file)
@@ -214,7 +214,7 @@ gst_gl_base_buffer_cpu_access (GstGLBaseBuffer * mem,
       data = gl->MapBufferRange (mem->target, 0, size, gl_map_flags);
 
       if (data)
-        memcpy (data, mem->data, size);
+        memcpy (mem->data, data, size);
 
       gl->UnmapBuffer (mem->target);
       ret = mem->data;
index a482086..87c688d 100644 (file)
@@ -70,13 +70,8 @@ typedef enum
  * GstGLBaseBuffer:
  * @mem: the parent object
  * @context: the #GstGLContext to use for GL operations
- * @tex_id: the texture id for this memory
- * @v_format: the video format of this texture
- * @gl_format: the format of the texture
- * @width: width of the texture
- * @height: height of the texture
- * @download: the object used to download this texture into @v_format
- * @upload: the object used to upload this texture from @v_format
+ * @id: the buffer id for this memory
+ * @target: the GL target of this texture for binding purposes
  *
  * Represents information about a GL buffer
  */
@@ -89,16 +84,15 @@ struct _GstGLBaseBuffer
   guint                 target;
 
   /* <protected> */
-  GstMapFlags           map_flags;       /* cumulative map flags */
-
   GMutex                lock;
+
+  GstMapFlags           map_flags;       /* cumulative map flags */
   gint                  map_count;
   gint                  gl_map_count;
 
   gpointer              data;
+  /* <private> */
   gpointer              alloc_data;
-
-  gpointer impl;
 };
 
 typedef gboolean          (*GstGLBaseBufferAllocatorCreateFunction)      (GstGLBaseBuffer * buffer, GError ** error);
index 5baee7a..b1264a9 100644 (file)
@@ -114,6 +114,7 @@ gst_gl_display_init (GstGLDisplay * display)
 
   GST_TRACE ("init %p", display);
 
+  gst_gl_base_buffer_init_once ();
   gst_gl_memory_init ();
 
 #if GST_GL_HAVE_PLATFORM_EGL
index 4bb0059..8f045c7 100644 (file)
@@ -413,17 +413,16 @@ _do_download (GstGLDownload * download, GstBuffer * inbuf)
 
   for (i = 0; i < out_planes; i++) {
     GstMemory *out_mem = gst_buffer_peek_memory (outbuf, i);
-    gpointer temp_data = ((GstGLMemory *) out_mem)->data;
-    ((GstGLMemory *) out_mem)->data = data[i];
-
-    gst_gl_memory_download_transfer ((GstGLMemory *) out_mem);
+    gpointer temp_data = ((GstGLBaseBuffer *) out_mem)->data;
+    ((GstGLBaseBuffer *) out_mem)->data = data[i];
 
     if (!gst_memory_map (out_mem, &map_info, GST_MAP_READ)) {
       GST_ERROR_OBJECT (download, "Failed to map memory");
       ret = FALSE;
     }
     gst_memory_unmap (out_mem, &map_info);
-    ((GstGLMemory *) out_mem)->data = temp_data;
+    ((GstGLBaseBuffer *) out_mem)->data = temp_data;
+    GST_MINI_OBJECT_FLAG_SET (out_mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
   }
 
   gst_buffer_unref (outbuf);
index 2deede4..66a3343 100644 (file)
@@ -34,7 +34,7 @@
  * @short_description: memory subclass for GL textures
  * @see_also: #GstMemory, #GstAllocator, #GstGLBufferPool
  *
- * GstGLMemory is a #GstMemory subclass providing support for the mapping of
+ * GstGLMemory is a #GstGLBaseBuffer subclass providing support for the mapping of
  * GL textures.  
  *
  * #GstGLMemory is created through gst_gl_memory_alloc() or system memory can
  * Data is uploaded or downloaded from the GPU as is necessary.
  */
 
+/* Implementation notes
+ *
+ * PBO transfer's are implemented using GstGLBaseBuffer.  We just need to
+ * ensure that the texture data is written/read to/from before/after calling
+ * the parent class which performs the pbo buffer transfer.
+ */
+
 #define USING_OPENGL(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL, 1, 0))
 #define USING_OPENGL3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_OPENGL3, 3, 1))
 #define USING_GLES(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES, 1, 0))
@@ -100,12 +107,9 @@ static GstAllocator *_gl_allocator;
 #ifndef GL_UNPACK_ROW_LENGTH
 #define GL_UNPACK_ROW_LENGTH 0x0CF2
 #endif
-#ifndef GL_MAP_READ_BIT
-#define GL_MAP_READ_BIT 0x0001
-#endif
-#ifndef GL_MAP_WRITE_BIT
-#define GL_MAP_WRITE_BIT 0x0002
-#endif
+
+G_DEFINE_TYPE (GstGLAllocator, gst_gl_allocator,
+    GST_TYPE_GL_BASE_BUFFER_ALLOCATOR);
 
 typedef struct
 {
@@ -389,32 +393,6 @@ typedef struct _GenTexture
   guint result;
 } GenTexture;
 
-static void
-_generate_texture (GstGLContext * context, GenTexture * data)
-{
-  const GstGLFuncs *gl = context->gl_vtable;
-  GLenum internal_format;
-
-  GST_TRACE ("Generating texture format:%u type:%u dimensions:%ux%u",
-      data->gl_format, data->gl_type, data->width, data->height);
-
-  internal_format =
-      gst_gl_sized_gl_format_from_gl_format_type (context, data->gl_format,
-      data->gl_type);
-
-  gl->GenTextures (1, &data->result);
-  gl->BindTexture (data->gl_target, data->result);
-  gl->TexImage2D (data->gl_target, 0, internal_format, data->width,
-      data->height, 0, data->gl_format, data->gl_type, NULL);
-
-  gl->TexParameteri (data->gl_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-  gl->TexParameteri (data->gl_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-  gl->TexParameteri (data->gl_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-  gl->TexParameteri (data->gl_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
-  GST_LOG ("generated texture id:%d", data->result);
-}
-
 /* find the difference between the start of the plane and where the video
  * data starts in the plane */
 static gsize
@@ -432,18 +410,19 @@ _find_plane_frame_start (GstGLMemory * gl_mem)
 
   /* offset between the plane data start and where the video frame starts */
   return (GST_VIDEO_INFO_PLANE_OFFSET (&gl_mem->info,
-          gl_mem->plane)) - plane_start + gl_mem->mem.offset;
+          gl_mem->plane)) - plane_start + gl_mem->mem.mem.offset;
 }
 
 static void
-_upload_memory (GstGLContext * context, GstGLMemory * gl_mem)
+_upload_memory (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize)
 {
+  GstGLContext *context = gl_mem->mem.context;
   const GstGLFuncs *gl;
   GLenum gl_format, gl_type, gl_target;
   gpointer data;
   gsize plane_start;
 
-  if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
+  if (!GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD)) {
     return;
   }
 
@@ -464,24 +443,24 @@ _upload_memory (GstGLContext * context, GstGLMemory * gl_mem)
   }
 
   GST_LOG ("upload for texture id:%u, with pbo %u %ux%u",
-      gl_mem->tex_id, gl_mem->transfer_pbo, gl_mem->tex_width,
+      gl_mem->tex_id, gl_mem->mem.id, gl_mem->tex_width,
       GL_MEM_HEIGHT (gl_mem));
 
   /* find the start of the plane data including padding */
   plane_start = _find_plane_frame_start (gl_mem);
 
-  if (gl_mem->transfer_pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) {
-    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->transfer_pbo);
+  if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context)) {
+    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.id);
     data = (void *) plane_start;
   } else {
-    data = (gpointer) ((gintptr) plane_start + (gintptr) gl_mem->data);
+    data = (gpointer) ((gintptr) plane_start + (gintptr) gl_mem->mem.data);
   }
 
   gl->BindTexture (gl_target, gl_mem->tex_id);
   gl->TexSubImage2D (gl_target, 0, 0, 0, gl_mem->tex_width,
       GL_MEM_HEIGHT (gl_mem), gl_format, gl_type, data);
 
-  if (gl_mem->transfer_pbo && CONTEXT_SUPPORTS_PBO_UPLOAD (context))
+  if (gl_mem->mem.id && CONTEXT_SUPPORTS_PBO_UPLOAD (context))
     gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
 
   /* Reset to default values */
@@ -493,11 +472,11 @@ _upload_memory (GstGLContext * context, GstGLMemory * gl_mem)
 
   gl->BindTexture (gl_target, 0);
 
-  GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
+  GST_MEMORY_FLAG_UNSET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
 }
 
 static inline void
-_calculate_unpack_length (GstGLMemory * gl_mem)
+_calculate_unpack_length (GstGLMemory * gl_mem, GstGLContext * context)
 {
   guint n_gl_bytes;
 
@@ -512,10 +491,10 @@ _calculate_unpack_length (GstGLMemory * gl_mem)
     return;
   }
 
-  if (USING_OPENGL (gl_mem->context) || USING_GLES3 (gl_mem->context)
-      || USING_OPENGL3 (gl_mem->context)) {
+  if (USING_OPENGL (context) || USING_GLES3 (context)
+      || USING_OPENGL3 (context)) {
     gl_mem->unpack_length = GL_MEM_STRIDE (gl_mem) / n_gl_bytes;
-  } else if (USING_GLES2 (gl_mem->context)) {
+  } else if (USING_GLES2 (context)) {
     guint j = 8;
 
     while (j >= n_gl_bytes) {
@@ -573,144 +552,68 @@ _calculate_unpack_length (GstGLMemory * gl_mem)
   }
 }
 
-static void
-_transfer_download (GstGLContext * context, GstGLMemory * gl_mem)
+static guint
+_new_texture (GstGLContext * context, guint target, guint internal_format,
+    guint format, guint type, guint width, guint height)
 {
-  const GstGLFuncs *gl;
-  gsize plane_start;
-  gsize size;
-  guint format, type;
-  guint fboId;
-
-  if (!CONTEXT_SUPPORTS_PBO_DOWNLOAD (context)
-      || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
-      || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)
-    /* not supported */
-    return;
-
-  gl = context->gl_vtable;
-
-  if (!gl_mem->transfer_pbo)
-    gl->GenBuffers (1, &gl_mem->transfer_pbo);
-
-  GST_DEBUG ("downloading texture %u using pbo %u",
-      gl_mem->tex_id, gl_mem->transfer_pbo);
-
-  size = gst_gl_get_plane_data_size (&gl_mem->info, &gl_mem->valign,
-      gl_mem->plane);
-  plane_start = _find_plane_frame_start (gl_mem);
-  format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
-  type = GL_UNSIGNED_BYTE;
-  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
-    type = GL_UNSIGNED_SHORT_5_6_5;
-
-  gl->BindBuffer (GL_PIXEL_PACK_BUFFER, gl_mem->transfer_pbo);
-  gl->BufferData (GL_PIXEL_PACK_BUFFER, size, NULL, GL_STREAM_READ);
-
-  /* FIXME: try and avoid creating and destroying fbo's every download... */
-  /* create a framebuffer object */
-  gl->GenFramebuffers (1, &fboId);
-  gl->BindFramebuffer (GL_FRAMEBUFFER, fboId);
-
-  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-      GL_TEXTURE_2D, gl_mem->tex_id, 0);
-
-  if (!gst_gl_context_check_framebuffer_status (context)) {
-    GST_ERROR ("failed to download texture");
-    goto fbo_error;
-  }
+  const GstGLFuncs *gl = context->gl_vtable;
+  guint tex_id;
 
-  gl->ReadPixels (0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), format,
-      type, (void *) plane_start);
+  gl->GenTextures (1, &tex_id);
+  gl->BindTexture (target, tex_id);
+  gl->TexImage2D (target, 0, internal_format, width, height, 0, format, type,
+      NULL);
 
-fbo_error:
-  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
-  gl->DeleteFramebuffers (1, &fboId);
+  gl->TexParameteri (target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  gl->TexParameteri (target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  gl->TexParameteri (target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+  gl->TexParameteri (target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
-  gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+  return tex_id;
 }
 
-static void
-_download_memory (GstGLContext * context, GstGLMemory * gl_mem)
+static gboolean
+_gl_mem_create (GstGLMemory * gl_mem, GError ** error)
 {
-  const GstGLFuncs *gl;
-  guint format, type;
-  GLuint fboId;
+  GstGLContext *context = gl_mem->mem.context;
+  const GstGLFuncs *gl = context->gl_vtable;
+  GLenum internal_format;
+  GLenum tex_format;
+  GLenum tex_type;
 
-  gl = context->gl_vtable;
-  format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
-  type = GL_UNSIGNED_BYTE;
+  tex_format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
+  tex_type = GL_UNSIGNED_BYTE;
   if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
-    type = GL_UNSIGNED_SHORT_5_6_5;
+    tex_type = GL_UNSIGNED_SHORT_5_6_5;
 
-  if (!gl->GenFramebuffers) {
-    gst_gl_context_set_error (context, "Cannot download GL texture "
-        "without support for Framebuffers");
-    goto error;
-  }
-
-  if (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2
-      && (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
-          || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)) {
-    gst_gl_context_set_error (context, "Cannot download GL luminance/"
-        "luminance alpha textures");
-    goto error;
-  }
-
-  GST_LOG ("downloading memory %p, tex %u into %p",
-      gl_mem, gl_mem->tex_id, gl_mem->data);
-
-  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
-      || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA) {
-    gl->BindTexture (gl_mem->tex_target, gl_mem->tex_id);
-    gl->GetTexImage (gl_mem->tex_target, 0, format, type, gl_mem->data);
-    gl->BindTexture (gl_mem->tex_target, 0);
-  } else if (gl_mem->transfer_pbo && CONTEXT_SUPPORTS_PBO_DOWNLOAD (context)) {
-    gsize size, plane_start;
-    gpointer map_data = NULL;
-
-    size = gst_gl_get_plane_data_size (&gl_mem->info, &gl_mem->valign,
-        gl_mem->plane);
-
-    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, gl_mem->transfer_pbo);
-    map_data =
-        gl->MapBufferRange (GL_PIXEL_PACK_BUFFER, 0, size, GL_MAP_READ_BIT);
-    if (!map_data) {
-      GST_WARNING ("error mapping buffer for download");
-      gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
-      goto read_pixels;
-    }
-
-    /* FIXME: COPY! use glMapBuffer + glSync everywhere to remove this */
-    plane_start = _find_plane_frame_start (gl_mem);
-    memcpy ((guint8 *) gl_mem->data + plane_start, map_data, size);
-
-    gl->UnmapBuffer (GL_PIXEL_PACK_BUFFER);
-    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
-  } else {
-  read_pixels:
-    /* FIXME: try and avoid creating and destroying fbo's every download... */
-    /* create a framebuffer object */
-    gl->GenFramebuffers (1, &fboId);
-    gl->BindFramebuffer (GL_FRAMEBUFFER, fboId);
-
-    gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
-        gl_mem->tex_target, gl_mem->tex_id, 0);
+  GST_TRACE ("Generating texture format:%u type:%u dimensions:%ux%u",
+      tex_format, tex_type, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem));
 
-    if (!gst_gl_context_check_framebuffer_status (context))
-      goto fbo_error;
+  internal_format =
+      gst_gl_sized_gl_format_from_gl_format_type (context, tex_format,
+      tex_type);
 
-    gl->ReadPixels (0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), format,
-        type, gl_mem->data);
+  if (!gl_mem->tex_id) {
+    gl_mem->tex_id =
+        _new_texture (context, gl_mem->tex_target, internal_format, tex_format,
+        tex_type, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem));
+  }
 
-    gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
+  GST_LOG ("generated texture id:%d", gl_mem->tex_id);
 
-  fbo_error:
-    gl->DeleteFramebuffers (1, &fboId);
+  if (USING_OPENGL (context) || USING_OPENGL3 (context)
+      || USING_GLES3 (context)) {
+    /* FIXME: lazy init this for resource constrained platforms
+     * Will need to fix pbo detection based on the existence of the mem.id then */
+    gl->GenBuffers (1, &gl_mem->mem.id);
+    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.id);
+    gl->BufferData (GL_PIXEL_UNPACK_BUFFER, gl_mem->mem.mem.maxsize, NULL,
+        GL_STREAM_DRAW);
+    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
+    GST_LOG ("generated pbo %u", gl_mem->mem.id);
   }
 
-error:
-  return;
+  return TRUE;
 }
 
 static void
@@ -719,8 +622,7 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
     GstVideoAlignment * valign, guint plane, gpointer user_data,
     GDestroyNotify notify)
 {
-  gsize size, maxsize;
-  gsize align = gst_memory_alignment, offset = 0;
+  gsize size;
 
   g_return_if_fail (plane < GST_VIDEO_INFO_N_PLANES (info));
 
@@ -730,36 +632,27 @@ _gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
   else
     gst_video_alignment_reset (&mem->valign);
 
-  size = maxsize = gst_gl_get_plane_data_size (info, valign, plane);
-
-  if (params) {
-    align |= params->align;
-    offset = params->prefix;
-    maxsize += params->prefix + params->padding + align;
-  }
+  size = gst_gl_get_plane_data_size (info, valign, plane);
 
-  gst_memory_init (GST_MEMORY_CAST (mem), 0, allocator, parent, maxsize, align,
-      offset, size);
-
-  mem->context = gst_object_ref (context);
+  /* we always operate on 2D textures unless we're dealing with wrapped textures */
+  mem->tex_target = GL_TEXTURE_2D;
   mem->tex_type =
       gst_gl_texture_type_from_format (context, GST_VIDEO_INFO_FORMAT (info),
       plane);
-  /* we always operate on 2D textures unless we're dealing with wrapped textures */
-  mem->tex_target = GL_TEXTURE_2D;
   mem->plane = plane;
   mem->notify = notify;
   mem->user_data = user_data;
-  mem->texture_wrapped = FALSE;
 
-  g_mutex_init (&mem->lock);
+  _calculate_unpack_length (mem, context);
 
-  _calculate_unpack_length (mem);
+  /* calls _gl_mem_create() */
+  gst_gl_base_buffer_init ((GstGLBaseBuffer *) mem, allocator, parent, context,
+      params, size);
 
   GST_DEBUG ("new GL texture context:%" GST_PTR_FORMAT " memory:%p format:%u "
       "dimensions:%ux%u stride:%u size:%" G_GSIZE_FORMAT, context, mem,
       mem->tex_type, mem->tex_width, GL_MEM_HEIGHT (mem), GL_MEM_STRIDE (mem),
-      maxsize);
+      mem->mem.mem.size);
 }
 
 static GstGLMemory *
@@ -769,136 +662,222 @@ _gl_mem_new (GstAllocator * allocator, GstMemory * parent,
     GDestroyNotify notify)
 {
   GstGLMemory *mem;
-  GenTexture data = { 0, };
   mem = g_slice_new0 (GstGLMemory);
+  mem->texture_wrapped = FALSE;
+
   _gl_mem_init (mem, allocator, parent, context, params, info, valign, plane,
       user_data, notify);
 
-  data.width = mem->tex_width;
-  data.height = GL_MEM_HEIGHT (mem);
-  data.gl_format = gst_gl_format_from_gl_texture_type (mem->tex_type);
-  data.gl_type = GL_UNSIGNED_BYTE;
-  data.gl_target = mem->tex_target;
-  if (mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
-    data.gl_type = GL_UNSIGNED_SHORT_5_6_5;
-
-  gst_gl_context_thread_add (context,
-      (GstGLContextThreadFunc) _generate_texture, &data);
-  if (!data.result) {
-    GST_WARNING ("Could not create GL texture with context:%" GST_PTR_FORMAT,
-        context);
+  return mem;
+}
+
+static gboolean
+_gl_mem_read_pixels (GstGLMemory * gl_mem, GstMapInfo * info,
+    gsize size, gpointer read_pointer)
+{
+  GstGLContext *context = gl_mem->mem.context;
+  const GstGLFuncs *gl = context->gl_vtable;
+  guint format, type;
+  guint fbo;
+
+  format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
+  type = GL_UNSIGNED_BYTE;
+  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
+    type = GL_UNSIGNED_SHORT_5_6_5;
+
+  gl->GenFramebuffers (1, &fbo);
+  gl->BindFramebuffer (GL_FRAMEBUFFER, fbo);
+
+  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+      gl_mem->tex_target, gl_mem->tex_id, 0);
+
+  if (!gst_gl_context_check_framebuffer_status (context)) {
+    GST_CAT_WARNING (GST_CAT_GL_MEMORY,
+        "Could not create framebuffer to read pixels for memory %p", gl_mem);
+    gl->DeleteFramebuffers (1, &fbo);
+    return FALSE;
   }
 
-  GST_TRACE ("created texture %u", data.result);
+  gl->ReadPixels (0, 0, gl_mem->tex_width, GL_MEM_HEIGHT (gl_mem), format,
+      type, read_pointer);
 
-  mem->tex_id = data.result;
-  mem->tex_target = data.gl_target;
+  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);
 
-  return mem;
+  gl->DeleteFramebuffers (1, &fbo);
+
+  return TRUE;
 }
 
-static GstGLMemory *
-_gl_mem_alloc_data (GstGLMemory * mem)
+static gpointer
+_pbo_download_transfer (GstGLMemory * gl_mem, GstMapInfo * info, gsize size)
 {
-  guint8 *data;
-  gsize align, aoffset;
-
-  data = g_try_malloc (mem->mem.maxsize);
-  mem->alloc_data = mem->data = data;
+  GstGLBaseBufferAllocatorClass *alloc_class;
+  const GstGLFuncs *gl;
+  gpointer data;
 
-  if (data == NULL) {
-    gst_memory_unref ((GstMemory *) mem);
+  if (!gl_mem->mem.id || !CONTEXT_SUPPORTS_PBO_DOWNLOAD (gl_mem->mem.context)
+      || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
+      || gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)
+    /* unsupported */
     return NULL;
-  }
 
-  /* do alignment */
-  align = mem->mem.align;
-  if ((aoffset = ((guintptr) data & align))) {
-    aoffset = (align + 1) - aoffset;
-    data += aoffset;
-    mem->mem.maxsize -= aoffset;
-    mem->data = data;
+  GST_DEBUG ("downloading texture %u using pbo %u", gl_mem->tex_id,
+      gl_mem->mem.id);
+
+  alloc_class =
+      GST_GL_BASE_BUFFER_ALLOCATOR_CLASS (gst_gl_allocator_parent_class);
+  gl = gl_mem->mem.context->gl_vtable;
+
+  if (GST_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD)
+      && info->flags & GST_MAP_READ) {
+    /* copy texture data into into the pbo and map that */
+    gsize plane_start = _find_plane_frame_start (gl_mem);
+
+    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, gl_mem->mem.id);
+
+    if (!_gl_mem_read_pixels (gl_mem, info, -1, (gpointer) plane_start)) {
+      gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
+      return NULL;
+    }
+
+    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
   }
 
-  return mem;
+  /* get a cpu accessible mapping from the pbo */
+  gl_mem->mem.target = GL_PIXEL_PACK_BUFFER;
+  data = alloc_class->map_buffer ((GstGLBaseBuffer *) gl_mem, info, size);
+
+  return data;
 }
 
 static gpointer
-_gl_mem_map (GstGLMemory * gl_mem, gsize maxsize, GstMapFlags flags)
+_gl_mem_download_get_tex_image (GstGLMemory * gl_mem, GstMapInfo * info,
+    gsize size)
+{
+  GstGLContext *context = gl_mem->mem.context;
+  const GstGLFuncs *gl = context->gl_vtable;
+  guint format, type;
+
+  if (size != -1 && size != ((GstMemory *) gl_mem)->maxsize)
+    return NULL;
+
+  if (USING_GLES2 (context) || USING_GLES3 (context))
+    return NULL;
+
+  /* taken care of by read pixels */
+  if (gl_mem->tex_type != GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE
+      && gl_mem->tex_type != GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA)
+    return NULL;
+
+  gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) gl_mem);
+
+  format = gst_gl_format_from_gl_texture_type (gl_mem->tex_type);
+  type = GL_UNSIGNED_BYTE;
+  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
+    type = GL_UNSIGNED_SHORT_5_6_5;
+
+  gl->BindTexture (gl_mem->tex_target, gl_mem->tex_id);
+  gl->GetTexImage (gl_mem->tex_target, 0, format, type, gl_mem->mem.data);
+  gl->BindTexture (gl_mem->tex_target, 0);
+
+  return gl_mem->mem.data;
+}
+
+static gpointer
+_gl_mem_download_read_pixels (GstGLMemory * gl_mem, GstMapInfo * info,
+    gsize size)
+{
+  if (size != -1 && size != ((GstMemory *) gl_mem)->maxsize)
+    return NULL;
+
+  gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) gl_mem);
+
+  if (!_gl_mem_read_pixels (gl_mem, info, size, gl_mem->mem.data))
+    return NULL;
+
+  return gl_mem->mem.data;
+}
+
+static gpointer
+_gl_mem_map_cpu_access (GstGLMemory * gl_mem, GstMapInfo * info, gsize size)
 {
   gpointer data;
 
-  g_return_val_if_fail (maxsize == gl_mem->mem.maxsize, NULL);
+  data = _pbo_download_transfer (gl_mem, info, size);
+  if (!data)
+    data = _gl_mem_download_get_tex_image (gl_mem, info, size);
+
+  if (!data)
+    data = _gl_mem_download_read_pixels (gl_mem, info, size);
+
+  return data;
+}
+
+static gpointer
+_gl_mem_map_buffer (GstGLMemory * gl_mem, GstMapInfo * info, gsize maxsize)
+{
+  GstGLBaseBufferAllocatorClass *alloc_class;
+  gpointer data;
 
-  g_mutex_lock (&gl_mem->lock);
+  alloc_class =
+      GST_GL_BASE_BUFFER_ALLOCATOR_CLASS (gst_gl_allocator_parent_class);
 
-  if ((flags & GST_MAP_GL) == GST_MAP_GL) {
-    if ((flags & GST_MAP_READ) == GST_MAP_READ) {
+  if ((info->flags & GST_MAP_GL) == GST_MAP_GL) {
+    if ((info->flags & GST_MAP_READ) == GST_MAP_READ) {
       GST_TRACE ("mapping GL texture:%u for reading", gl_mem->tex_id);
-      if (GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
-        gst_gl_context_thread_add (gl_mem->context,
-            (GstGLContextThreadFunc) _upload_memory, gl_mem);
-        GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
-      }
+      gl_mem->mem.target = GL_PIXEL_UNPACK_BUFFER;
+      /* data -> pbo */
+      alloc_class->map_buffer ((GstGLBaseBuffer *) gl_mem, info, maxsize);
+      /* pbo -> texture */
+      _upload_memory (gl_mem, info, maxsize);
     }
 
-    if ((flags & GST_MAP_WRITE) == GST_MAP_WRITE) {
+    if ((info->flags & GST_MAP_WRITE) == GST_MAP_WRITE) {
       GST_TRACE ("mapping GL texture:%u for writing", gl_mem->tex_id);
-      GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
-      GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
+      GST_MINI_OBJECT_FLAG_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
     }
+    GST_MEMORY_FLAG_UNSET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
 
     data = &gl_mem->tex_id;
   } else {                      /* not GL */
-    if ((flags & GST_MAP_READ) == GST_MAP_READ) {
-      GST_TRACE ("mapping GL texture:%u for reading from system memory",
-          gl_mem->tex_id);
-      if (GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD)) {
-        gst_gl_context_thread_add (gl_mem->context,
-            (GstGLContextThreadFunc) _download_memory, gl_mem);
-        GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
-      }
-    }
-
-    if ((flags & GST_MAP_WRITE) == GST_MAP_WRITE) {
-      GST_TRACE ("mapping GL texture:%u for writing to system memory",
-          gl_mem->tex_id);
-      GST_GL_MEMORY_FLAG_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
-      GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
-    }
-
-    data = gl_mem->data;
+    data = _gl_mem_map_cpu_access (gl_mem, info, maxsize);
+    if (info->flags & GST_MAP_WRITE)
+      GST_MINI_OBJECT_FLAG_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
   }
 
-  /* only store the first map flags, subsequent maps must be a subset of this */
-  if (gl_mem->map_count++ == 0)
-    gl_mem->map_flags = flags;
-
-  g_mutex_unlock (&gl_mem->lock);
-
   return data;
 }
 
-void
-gst_gl_memory_download_transfer (GstGLMemory * gl_mem)
+static void
+_gl_mem_unmap_cpu_access (GstGLMemory * gl_mem, GstMapInfo * info)
 {
-  g_mutex_lock (&gl_mem->lock);
+  GstGLBaseBufferAllocatorClass *alloc_class;
+  const GstGLFuncs *gl;
 
-  gst_gl_context_thread_add (gl_mem->context,
-      (GstGLContextThreadFunc) _transfer_download, gl_mem);
+  alloc_class =
+      GST_GL_BASE_BUFFER_ALLOCATOR_CLASS (gst_gl_allocator_parent_class);
+  gl = gl_mem->mem.context->gl_vtable;
+
+  if (!gl_mem->mem.id)
+    /* PBO's not supported */
+    return;
 
-  g_mutex_unlock (&gl_mem->lock);
+  gl_mem->mem.target = GL_PIXEL_PACK_BUFFER;
+  alloc_class->unmap_buffer ((GstGLBaseBuffer *) gl_mem, info);
+  gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
 }
 
 static void
-_gl_mem_unmap (GstGLMemory * gl_mem)
+_gl_mem_unmap_buffer (GstGLMemory * gl_mem, GstMapInfo * info)
 {
-  g_mutex_lock (&gl_mem->lock);
-
-  if (--gl_mem->map_count <= 0)
-    gl_mem->map_flags = 0;
-
-  g_mutex_unlock (&gl_mem->lock);
+  if ((info->flags & GST_MAP_GL) == 0) {
+    _gl_mem_unmap_cpu_access (gl_mem, info);
+    if (info->flags & GST_MAP_WRITE)
+      GST_MINI_OBJECT_FLAG_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
+  } else {
+    if (info->flags & GST_MAP_WRITE)
+      GST_MINI_OBJECT_FLAG_SET (gl_mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
+  }
 }
 
 static void
@@ -923,7 +902,7 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
   out_height = copy_params->out_height;
   out_stride = copy_params->out_stride;
 
-  gl = src->context->gl_vtable;
+  gl = context->gl_vtable;
   out_gl_format = gst_gl_format_from_gl_texture_type (copy_params->out_format);
   out_gl_type = GL_UNSIGNED_BYTE;
   if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
@@ -934,7 +913,7 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
     in_gl_type = GL_UNSIGNED_SHORT_5_6_5;
 
   if (!gl->GenFramebuffers) {
-    gst_gl_context_set_error (src->context,
+    gst_gl_context_set_error (context,
         "Context, EXT_framebuffer_object not supported");
     goto error;
   }
@@ -952,21 +931,24 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
   }
 
   if (!tex_id) {
-    GenTexture data = { 0, };
-    data.width = copy_params->out_width;
-    data.height = copy_params->out_height;
-    data.gl_target = out_tex_target;
-    data.gl_format = out_gl_format;
-    data.gl_type = GL_UNSIGNED_BYTE;
+    guint internal_format;
+    guint out_gl_type;
+
+    out_gl_type = GL_UNSIGNED_BYTE;
     if (copy_params->out_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
-      data.gl_type = GL_UNSIGNED_SHORT_5_6_5;
+      out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
+
+    internal_format =
+        gst_gl_sized_gl_format_from_gl_format_type (context, out_gl_format,
+        out_gl_type);
 
-    _generate_texture (context, &data);
-    tex_id = data.result;
+    tex_id =
+        _new_texture (context, out_tex_target, internal_format, out_gl_format,
+        out_gl_type, copy_params->out_width, copy_params->out_height);
   }
 
   if (!tex_id) {
-    GST_WARNING ("Could not create GL texture with context:%p", src->context);
+    GST_WARNING ("Could not create GL texture with context:%p", context);
   }
 
   GST_LOG ("copying memory %p, tex %u into texture %i",
@@ -985,9 +967,9 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
 
   gl->BindTexture (out_tex_target, tex_id);
   if (copy_params->respecify) {
-    if (!gl->GenBuffers) {
+    if (!gl->GenBuffers || !src->mem.id) {
       gst_gl_context_set_error (context, "Cannot reinterpret texture contents "
-          "without buffer objects");
+          "without pixel buffer objects");
       gl->BindTexture (out_tex_target, 0);
       goto fbo_error;
     }
@@ -1000,21 +982,18 @@ _gl_mem_copy_thread (GstGLContext * context, gpointer data)
       goto fbo_error;
     }
 
-    if (!src->pbo)
-      gl->GenBuffers (1, &src->pbo);
-
     GST_TRACE ("copying texture data with size of %u*%u*%u",
         _gl_format_type_n_bytes (in_gl_format, in_gl_type), src->tex_width,
         GL_MEM_HEIGHT (src));
 
     /* copy tex */
-    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, src->pbo);
+    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, src->mem.id);
     gl->BufferData (GL_PIXEL_PACK_BUFFER, in_size, NULL, GL_STREAM_COPY);
     gl->ReadPixels (0, 0, src->tex_width, GL_MEM_HEIGHT (src), in_gl_format,
         in_gl_type, 0);
     gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);
 
-    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, src->pbo);
+    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, src->mem.id);
     gl->TexSubImage2D (out_tex_target, 0, 0, 0, out_width, out_height,
         out_gl_format, out_gl_type, 0);
 
@@ -1054,33 +1033,33 @@ error:
 static GstMemory *
 _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
 {
-  GstGLAllocator *allocator = (GstGLAllocator *) src->mem.allocator;
+  GstGLAllocator *allocator = (GstGLAllocator *) src->mem.mem.allocator;
   GstMemory *ret = NULL;
 
-  g_mutex_lock (&((GstGLMemory *) src)->lock);
-
   /* If not doing a full copy, then copy to sysmem, the 2D represention of the
    * texture would become wrong */
-  if (offset > 0 || size < src->mem.size) {
-    ret = allocator->fallback_mem_copy (&src->mem, offset, size);
-  } else if (GST_GL_MEMORY_FLAG_IS_SET (src, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
-    GstAllocationParams params = { 0, src->mem.align, 0, 0 };
+  if (offset > 0 || size < src->mem.mem.size) {
+    ret = allocator->fallback_mem_copy (&src->mem.mem, offset, size);
+  } else if (GST_MEMORY_FLAG_IS_SET (src, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD)) {
+    GstAllocationParams params = { 0, src->mem.mem.align, 0, 0 };
     GstGLMemory *dest;
 
-    dest = _gl_mem_new (src->mem.allocator, NULL, src->context, &params,
+    dest = _gl_mem_new (src->mem.mem.allocator, NULL, src->mem.context, &params,
         &src->info, &src->valign, src->plane, NULL, NULL);
-    dest = _gl_mem_alloc_data (dest);
+    dest = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *)
+        dest);
 
     if (dest == NULL) {
       GST_WARNING ("Could not copy GL Memory");
       goto done;
     }
 
-    memcpy (dest->data, (guint8 *) src->data + src->mem.offset, src->mem.size);
-    GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
+    memcpy (dest->mem.data, (guint8 *) src->mem.data + src->mem.mem.offset,
+        src->mem.mem.size);
+    GST_MINI_OBJECT_FLAG_SET (dest, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
     ret = (GstMemory *) dest;
   } else {
-    GstAllocationParams params = { 0, src->mem.align, 0, 0 };
+    GstAllocationParams params = { 0, src->mem.mem.align, 0, 0 };
     GstGLMemoryCopyParams copy_params;
     GstGLMemory *dest;
 
@@ -1093,7 +1072,7 @@ _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
     copy_params.out_stride = GL_MEM_STRIDE (src);
     copy_params.respecify = FALSE;
 
-    gst_gl_context_thread_add (src->context, _gl_mem_copy_thread, &copy_params);
+    _gl_mem_copy_thread (src->mem.context, &copy_params);
 
     if (!copy_params.result) {
       GST_WARNING ("Could not copy GL Memory");
@@ -1101,35 +1080,25 @@ _gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
     }
 
     dest = g_slice_new0 (GstGLMemory);
-    _gl_mem_init (dest, src->mem.allocator, NULL, src->context, &params,
+    /* don't create our own texture */
+    dest->texture_wrapped = TRUE;
+    _gl_mem_init (dest, src->mem.mem.allocator, NULL, src->mem.context, &params,
         &src->info, &src->valign, src->plane, NULL, NULL);
+    dest->texture_wrapped = FALSE;
 
     dest->tex_id = copy_params.tex_id;
     dest->tex_target = copy_params.tex_target;
-    dest = _gl_mem_alloc_data (dest);
-    GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
+    dest = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *)
+        dest);
+    GST_MINI_OBJECT_FLAG_SET (dest, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
     ret = (GstMemory *) dest;
   }
 
 done:
-  g_mutex_unlock (&((GstGLMemory *) src)->lock);
-
   return ret;
 }
 
 static GstMemory *
-_gl_mem_share (GstGLMemory * mem, gssize offset, gssize size)
-{
-  return NULL;
-}
-
-static gboolean
-_gl_mem_is_span (GstGLMemory * mem1, GstGLMemory * mem2, gsize * offset)
-{
-  return FALSE;
-}
-
-static GstMemory *
 _gl_mem_alloc (GstAllocator * allocator, gsize size,
     GstAllocationParams * params)
 {
@@ -1140,17 +1109,15 @@ _gl_mem_alloc (GstAllocator * allocator, gsize size,
 }
 
 static void
-_destroy_gl_objects (GstGLContext * context, GstGLMemory * gl_mem)
+_gl_mem_destroy (GstGLMemory * gl_mem)
 {
-  const GstGLFuncs *gl = context->gl_vtable;
+  const GstGLFuncs *gl = gl_mem->mem.context->gl_vtable;
 
   if (gl_mem->tex_id && !gl_mem->texture_wrapped)
     gl->DeleteTextures (1, &gl_mem->tex_id);
 
-  if (gl_mem->pbo)
-    gl->DeleteBuffers (1, &gl_mem->pbo);
-  if (gl_mem->transfer_pbo)
-    gl->DeleteBuffers (1, &gl_mem->transfer_pbo);
+  if (gl_mem->mem.id)
+    gl->DeleteBuffers (1, &gl_mem->mem.id);
 }
 
 static void
@@ -1158,24 +1125,47 @@ _gl_mem_free (GstAllocator * allocator, GstMemory * mem)
 {
   GstGLMemory *gl_mem = (GstGLMemory *) mem;
 
-  GST_TRACE ("freeing texture %u", gl_mem->tex_id);
-
-  gst_gl_context_thread_add (gl_mem->context,
-      (GstGLContextThreadFunc) _destroy_gl_objects, gl_mem);
+  GST_ALLOCATOR_CLASS (gst_gl_allocator_parent_class)->free (allocator, mem);
 
   if (gl_mem->notify)
     gl_mem->notify (gl_mem->user_data);
 
-  if (gl_mem->alloc_data) {
-    g_free (gl_mem->alloc_data);
-    gl_mem->alloc_data = NULL;
-    gl_mem->data = NULL;
-  }
+  g_slice_free (GstGLMemory, gl_mem);
+}
+
+static void
+gst_gl_allocator_class_init (GstGLAllocatorClass * klass)
+{
+  GstGLBaseBufferAllocatorClass *gl_base;
+  GstAllocatorClass *allocator_class;
 
-  g_mutex_clear (&gl_mem->lock);
+  gl_base = (GstGLBaseBufferAllocatorClass *) klass;
+  allocator_class = (GstAllocatorClass *) klass;
 
-  gst_object_unref (gl_mem->context);
-  g_slice_free (GstGLMemory, gl_mem);
+  gl_base->create = (GstGLBaseBufferAllocatorCreateFunction) _gl_mem_create;
+  gl_base->map_buffer =
+      (GstGLBaseBufferAllocatorMapBufferFunction) _gl_mem_map_buffer;
+  gl_base->unmap_buffer =
+      (GstGLBaseBufferAllocatorUnmapBufferFunction) _gl_mem_unmap_buffer;
+  gl_base->copy = (GstGLBaseBufferAllocatorCopyFunction) _gl_mem_copy;
+  gl_base->destroy = (GstGLBaseBufferAllocatorDestroyFunction) _gl_mem_destroy;
+
+  allocator_class->alloc = _gl_mem_alloc;
+  allocator_class->free = _gl_mem_free;
+}
+
+static void
+gst_gl_allocator_init (GstGLAllocator * allocator)
+{
+  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
+
+  /* Keep the fallback copy function around, we will need it when copying with
+   * at an offset or smaller size */
+  allocator->fallback_mem_copy = alloc->mem_copy;
+
+  alloc->mem_type = GST_GL_MEMORY_ALLOCATOR;
+
+  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
 }
 
 /**
@@ -1220,7 +1210,7 @@ gst_gl_memory_copy_into_texture (GstGLMemory * gl_mem, guint tex_id,
   copy_params.out_stride = stride;
   copy_params.respecify = respecify;
 
-  gst_gl_context_thread_add (gl_mem->context, _gl_mem_copy_thread,
+  gst_gl_context_thread_add (gl_mem->mem.context, _gl_mem_copy_thread,
       &copy_params);
 
   return copy_params.result;
@@ -1249,15 +1239,17 @@ gst_gl_memory_wrapped_texture (GstGLContext * context,
   GstGLMemory *mem;
 
   mem = g_slice_new0 (GstGLMemory);
+
+  mem->tex_id = texture_id;
+
   _gl_mem_init (mem, _gl_allocator, NULL, context, NULL, info, valign, plane,
       user_data, notify);
 
-  mem->tex_id = texture_id;
   mem->tex_target = texture_target;
   mem->texture_wrapped = TRUE;
 
-  mem = _gl_mem_alloc_data (mem);
-  GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
+  mem = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) mem);
+  GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
 
   return mem;
 }
@@ -1283,7 +1275,7 @@ gst_gl_memory_alloc (GstGLContext * context, GstAllocationParams * params,
 
   mem = _gl_mem_new (_gl_allocator, NULL, context, params, info, valign, plane,
       NULL, NULL);
-  mem = _gl_mem_alloc_data (mem);
+  mem = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) mem);
 
   return (GstMemory *) mem;
 }
@@ -1313,10 +1305,13 @@ gst_gl_memory_wrapped (GstGLContext * context, GstVideoInfo * info,
 
   mem = _gl_mem_new (_gl_allocator, NULL, context, NULL, info, valign, plane,
       user_data, notify);
+  mem = (GstGLMemory *) gst_gl_base_buffer_alloc_data ((GstGLBaseBuffer *) mem);
+  if (!mem)
+    return NULL;
 
-  mem->data = data;
+  memcpy (mem->mem.data, data, ((GstMemory *) mem)->maxsize);
 
-  GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
+  GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
 
   return mem;
 }
@@ -1337,38 +1332,6 @@ gst_gl_memory_get_texture_height (GstGLMemory * gl_mem)
   return _get_plane_height (&gl_mem->info, gl_mem->plane);
 }
 
-G_DEFINE_TYPE (GstGLAllocator, gst_gl_allocator, GST_TYPE_ALLOCATOR);
-
-static void
-gst_gl_allocator_class_init (GstGLAllocatorClass * klass)
-{
-  GstAllocatorClass *allocator_class;
-
-  allocator_class = (GstAllocatorClass *) klass;
-
-  allocator_class->alloc = _gl_mem_alloc;
-  allocator_class->free = _gl_mem_free;
-}
-
-static void
-gst_gl_allocator_init (GstGLAllocator * allocator)
-{
-  GstAllocator *alloc = GST_ALLOCATOR_CAST (allocator);
-
-  /* Keep the fallback copy function around, we will need it when copying with
-   * at an offset or smaller size */
-  allocator->fallback_mem_copy = alloc->mem_copy;
-
-  alloc->mem_type = GST_GL_MEMORY_ALLOCATOR;
-  alloc->mem_map = (GstMemoryMapFunction) _gl_mem_map;
-  alloc->mem_unmap = (GstMemoryUnmapFunction) _gl_mem_unmap;
-  alloc->mem_copy = (GstMemoryCopyFunction) _gl_mem_copy;
-  alloc->mem_share = (GstMemoryShareFunction) _gl_mem_share;
-  alloc->mem_is_span = (GstMemoryIsSpanFunction) _gl_mem_is_span;
-
-  GST_OBJECT_FLAG_SET (allocator, GST_ALLOCATOR_FLAG_CUSTOM_ALLOC);
-}
-
 /**
  * gst_gl_memory_init:
  *
@@ -1400,7 +1363,8 @@ gst_gl_memory_init (void)
 gboolean
 gst_is_gl_memory (GstMemory * mem)
 {
-  return mem != NULL && mem->allocator == _gl_allocator;
+  return mem != NULL && mem->allocator != NULL
+      && g_type_is_a (G_OBJECT_TYPE (mem->allocator), GST_TYPE_GL_ALLOCATOR);
 }
 
 /**
index 68a4aeb..66b6c20 100644 (file)
@@ -26,6 +26,7 @@
 #include <gst/gstmemory.h>
 #include <gst/video/video.h>
 
+#include <gst/gl/gstglbasebuffer.h>
 #include <gst/gl/gl.h>
 
 G_BEGIN_DECLS
@@ -41,48 +42,23 @@ GType gst_gl_allocator_get_type(void);
 #define GST_GL_ALLOCATOR_CAST(obj)            ((GstGLAllocator *)(obj))
 
 /**
- * GstGLMemoryFlags:
- *
- * Flags indicating the current state of a #GstGLMemory
- */
-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:
  * @mem: the parent object
  * @context: the #GstGLContext to use for GL operations
- * @tex_id: the texture id for this memory
- * @v_format: the video format of this texture
- * @gl_format: the format of the texture
- * @width: width of the texture
- * @height: height of the texture
- * @download: the object used to download this texture into @v_format
- * @upload: the object used to upload this texture from @v_format
+ * @tex_id: the GL texture id for this memory
+ * @tex_target: the GL texture target for this memory
+ * @tex_type: the texture type
+ * @info: the texture's #GstVideoInfo
+ * @valign: data alignment for system memory mapping
+ * @plane: data plane in @info
+ * @tex_scaling: GL shader scaling parameters for @valign and/or width/height
  *
  * Represents information about a GL texture
  */
 struct _GstGLMemory
 {
-  GstMemory                    mem;
+  GstGLBaseBuffer       mem;
 
-  GstGLContext         *context;
   guint                 tex_id;
   guint                 tex_target;
   GstVideoGLTextureType tex_type;
@@ -92,20 +68,11 @@ struct _GstGLMemory
   gfloat                tex_scaling[2];
 
   /* <private> */
-  gpointer              alloc_data;
-  gpointer              data;
-
   gboolean              texture_wrapped;
   GDestroyNotify        notify;
   gpointer              user_data;
-  guint                 pbo;
   guint                 unpack_length;
   guint                 tex_width;
-  guint                 transfer_pbo;
-  GstMapFlags           map_flags;
-  guint                 map_count;
-
-  GMutex                lock;
 };
 
 #define GST_CAPS_FEATURE_MEMORY_GL_MEMORY "memory:GLMemory"
@@ -117,71 +84,57 @@ struct _GstGLMemory
 /**
  * GST_GL_MEMORY_ALLOCATOR:
  *
- * The name of the GL memore allocator
+ * The name of the GL memory allocator
  */
 #define GST_GL_MEMORY_ALLOCATOR   "GLMemory"
 
-/**
- * GST_GL_MEMORY_FLAGS:
- * @mem: a #GstGLMemory
- *
- * Get the currently set flags on @mem
- */
-#define GST_GL_MEMORY_FLAGS(mem) GST_MEMORY_FLAGS(mem)
-
-/**
- * GST_GL_MEMORY_FLAG_IS_SET:
- * @mem: a #GstGLMemory
- * @flag: a flag
- *
- * Whether @flag is set on @mem
- */
-#define GST_GL_MEMORY_FLAG_IS_SET(mem,flag) GST_MEMORY_FLAG_IS_SET(mem,flag)
-
-/**
- * GST_GL_MEMORY_FLAG_SET:
- * @mem: a #GstGLMemory
- * @flag: a flag
- *
- * Set @flag on @mem
- */
-#define GST_GL_MEMORY_FLAG_SET(mem,flag) GST_MINI_OBJECT_FLAG_SET(mem,flag)
-
-/**
- * GST_GL_MEMORY_FLAG_UNSET:
- * @mem: a #GstGLMemory
- * @flag: a flag
- *
- * Unset @flag on @mem
- */
-#define GST_GL_MEMORY_FLAG_UNSET(mem,flag) GST_MEMORY_FLAG_UNSET(mem,flag)
-
 void          gst_gl_memory_init (void);
 gboolean      gst_is_gl_memory (GstMemory * mem);
 
-GstMemory *   gst_gl_memory_alloc   (GstGLContext * context, GstAllocationParams *params,
-                                     GstVideoInfo * info, guint plane, GstVideoAlignment *valign);
-GstGLMemory * gst_gl_memory_wrapped (GstGLContext * context, GstVideoInfo * info, guint plane,
-                                     GstVideoAlignment *valign, gpointer data,
-                                     gpointer user_data, GDestroyNotify notify);
-GstGLMemory * gst_gl_memory_wrapped_texture (GstGLContext * context, guint texture_id, guint texture_target,
-                                             GstVideoInfo * info, guint plane, GstVideoAlignment *valign,
-                                             gpointer user_data, GDestroyNotify notify);
-
-gboolean      gst_gl_memory_copy_into_texture (GstGLMemory *gl_mem, guint tex_id,
+GstMemory *   gst_gl_memory_alloc   (GstGLContext * context,
+                                     GstAllocationParams *params,
+                                     GstVideoInfo * info,
+                                     guint plane,
+                                     GstVideoAlignment *valign);
+GstGLMemory * gst_gl_memory_wrapped (GstGLContext * context,
+                                     GstVideoInfo * info,
+                                     guint plane,
+                                     GstVideoAlignment *valign,
+                                     gpointer data,
+                                     gpointer user_data,
+                                     GDestroyNotify notify);
+GstGLMemory * gst_gl_memory_wrapped_texture (GstGLContext * context,
+                                             guint texture_id,
+                                             guint texture_target,
+                                             GstVideoInfo * info,
+                                             guint plane,
+                                             GstVideoAlignment *valign,
+                                             gpointer user_data,
+                                             GDestroyNotify notify);
+
+gboolean      gst_gl_memory_copy_into_texture (GstGLMemory *gl_mem,
+                                               guint tex_id,
                                                GstVideoGLTextureType tex_type,
-                                               gint width, gint height, gint stride,
+                                               gint width,
+                                               gint height,
+                                               gint stride,
                                                gboolean respecify);
 
-gboolean      gst_gl_memory_setup_buffer  (GstGLContext * context, GstAllocationParams * params,
-                                           GstVideoInfo * info, GstVideoAlignment *valign, GstBuffer * buffer);
-gboolean      gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info, GstVideoAlignment *valign,
+gboolean      gst_gl_memory_setup_buffer  (GstGLContext * context,
+                                           GstAllocationParams * params,
+                                           GstVideoInfo * info,
+                                           GstVideoAlignment *valign,
+                                           GstBuffer * buffer);
+gboolean      gst_gl_memory_setup_wrapped (GstGLContext * context,
+                                           GstVideoInfo * info,
+                                           GstVideoAlignment *valign,
                                            gpointer data[GST_VIDEO_MAX_PLANES],
                                            GstGLMemory *textures[GST_VIDEO_MAX_PLANES]);
 
 gint          gst_gl_memory_get_texture_width  (GstGLMemory * gl_mem);
 gint          gst_gl_memory_get_texture_height (GstGLMemory * gl_mem);
 
+/* utility functions */
 GstVideoGLTextureType gst_gl_texture_type_from_format (GstGLContext *context,
                                                        GstVideoFormat v_format,
                                                        guint plane);
@@ -190,8 +143,6 @@ guint                 gst_gl_sized_gl_format_from_gl_format_type (GstGLContext *
                                                                   guint format,
                                                                   guint type);
 
-void gst_gl_memory_download_transfer (GstGLMemory * gl_mem);
-
 /**
  * GstGLAllocator
  *
@@ -199,7 +150,7 @@ void gst_gl_memory_download_transfer (GstGLMemory * gl_mem);
  */
 struct _GstGLAllocator
 {
-  GstAllocator parent;
+  GstGLBaseBufferAllocator parent;
   GstMemoryCopyFunction fallback_mem_copy;
 };
 
@@ -210,7 +161,7 @@ struct _GstGLAllocator
  */
 struct _GstGLAllocatorClass
 {
-  GstAllocatorClass parent_class;
+  GstGLBaseBufferAllocatorClass parent_class;
 };
 
 G_END_DECLS
index e089a13..851d9de 100644 (file)
@@ -266,7 +266,8 @@ _gl_memory_upload_perform (gpointer impl, GstBuffer * buffer,
     GstMemory *mem = gst_buffer_peek_memory (buffer, i);
 
     gl_mem = (GstGLMemory *) mem;
-    if (!gst_gl_context_can_share (upload->upload->context, gl_mem->context))
+    if (!gst_gl_context_can_share (upload->upload->context,
+            gl_mem->mem.context))
       return GST_GL_UPLOAD_UNSHARED_GL_CONTEXT;
   }
 
@@ -434,8 +435,8 @@ _egl_image_upload_perform_gl_thread (GstGLContext * context,
   }
 
   if (GST_IS_GL_BUFFER_POOL (image->buffer->pool))
-    gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (image->buffer->
-            pool), image->buffer);
+    gst_gl_buffer_pool_replace_last_buffer (GST_GL_BUFFER_POOL (image->
+            buffer->pool), image->buffer);
 }
 
 static GstGLUploadReturn
@@ -581,11 +582,11 @@ _upload_meta_upload_propose_allocation (gpointer impl, GstQuery * decide_query,
   gpointer handle;
 
   gl_apis =
-      gst_gl_api_to_string (gst_gl_context_get_gl_api (upload->
-          upload->context));
+      gst_gl_api_to_string (gst_gl_context_get_gl_api (upload->upload->
+          context));
   platform =
-      gst_gl_platform_to_string (gst_gl_context_get_gl_platform
-      (upload->upload->context));
+      gst_gl_platform_to_string (gst_gl_context_get_gl_platform (upload->
+          upload->context));
   handle = (gpointer) gst_gl_context_get_gl_context (upload->upload->context);
 
   gl_context =
@@ -791,13 +792,6 @@ _raw_data_upload_perform (gpointer impl, GstBuffer * buffer,
   gst_gl_memory_setup_wrapped (raw->upload->context,
       &raw->upload->priv->in_info, NULL, raw->in_frame.data, in_tex);
 
-  for (i = 0; i < GST_GL_UPLOAD_MAX_PLANES; i++) {
-    if (in_tex[i]) {
-      in_tex[i]->data = raw->in_frame.data[i];
-      GST_GL_MEMORY_FLAG_SET (in_tex[i], GST_GL_MEMORY_FLAG_NEED_UPLOAD);
-    }
-  }
-
   *outbuf = gst_buffer_new ();
   for (i = 0; i < max_planes; i++) {
     gst_buffer_append_memory (*outbuf, (GstMemory *) in_tex[i]);
index 5edf29b..e47e006 100644 (file)
@@ -205,7 +205,7 @@ _perform_with_gl_memory (GstGLUploadMeta * upload, GstVideoGLTextureUploadMeta *
   for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->info); i++) {
     GstGLMemory *in_mem = upload->priv->in_tex[i];
 
-    if (GST_GL_MEMORY_FLAG_IS_SET (in_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
+    if (GST_MEMORY_FLAG_IS_SET (in_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD)) {
       GstMapInfo map_info;
       guint tex_id;
 
@@ -219,7 +219,7 @@ _perform_with_gl_memory (GstGLUploadMeta * upload, GstVideoGLTextureUploadMeta *
       gst_memory_unmap ((GstMemory *) in_mem, &map_info);
 
       in_mem->tex_id = tex_id;
-      GST_GL_MEMORY_FLAG_SET (in_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
+      GST_MINI_OBJECT_FLAG_SET (in_mem, GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD);
     } else {
       GstGLMemory *out_mem;
       gint mem_width, mem_height;
@@ -234,7 +234,7 @@ _perform_with_gl_memory (GstGLUploadMeta * upload, GstVideoGLTextureUploadMeta *
 
       if (out_mem->tex_id != texture_id[i]) {
         out_mem->tex_id = texture_id[i];
-        GST_GL_MEMORY_FLAG_SET (out_mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
+        GST_MINI_OBJECT_FLAG_SET (out_mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
       }
 
       mem_width = gst_gl_memory_get_texture_width (out_mem);
@@ -262,8 +262,6 @@ _perform_with_data_unlocked (GstGLUploadMeta * upload,
     if (!upload->priv->in_tex[i])
       upload->priv->in_tex[i] = gst_gl_memory_wrapped (upload->context,
           &upload->info, i, NULL, data[i], NULL, NULL);
-
-    upload->priv->in_tex[i]->data = data[i];
   }
 
   return _perform_with_gl_memory (upload, meta, texture_id);
index 295791b..da8df71 100644 (file)
@@ -203,6 +203,7 @@ endif
 
 if USE_GL
 check_gl=libs/gstglcontext \
+    libs/gstglbuffer \
     libs/gstglmemory \
     libs/gstglupload \
     libs/gstglcolorconvert \
@@ -489,6 +490,16 @@ libs_gstglmemory_CFLAGS = \
        -DGST_USE_UNSTABLE_API \
        $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
 
+libs_gstglbuffer_LDADD = \
+       $(top_builddir)/gst-libs/gst/gl/libgstgl-@GST_API_VERSION@.la \
+       $(GST_PLUGINS_BASE_LIBS) -lgstvideo-$(GST_API_VERSION) \
+       $(GST_BASE_LIBS) $(GST_LIBS) $(LDADD)
+
+libs_gstglbuffer_CFLAGS = \
+       $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
+       -DGST_USE_UNSTABLE_API \
+       $(GST_BASE_CFLAGS) $(GST_CFLAGS) $(AM_CFLAGS)
+
 libs_gstglupload_CFLAGS = \
        $(GST_PLUGINS_BAD_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) \
        -DGST_USE_UNSTABLE_API \
index 74ab15b..bc9348d 100644 (file)
@@ -79,7 +79,7 @@ GST_START_TEST (test_basic)
 
       /* test init params */
       fail_if (gst_video_info_is_equal (&v_info, &gl_mem->info) == FALSE);
-      fail_if (gl_mem->context != context);
+      fail_if (gl_mem->mem.context != context);
       fail_if (gl_mem->tex_id == 0);
 
       /* copy the memory */
@@ -90,7 +90,7 @@ GST_START_TEST (test_basic)
       /* test params */
       fail_if (gst_video_info_is_equal (&gl_mem2->info,
               &gl_mem->info) == FALSE);
-      fail_if (gl_mem->context != gl_mem2->context);
+      fail_if (gl_mem->mem.context != gl_mem2->mem.context);
 
       if (gst_gl_context_get_error ())
         printf ("%s\n", gst_gl_context_get_error ());
@@ -125,10 +125,10 @@ GST_START_TEST (test_transfer)
 
   /* texture creation */
   mem = (GstMemory *) gst_gl_memory_alloc (context, NULL, &v_info, 0, NULL);
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   /* test wrapping raw data */
   mem2 =
@@ -136,27 +136,27 @@ GST_START_TEST (test_transfer)
       rgba_pixel, NULL, NULL);
   fail_if (mem == NULL);
 
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   /* wrapped texture creation */
   mem3 = (GstMemory *) gst_gl_memory_wrapped_texture (context,
       ((GstGLMemory *) mem)->tex_id, GL_TEXTURE_2D, &v_info, 0, NULL, NULL,
       NULL);
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   /* check data/flags are correct */
   fail_unless (gst_memory_map (mem2, &map_info, GST_MAP_READ));
 
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   fail_unless (((gchar *) map_info.data)[0] == rgba_pixel[0]);
   fail_unless (((gchar *) map_info.data)[1] == rgba_pixel[1]);
@@ -165,32 +165,32 @@ GST_START_TEST (test_transfer)
 
   gst_memory_unmap (mem2, &map_info);
 
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   fail_unless (gst_memory_map (mem2, &map_info, GST_MAP_READ | GST_MAP_GL));
 
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   /* test texture copy */
   fail_unless (gst_gl_memory_copy_into_texture ((GstGLMemory *) mem2,
           ((GstGLMemory *) mem)->tex_id, GST_VIDEO_GL_TEXTURE_TYPE_RGBA, 1, 1,
           4, FALSE));
-  GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
+  GST_MINI_OBJECT_FLAG_SET (mem, GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD);
 
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem2,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem2,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   gst_memory_unmap (mem2, &map_info);
 
@@ -207,10 +207,10 @@ GST_START_TEST (test_transfer)
   /* test download of wrapped copied texture */
   fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_READ));
 
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   fail_unless (((gchar *) map_info.data)[0] == rgba_pixel[0]);
   fail_unless (((gchar *) map_info.data)[1] == rgba_pixel[1]);
@@ -223,19 +223,19 @@ GST_START_TEST (test_transfer)
   fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_WRITE));
   gst_memory_unmap (mem3, &map_info);
 
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   /* test download flag */
   fail_unless (gst_memory_map (mem3, &map_info, GST_MAP_WRITE | GST_MAP_GL));
   gst_memory_unmap (mem3, &map_info);
 
-  fail_unless (!GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_UPLOAD));
-  fail_unless (GST_GL_MEMORY_FLAG_IS_SET (mem3,
-          GST_GL_MEMORY_FLAG_NEED_DOWNLOAD));
+  fail_unless (!GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_UPLOAD));
+  fail_unless (GST_MEMORY_FLAG_IS_SET (mem3,
+          GST_GL_BASE_BUFFER_FLAG_NEED_DOWNLOAD));
 
   if (gst_gl_context_get_error ())
     printf ("%s\n", gst_gl_context_get_error ());