/* VP8
 * Copyright (C) 2006 David Schleef <ds@schleef.org>
 * Copyright (C) 2010 Entropy Wave Inc
 * Copyright (C) 2010-2012 Sebastian Dröge <sebastian.droege@collabora.co.uk>
 *
 * 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-vp8enc
 * @see_also: vp8dec, webmmux, oggmux
 *
 * This element encodes raw video into a VP8 stream.
 * <ulink url="http://www.webmproject.org">VP8</ulink> is a royalty-free
 * video codec maintained by <ulink url="http://www.google.com/">Google
 * </ulink>. It's the successor of On2 VP3, which was the base of the
 * Theora video codec.
 *
 * To control the quality of the encoding, the #GstVP8Enc::target-bitrate,
 * #GstVP8Enc::min-quantizer, #GstVP8Enc::max-quantizer or #GstVP8Enc::cq-level
 * properties can be used. Which one is used depends on the mode selected by
 * the #GstVP8Enc::end-usage property.
 * See <ulink url="http://www.webmproject.org/docs/encoder-parameters/">Encoder Parameters</ulink>
 * for explanation, examples for useful encoding parameters and more details
 * on the encoding parameters.
 *
 * <refsect2>
 * <title>Example pipeline</title>
 * |[
 * gst-launch-1.0 -v videotestsrc num-buffers=1000 ! vp8enc ! webmmux ! filesink location=videotestsrc.webm
 * ]| This example pipeline will encode a test video source to VP8 muxed in an
 * WebM container.
 * </refsect2>
 */

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

#ifdef HAVE_VP8_ENCODER

/* glib decided in 2.32 it would be a great idea to deprecated GValueArray without
 * providing an alternative
 *
 * See https://bugzilla.gnome.org/show_bug.cgi?id=667228
 * */
#define GLIB_DISABLE_DEPRECATION_WARNINGS

#include <gst/tag/tag.h>
#include <gst/video/video.h>
#include <string.h>

#include "gstvp8utils.h"
#include "gstvp8enc.h"

GST_DEBUG_CATEGORY_STATIC (gst_vp8enc_debug);
#define GST_CAT_DEFAULT gst_vp8enc_debug

typedef struct
{
  vpx_image_t *image;
  GList *invisible;
} GstVP8EncUserData;

static void
_gst_mini_object_unref0 (GstMiniObject * obj)
{
  if (obj)
    gst_mini_object_unref (obj);
}

static void
gst_vp8_enc_user_data_free (GstVP8EncUserData * user_data)
{
  if (user_data->image)
    g_slice_free (vpx_image_t, user_data->image);

  g_list_foreach (user_data->invisible, (GFunc) _gst_mini_object_unref0, NULL);
  g_list_free (user_data->invisible);
  g_slice_free (GstVP8EncUserData, user_data);
}

static vpx_codec_iface_t *gst_vp8_enc_get_algo (GstVPXEnc * enc);
static gboolean gst_vp8_enc_enable_scaling (GstVPXEnc * enc);
static void gst_vp8_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image);
static GstCaps *gst_vp8_enc_get_new_simple_caps (GstVPXEnc * enc);
static void gst_vp8_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
    GstVideoInfo * info);
static void *gst_vp8_enc_process_frame_user_data (GstVPXEnc * enc,
    GstVideoCodecFrame * frame);
static GstFlowReturn gst_vp8_enc_handle_invisible_frame_buffer (GstVPXEnc * enc,
    void *user_data, GstBuffer * buffer);
static void gst_vp8_enc_set_frame_user_data (GstVPXEnc * enc,
    GstVideoCodecFrame * frame, vpx_image_t * image);

static GstFlowReturn gst_vp8_enc_pre_push (GstVideoEncoder * encoder,
    GstVideoCodecFrame * frame);

static GstStaticPadTemplate gst_vp8_enc_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw, "
        "format = (string) \"I420\", "
        "width = (int) [1, 16383], "
        "height = (int) [1, 16383], framerate = (fraction) [ 0/1, MAX ]")
    );

static GstStaticPadTemplate gst_vp8_enc_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-vp8, " "profile = (string) {0, 1, 2, 3}")
    );

#define parent_class gst_vp8_enc_parent_class
G_DEFINE_TYPE (GstVP8Enc, gst_vp8_enc, GST_TYPE_VPX_ENC);

static void
gst_vp8_enc_class_init (GstVP8EncClass * klass)
{
  GstElementClass *element_class;
  GstVideoEncoderClass *video_encoder_class;
  GstVPXEncClass *vpx_encoder_class;

  element_class = GST_ELEMENT_CLASS (klass);
  video_encoder_class = GST_VIDEO_ENCODER_CLASS (klass);
  vpx_encoder_class = GST_VPX_ENC_CLASS (klass);


  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_vp8_enc_src_template));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&gst_vp8_enc_sink_template));

  gst_element_class_set_static_metadata (element_class,
      "On2 VP8 Encoder",
      "Codec/Encoder/Video",
      "Encode VP8 video streams", "David Schleef <ds@entropywave.com>, "
      "Sebastian Dröge <sebastian.droege@collabora.co.uk>");

  video_encoder_class->pre_push = gst_vp8_enc_pre_push;

  vpx_encoder_class->get_algo = gst_vp8_enc_get_algo;
  vpx_encoder_class->enable_scaling = gst_vp8_enc_enable_scaling;
  vpx_encoder_class->set_image_format = gst_vp8_enc_set_image_format;
  vpx_encoder_class->get_new_vpx_caps = gst_vp8_enc_get_new_simple_caps;
  vpx_encoder_class->set_stream_info = gst_vp8_enc_set_stream_info;
  vpx_encoder_class->process_frame_user_data =
      gst_vp8_enc_process_frame_user_data;
  vpx_encoder_class->handle_invisible_frame_buffer =
      gst_vp8_enc_handle_invisible_frame_buffer;
  vpx_encoder_class->set_frame_user_data = gst_vp8_enc_set_frame_user_data;

  GST_DEBUG_CATEGORY_INIT (gst_vp8enc_debug, "vp8enc", 0, "VP8 Encoder");
}

static void
gst_vp8_enc_init (GstVP8Enc * gst_vp8_enc)
{
  vpx_codec_err_t status;
  GstVPXEnc *gst_vpx_enc = GST_VPX_ENC (gst_vp8_enc);
  GST_DEBUG_OBJECT (gst_vp8_enc, "gst_vp8_enc_init");
  status =
      vpx_codec_enc_config_default (gst_vp8_enc_get_algo (gst_vpx_enc),
      &gst_vpx_enc->cfg, 0);
  if (status != VPX_CODEC_OK) {
    GST_ERROR_OBJECT (gst_vpx_enc,
        "Failed to get default encoder configuration: %s",
        gst_vpx_error_name (status));
    gst_vpx_enc->have_default_config = FALSE;
  } else {
    gst_vpx_enc->have_default_config = TRUE;
  }
}

static vpx_codec_iface_t *
gst_vp8_enc_get_algo (GstVPXEnc * enc)
{
  return &vpx_codec_vp8_cx_algo;
}

static gboolean
gst_vp8_enc_enable_scaling (GstVPXEnc * enc)
{
  return TRUE;
}

static void
gst_vp8_enc_set_image_format (GstVPXEnc * enc, vpx_image_t * image)
{
  image->fmt = VPX_IMG_FMT_I420;
  image->bps = 12;
  image->x_chroma_shift = image->y_chroma_shift = 1;
}

static GstCaps *
gst_vp8_enc_get_new_simple_caps (GstVPXEnc * enc)
{
  GstCaps *caps;
  gchar *profile_str = g_strdup_printf ("%d", enc->cfg.g_profile);
  caps = gst_caps_new_simple ("video/x-vp8",
      "profile", G_TYPE_STRING, profile_str, NULL);
  g_free (profile_str);
  return caps;
}

static void
gst_vp8_enc_set_stream_info (GstVPXEnc * enc, GstCaps * caps,
    GstVideoInfo * info)
{
  GstStructure *s;
  GstVideoEncoder *video_encoder;
  GstBuffer *stream_hdr, *vorbiscomment;
  const GstTagList *iface_tags;
  GValue array = { 0, };
  GValue value = { 0, };
  guint8 *data = NULL;
  GstMapInfo map;

  video_encoder = GST_VIDEO_ENCODER (enc);
  s = gst_caps_get_structure (caps, 0);

  /* put buffers in a fixed list */
  g_value_init (&array, GST_TYPE_ARRAY);
  g_value_init (&value, GST_TYPE_BUFFER);

  /* Create Ogg stream-info */
  stream_hdr = gst_buffer_new_and_alloc (26);
  gst_buffer_map (stream_hdr, &map, GST_MAP_WRITE);
  data = map.data;

  GST_WRITE_UINT8 (data, 0x4F);
  GST_WRITE_UINT32_BE (data + 1, 0x56503830);   /* "VP80" */
  GST_WRITE_UINT8 (data + 5, 0x01);     /* stream info header */
  GST_WRITE_UINT8 (data + 6, 1);        /* Major version 1 */
  GST_WRITE_UINT8 (data + 7, 0);        /* Minor version 0 */
  GST_WRITE_UINT16_BE (data + 8, GST_VIDEO_INFO_WIDTH (info));
  GST_WRITE_UINT16_BE (data + 10, GST_VIDEO_INFO_HEIGHT (info));
  GST_WRITE_UINT24_BE (data + 12, GST_VIDEO_INFO_PAR_N (info));
  GST_WRITE_UINT24_BE (data + 15, GST_VIDEO_INFO_PAR_D (info));
  GST_WRITE_UINT32_BE (data + 18, GST_VIDEO_INFO_FPS_N (info));
  GST_WRITE_UINT32_BE (data + 22, GST_VIDEO_INFO_FPS_D (info));

  gst_buffer_unmap (stream_hdr, &map);

  GST_BUFFER_FLAG_SET (stream_hdr, GST_BUFFER_FLAG_HEADER);
  gst_value_set_buffer (&value, stream_hdr);
  gst_value_array_append_value (&array, &value);
  g_value_unset (&value);
  gst_buffer_unref (stream_hdr);

  iface_tags = gst_tag_setter_get_tag_list (GST_TAG_SETTER (video_encoder));
  if (iface_tags) {
    vorbiscomment =
        gst_tag_list_to_vorbiscomment_buffer (iface_tags,
        (const guint8 *) "OVP80\2 ", 7,
        "Encoded with GStreamer vp8enc " PACKAGE_VERSION);

    GST_BUFFER_FLAG_SET (vorbiscomment, GST_BUFFER_FLAG_HEADER);

    g_value_init (&value, GST_TYPE_BUFFER);
    gst_value_set_buffer (&value, vorbiscomment);
    gst_value_array_append_value (&array, &value);
    g_value_unset (&value);
    gst_buffer_unref (vorbiscomment);
  }

  gst_structure_set_value (s, "streamheader", &array);
  g_value_unset (&array);

}

static void *
gst_vp8_enc_process_frame_user_data (GstVPXEnc * enc,
    GstVideoCodecFrame * frame)
{
  GstVP8EncUserData *user_data;
  user_data = gst_video_codec_frame_get_user_data (frame);
  if (user_data->image)
    g_slice_free (vpx_image_t, user_data->image);
  user_data->image = NULL;
  return user_data;
}

static GstFlowReturn
gst_vp8_enc_handle_invisible_frame_buffer (GstVPXEnc * enc, void *user_data,
    GstBuffer * buffer)
{
  GstVP8EncUserData *vp8_user_data = (GstVP8EncUserData *) user_data;
  vp8_user_data->invisible = g_list_append (vp8_user_data->invisible, buffer);
  return GST_FLOW_OK;
}

static void
gst_vp8_enc_set_frame_user_data (GstVPXEnc * enc, GstVideoCodecFrame * frame,
    vpx_image_t * image)
{
  GstVP8EncUserData *user_data;
  user_data = g_slice_new0 (GstVP8EncUserData);
  user_data->image = image;
  gst_video_codec_frame_set_user_data (frame, user_data,
      (GDestroyNotify) gst_vp8_enc_user_data_free);
  return;
}

static guint64
_to_granulepos (guint64 frame_end_number, guint inv_count, guint keyframe_dist)
{
  guint64 granulepos;
  guint inv;

  inv = (inv_count == 0) ? 0x3 : inv_count - 1;

  granulepos = (frame_end_number << 32) | (inv << 30) | (keyframe_dist << 3);
  return granulepos;
}

static GstFlowReturn
gst_vp8_enc_pre_push (GstVideoEncoder * video_encoder,
    GstVideoCodecFrame * frame)
{
  GstVP8Enc *encoder;
  GstVPXEnc *vpx_enc;
  GstBuffer *buf;
  GstFlowReturn ret = GST_FLOW_OK;
  GstVP8EncUserData *user_data = gst_video_codec_frame_get_user_data (frame);
  GList *l;
  gint inv_count;
  GstVideoInfo *info;

  GST_DEBUG_OBJECT (video_encoder, "pre_push");

  encoder = GST_VP8_ENC (video_encoder);
  vpx_enc = GST_VPX_ENC (encoder);

  info = &vpx_enc->input_state->info;

  g_assert (user_data != NULL);

  for (inv_count = 0, l = user_data->invisible; l; inv_count++, l = l->next) {
    buf = l->data;
    l->data = NULL;

    /* FIXME : All of this should have already been handled by base classes, no ? */
    if (l == user_data->invisible
        && GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
      GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
      encoder->keyframe_distance = 0;
    } else {
      GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
      encoder->keyframe_distance++;
    }

    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DECODE_ONLY);
    GST_BUFFER_TIMESTAMP (buf) = GST_BUFFER_TIMESTAMP (frame->output_buffer);
    GST_BUFFER_DURATION (buf) = 0;
    if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
      GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
      GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
    } else {
      GST_BUFFER_OFFSET_END (buf) =
          _to_granulepos (frame->presentation_frame_number + 1,
          inv_count, encoder->keyframe_distance);
      GST_BUFFER_OFFSET (buf) =
          gst_util_uint64_scale (frame->presentation_frame_number + 1,
          GST_SECOND * GST_VIDEO_INFO_FPS_D (info),
          GST_VIDEO_INFO_FPS_N (info));
    }

    ret = gst_pad_push (GST_VIDEO_ENCODER_SRC_PAD (video_encoder), buf);

    if (ret != GST_FLOW_OK) {
      GST_WARNING_OBJECT (encoder, "flow error %d", ret);
      goto done;
    }
  }

  buf = frame->output_buffer;

  /* FIXME : All of this should have already been handled by base classes, no ? */
  if (!user_data->invisible && GST_VIDEO_CODEC_FRAME_IS_SYNC_POINT (frame)) {
    GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
    encoder->keyframe_distance = 0;
  } else {
    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
    encoder->keyframe_distance++;
  }

  if (GST_VIDEO_INFO_FPS_D (info) == 0 || GST_VIDEO_INFO_FPS_N (info) == 0) {
    GST_BUFFER_OFFSET_END (buf) = GST_BUFFER_OFFSET_NONE;
    GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET_NONE;
  } else {
    GST_BUFFER_OFFSET_END (buf) =
        _to_granulepos (frame->presentation_frame_number + 1, 0,
        encoder->keyframe_distance);
    GST_BUFFER_OFFSET (buf) =
        gst_util_uint64_scale (frame->presentation_frame_number + 1,
        GST_SECOND * GST_VIDEO_INFO_FPS_D (info), GST_VIDEO_INFO_FPS_N (info));
  }

  GST_LOG_OBJECT (video_encoder, "src ts: %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));

done:
  return ret;
}

#endif /* HAVE_VP8_ENCODER */
