/* GStreamer
 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
 *
 * 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-smokeenc
 *
 * Encodes images in smoke format.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>

#include "gstsmokeenc.h"
#include <gst/video/video.h>

GST_DEBUG_CATEGORY_STATIC (smokeenc_debug);
#define GST_CAT_DEFAULT smokeenc_debug


/* SmokeEnc signals and args */
enum
{
  FRAME_ENCODED,
  /* FILL ME */
  LAST_SIGNAL
};

#define DEFAULT_PROP_MIN_QUALITY 10
#define DEFAULT_PROP_MAX_QUALITY 85
#define DEFAULT_PROP_THRESHOLD 3000
#define DEFAULT_PROP_KEYFRAME 20

enum
{
  PROP_0,
  PROP_MIN_QUALITY,
  PROP_MAX_QUALITY,
  PROP_THRESHOLD,
  PROP_KEYFRAME
      /* FILL ME */
};

static void gst_smokeenc_base_init (gpointer g_class);
static void gst_smokeenc_class_init (GstSmokeEnc * klass);
static void gst_smokeenc_init (GstSmokeEnc * smokeenc);
static void gst_smokeenc_finalize (GObject * object);

static GstStateChangeReturn
gst_smokeenc_change_state (GstElement * element, GstStateChange transition);

static GstFlowReturn gst_smokeenc_chain (GstPad * pad, GstBuffer * buf);
static GstCaps *gst_smokeenc_getcaps (GstPad * pad);
static gboolean gst_smokeenc_setcaps (GstPad * pad, GstCaps * caps);

static gboolean gst_smokeenc_resync (GstSmokeEnc * smokeenc);
static void gst_smokeenc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_smokeenc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstElementClass *parent_class = NULL;

GType
gst_smokeenc_get_type (void)
{
  static GType smokeenc_type = 0;

  if (!smokeenc_type) {
    static const GTypeInfo smokeenc_info = {
      sizeof (GstSmokeEncClass),
      (GBaseInitFunc) gst_smokeenc_base_init,
      NULL,
      (GClassInitFunc) gst_smokeenc_class_init,
      NULL,
      NULL,
      sizeof (GstSmokeEnc),
      0,
      (GInstanceInitFunc) gst_smokeenc_init,
    };

    smokeenc_type =
        g_type_register_static (GST_TYPE_ELEMENT, "GstSmokeEnc", &smokeenc_info,
        0);
  }
  return smokeenc_type;
}

static GstStaticPadTemplate gst_smokeenc_sink_pad_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("I420"))
    );

static GstStaticPadTemplate gst_smokeenc_src_pad_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-smoke, "
        "width = (int) [ 16, 4096 ], "
        "height = (int) [ 16, 4096 ], " "framerate = (fraction) [ 0/1, MAX ]")
    );

static void
gst_smokeenc_base_init (gpointer g_class)
{
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_add_static_pad_template (element_class,
      &gst_smokeenc_sink_pad_template);
  gst_element_class_add_static_pad_template (element_class,
      &gst_smokeenc_src_pad_template);
  gst_element_class_set_static_metadata (element_class, "Smoke video encoder",
      "Codec/Encoder/Video", "Encode images into the Smoke format",
      "Wim Taymans <wim@fluendo.com>");
}

static void
gst_smokeenc_class_init (GstSmokeEnc * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_smokeenc_finalize;
  gobject_class->set_property = gst_smokeenc_set_property;
  gobject_class->get_property = gst_smokeenc_get_property;

  g_object_class_install_property (gobject_class, PROP_MIN_QUALITY,
      g_param_spec_int ("qmin", "Qmin", "Minimum quality",
          0, 100, DEFAULT_PROP_MIN_QUALITY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_MAX_QUALITY,
      g_param_spec_int ("qmax", "Qmax", "Maximum quality",
          0, 100, DEFAULT_PROP_MAX_QUALITY,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_THRESHOLD,
      g_param_spec_int ("threshold", "Threshold", "Motion estimation threshold",
          0, 100000000, DEFAULT_PROP_THRESHOLD,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_KEYFRAME,
      g_param_spec_int ("keyframe", "Keyframe",
          "Insert keyframe every N frames", 1, 100000,
          DEFAULT_PROP_KEYFRAME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_smokeenc_change_state);

  GST_DEBUG_CATEGORY_INIT (smokeenc_debug, "smokeenc", 0,
      "Smoke encoding element");
}

static void
gst_smokeenc_init (GstSmokeEnc * smokeenc)
{
  /* create the sink and src pads */
  smokeenc->sinkpad =
      gst_pad_new_from_static_template (&gst_smokeenc_sink_pad_template,
      "sink");
  gst_pad_set_chain_function (smokeenc->sinkpad, gst_smokeenc_chain);
  gst_pad_set_getcaps_function (smokeenc->sinkpad, gst_smokeenc_getcaps);
  gst_pad_set_setcaps_function (smokeenc->sinkpad, gst_smokeenc_setcaps);
  gst_element_add_pad (GST_ELEMENT (smokeenc), smokeenc->sinkpad);

  smokeenc->srcpad =
      gst_pad_new_from_static_template (&gst_smokeenc_src_pad_template, "src");
  gst_pad_set_getcaps_function (smokeenc->srcpad, gst_smokeenc_getcaps);
  gst_pad_use_fixed_caps (smokeenc->srcpad);
  gst_element_add_pad (GST_ELEMENT (smokeenc), smokeenc->srcpad);

  smokeenc->min_quality = DEFAULT_PROP_MIN_QUALITY;
  smokeenc->max_quality = DEFAULT_PROP_MAX_QUALITY;
  smokeenc->threshold = DEFAULT_PROP_THRESHOLD;
  smokeenc->keyframe = DEFAULT_PROP_KEYFRAME;
}

static void
gst_smokeenc_finalize (GObject * object)
{
  GstSmokeEnc *enc = GST_SMOKEENC (object);

  if (enc->info)
    smokecodec_info_free (enc->info);

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

static GstCaps *
gst_smokeenc_getcaps (GstPad * pad)
{
  GstSmokeEnc *smokeenc = GST_SMOKEENC (gst_pad_get_parent (pad));
  GstPad *otherpad;
  GstCaps *result, *caps;
  const GstCaps *tcaps;
  const char *name;
  int i;
  GstStructure *structure = NULL;

  /* we want to proxy properties like width, height and framerate from the
     other end of the element */
  otherpad = (pad == smokeenc->srcpad) ? smokeenc->sinkpad : smokeenc->srcpad;

  /* get template caps, we always need this to fiter the peer caps */
  tcaps = gst_pad_get_pad_template_caps (otherpad);

  /* get any constraints on the peer pad */
  caps = gst_pad_peer_get_caps (otherpad);

  if (caps == NULL)
    caps = gst_caps_copy (tcaps);
  else
    caps = gst_caps_make_writable (caps);

  /* intersect with the template */
  result = gst_caps_intersect (caps, tcaps);
  gst_caps_unref (caps);

  if (pad == smokeenc->srcpad) {
    name = "video/x-smoke";
  } else {
    name = "video/x-raw-yuv";
  }

  /* we can only copy width, height, framerate from one side to the other */
  for (i = 0; i < gst_caps_get_size (result); i++) {
    structure = gst_caps_get_structure (result, i);

    gst_structure_set_name (structure, name);
    gst_structure_remove_field (structure, "format");
    /* ... but for the sink pad, we only do I420 anyway, so add that */
    if (pad == smokeenc->sinkpad) {
      gst_structure_set (structure, "format", GST_TYPE_FOURCC,
          GST_STR_FOURCC ("I420"), NULL);
    }
  }

  gst_object_unref (smokeenc);

  return result;
}

static gboolean
gst_smokeenc_setcaps (GstPad * pad, GstCaps * caps)
{
  GstSmokeEnc *smokeenc;
  GstStructure *structure;
  const GValue *framerate;
  gboolean ret;
  GstCaps *srccaps;

  smokeenc = GST_SMOKEENC (gst_pad_get_parent (pad));

  structure = gst_caps_get_structure (caps, 0);
  framerate = gst_structure_get_value (structure, "framerate");
  if (framerate) {
    smokeenc->fps_num = gst_value_get_fraction_numerator (framerate);
    smokeenc->fps_denom = gst_value_get_fraction_denominator (framerate);
  } else {
    smokeenc->fps_num = 0;
    smokeenc->fps_denom = 1;
  }

  gst_structure_get_int (structure, "width", &smokeenc->width);
  gst_structure_get_int (structure, "height", &smokeenc->height);

  if ((smokeenc->width & 0x0f) != 0 || (smokeenc->height & 0x0f) != 0)
    goto width_or_height_notx16;

  if (!gst_smokeenc_resync (smokeenc))
    goto init_failed;

  srccaps = gst_caps_new_simple ("video/x-smoke",
      "width", G_TYPE_INT, smokeenc->width,
      "height", G_TYPE_INT, smokeenc->height,
      "framerate", GST_TYPE_FRACTION, smokeenc->fps_num, smokeenc->fps_denom,
      NULL);

  ret = gst_pad_set_caps (smokeenc->srcpad, srccaps);
  gst_caps_unref (srccaps);

  gst_object_unref (smokeenc);

  return ret;

width_or_height_notx16:
  {
    GST_WARNING_OBJECT (smokeenc, "width and height must be multiples of 16"
        ", %dx%d not allowed", smokeenc->width, smokeenc->height);
    gst_object_unref (smokeenc);
    return FALSE;
  }
init_failed:
  {
    GST_WARNING_OBJECT (smokeenc, "could not init decoder");
    gst_object_unref (smokeenc);
    return FALSE;
  }
}

static gboolean
gst_smokeenc_resync (GstSmokeEnc * smokeenc)
{
  int ret;

  GST_DEBUG ("resync: %dx%d@%d/%dfps", smokeenc->width, smokeenc->height,
      smokeenc->fps_num, smokeenc->fps_denom);

  if (smokeenc->info)
    smokecodec_info_free (smokeenc->info);

  ret = smokecodec_encode_new (&smokeenc->info, smokeenc->width,
      smokeenc->height, smokeenc->fps_num, smokeenc->fps_denom);

  if (ret != SMOKECODEC_OK)
    goto init_failed;

  smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
      smokeenc->max_quality);

  GST_DEBUG ("resync done");
  return TRUE;

  /* ERRORS */
init_failed:
  {
    GST_WARNING_OBJECT (smokeenc, "smokecodec_encode_new() failed: %d", ret);
    return FALSE;
  }
}

static GstFlowReturn
gst_smokeenc_chain (GstPad * pad, GstBuffer * buf)
{
  GstSmokeEnc *smokeenc;
  guchar *data, *outdata;
  gulong size;
  gint outsize;
  guint encsize;
  GstBuffer *outbuf;
  SmokeCodecFlags flags;
  GstFlowReturn ret;

  smokeenc = GST_SMOKEENC (GST_OBJECT_PARENT (pad));

  data = GST_BUFFER_DATA (buf);
  size = GST_BUFFER_SIZE (buf);

  GST_LOG_OBJECT (smokeenc, "got buffer of %lu bytes", size);

  if (smokeenc->need_header) {
    outbuf = gst_buffer_new_and_alloc (256);
    outdata = GST_BUFFER_DATA (outbuf);

    GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
    GST_BUFFER_DURATION (outbuf) = GST_BUFFER_DURATION (buf);

    smokecodec_encode_id (smokeenc->info, outdata, &encsize);

    GST_BUFFER_SIZE (outbuf) = encsize;
    gst_buffer_set_caps (outbuf, GST_PAD_CAPS (smokeenc->srcpad));

    ret = gst_pad_push (smokeenc->srcpad, outbuf);
    if (ret != GST_FLOW_OK)
      goto done;

    smokeenc->need_header = FALSE;
  }

  encsize = outsize = smokeenc->width * smokeenc->height * 3;
  outbuf = gst_buffer_new_and_alloc (outsize);
  outdata = GST_BUFFER_DATA (outbuf);

  GST_BUFFER_TIMESTAMP (outbuf) = GST_BUFFER_TIMESTAMP (buf);
  GST_BUFFER_DURATION (outbuf) =
      gst_util_uint64_scale_int (GST_SECOND, smokeenc->fps_denom,
      smokeenc->fps_num);
  gst_buffer_set_caps (outbuf, GST_PAD_CAPS (smokeenc->srcpad));

  flags = 0;
  if ((smokeenc->frame % smokeenc->keyframe) == 0) {
    flags |= SMOKECODEC_KEYFRAME;
  }
  smokecodec_set_quality (smokeenc->info, smokeenc->min_quality,
      smokeenc->max_quality);
  smokecodec_set_threshold (smokeenc->info, smokeenc->threshold);
  smokecodec_encode (smokeenc->info, data, flags, outdata, &encsize);
  gst_buffer_unref (buf);

  GST_BUFFER_SIZE (outbuf) = encsize;
  GST_BUFFER_OFFSET (outbuf) = smokeenc->frame;
  GST_BUFFER_OFFSET_END (outbuf) = smokeenc->frame + 1;

  ret = gst_pad_push (smokeenc->srcpad, outbuf);

  smokeenc->frame++;

done:

  return ret;
}

static void
gst_smokeenc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSmokeEnc *smokeenc;

  g_return_if_fail (GST_IS_SMOKEENC (object));
  smokeenc = GST_SMOKEENC (object);

  switch (prop_id) {
    case PROP_MIN_QUALITY:
      smokeenc->min_quality = g_value_get_int (value);
      break;
    case PROP_MAX_QUALITY:
      smokeenc->max_quality = g_value_get_int (value);
      break;
    case PROP_THRESHOLD:
      smokeenc->threshold = g_value_get_int (value);
      break;
    case PROP_KEYFRAME:
      smokeenc->keyframe = g_value_get_int (value);
      break;
    default:
      break;
  }
}

static void
gst_smokeenc_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSmokeEnc *smokeenc;

  g_return_if_fail (GST_IS_SMOKEENC (object));
  smokeenc = GST_SMOKEENC (object);

  switch (prop_id) {
    case PROP_MIN_QUALITY:
      g_value_set_int (value, smokeenc->min_quality);
      break;
    case PROP_MAX_QUALITY:
      g_value_set_int (value, smokeenc->max_quality);
      break;
    case PROP_THRESHOLD:
      g_value_set_int (value, smokeenc->threshold);
      break;
    case PROP_KEYFRAME:
      g_value_set_int (value, smokeenc->keyframe);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_smokeenc_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstSmokeEnc *enc;

  enc = GST_SMOKEENC (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      /* reset the initial video state */
      enc->width = 0;
      enc->height = 0;
      enc->frame = 0;
      enc->need_header = TRUE;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  if (ret != GST_STATE_CHANGE_SUCCESS)
    return ret;

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      break;
    default:
      break;
  }

  return ret;
}
