/*
 * GStreamer
 * Copyright (C) 2012 Matthew Waters <ystreet00@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include <gst/video/video.h>

#include "gstglmemory.h"

/**
 * SECTION:gstglmemory
 * @short_description: memory subclass for GL textures
 * @see_also: #GstMemory, #GstAllocator, #GstGLBufferPool
 *
 * GstGLMemory is a #GstMemory subclass providing support for the mapping of
 * GL textures.  
 *
 * #GstGLMemory is created through gst_gl_memory_alloc() or system memory can
 * be wrapped through gst_gl_memory_wrapped().
 *
 * Data is uploaded or downloaded from the GPU as is necessary.
 */

#define USING_OPENGL(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL)
#define USING_OPENGL3(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_OPENGL3)
#define USING_GLES(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES)
#define USING_GLES2(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES2)
#define USING_GLES3(context) (gst_gl_context_get_gl_api (context) & GST_GL_API_GLES3)

GST_DEBUG_CATEGORY_STATIC (GST_CAT_GL_MEMORY);
#define GST_CAT_DEFUALT GST_CAT_GL_MEMORY

static GstAllocator *_gl_allocator;

/* compatability definitions... */
#ifndef GL_RED
#define GL_RED 0x1903
#endif
#ifndef GL_RG
#define GL_RG 0x8227
#endif
#ifndef GL_PIXEL_PACK_BUFFER
#define GL_PIXEL_PACK_BUFFER 0x88EB
#endif
#ifndef GL_PIXEL_UNPACK_BUFFER
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#endif
#ifndef GL_STREAM_COPY
#define GL_STREAM_COPY 0x88E2
#endif

typedef struct
{
  /* in */
  GstGLMemory *src;
  GstVideoGLTextureType out_format;
  guint out_width, out_height;
  guint out_stride;
  gboolean respecify;
  /* inout */
  guint tex_id;
  /* out */
  gboolean result;
} GstGLMemoryCopyParams;

static inline guint
_gl_format_n_components (guint format)
{
  switch (format) {
    case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
    case GL_RGBA:
      return 4;
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
    case GL_RGB:
      return 3;
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
    case GST_VIDEO_GL_TEXTURE_TYPE_RG:
    case GL_LUMINANCE_ALPHA:
    case GL_RG:
      return 2;
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
    case GST_VIDEO_GL_TEXTURE_TYPE_R:
    case GL_LUMINANCE:
    case GL_RED:
      return 1;
    default:
      return 0;
  }
}

static inline guint
_gl_type_n_components (guint type)
{
  switch (type) {
    case GL_UNSIGNED_BYTE:
      return 1;
    case GL_UNSIGNED_SHORT_5_6_5:
      return 3;
    default:
      g_assert_not_reached ();
      return 0;
  }
}

static inline guint
_gl_type_n_bytes (guint type)
{
  switch (type) {
    case GL_UNSIGNED_BYTE:
      return 1;
    case GL_UNSIGNED_SHORT_5_6_5:
      return 2;
    default:
      g_assert_not_reached ();
      return 0;
  }
}

static inline guint
_gl_format_type_n_bytes (guint format, guint type)
{
  return _gl_format_n_components (format) / _gl_type_n_components (type) *
      _gl_type_n_bytes (type);
}

static inline GLenum
_gst_gl_format_from_gl_texture_type (GstVideoGLTextureType tex_format)
{
  switch (tex_format) {
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA:
      return GL_LUMINANCE_ALPHA;
    case GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE:
      return GL_LUMINANCE;
    case GST_VIDEO_GL_TEXTURE_TYPE_RGBA:
      return GL_RGBA;
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB:
    case GST_VIDEO_GL_TEXTURE_TYPE_RGB16:
      return GL_RGB;
    case GST_VIDEO_GL_TEXTURE_TYPE_RG:
      return GL_RG;
    case GST_VIDEO_GL_TEXTURE_TYPE_R:
      return GL_RED;
    default:
      return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
  }
}

static inline guint
_gl_texture_type_n_bytes (GstVideoGLTextureType tex_format)
{
  guint format, type;

  format = _gst_gl_format_from_gl_texture_type (tex_format);
  type = GL_UNSIGNED_BYTE;
  if (tex_format == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    type = GL_UNSIGNED_SHORT_5_6_5;

  return _gl_format_type_n_bytes (format, type);
}

GstVideoGLTextureType
gst_gl_texture_type_from_format (GstVideoFormat v_format, guint plane)
{
  switch (v_format) {
    case GST_VIDEO_FORMAT_RGBx:
    case GST_VIDEO_FORMAT_BGRx:
    case GST_VIDEO_FORMAT_xRGB:
    case GST_VIDEO_FORMAT_xBGR:
    case GST_VIDEO_FORMAT_RGBA:
    case GST_VIDEO_FORMAT_BGRA:
    case GST_VIDEO_FORMAT_ARGB:
    case GST_VIDEO_FORMAT_ABGR:
    case GST_VIDEO_FORMAT_AYUV:
      return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
      break;
    case GST_VIDEO_FORMAT_RGB:
    case GST_VIDEO_FORMAT_BGR:
      return GST_VIDEO_GL_TEXTURE_TYPE_RGB;
      break;
    case GST_VIDEO_FORMAT_GRAY8:
      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
      break;
    case GST_VIDEO_FORMAT_GRAY16_BE:
    case GST_VIDEO_FORMAT_GRAY16_LE:
      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
      break;
    case GST_VIDEO_FORMAT_YUY2:
    case GST_VIDEO_FORMAT_UYVY:
      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
      break;
    case GST_VIDEO_FORMAT_NV12:
    case GST_VIDEO_FORMAT_NV21:
      if (plane == 0)
        return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE_ALPHA;
      break;
    case GST_VIDEO_FORMAT_Y444:
    case GST_VIDEO_FORMAT_Y42B:
    case GST_VIDEO_FORMAT_Y41B:
    case GST_VIDEO_FORMAT_I420:
    case GST_VIDEO_FORMAT_YV12:
      return GST_VIDEO_GL_TEXTURE_TYPE_LUMINANCE;
      break;
    default:
      g_assert_not_reached ();
      break;
  }
  return GST_VIDEO_GL_TEXTURE_TYPE_RGBA;
}

static inline guint
_get_plane_width (GstVideoInfo * info, guint plane)
{
  if (GST_VIDEO_INFO_IS_YUV (info))
    /* For now component width and plane width are the same and the
     * plane-component mapping matches
     */
    return GST_VIDEO_INFO_COMP_WIDTH (info, plane);
  else                          /* RGB, GRAY */
    return GST_VIDEO_INFO_WIDTH (info);
}

static inline guint
_get_plane_height (GstVideoInfo * info, guint plane)
{
  if (GST_VIDEO_INFO_IS_YUV (info))
    /* For now component width and plane width are the same and the
     * plane-component mapping matches
     */
    return GST_VIDEO_INFO_COMP_HEIGHT (info, plane);
  else                          /* RGB, GRAY */
    return GST_VIDEO_INFO_HEIGHT (info);
}

typedef struct _GenTexture
{
  guint width, height;
  GLenum gl_format;
  GLenum gl_type;
  guint result;
} GenTexture;

static void
_generate_texture (GstGLContext * context, GenTexture * data)
{
  const GstGLFuncs *gl = context->gl_vtable;

  GST_CAT_TRACE (GST_CAT_GL_MEMORY,
      "Generating texture format:%u type:%u dimensions:%ux%u", data->gl_format,
      data->gl_type, data->width, data->height);

  gl->GenTextures (1, &data->result);
  gl->BindTexture (GL_TEXTURE_2D, data->result);
  gl->TexImage2D (GL_TEXTURE_2D, 0, data->gl_format, data->width,
      data->height, 0, data->gl_format, data->gl_type, NULL);

  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "generated texture id:%d", data->result);
}

static void
_upload_memory (GstGLContext * context, GstGLMemory * gl_mem)
{
  const GstGLFuncs *gl;
  GLenum gl_format, gl_type;

  if (!GST_GL_MEMORY_FLAG_IS_SET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
    return;
  }

  gl = context->gl_vtable;

  gl_type = GL_UNSIGNED_BYTE;
  if (gl_mem->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    gl_type = GL_UNSIGNED_SHORT_5_6_5;

  gl_format = _gst_gl_format_from_gl_texture_type (gl_mem->tex_type);

#if GST_GL_HAVE_OPENGL || GST_GL_HAVE_GLES3
  if (USING_OPENGL (context) || USING_GLES3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, gl_mem->unpack_length);
  }
#endif
#if GST_GL_HAVE_GLES2
  if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, gl_mem->unpack_length);
  }
#endif

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "upload for texture id:%u, %ux%u",
      gl_mem->tex_id, gl_mem->width, gl_mem->height);

  gl->BindTexture (GL_TEXTURE_2D, gl_mem->tex_id);
  gl->TexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, gl_mem->width, gl_mem->height,
      gl_format, gl_type, gl_mem->data);

  /* Reset to default values */
#if GST_GL_HAVE_OPENGL || GST_GL_HAVE_GLES3
  if (USING_OPENGL (context) || USING_GLES3 (context)) {
    gl->PixelStorei (GL_UNPACK_ROW_LENGTH, 0);
  }
#endif
#if GST_GL_HAVE_GLES2
  if (USING_GLES2 (context)) {
    gl->PixelStorei (GL_UNPACK_ALIGNMENT, 4);
  }
#endif
  gl->BindTexture (GL_TEXTURE_2D, 0);

  GST_GL_MEMORY_FLAG_UNSET (gl_mem, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
}

static inline void
_calculate_unpack_length (GstGLMemory * gl_mem)
{
  guint n_gl_bytes;

  gl_mem->tex_scaling[0] = 1.0f;
  gl_mem->tex_scaling[1] = 1.0f;
  gl_mem->unpack_length = 1;

  n_gl_bytes = _gl_texture_type_n_bytes (gl_mem->tex_type);
  if (n_gl_bytes == 0) {
    GST_CAT_ERROR (GST_CAT_GL_MEMORY, "Unsupported texture type %d",
        gl_mem->tex_type);
    return;
  }
#if GST_GL_HAVE_OPENGL || GST_GL_HAVE_GLES3
  if (USING_OPENGL (gl_mem->context) || USING_GLES3 (gl_mem->context)) {
    gl_mem->unpack_length = gl_mem->stride / n_gl_bytes;
  }
#endif
#if GST_GL_HAVE_GLES2
  if (USING_GLES2 (gl_mem->context)) {
    guint j = 8;

    while (j >= n_gl_bytes) {
      /* GST_ROUND_UP_j(gl_mem->width * n_gl_bytes) */
      guint round_up_j = ((gl_mem->width * n_gl_bytes) + j - 1) & ~(j - 1);

      if (round_up_j == gl_mem->stride) {
        GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based on width "
            "(with plane width:%u, plane stride:%u and pixel stride:%u. "
            "RU%u(%u*%u) = %u)", j, gl_mem->width, gl_mem->stride, n_gl_bytes,
            j, gl_mem->width, n_gl_bytes, round_up_j);

        gl_mem->unpack_length = j;
        break;
      }
      j >>= 1;
    }

    if (j < n_gl_bytes) {
      /* Failed to find a suitable alignment, try based on plane_stride and
       * scale in the shader.  Useful for alignments that are greater than 8.
       */
      j = 8;

      while (j >= n_gl_bytes) {
        /* GST_ROUND_UP_j(gl_mem->stride) */
        guint round_up_j = ((gl_mem->stride) + j - 1) & ~(j - 1);

        if (round_up_j == gl_mem->stride) {
          GST_CAT_LOG (GST_CAT_GL_MEMORY, "Found alignment of %u based on "
              "stride (with plane stride:%u and pixel stride:%u. "
              "RU%u(%u) = %u)", j, gl_mem->stride, n_gl_bytes, j,
              gl_mem->stride, round_up_j);

          gl_mem->unpack_length = j;
          gl_mem->tex_scaling[0] =
              (gfloat) (gl_mem->width * n_gl_bytes) / (gfloat) gl_mem->stride;
          gl_mem->width = gl_mem->stride / n_gl_bytes;
          break;
        }
        j >>= 1;
      }

      if (j < n_gl_bytes) {
        GST_CAT_ERROR
            (GST_CAT_GL_MEMORY, "Failed to find matching alignment. Image may "
            "look corrupted. plane width:%u, plane stride:%u and pixel "
            "stride:%u", gl_mem->width, gl_mem->stride, n_gl_bytes);
      }
    }
  }
#endif
}

static void
_download_memory (GstGLContext * context, GstGLMemory * gl_mem)
{
  const GstGLFuncs *gl;
  guint format, type;
  GLuint fboId;

  gl = context->gl_vtable;
  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;

  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_CAT_LOG (GST_CAT_GL_MEMORY, "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_TEXTURE_2D, gl_mem->tex_id);
    gl->GetTexImage (GL_TEXTURE_2D, 0, format, type, gl_mem->data);
    gl->BindTexture (GL_TEXTURE_2D, 0);
  } else {
    /* 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))
      goto fbo_error;

    gl->ReadPixels (0, 0, gl_mem->width, gl_mem->height, format, type,
        gl_mem->data);

    gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  fbo_error:
    gl->DeleteFramebuffers (1, &fboId);
  }

error:
  return;
}

static void
_gl_mem_init (GstGLMemory * mem, GstAllocator * allocator, GstMemory * parent,
    GstGLContext * context, GstVideoGLTextureType tex_type, gint width,
    gint height, gint stride, gpointer user_data, GDestroyNotify notify)
{
  gsize maxsize;

  maxsize = _gl_texture_type_n_bytes (tex_type) * stride * height;

  gst_memory_init (GST_MEMORY_CAST (mem), GST_MEMORY_FLAG_NO_SHARE,
      allocator, parent, maxsize, 0, 0, maxsize);

  mem->context = gst_object_ref (context);
  mem->tex_type = tex_type;
  mem->width = width;
  mem->height = height;
  mem->stride = stride;
  mem->notify = notify;
  mem->user_data = user_data;
  mem->data_wrapped = FALSE;
  mem->texture_wrapped = FALSE;

  _calculate_unpack_length (mem);

  GST_CAT_DEBUG (GST_CAT_GL_MEMORY, "new GL texture memory:%p format:%u "
      "dimensions:%ux%u", mem, tex_type, width, height);
}

static GstGLMemory *
_gl_mem_new (GstAllocator * allocator, GstMemory * parent,
    GstGLContext * context, GstVideoGLTextureType tex_type, gint width,
    gint height, gint stride, gpointer user_data, GDestroyNotify notify)
{
  GstGLMemory *mem;
  GenTexture data = { 0, };
  mem = g_slice_new0 (GstGLMemory);
  _gl_mem_init (mem, allocator, parent, context, tex_type, width, height,
      stride, user_data, notify);

  data.width = mem->width;
  data.height = mem->height;
  data.gl_format = _gst_gl_format_from_gl_texture_type (tex_type);
  data.gl_type = GL_UNSIGNED_BYTE;
  if (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_CAT_WARNING (GST_CAT_GL_MEMORY,
        "Could not create GL texture with context:%p", context);
  }

  GST_CAT_TRACE (GST_CAT_GL_MEMORY, "created texture %u", data.result);

  mem->tex_id = data.result;

  return mem;
}

static gpointer
_gl_mem_map (GstGLMemory * gl_mem, gsize maxsize, GstMapFlags flags)
{
  gpointer data;

  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) {
      GST_CAT_TRACE (GST_CAT_GL_MEMORY, "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);
      }
    } else {
      GST_CAT_TRACE (GST_CAT_GL_MEMORY, "mapping GL texture:%u for writing",
          gl_mem->tex_id);
    }

    data = &gl_mem->tex_id;
  } else {                      /* not GL */
    if ((flags & GST_MAP_READ) == GST_MAP_READ) {
      GST_CAT_TRACE (GST_CAT_GL_MEMORY,
          "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);
      }
    } else {
      GST_CAT_TRACE (GST_CAT_GL_MEMORY,
          "mapping GL texture:%u for writing to system memory", gl_mem->tex_id);
    }

    data = gl_mem->data;
  }

  gl_mem->map_flags = flags;

  return data;
}

static void
_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;
}

static void
_gl_mem_copy_thread (GstGLContext * context, gpointer data)
{
  const GstGLFuncs *gl;
  GstGLMemoryCopyParams *copy_params;
  GstGLMemory *src;
  guint tex_id;
  GLuint fboId;
  gsize out_width, out_height, out_stride;
  GLuint out_gl_format, out_gl_type;
  GLuint in_gl_format, in_gl_type;
  gsize in_size, out_size;

  copy_params = (GstGLMemoryCopyParams *) data;
  src = copy_params->src;
  tex_id = copy_params->tex_id;
  out_width = copy_params->out_width;
  out_height = copy_params->out_height;
  out_stride = copy_params->out_stride;

  gl = src->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)
    out_gl_type = GL_UNSIGNED_SHORT_5_6_5;
  in_gl_format = _gst_gl_format_from_gl_texture_type (src->tex_type);
  in_gl_type = GL_UNSIGNED_BYTE;
  if (src->tex_type == GST_VIDEO_GL_TEXTURE_TYPE_RGB16)
    in_gl_type = GL_UNSIGNED_SHORT_5_6_5;

  if (!gl->GenFramebuffers) {
    gst_gl_context_set_error (src->context,
        "Context, EXT_framebuffer_object not supported");
    goto error;
  }

  in_size = src->height * src->stride;
  out_size = out_height * out_stride;

  if (copy_params->respecify) {
    if (in_size != out_size) {
      GST_ERROR ("Cannot copy between textures with backing data of different"
          "sizes. input %" G_GSIZE_FORMAT " output %" G_GSIZE_FORMAT, in_size,
          out_size);
      goto error;
    }
  }

  if (!tex_id) {
    GenTexture data = { 0, };
    data.width = copy_params->out_width;
    data.height = copy_params->out_height;
    data.gl_format = out_gl_format;
    data.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;

    _generate_texture (context, &data);
    tex_id = data.result;
  }

  if (!tex_id) {
    GST_CAT_WARNING (GST_CAT_GL_MEMORY,
        "Could not create GL texture with context:%p", src->context);
  }

  GST_CAT_LOG (GST_CAT_GL_MEMORY, "copying memory %p, tex %u into texture %i",
      src, src->tex_id, tex_id);

  /* FIXME: try and avoid creating and destroying fbo's every copy... */
  /* create a framebuffer object */
  gl->GenFramebuffers (1, &fboId);
  gl->BindFramebuffer (GL_FRAMEBUFFER, fboId);

  gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
      GL_TEXTURE_2D, src->tex_id, 0);

//  if (!gst_gl_context_check_framebuffer_status (src->context))
//    goto fbo_error;

  gl->BindTexture (GL_TEXTURE_2D, tex_id);
  if (copy_params->respecify) {
    if (!gl->GenBuffers) {
      gst_gl_context_set_error (context, "Cannot reinterpret texture contents "
          "without buffer objects");
      gl->BindTexture (GL_TEXTURE_2D, 0);
      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->width,
        src->height);

    /* copy tex */
    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, src->pbo);
    gl->BufferData (GL_PIXEL_PACK_BUFFER, in_size, NULL, GL_STREAM_COPY);
    gl->ReadPixels (0, 0, src->width, src->height, in_gl_format, in_gl_type, 0);
    gl->BindBuffer (GL_PIXEL_PACK_BUFFER, 0);

    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, src->pbo);
    gl->TexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, out_width, out_height,
        out_gl_format, out_gl_type, 0);

    gl->BindBuffer (GL_PIXEL_UNPACK_BUFFER, 0);
  } else {                      /* different sizes */
    gl->CopyTexImage2D (GL_TEXTURE_2D, 0, out_gl_format, 0, 0, out_width,
        out_height, 0);
  }

  gl->BindTexture (GL_TEXTURE_2D, 0);
  gl->BindFramebuffer (GL_FRAMEBUFFER, 0);

  gl->DeleteFramebuffers (1, &fboId);

  copy_params->tex_id = tex_id;
  copy_params->result = TRUE;

  return;

/* ERRORS */
fbo_error:
  {
    gl->DeleteFramebuffers (1, &fboId);

    copy_params->tex_id = 0;
    copy_params->result = FALSE;
    return;
  }

error:
  {
    copy_params->result = FALSE;
    return;
  }
}

static GstMemory *
_gl_mem_copy (GstGLMemory * src, gssize offset, gssize size)
{
  GstGLMemory *dest;

  if (GST_GL_MEMORY_FLAG_IS_SET (src, GST_GL_MEMORY_FLAG_NEED_UPLOAD)) {
    dest = _gl_mem_new (src->mem.allocator, NULL, src->context, src->tex_type,
        src->width, src->height, src->stride, NULL, NULL);
    dest->data = g_malloc (src->mem.maxsize);
    memcpy (dest->data, src->data, src->mem.maxsize);
    GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_UPLOAD);
  } else {
    GstGLMemoryCopyParams copy_params;

    copy_params.src = src;
    copy_params.tex_id = 0;
    copy_params.out_format = src->tex_type;
    copy_params.out_width = src->width;
    copy_params.out_height = src->height;
    copy_params.out_stride = src->height;
    copy_params.respecify = FALSE;

    gst_gl_context_thread_add (src->context, _gl_mem_copy_thread, &copy_params);

    dest = g_slice_new0 (GstGLMemory);
    _gl_mem_init (dest, src->mem.allocator, NULL, src->context, src->tex_type,
        src->width, src->height, src->stride, NULL, NULL);

    if (!copy_params.result) {
      GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory");
      gst_memory_unref ((GstMemory *) dest);
      return NULL;
    }

    dest->tex_id = copy_params.tex_id;
    dest->data = g_malloc (src->mem.maxsize);
    if (dest->data == NULL) {
      GST_CAT_WARNING (GST_CAT_GL_MEMORY, "Could not copy GL Memory");
      gst_memory_unref ((GstMemory *) dest);
      return NULL;
    }
    GST_GL_MEMORY_FLAG_SET (dest, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);
  }

  return (GstMemory *) dest;
}

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)
{
  g_warning ("use gst_gl_memory_alloc () to allocate from this "
      "GstGLMemory allocator");

  return NULL;
}

static void
_destroy_gl_objects (GstGLContext * context, GstGLMemory * gl_mem)
{
  const GstGLFuncs *gl = 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);
}

static void
_gl_mem_free (GstAllocator * allocator, GstMemory * mem)
{
  GstGLMemory *gl_mem = (GstGLMemory *) mem;

  gst_gl_context_thread_add (gl_mem->context,
      (GstGLContextThreadFunc) _destroy_gl_objects, gl_mem);

  if (gl_mem->notify)
    gl_mem->notify (gl_mem->user_data);

  if (gl_mem->data && !gl_mem->data_wrapped) {
    g_free (gl_mem->data);
    gl_mem->data = NULL;
  }

  gst_object_unref (gl_mem->context);
  g_slice_free (GstGLMemory, gl_mem);
}

/**
 * gst_gl_memory_copy_into_texture:
 * @gl_mem:a #GstGLMemory
 * @tex_id:OpenGL texture id
 * @tex_type: a #GstVideoGLTextureType
 * @width: width of @tex_id
 * @height: height of @tex_id
 * @stride: stride of the backing texture data
 * @respecify: whether to copy the data or copy per texel
 *
 * Copies @gl_mem into the texture specfified by @tex_id.  The format of @tex_id
 * is specified by @tex_type, @width and @height.
 *
 * If @respecify is %TRUE, then the copy is performed in terms of the texture
 * data.  This is useful for splitting RGBA textures into RG or R textures or
 * vice versa. The requirement for this to succeed is that the backing texture
 * data must be the same size, i.e. say a RGBA8 texture is converted into a RG8
 * texture, then the RG texture must have twice as many pixels available for
 * output as the RGBA texture.
 *
 * Otherwise, if @respecify is %FALSE, then the copy is performed per texel
 * using glCopyTexImage.  See the OpenGL specification for details on the
 * mappings between texture formats.
 *
 * Returns: Whether the copy suceeded
 */
gboolean
gst_gl_memory_copy_into_texture (GstGLMemory * gl_mem, guint tex_id,
    GstVideoGLTextureType tex_type, gint width, gint height, gint stride,
    gboolean respecify)
{
  GstGLMemoryCopyParams copy_params;

  copy_params.src = gl_mem;
  copy_params.tex_id = tex_id;
  copy_params.out_format = tex_type;
  copy_params.out_width = width;
  copy_params.out_height = height;
  copy_params.out_stride = stride;
  copy_params.respecify = respecify;

  gst_gl_context_thread_add (gl_mem->context, _gl_mem_copy_thread,
      &copy_params);

  return copy_params.result;
}

GstGLMemory *
gst_gl_memory_wrapped_texture (GstGLContext * context, guint texture_id,
    GstVideoGLTextureType tex_type, gint width, gint height, gpointer user_data,
    GDestroyNotify notify)
{
  GstGLMemory *mem;
  guint n_gl_bytes = _gl_texture_type_n_bytes (tex_type);

  mem = g_slice_new0 (GstGLMemory);
  _gl_mem_init (mem, _gl_allocator, NULL, context, tex_type, width, height,
      width * n_gl_bytes, NULL, NULL);

  mem->tex_id = texture_id;
  mem->texture_wrapped = TRUE;
  mem->data = g_malloc (mem->mem.maxsize);
  if (mem->data == NULL) {
    gst_memory_unref ((GstMemory *) mem);
    return NULL;
  }

  GST_GL_MEMORY_FLAG_SET (mem, GST_GL_MEMORY_FLAG_NEED_DOWNLOAD);

  return mem;
}

/**
 * gst_gl_memory_alloc:
 * @context:a #GstGLContext
 * @v_info: the #GstVideoInfo of the memory
 *
 * Returns: a #GstMemory object with a GL texture specified by @v_info
 *          from @context
 */
GstMemory *
gst_gl_memory_alloc (GstGLContext * context, GstVideoGLTextureType tex_type,
    gint width, gint height, gint stride)
{
  GstGLMemory *mem;

  mem = _gl_mem_new (_gl_allocator, NULL, context, tex_type, width, height,
      stride, 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
 * @context:a #GstGLContext
 * @v_info: the #GstVideoInfo of the memory and data
 * @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 #GstGLMemory object with a GL texture specified by @v_info
 *          from @context and contents specified by @data
 */
GstGLMemory *
gst_gl_memory_wrapped (GstGLContext * context, GstVideoGLTextureType tex_type,
    gint width, gint height, gint stride, gpointer data, gpointer user_data,
    GDestroyNotify notify)
{
  GstGLMemory *mem;

  mem = _gl_mem_new (_gl_allocator, NULL, context, tex_type, width, height,
      stride, user_data, notify);

  mem->data = data;
  mem->data_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);

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);

  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_gl_memory_init:
 *
 * Initializes the GL Memory allocator. It is safe to call this function
 * multiple times.  This must be called before any other GstGLMemory operation.
 */
void
gst_gl_memory_init (void)
{
  static volatile gsize _init = 0;

  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);

    gst_allocator_register (GST_GL_MEMORY_ALLOCATOR,
        gst_object_ref (_gl_allocator));
    g_once_init_leave (&_init, 1);
  }
}

/**
 * gst_is_gl_memory:
 * @mem:a #GstMemory
 * 
 * Returns: whether the memory at @mem is a #GstGLMemory
 */
gboolean
gst_is_gl_memory (GstMemory * mem)
{
  return mem != NULL && mem->allocator == _gl_allocator;
}

/**
 * gst_gl_memory_setup_buffer:
 * @context: a #GstGLContext
 * @info: a #GstVideoInfo
 * @buffer: a #GstBuffer
 *
 * Adds the required #GstGLMemory<!--  -->s with the correct configuration to
 * @buffer based on @info.
 *
 * Returns: whether the memory's were sucessfully added.
 */
gboolean
gst_gl_memory_setup_buffer (GstGLContext * context, GstVideoInfo * info,
    GstBuffer * buffer)
{
  GstGLMemory *gl_mem[GST_VIDEO_MAX_PLANES] = { NULL, };
  GstVideoGLTextureType tex_type;
  guint n_mem, i;

  n_mem = GST_VIDEO_INFO_N_PLANES (info);

  for (i = 0; i < n_mem; i++) {
    tex_type =
        gst_gl_texture_type_from_format (GST_VIDEO_INFO_FORMAT (info), i);
    gl_mem[i] =
        (GstGLMemory *) gst_gl_memory_alloc (context, tex_type,
        _get_plane_width (info, i), _get_plane_height (info, i),
        GST_VIDEO_INFO_PLANE_STRIDE (info, i));

    gst_buffer_append_memory (buffer, (GstMemory *) gl_mem[i]);
  }

  gst_buffer_add_video_meta_full (buffer, 0,
      GST_VIDEO_INFO_FORMAT (info), GST_VIDEO_INFO_WIDTH (info),
      GST_VIDEO_INFO_HEIGHT (info), n_mem, info->offset, info->stride);

  return TRUE;
}

/**
 * gst_gl_memory_setup_wrapped:
 * @context: a #GstGLContext
 * @info: a #GstVideoInfo
 * @data: a list of per plane data pointers
 * @textures: (transfer out): a list of #GstGLMemory
 *
 * Wraps per plane data pointer in @data into the corresponding entry in
 * @textures based on @info.
 *
 * Returns: whether the memory's were sucessfully created.
 */
gboolean
gst_gl_memory_setup_wrapped (GstGLContext * context, GstVideoInfo * info,
    gpointer data[GST_VIDEO_MAX_PLANES],
    GstGLMemory * textures[GST_VIDEO_MAX_PLANES])
{
  GstVideoGLTextureType tex_type;
  gint i;

  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (info); i++) {
    tex_type =
        gst_gl_texture_type_from_format (GST_VIDEO_INFO_FORMAT (info), i);

    textures[i] = (GstGLMemory *) gst_gl_memory_wrapped (context, tex_type,
        _get_plane_width (info, i), _get_plane_height (info, i),
        GST_VIDEO_INFO_PLANE_STRIDE (info, i), data[i], NULL, NULL);
  }

  return TRUE;
}
