/*
 * GStreamer
 * Copyright (C) 2009 Julien Isorce <julien.isorce@mail.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.
 */

/**
 * SECTION:element-deinterlace
 *
 * Deinterlacing using based on fragment shaders.
 *
 * <refsect2>
 * <title>Examples</title>
 * |[
 * gst-launch videotestsrc ! glupload ! gldeinterlace ! glimagesink
 * ]|
 * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
 * </refsect2>
 */

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

#include "gstgldeinterlace.h"

#define GST_CAT_DEFAULT gst_gl_deinterlace_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0
};

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_deinterlace_debug, "gldeinterlace", 0, "gldeinterlace element");
#define gst_gl_deinterlace_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstGLDeinterlace, gst_gl_deinterlace,
    GST_TYPE_GL_FILTER, DEBUG_INIT);

static void gst_gl_deinterlace_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_gl_deinterlace_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_gl_deinterlace_reset (GstBaseTransform * trans);
static gboolean gst_gl_deinterlace_init_shader (GstGLFilter * filter);
static gboolean gst_gl_deinterlace_filter (GstGLFilter * filter,
    GstBuffer * inbuf, GstBuffer * outbuf);
static gboolean gst_gl_deinterlace_filter_texture (GstGLFilter * filter,
    guint in_tex, guint out_tex);
static void gst_gl_deinterlace_callback (gint width, gint height,
    guint texture, gpointer stuff);

/* *INDENT-OFF* */
static const gchar *greedyh_fragment_source =
  "uniform sampler2D tex;\n"
  "uniform sampler2D tex_prev;\n"
  "uniform float max_comb;\n"
  "uniform float motion_threshold;\n"
  "uniform float motion_sense;\n"
  "uniform float width;\n"
  "uniform float height;\n"

  "void main () {\n"
  "  vec2 texcoord = gl_TexCoord[0].xy;\n"
  "  if (int(mod(texcoord.y * height, 2.0)) == 0) {\n"
  "    gl_FragColor = vec4(texture2D(tex_prev, texcoord).rgb, 1.0);\n"
  "  } else {\n"
  "    vec2 texcoord_L1_a1, texcoord_L3_a1, texcoord_L1, texcoord_L3, texcoord_L1_1, texcoord_L3_1;\n"
  "    vec3 L1_a1, L3_a1, L1, L3, L1_1, L3_1;\n"

  "    texcoord_L1 = vec2(texcoord.x, texcoord.y - 1.0 / height);\n"
  "    texcoord_L3 = vec2(texcoord.x, texcoord.y + 1.0 / height);\n"
  "    L1 = texture2D(tex_prev, texcoord_L1).rgb;\n"
  "    L3 = texture2D(tex_prev, texcoord_L3).rgb;\n"
  "    if (texcoord.x == 1.0 && texcoord.y == 1.0) {\n"
  "      L1_1 = L1;\n"
  "      L3_1 = L3;\n"
  "    } else {\n"
  "      texcoord_L1_1 = vec2(texcoord.x + 1.0 / width, texcoord.y - 1.0 / height);\n"
  "      texcoord_L3_1 = vec2(texcoord.x + 1.0 / width, texcoord.y + 1.0 / height);\n"
  "      L1_1 = texture2D(tex_prev, texcoord_L1_1).rgb;\n"
  "      L3_1 = texture2D(tex_prev, texcoord_L3_1).rgb;\n"
  "    }\n"

  "    if (int(ceil(texcoord.x + texcoord.y)) == 0) {\n"
  "      L1_a1 = L1;\n"
  "      L3_a1 = L3;\n"
  "    } else {\n"
  "      texcoord_L1_a1 = vec2(texcoord.x - 1.0 / width, texcoord.y - 1.0 / height);\n"
  "      texcoord_L3_a1 = vec2(texcoord.x - 1.0 / width, texcoord.y + 1.0 / height);\n"
  "      L1_a1 = texture2D(tex_prev, texcoord_L1_a1).rgb;\n"
  "      L3_a1 = texture2D(tex_prev, texcoord_L3_a1).rgb;\n"
  "    }\n"
          //STEP 1
  "    vec3 avg_a1 = (L1_a1 + L3_a1) / 2.0;\n"
  "    vec3 avg = (L1 + L3) / 2.0;\n"
  "    vec3 avg_1 = (L1_1 + L3_1) / 2.0;\n"
  "    vec3 avg_s = (avg_a1 + avg_1) / 2.0;\n"
  "    vec3 avg_sc = (avg_s + avg) / 2.0;\n"
  "    vec3 L2 = texture2D(tex, texcoord).rgb;\n"
  "    vec3 LP2 = texture2D(tex_prev, texcoord).rgb;\n"
  "    vec3 best;\n"
  "    if (abs(L2.r - avg_sc.r) < abs(LP2.r - avg_sc.r)) {\n"
  "      best.r = L2.r;\n" "    } else {\n"
  "      best.r = LP2.r;\n"
  "    }\n"

  "    if (abs(L2.g - avg_sc.g) < abs(LP2.g - avg_sc.g)) {\n"
  "      best.g = L2.g;\n"
  "    } else {\n"
  "      best.g = LP2.g;\n"
  "    }\n"

  "    if (abs(L2.b - avg_sc.b) < abs(LP2.b - avg_sc.b)) {\n"
  "      best.b = L2.b;\n"
  "    } else {\n"
  "      best.b = LP2.b;\n"
  "    }\n"
          //STEP 2
  "    vec3 last;\n"
  "    last.r = clamp(best.r, max(min(L1.r, L3.r) - max_comb, 0.0), min(max(L1.r, L3.r) + max_comb, 1.0));\n"
  "    last.g = clamp(best.g, max(min(L1.g, L3.g) - max_comb, 0.0), min(max(L1.g, L3.g) + max_comb, 1.0));\n"
  "    last.b = clamp(best.b, max(min(L1.b, L3.b) - max_comb, 0.0), min(max(L1.b, L3.b) + max_comb, 1.0));\n"
          //STEP 3
  "    const vec3 luma = vec3 (0.299011, 0.586987, 0.114001);"
  "    float mov = min(max(abs(dot(L2 - LP2, luma)) - motion_threshold, 0.0) * motion_sense, 1.0);\n"
  "    last = last * (1.0 - mov) + avg_sc * mov;\n"
  "    gl_FragColor = vec4(last, 1.0);\n"
  "  }\n"
  "}\n";
/* *INDENT-ON* */

static void
gst_gl_deinterlace_class_init (GstGLDeinterlaceClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

  gobject_class = (GObjectClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  gobject_class->set_property = gst_gl_deinterlace_set_property;
  gobject_class->get_property = gst_gl_deinterlace_get_property;

  gst_element_class_set_metadata (element_class,
      "OpenGL deinterlacing filter", "Deinterlace",
      "Deinterlacing based on fragment shaders",
      "Julien Isorce <julien.isorce@mail.com>");

  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_deinterlace_reset;

  GST_GL_FILTER_CLASS (klass)->filter = gst_gl_deinterlace_filter;
  GST_GL_FILTER_CLASS (klass)->filter_texture =
      gst_gl_deinterlace_filter_texture;
  GST_GL_FILTER_CLASS (klass)->init_fbo = gst_gl_deinterlace_init_shader;

  GST_GL_BASE_FILTER_CLASS (klass)->supported_gl_api = GST_GL_API_OPENGL;
}

static void
gst_gl_deinterlace_init (GstGLDeinterlace * filter)
{
  filter->shader = NULL;
  filter->prev_buffer = NULL;
  filter->prev_tex = 0;
}

static gboolean
gst_gl_deinterlace_reset (GstBaseTransform * trans)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (trans);

  gst_buffer_replace (&deinterlace_filter->prev_buffer, NULL);

  //blocking call, wait the opengl thread has destroyed the shader
  if (deinterlace_filter->shader)
    gst_gl_context_del_shader (GST_GL_BASE_FILTER (trans)->context,
        deinterlace_filter->shader);
  deinterlace_filter->shader = NULL;

  return GST_BASE_TRANSFORM_CLASS (parent_class)->stop (trans);
}

static void
gst_gl_deinterlace_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  //GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_deinterlace_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  //GstGLDeinterlace *filter = GST_GL_DEINTERLACE (object);

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static gboolean
gst_gl_deinterlace_init_shader (GstGLFilter * filter)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, wait the opengl thread has compiled the shader
  return gst_gl_context_gen_shader (GST_GL_BASE_FILTER (filter)->context, 0,
      greedyh_fragment_source, &deinterlace_filter->shader);
}

static gboolean
gst_gl_deinterlace_filter_texture (GstGLFilter * filter, guint in_tex,
    guint out_tex)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  //blocking call, use a FBO
  gst_gl_filter_render_to_target (filter, TRUE, in_tex, out_tex,
      gst_gl_deinterlace_callback, deinterlace_filter);

  return TRUE;
}

static gboolean
gst_gl_deinterlace_filter (GstGLFilter * filter, GstBuffer * inbuf,
    GstBuffer * outbuf)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (filter);

  gst_gl_filter_filter_texture (filter, inbuf, outbuf);

  gst_buffer_replace (&deinterlace_filter->prev_buffer, inbuf);

  return TRUE;
}

//opengl scene, params: input texture (not the output filter->texture)
static void
gst_gl_deinterlace_callback (gint width, gint height, guint texture,
    gpointer stuff)
{
  GstGLDeinterlace *deinterlace_filter = GST_GL_DEINTERLACE (stuff);
  GstGLFilter *filter = GST_GL_FILTER (stuff);
  GstGLFuncs *gl = GST_GL_BASE_FILTER (filter)->context->gl_vtable;
  guint temp;

  GLfloat verts[] = { -1.0, -1.0,
    1.0, -1.0,
    1.0, 1.0,
    -1.0, 1.0
  };
  GLfloat texcoords0[] = { 0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
  };
  GLfloat texcoords1[] = { 0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
  };

  gl->MatrixMode (GL_PROJECTION);
  gl->LoadIdentity ();

  gst_gl_shader_use (deinterlace_filter->shader);

  if (G_UNLIKELY (deinterlace_filter->prev_tex == 0)) {
    gst_gl_context_gen_texture (GST_GL_BASE_FILTER (filter)->context,
        &deinterlace_filter->prev_tex,
        GST_VIDEO_INFO_FORMAT (&filter->out_info),
        GST_VIDEO_INFO_WIDTH (&filter->out_info),
        GST_VIDEO_INFO_HEIGHT (&filter->out_info));
  } else {
    gl->ActiveTexture (GL_TEXTURE1);
    gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex_prev", 1);
    gl->BindTexture (GL_TEXTURE_2D, deinterlace_filter->prev_tex);
  }

  gl->ActiveTexture (GL_TEXTURE0);
  gst_gl_shader_set_uniform_1i (deinterlace_filter->shader, "tex", 0);

  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "max_comb",
      5.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_threshold",
      25.0f / 255.0f);
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "motion_sense",
      30.0f / 255.0f);

  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "width",
      GST_VIDEO_INFO_WIDTH (&filter->out_info));
  gst_gl_shader_set_uniform_1f (deinterlace_filter->shader, "height",
      GST_VIDEO_INFO_HEIGHT (&filter->out_info));

  gl->ClientActiveTexture (GL_TEXTURE0);

  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->EnableClientState (GL_VERTEX_ARRAY);

  gl->VertexPointer (2, GL_FLOAT, 0, &verts);
  gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords0);

  gl->ClientActiveTexture (GL_TEXTURE1);
  gl->EnableClientState (GL_TEXTURE_COORD_ARRAY);
  gl->TexCoordPointer (2, GL_FLOAT, 0, &texcoords1);

  gl->DrawArrays (GL_TRIANGLE_FAN, 0, 4);

  gl->DisableClientState (GL_VERTEX_ARRAY);
  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);

  gl->ClientActiveTexture (GL_TEXTURE0);
  gl->DisableClientState (GL_TEXTURE_COORD_ARRAY);

  if (texture == filter->in_tex_id) {
    temp = filter->in_tex_id;
    filter->in_tex_id = deinterlace_filter->prev_tex;
    deinterlace_filter->prev_tex = temp;
  } else {
    deinterlace_filter->prev_tex = texture;
  }
}
