/*
 * Copyright (C) 2018 Metrological Group B.V.
 * Copyright (C) 2018 Igalia S.L. All rights reserved.
 *
 * 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
 * aint with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

/* NOTE: This file respects GStreamer coding style as we might want to upstream
 * that element in the future */

#include "config.h"

#if ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
#include "GStreamerVideoEncoder.h"

GST_DEBUG_CATEGORY (gst_webrtcenc_debug);
#define GST_CAT_DEFAULT gst_webrtcenc_debug

#define KBIT_TO_BIT 1024

static GstStaticPadTemplate sinkTemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-raw(ANY);"));

static GstStaticPadTemplate srcTemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("video/x-h264;video/x-vp8"));

typedef void (*SetBitrateFunc) (GObject * encoder, const gchar * propname,
    gint bitrate);
typedef void (*SetupFunc) (GstWebrtcVideoEncoder * self);
typedef struct
{
  gboolean avalaible;
  GstCaps *caps;
  const gchar *name;
  const gchar *parser_name;
  GstCaps *encoded_format;
  SetBitrateFunc setBitrate;
  SetupFunc setupEncoder;
  const gchar *bitrate_propname;
  const gchar *keyframe_interval_propname;
} EncoderDefinition;

typedef enum
{
  ENCODER_NONE = 0,
  ENCODER_X264,
  ENCODER_OPENH264,
  ENCODER_OMXH264,
  ENCODER_VP8,
  ENCODER_LAST,
} EncoderId;

EncoderDefinition encoders[ENCODER_LAST] = {
  FALSE,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
  NULL,
};

typedef struct
{
  EncoderId encoderId;
  GstElement *encoder;
  GstElement *parser;
  GstElement *capsfilter;
  guint bitrate;
} GstWebrtcVideoEncoderPrivate;

/*  *INDENT-OFF* */
G_DEFINE_TYPE_WITH_PRIVATE (GstWebrtcVideoEncoder, gst_webrtc_video_encoder,
    GST_TYPE_BIN)
#define PRIV(self) ((GstWebrtcVideoEncoderPrivate*)gst_webrtc_video_encoder_get_instance_private(self))
/*  *INDENT-ON* */

enum
{
  PROP_0,
  PROP_FORMAT,
  PROP_ENCODER,
  PROP_BITRATE,
  PROP_KEYFRAME_INTERVAL,
  N_PROPS
};

static void
gst_webrtc_video_encoder_finalize (GObject * object)
{
  G_OBJECT_CLASS (gst_webrtc_video_encoder_parent_class)->finalize (object);
}

static void
gst_webrtc_video_encoder_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);

  switch (prop_id) {
    case PROP_FORMAT:
      if (priv->encoderId != ENCODER_NONE)
        g_value_set_boxed (value, encoders[priv->encoderId].caps);
      else
        g_value_set_boxed (value, NULL);
      break;
    case PROP_ENCODER:
      g_value_set_object (value, priv->encoder);
      break;
    case PROP_BITRATE:
      g_value_set_uint (value, priv->bitrate);
      break;
    case PROP_KEYFRAME_INTERVAL:
      if (priv->encoder)
        g_object_get_property (G_OBJECT (priv->encoder),
            encoders[priv->encoderId].keyframe_interval_propname, value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
  }
}

static void
gst_webrtc_video_encoder_set_bitrate (GstWebrtcVideoEncoder * self,
    guint bitrate)
{
  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);

  priv->bitrate = bitrate;
  if (priv->encoder) {
    encoders[priv->encoderId].setBitrate (G_OBJECT (priv->encoder),
        encoders[priv->encoderId].bitrate_propname, priv->bitrate);
  }
}

static void
gst_webrtc_video_encoder_set_format (GstWebrtcVideoEncoder * self,
    const GstCaps * caps)
{
  gint i;
  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);
  g_return_if_fail (priv->encoderId == ENCODER_NONE);
  g_return_if_fail (caps);

  for (i = 1; i < ENCODER_LAST; i++) {
    if (encoders[i].avalaible
        && gst_caps_can_intersect (encoders[i].caps, caps)) {
      GstPad *tmppad;
      priv->encoderId = (EncoderId) i;
      priv->encoder = gst_element_factory_make (encoders[i].name, NULL);

      if (encoders[i].parser_name)
        priv->parser = gst_element_factory_make (encoders[i].parser_name, NULL);

      encoders[priv->encoderId].setupEncoder (self);
      if (encoders[i].encoded_format) {
        priv->capsfilter = gst_element_factory_make ("capsfilter", NULL);
        g_object_set (priv->capsfilter, "caps", encoders[i].encoded_format,
            NULL);
      }

      gst_bin_add (GST_BIN (self), priv->encoder);

      tmppad = gst_element_get_static_pad (priv->encoder, "sink");
      gst_ghost_pad_set_target (GST_GHOST_PAD (GST_ELEMENT (self)->
              sinkpads->data), tmppad);
      gst_object_unref (tmppad);

      tmppad = gst_element_get_static_pad (priv->encoder, "src");
      if (priv->parser) {
        gst_bin_add (GST_BIN (self), priv->parser);
        gst_element_link (priv->encoder, priv->parser);
        gst_object_unref (tmppad);
        tmppad = gst_element_get_static_pad (priv->parser, "src");
      }

      if (priv->capsfilter) {
        GstPad *tmppad2 = gst_element_get_static_pad (priv->capsfilter, "sink");

        gst_bin_add (GST_BIN (self), priv->capsfilter);
        gst_pad_link (tmppad, tmppad2);
        gst_object_unref (tmppad);
        tmppad = gst_element_get_static_pad (priv->capsfilter, "src");
        gst_object_unref (tmppad2);
      }

      g_assert (gst_ghost_pad_set_target (GST_GHOST_PAD (GST_ELEMENT
                  (self)->srcpads->data), tmppad));
      gst_object_unref (tmppad);

      gst_webrtc_video_encoder_set_bitrate (self, priv->bitrate);
      return;
    }
  }

  GST_ERROR ("No encoder found for format %" GST_PTR_FORMAT, caps);
}

static void
gst_webrtc_video_encoder_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstWebrtcVideoEncoder *self = GST_WEBRTC_VIDEO_ENCODER (object);
  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);

  switch (prop_id) {
    case PROP_FORMAT:
      gst_webrtc_video_encoder_set_format (self, gst_value_get_caps (value));
      break;
    case PROP_BITRATE:
      gst_webrtc_video_encoder_set_bitrate (self, g_value_get_uint (value));
      break;
    case PROP_KEYFRAME_INTERVAL:
      if (priv->encoder)
        g_object_set (priv->encoder,
            encoders[priv->encoderId].keyframe_interval_propname,
            g_value_get_uint (value), NULL);

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

static void
register_known_encoder (EncoderId encId, const gchar * name,
    const gchar * parser_name, const gchar * caps, const gchar * encoded_format,
    SetupFunc setupEncoder, const gchar * bitrate_propname,
    SetBitrateFunc setBitrate, const gchar * keyframe_interval_propname)
{
  GstPluginFeature *feature =
      gst_registry_lookup_feature (gst_registry_get (), name);
  if (!feature) {
    GST_WARNING ("Could not find %s", name);
    encoders[encId].avalaible = FALSE;

    return;
  }
  gst_object_unref (feature);

  encoders[encId].avalaible = TRUE;
  encoders[encId].name = name;
  encoders[encId].parser_name = parser_name;
  encoders[encId].caps = gst_caps_from_string (caps);
  if (encoded_format)
    encoders[encId].encoded_format = gst_caps_from_string (encoded_format);
  else
    encoders[encId].encoded_format = NULL;
  encoders[encId].setupEncoder = setupEncoder;
  encoders[encId].bitrate_propname = bitrate_propname;
  encoders[encId].setBitrate = setBitrate;
  encoders[encId].keyframe_interval_propname = keyframe_interval_propname;
}

static void
setup_x264enc (GstWebrtcVideoEncoder * self)
{
  gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "tune",
      "zerolatency");
  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
}

static void
setup_openh264enc (GstWebrtcVideoEncoder * self)
{
  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
}

static void
setup_omxh264enc (GstWebrtcVideoEncoder * self)
{
  gst_util_set_object_arg (G_OBJECT (PRIV (self)->encoder), "control-rate",
      "variable");
  g_object_set (PRIV (self)->parser, "config-interval", 1, NULL);
}


static void
set_bitrate_kbit_per_sec (GObject * encoder, const gchar * prop_name,
    gint bitrate)
{
  g_object_set (encoder, prop_name, bitrate, NULL);
}

static void
set_bitrate_bit_per_sec (GObject * encoder, const gchar * prop_name,
    gint bitrate)
{
  g_object_set (encoder, prop_name, bitrate * KBIT_TO_BIT, NULL);
}

static void
gst_webrtc_video_encoder_class_init (GstWebrtcVideoEncoderClass * klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_webrtcenc_debug, "webrtcencoder", 0,
      "Video encoder for WebRTC");

  object_class->finalize = gst_webrtc_video_encoder_finalize;
  object_class->get_property = gst_webrtc_video_encoder_get_property;
  object_class->set_property = gst_webrtc_video_encoder_set_property;

  g_object_class_install_property (object_class, PROP_FORMAT,
      g_param_spec_boxed ("format", "Format as caps",
          "Set the caps of the format to be used.",
          GST_TYPE_CAPS,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (object_class, PROP_ENCODER,
      g_param_spec_object ("encoder", "The actual encoder element",
          "The encoder element", GST_TYPE_ELEMENT,
          (GParamFlags) (G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)));

  g_object_class_install_property (object_class, PROP_BITRATE,
      g_param_spec_uint ("bitrate", "Bitrate",
          "The bitrate in kbit per second", 0, G_MAXINT, 2048,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
              G_PARAM_CONSTRUCT)));

  g_object_class_install_property (object_class, PROP_KEYFRAME_INTERVAL,
      g_param_spec_uint ("keyframe-interval", "Keyframe interval",
          "The interval between keyframes", 0, G_MAXINT, 0,
          (GParamFlags) (G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
              G_PARAM_CONSTRUCT)));

  register_known_encoder (ENCODER_OMXH264, "omxh264enc", "h264parse",
      "video/x-h264",
      "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
      setup_omxh264enc, "target-bitrate", set_bitrate_bit_per_sec, "interval-intraframes");
  register_known_encoder (ENCODER_X264, "x264enc", "h264parse", "video/x-h264",
      "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
      setup_x264enc, "bitrate", set_bitrate_kbit_per_sec, "key-int-max");
  register_known_encoder (ENCODER_OPENH264, "openh264enc", "h264parse",
      "video/x-h264",
      "video/x-h264,alignment=au,stream-format=byte-stream,profile=baseline",
      setup_openh264enc, "bitrate", set_bitrate_bit_per_sec, "gop-size");
}

static void
gst_webrtc_video_encoder_init (GstWebrtcVideoEncoder * self)
{
  GstWebrtcVideoEncoderPrivate *priv = PRIV (self);

  priv->encoderId = ENCODER_NONE;
  gst_element_add_pad (GST_ELEMENT (self),
      gst_ghost_pad_new_no_target_from_template ("sink",
          gst_static_pad_template_get (&sinkTemplate)));

  gst_element_add_pad (GST_ELEMENT (self),
      gst_ghost_pad_new_no_target_from_template ("src",
          gst_static_pad_template_get (&srcTemplate)));
}

#endif // ENABLE(VIDEO) && ENABLE(MEDIA_STREAM) && USE(LIBWEBRTC) && USE(GSTREAMER)
