/*
 * GStreamer
 * Copyright (C) 2009 Julien Isorce <julien.isorce@mail.com>
 * Copyright (C) 2014 Jan Schmidt <jan@centricular.com>
 * Copyright (C) 2015 Matthew Waters <matthew@centricular.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-glviewconvert
 * @title: glviewconvert
 *
 * Convert stereoscopic video between different representations using fragment shaders.
 *
 * The element can use either property settings or caps negotiation to choose the
 * input and output formats to process.
 *
 * ## Examples
 * |[
 * gst-launch-1.0 videotestsrc ! glupload ! glviewconvert ! glimagesink
 * ]| Simple placebo example demonstrating identity passthrough of mono video
 * |[
 * gst-launch-1.0 videotestsrc pattern=checkers-1 ! glupload ! \
 *     glviewconvert input-mode-override=side-by-side ! glimagesink -v
 * ]| Force re-interpretation of the input checkers pattern as a side-by-side stereoscopic
 *    image and display in glimagesink.
 * FBO (Frame Buffer Object) and GLSL (OpenGL Shading Language) are required.
 *
 */

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

#include <gst/base/gstbasetransform.h>
#include "gstglviewconvert.h"

#define GST_CAT_DEFAULT gst_gl_view_convert_element_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);

enum
{
  PROP_0,
  PROP_INPUT_LAYOUT,
  PROP_INPUT_FLAGS,
  PROP_OUTPUT_LAYOUT,
  PROP_OUTPUT_FLAGS,
  PROP_OUTPUT_DOWNMIX_MODE
};

#define DEFAULT_DOWNMIX GST_GL_STEREO_DOWNMIX_ANAGLYPH_GREEN_MAGENTA_DUBOIS

#define DEBUG_INIT \
  GST_DEBUG_CATEGORY_INIT (gst_gl_view_convert_element_debug, "glview_convertelement", 0, "glview_convert element");

G_DEFINE_TYPE_WITH_CODE (GstGLViewConvertElement, gst_gl_view_convert_element,
    GST_TYPE_GL_FILTER, DEBUG_INIT);
#define parent_class gst_gl_view_convert_element_parent_class

static void gst_gl_view_convert_dispose (GObject * object);
static void gst_gl_view_convert_element_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_gl_view_convert_element_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_gl_view_convert_element_stop (GstBaseTransform * bt);
static gboolean
gst_gl_view_convert_element_set_caps (GstGLFilter * filter, GstCaps * incaps,
    GstCaps * outcaps);
static GstCaps *gst_gl_view_convert_element_transform_internal_caps (GstGLFilter
    * filter, GstPadDirection direction, GstCaps * caps, GstCaps * filter_caps);
static GstCaps *gst_gl_view_convert_element_fixate_caps (GstBaseTransform *
    trans, GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static GstFlowReturn
gst_gl_view_convert_element_submit_input_buffer (GstBaseTransform * trans,
    gboolean is_discont, GstBuffer * input);
static GstFlowReturn
gst_gl_view_convert_element_generate_output_buffer (GstBaseTransform * bt,
    GstBuffer ** outbuf);

static void
gst_gl_view_convert_element_class_init (GstGLViewConvertElementClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *element_class;

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

  gobject_class->set_property = gst_gl_view_convert_element_set_property;
  gobject_class->get_property = gst_gl_view_convert_element_get_property;
  gobject_class->dispose = gst_gl_view_convert_dispose;

  gst_element_class_set_metadata (element_class,
      "OpenGL Multiview/3D conversion filter", "Filter",
      "Convert stereoscopic/multiview video formats",
      "Jan Schmidt <jan@centricular.com>\n"
      "Matthew Waters <matthew@centricular.com>");

  GST_GL_FILTER_CLASS (klass)->set_caps = gst_gl_view_convert_element_set_caps;

  GST_GL_FILTER_CLASS (klass)->transform_internal_caps =
      gst_gl_view_convert_element_transform_internal_caps;
  GST_BASE_TRANSFORM_CLASS (klass)->stop = gst_gl_view_convert_element_stop;
  GST_BASE_TRANSFORM_CLASS (klass)->fixate_caps =
      gst_gl_view_convert_element_fixate_caps;
  GST_BASE_TRANSFORM_CLASS (klass)->submit_input_buffer =
      gst_gl_view_convert_element_submit_input_buffer;
  GST_BASE_TRANSFORM_CLASS (klass)->generate_output =
      gst_gl_view_convert_element_generate_output_buffer;

  g_object_class_install_property (gobject_class, PROP_INPUT_LAYOUT,
      g_param_spec_enum ("input-mode-override",
          "Input Multiview Mode Override",
          "Override any input information about multiview layout",
          GST_TYPE_VIDEO_MULTIVIEW_FRAME_PACKING,
          GST_VIDEO_MULTIVIEW_MODE_NONE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_INPUT_FLAGS,
      g_param_spec_flags ("input-flags-override",
          "Input Multiview Flags Override",
          "Override any input information about multiview layout flags",
          GST_TYPE_VIDEO_MULTIVIEW_FLAGS, GST_VIDEO_MULTIVIEW_FLAGS_NONE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OUTPUT_LAYOUT,
      g_param_spec_enum ("output-mode-override",
          "Output Multiview Mode Override",
          "Override automatic output mode selection for multiview layout",
          GST_TYPE_VIDEO_MULTIVIEW_MODE, GST_VIDEO_MULTIVIEW_MODE_NONE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OUTPUT_FLAGS,
      g_param_spec_flags ("output-flags-override",
          "Output Multiview Flags Override",
          "Override automatic negotiation for output multiview layout flags",
          GST_TYPE_VIDEO_MULTIVIEW_FLAGS, GST_VIDEO_MULTIVIEW_FLAGS_NONE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_OUTPUT_DOWNMIX_MODE,
      g_param_spec_enum ("downmix-mode", "Mode for mono downmixed output",
          "Output anaglyph type to generate when downmixing to mono",
          GST_TYPE_GL_STEREO_DOWNMIX_MODE_TYPE, DEFAULT_DOWNMIX,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
}

static void
gst_gl_view_convert_element_init (GstGLViewConvertElement * convert)
{
  convert->viewconvert = gst_gl_view_convert_new ();
}

static void
gst_gl_view_convert_dispose (GObject * object)
{
  GstGLViewConvertElement *convert = GST_GL_VIEW_CONVERT_ELEMENT (object);

  if (convert->viewconvert) {
    gst_object_unref (convert->viewconvert);
    convert->viewconvert = NULL;
  }
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static gboolean
gst_gl_view_convert_element_set_caps (GstGLFilter * filter, GstCaps * incaps,
    GstCaps * outcaps)
{
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (filter);
  GstCapsFeatures *gl_features;
  gboolean ret;

  GST_DEBUG_OBJECT (filter, "incaps %" GST_PTR_FORMAT
      " outcaps %" GST_PTR_FORMAT, incaps, outcaps);
  /* The view_convert component needs RGBA caps */
  incaps = gst_caps_copy (incaps);
  outcaps = gst_caps_copy (outcaps);

  gst_caps_set_simple (incaps, "format", G_TYPE_STRING, "RGBA", NULL);
  gl_features =
      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
  gst_caps_set_features (incaps, 0, gl_features);

  gst_caps_set_simple (outcaps, "format", G_TYPE_STRING, "RGBA", NULL);
  gl_features =
      gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_GL_MEMORY);
  gst_caps_set_features (outcaps, 0, gl_features);

  ret = gst_gl_view_convert_set_caps (viewconvert_filter->viewconvert,
      incaps, outcaps);

  gst_caps_unref (incaps);
  gst_caps_unref (outcaps);

  return ret;
}

static GstCaps *
gst_gl_view_convert_element_transform_internal_caps (GstGLFilter * filter,
    GstPadDirection direction, GstCaps * caps, GstCaps * filter_caps)
{
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (filter);
  GstCaps *result;

  GST_DEBUG_OBJECT (filter, "dir %s transforming caps: %" GST_PTR_FORMAT,
      direction == GST_PAD_SINK ? "sink" : "src", caps);

  result =
      gst_gl_view_convert_transform_caps (viewconvert_filter->viewconvert,
      direction, caps, NULL);

  GST_DEBUG_OBJECT (filter, "returning caps: %" GST_PTR_FORMAT, result);

  return result;
}

static GstCaps *
gst_gl_view_convert_element_fixate_caps (GstBaseTransform * trans,
    GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (trans);

  othercaps = gst_gl_view_convert_fixate_caps (viewconvert_filter->viewconvert,
      direction, caps, othercaps);

  if (gst_caps_is_empty (othercaps))
    return othercaps;

  /* Let GLfilter do the rest */
  return
      GST_BASE_TRANSFORM_CLASS
      (gst_gl_view_convert_element_parent_class)->fixate_caps (trans, direction,
      caps, othercaps);
}

static gboolean
gst_gl_view_convert_element_stop (GstBaseTransform * bt)
{
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (bt);

  gst_gl_view_convert_reset (viewconvert_filter->viewconvert);

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

static void
gst_gl_view_convert_element_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstGLViewConvertElement *convert = GST_GL_VIEW_CONVERT_ELEMENT (object);

  switch (prop_id) {
    case PROP_INPUT_LAYOUT:
    case PROP_INPUT_FLAGS:
      g_object_set_property (G_OBJECT (convert->viewconvert), pspec->name,
          value);
      gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (convert));
      break;
    case PROP_OUTPUT_LAYOUT:
    case PROP_OUTPUT_FLAGS:
      g_object_set_property (G_OBJECT (convert->viewconvert), pspec->name,
          value);
      gst_base_transform_reconfigure_src (GST_BASE_TRANSFORM (convert));
      break;
    case PROP_OUTPUT_DOWNMIX_MODE:
      g_object_set_property (G_OBJECT (convert->viewconvert), pspec->name,
          value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_gl_view_convert_element_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstGLViewConvertElement *convert = GST_GL_VIEW_CONVERT_ELEMENT (object);

  switch (prop_id) {
    case PROP_INPUT_LAYOUT:
    case PROP_INPUT_FLAGS:
    case PROP_OUTPUT_LAYOUT:
    case PROP_OUTPUT_FLAGS:
    case PROP_OUTPUT_DOWNMIX_MODE:
      g_object_get_property (G_OBJECT (convert->viewconvert), pspec->name,
          value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstFlowReturn
gst_gl_view_convert_element_submit_input_buffer (GstBaseTransform * trans,
    gboolean is_discont, GstBuffer * input)
{
  GstGLContext *context = GST_GL_BASE_FILTER (trans)->context;
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (trans);
  GstFlowReturn ret;

  ret =
      GST_BASE_TRANSFORM_CLASS (parent_class)->submit_input_buffer (trans,
      is_discont, input);
  if (ret != GST_FLOW_OK || trans->queued_buf == NULL)
    return ret;

  gst_gl_view_convert_set_context (viewconvert_filter->viewconvert, context);

  /* Takes the ref to the input buffer */
  ret =
      gst_gl_view_convert_submit_input_buffer (viewconvert_filter->viewconvert,
      is_discont, input);
  trans->queued_buf = NULL;

  return ret;
}

static GstFlowReturn
gst_gl_view_convert_element_generate_output_buffer (GstBaseTransform * bt,
    GstBuffer ** outbuf_ptr)
{
  GstGLFilter *filter = GST_GL_FILTER (bt);
  GstGLViewConvertElement *viewconvert_filter =
      GST_GL_VIEW_CONVERT_ELEMENT (bt);
  GstFlowReturn ret = GST_FLOW_OK;

  ret = gst_gl_view_convert_get_output (viewconvert_filter->viewconvert,
      outbuf_ptr);

  if (ret != GST_FLOW_OK) {
    GST_ELEMENT_ERROR (filter, RESOURCE, SETTINGS,
        ("failed to perform view conversion on input buffer"), (NULL));
    return ret;
  }

  return ret;
}
