/*
 * GStreamer
 * Copyright (C) 2012-2014 Matthew Waters <ystree00@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 <stdio.h>

#include "gl.h"
#include "gstglupload.h"

#if GST_GL_HAVE_PLATFORM_EGL
#include "egl/gsteglimagememory.h"
#endif

/**
 * SECTION:gstglupload
 * @short_description: an object that uploads to GL textures
 * @see_also: #GstGLDownload, #GstGLMemory
 *
 * #GstGLUpload is an object that uploads data from system memory into GL textures.
 *
 * A #GstGLUpload can be created with gst_gl_upload_new()
 */

#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))
#define USING_GLES2(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 2, 0))
#define USING_GLES3(context) (gst_gl_context_check_gl_version (context, GST_GL_API_GLES2, 3, 0))

static gboolean _upload_memory (GstGLUpload * upload);
static gboolean _init_upload (GstGLUpload * upload);
static gboolean _gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload,
    GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES]);
static void _do_upload_with_meta (GstGLContext * context, GstGLUpload * upload);
static void gst_gl_upload_reset (GstGLUpload * upload);

struct _GstGLUploadPrivate
{
  gboolean result;
  guint tex_id;

  gboolean mapped;
  GstVideoFrame frame;

  GstVideoGLTextureUploadMeta *meta;

  GstBuffer *outbuf;
  gboolean released;
};

GST_DEBUG_CATEGORY_STATIC (gst_gl_upload_debug);
#define GST_CAT_DEFAULT gst_gl_upload_debug

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_upload_debug, "glupload", 0, "upload");

G_DEFINE_TYPE_WITH_CODE (GstGLUpload, gst_gl_upload, GST_TYPE_OBJECT,
    DEBUG_INIT);
static void gst_gl_upload_finalize (GObject * object);

#define GST_GL_UPLOAD_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
    GST_TYPE_GL_UPLOAD, GstGLUploadPrivate))

static void
gst_gl_upload_class_init (GstGLUploadClass * klass)
{
  g_type_class_add_private (klass, sizeof (GstGLUploadPrivate));

  G_OBJECT_CLASS (klass)->finalize = gst_gl_upload_finalize;
}

static void
gst_gl_upload_init (GstGLUpload * upload)
{
  upload->priv = GST_GL_UPLOAD_GET_PRIVATE (upload);

  upload->context = NULL;
  upload->priv->tex_id = 0;

  gst_video_info_set_format (&upload->in_info, GST_VIDEO_FORMAT_ENCODED, 0, 0);
}

/**
 * gst_gl_upload_new:
 * @context: a #GstGLContext
 *
 * Returns: a new #GstGLUpload object
 */
GstGLUpload *
gst_gl_upload_new (GstGLContext * context)
{
  GstGLUpload *upload;

  upload = g_object_new (GST_TYPE_GL_UPLOAD, NULL);

  upload->context = gst_object_ref (context);
  upload->convert = gst_gl_color_convert_new (context);

  return upload;
}

static void
gst_gl_upload_finalize (GObject * object)
{
  GstGLUpload *upload;

  upload = GST_GL_UPLOAD (object);

  gst_gl_upload_reset (upload);

  if (upload->context) {
    gst_object_unref (upload->context);
    upload->context = NULL;
  }

  G_OBJECT_CLASS (gst_gl_upload_parent_class)->finalize (object);
}

static void
gst_gl_upload_reset (GstGLUpload * upload)
{
  guint i;

  if (upload->priv->tex_id) {
    gst_gl_context_del_texture (upload->context, &upload->priv->tex_id);
    upload->priv->tex_id = 0;
  }

  if (upload->convert) {
    gst_object_unref (upload->convert);
    upload->convert = NULL;
  }

  if (upload->out_tex) {
    gst_memory_unref ((GstMemory *) upload->out_tex);
    upload->out_tex = NULL;
  }

  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
    if (upload->in_tex[i]) {
      gst_memory_unref ((GstMemory *) upload->in_tex[i]);
      upload->in_tex[i] = NULL;
    }
  }

  gst_gl_upload_release_buffer (upload);
}

static void
_gst_gl_upload_set_format_unlocked (GstGLUpload * upload,
    GstVideoInfo * in_info)
{
  g_return_if_fail (upload != NULL);
  g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) !=
      GST_VIDEO_FORMAT_UNKNOWN);
  g_return_if_fail (GST_VIDEO_INFO_FORMAT (in_info) !=
      GST_VIDEO_FORMAT_ENCODED);

  if (gst_video_info_is_equal (&upload->in_info, in_info))
    return;

  gst_gl_upload_reset (upload);
  upload->convert = gst_gl_color_convert_new (upload->context);
  upload->in_info = *in_info;
  upload->initted = FALSE;
}

/**
 * gst_gl_upload_set_format:
 * @upload: a #GstGLUpload
 * @in_info: input #GstVideoInfo
 *
 * Initializes @upload with the information required for upload.
 */
void
gst_gl_upload_set_format (GstGLUpload * upload, GstVideoInfo * in_info)
{
  GST_OBJECT_LOCK (upload);
  _gst_gl_upload_set_format_unlocked (upload, in_info);
  GST_OBJECT_UNLOCK (upload);
}

/**
 * gst_gl_upload_get_format:
 * @upload: a #GstGLUpload
 *
 * Returns: (transfer none): The #GstVideoInfo set by gst_gl_upload_set_format()
 */
GstVideoInfo *
gst_gl_upload_get_format (GstGLUpload * upload)
{
  GstVideoInfo *ret;

  GST_OBJECT_LOCK (upload);
  ret = &upload->in_info;
  GST_OBJECT_UNLOCK (upload);

  return ret;
}

/**
 * gst_gl_upload_perform_with_buffer:
 * @upload: a #GstGLUpload
 * @buffer: a #GstBuffer
 * @tex_id: resulting texture
 *
 * Uploads @buffer to the texture given by @tex_id.  @tex_id is valid
 * until gst_gl_upload_release_buffer() is called.
 *
 * Returns: whether the upload was successful
 */
gboolean
gst_gl_upload_perform_with_buffer (GstGLUpload * upload, GstBuffer * buffer,
    guint * tex_id)
{
  GstMemory *mem;
  GstVideoGLTextureUploadMeta *gl_tex_upload_meta;
  guint texture_ids[] = { 0, 0, 0, 0 };
  gint i;
  gboolean ret;

  g_return_val_if_fail (upload != NULL, FALSE);
  g_return_val_if_fail (buffer != NULL, FALSE);
  g_return_val_if_fail (tex_id != NULL, FALSE);
  g_return_val_if_fail (gst_buffer_n_memory (buffer) > 0, FALSE);

  gst_gl_upload_release_buffer (upload);

  /* GstGLMemory */
  mem = gst_buffer_peek_memory (buffer, 0);

  if (gst_is_gl_memory (mem)) {
    GstGLMemory *gl_mem = (GstGLMemory *) gst_buffer_peek_memory (buffer, 0);

    if (!gst_gl_context_can_share (upload->context, gl_mem->context))
      goto raw_data_upload;

    if (GST_VIDEO_INFO_FORMAT (&upload->in_info) == GST_VIDEO_FORMAT_RGBA) {
      GstMapInfo map_info;

      gst_memory_map (mem, &map_info, GST_MAP_READ | GST_MAP_GL);
      gst_memory_unmap (mem, &map_info);

      *tex_id = ((GstGLMemory *) mem)->tex_id;
      return TRUE;
    }

    GST_LOG_OBJECT (upload, "Attempting upload with GstGLMemory");
    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) {
      upload->in_tex[i] = (GstGLMemory *) gst_buffer_peek_memory (buffer, i);
    }

    ret = _upload_memory (upload);

    *tex_id = upload->out_tex->tex_id;
    for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) {
      upload->in_tex[i] = NULL;
    }
    return ret;
  }
#if GST_GL_HAVE_PLATFORM_EGL
  if (!upload->priv->tex_id && gst_is_egl_image_memory (mem))
    gst_gl_context_gen_texture (upload->context, &upload->priv->tex_id,
        GST_VIDEO_FORMAT_RGBA, 0, 0);
#endif

  if (!upload->priv->tex_id)
    gst_gl_context_gen_texture (upload->context, &upload->priv->tex_id,
        GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH (&upload->in_info),
        GST_VIDEO_INFO_HEIGHT (&upload->in_info));

  /* GstVideoGLTextureUploadMeta */
  gl_tex_upload_meta = gst_buffer_get_video_gl_texture_upload_meta (buffer);
  if (gl_tex_upload_meta) {
    GST_LOG_OBJECT (upload, "Attempting upload with "
        "GstVideoGLTextureUploadMeta");
    texture_ids[0] = upload->priv->tex_id;

    if (!gst_gl_upload_perform_with_gl_texture_upload_meta (upload,
            gl_tex_upload_meta, texture_ids)) {
      GST_DEBUG_OBJECT (upload, "Upload with GstVideoGLTextureUploadMeta "
          "failed");
    } else {
      upload->priv->mapped = FALSE;
      *tex_id = upload->priv->tex_id;
      return TRUE;
    }
  }

raw_data_upload:
  GST_LOG_OBJECT (upload, "Attempting upload with raw data");
  /* GstVideoMeta map */
  if (!gst_video_frame_map (&upload->priv->frame, &upload->in_info, buffer,
          GST_MAP_READ)) {
    GST_ERROR_OBJECT (upload, "Failed to map memory");
    return FALSE;
  }
  upload->priv->mapped = TRUE;

  /* update the video info from the one updated by frame_map using video meta */
  gst_gl_upload_set_format (upload, &upload->priv->frame.info);

  if (!gst_gl_upload_perform_with_data (upload, tex_id,
          upload->priv->frame.data)) {
    return FALSE;
  }

  return TRUE;
}

void
gst_gl_upload_release_buffer (GstGLUpload * upload)
{
  g_return_if_fail (upload != NULL);

  if (upload->priv->mapped)
    gst_video_frame_unmap (&upload->priv->frame);
  upload->priv->mapped = FALSE;

  if (upload->priv->outbuf) {
    gst_buffer_unref (upload->priv->outbuf);
    upload->priv->outbuf = NULL;
  }

  upload->priv->released = TRUE;
}

/*
 * Uploads using gst_video_gl_texture_upload_meta_upload().
 * i.e. consumer of GstVideoGLTextureUploadMeta
 */
static void
_do_upload_with_meta (GstGLContext * context, GstGLUpload * upload)
{
  guint texture_ids[] = { upload->priv->tex_id, 0, 0, 0 };

  if (!gst_video_gl_texture_upload_meta_upload (upload->priv->meta,
          texture_ids))
    goto error;

  upload->priv->result = TRUE;
  return;

error:
  upload->priv->result = FALSE;
}

/**
 * gst_gl_upload_perform_with_gl_texture_upload_meta:
 * @upload: a #GstGLUpload
 * @meta: a #GstVideoGLTextureUploadMeta
 * @texture_id: resulting GL textures to place the data into.
 *
 * Uploads @meta into @texture_id.
 *
 * Returns: whether the upload was successful
 */
gboolean
gst_gl_upload_perform_with_gl_texture_upload_meta (GstGLUpload * upload,
    GstVideoGLTextureUploadMeta * meta, guint texture_id[4])
{
  gboolean ret;

  g_return_val_if_fail (upload != NULL, FALSE);
  g_return_val_if_fail (meta != NULL, FALSE);

  if (meta->texture_orientation !=
      GST_VIDEO_GL_TEXTURE_ORIENTATION_X_NORMAL_Y_NORMAL)
    GST_FIXME_OBJECT (upload, "only x-normal,y-normal textures supported, "
        "the images will not appear the right way up");
  if (meta->texture_type[0] != GST_VIDEO_GL_TEXTURE_TYPE_RGBA) {
    GST_FIXME_OBJECT (upload, "only single rgba texture supported");
    return FALSE;
  }

  GST_OBJECT_LOCK (upload);

  upload->priv->meta = meta;
  if (!upload->priv->tex_id)
    gst_gl_context_gen_texture (upload->context, &upload->priv->tex_id,
        GST_VIDEO_FORMAT_RGBA, GST_VIDEO_INFO_WIDTH (&upload->in_info),
        GST_VIDEO_INFO_HEIGHT (&upload->in_info));

  GST_LOG ("Uploading with GLTextureUploadMeta with textures %i,%i,%i,%i",
      texture_id[0], texture_id[1], texture_id[2], texture_id[3]);

  gst_gl_context_thread_add (upload->context,
      (GstGLContextThreadFunc) _do_upload_with_meta, upload);

  ret = upload->priv->result;

  GST_OBJECT_UNLOCK (upload);

  return ret;
}

/**
 * gst_gl_upload_perform_with_data:
 * @upload: a #GstGLUpload
 * @texture_id: (out): the texture id to upload into
 * @data: where the downloaded data should go
 *
 * Uploads @data into @texture_id. data size and format is specified by
 * the #GstVideoInfo<!--  -->s passed to gst_gl_upload_set_format() 
 *
 * Returns: whether the upload was successful
 */
gboolean
gst_gl_upload_perform_with_data (GstGLUpload * upload, GLuint * texture_id,
    gpointer data[GST_VIDEO_MAX_PLANES])
{
  gboolean ret;

  g_return_val_if_fail (upload != NULL, FALSE);

  GST_OBJECT_LOCK (upload);
  ret = _gst_gl_upload_perform_with_data_unlocked (upload, texture_id, data);
  GST_OBJECT_UNLOCK (upload);

  return ret;
}

static gboolean
_gst_gl_upload_perform_with_data_unlocked (GstGLUpload * upload,
    GLuint * texture_id, gpointer data[GST_VIDEO_MAX_PLANES])
{
  gboolean ret;
  guint i;

  g_return_val_if_fail (upload != NULL, FALSE);
  g_return_val_if_fail (texture_id != NULL, FALSE);

  if (!upload->in_tex[0])
    gst_gl_memory_setup_wrapped (upload->context, &upload->in_info, data,
        upload->in_tex);

  for (i = 0; i < GST_VIDEO_MAX_PLANES; i++) {
    if (upload->in_tex[i]) {
      upload->in_tex[i]->data = data[i];
      GST_GL_MEMORY_FLAG_SET (upload->in_tex[i],
          GST_GL_MEMORY_FLAG_NEED_UPLOAD);
    }
  }

  ret = _upload_memory (upload);
  *texture_id = upload->out_tex->tex_id;

  return ret;
}

/* Called in the gl thread */
static gboolean
_init_upload (GstGLUpload * upload)
{
  GstGLFuncs *gl;
  GstVideoFormat v_format;
  GstVideoInfo out_info;

  gl = upload->context->gl_vtable;

  v_format = GST_VIDEO_INFO_FORMAT (&upload->in_info);

  GST_INFO ("Initializing texture upload for format:%s",
      gst_video_format_to_string (v_format));

  if (!gl->CreateProgramObject && !gl->CreateProgram) {
    gst_gl_context_set_error (upload->context,
        "Cannot upload YUV formats without OpenGL shaders");
    goto error;
  }

  gst_video_info_set_format (&out_info, GST_VIDEO_FORMAT_RGBA,
      GST_VIDEO_INFO_WIDTH (&upload->in_info),
      GST_VIDEO_INFO_HEIGHT (&upload->in_info));

  gst_gl_color_convert_set_format (upload->convert, &upload->in_info,
      &out_info);

  upload->out_tex = gst_gl_memory_wrapped_texture (upload->context, 0,
      GST_VIDEO_GL_TEXTURE_TYPE_RGBA, GST_VIDEO_INFO_WIDTH (&upload->in_info),
      GST_VIDEO_INFO_HEIGHT (&upload->in_info), NULL, NULL);

  upload->initted = TRUE;

  return TRUE;

error:
  return FALSE;
}

static gboolean
_upload_memory (GstGLUpload * upload)
{
  guint in_width, in_height;
  guint in_texture[GST_VIDEO_MAX_PLANES];
  GstBuffer *inbuf;
  GstVideoFrame out_frame;
  GstVideoInfo out_info;
  gint i;

  in_width = GST_VIDEO_INFO_WIDTH (&upload->in_info);
  in_height = GST_VIDEO_INFO_HEIGHT (&upload->in_info);

  if (!upload->initted) {
    if (!_init_upload (upload)) {
      return FALSE;
    }
  }

  inbuf = gst_buffer_new ();
  for (i = 0; i < GST_VIDEO_INFO_N_PLANES (&upload->in_info); i++) {
    in_texture[i] = upload->in_tex[i]->tex_id;
    gst_buffer_append_memory (inbuf,
        gst_memory_ref ((GstMemory *) upload->in_tex[i]));
  }

  GST_TRACE ("uploading with textures:%u,%u,%u dimensions:%ux%u",
      in_texture[0], in_texture[1], in_texture[2], in_width, in_height);

  upload->priv->outbuf = gst_gl_color_convert_perform (upload->convert, inbuf);
  gst_buffer_unref (inbuf);

  gst_video_info_set_format (&out_info, GST_VIDEO_FORMAT_RGBA, in_width,
      in_height);
  if (!gst_video_frame_map (&out_frame, &out_info, upload->priv->outbuf,
          GST_MAP_READ | GST_MAP_GL)) {
    gst_buffer_unref (upload->priv->outbuf);
    upload->priv->outbuf = NULL;
    return FALSE;
  }

  upload->out_tex->tex_id = *(guint *) out_frame.data[0];

  gst_video_frame_unmap (&out_frame);
  upload->priv->released = FALSE;

  return TRUE;
}
