/* GStreamer plugin for forward error correction
 * Copyright (C) 2017 Pexip
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Author: Mikhail Fludkov <misha@pexip.com>
 */

#include <gst/rtp/gstrtp-enumtypes.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <string.h>

#include "rtpulpfeccommon.h"
#include "gstrtpulpfecenc.h"

static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp"));

static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp"));

#define UNDEF_PT                255
#define UNDEF_SSRC              0

#define DEFAULT_PT              UNDEF_PT
#define DEFAULT_SSRC            UNDEF_SSRC
#define DEFAULT_PCT             0
#define DEFAULT_PCT_IMPORTANT   0
#define DEFAULT_MULTIPACKET     FALSE
#define DEFAULT_MUX_SEQ         FALSE

#define PACKETS_BUF_MAX_LENGTH  (RTP_ULPFEC_PROTECTED_PACKETS_MAX(TRUE))

GST_DEBUG_CATEGORY (gst_rtp_ulpfec_enc_debug);
#define GST_CAT_DEFAULT (gst_rtp_ulpfec_enc_debug)

G_DEFINE_TYPE (GstRtpUlpFecEnc, gst_rtp_ulpfec_enc, GST_TYPE_ELEMENT);

enum
{
  PROP_0,
  PROP_SSRC,
  PROP_PT,
  PROP_MULTIPACKET,
  PROP_MUX_SEQ,
  PROP_PROTECTED,
  PROP_PERCENTAGE,
  PROP_PERCENTAGE_IMPORTANT,
};

#define RTP_FEC_MAP_INFO_NTH(ctx, data) (&g_array_index (\
    ((GstRtpUlpFecEncStreamCtx *)ctx)->info_arr, \
    RtpUlpFecMapInfo, \
    GPOINTER_TO_UINT(data)))

static void
gst_rtp_ulpfec_enc_stream_ctx_start (GstRtpUlpFecEncStreamCtx * ctx,
    GQueue * packets, guint fec_packets)
{
  GList *it = packets->tail;

  g_array_set_size (ctx->info_arr, packets->length);

  for (guint i = 0; i < packets->length; ++i) {
    GstBuffer *buffer = it->data;
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (ctx, i);

    if (!rtp_ulpfec_map_info_map (gst_buffer_ref (buffer), info))
      g_assert_not_reached ();

    GST_LOG_RTP_PACKET (ctx->parent, "rtp header (incoming)", &info->rtp);

    it = g_list_previous (it);
  }

  ctx->fec_packets = fec_packets;
  ctx->fec_packet_idx = 0;
}

static void
gst_rtp_ulpfec_enc_stream_ctx_stop (GstRtpUlpFecEncStreamCtx * ctx)
{
  g_array_set_size (ctx->info_arr, 0);
  g_array_set_size (ctx->scratch_buf, 0);

  ctx->fec_packets = 0;
  ctx->fec_packet_idx = 0;
}

static void
    gst_rtp_ulpfec_enc_stream_ctx_get_protection_parameters
    (GstRtpUlpFecEncStreamCtx * ctx, guint16 * dst_seq_base, guint64 * dst_mask,
    guint * dst_start, guint * dst_end)
{
  guint media_packets = ctx->info_arr->len;
  guint start = ctx->fec_packet_idx * media_packets / ctx->fec_packets;
  guint end =
      ((ctx->fec_packet_idx + 1) * media_packets + ctx->fec_packets -
      1) / ctx->fec_packets - 1;
  guint len = end - start + 1;
  guint64 mask = 0;
  guint16 seq_base = 0;

  len = MIN (len, RTP_ULPFEC_PROTECTED_PACKETS_MAX (TRUE));
  end = start + len - 1;

  for (guint i = start; i <= end; ++i) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (ctx, i);
    guint16 seq = gst_rtp_buffer_get_seq (&info->rtp);

    if (mask) {
      gint diff = gst_rtp_buffer_compare_seqnum (seq_base, seq);
      if (diff < 0) {
        seq_base = seq;
        mask = mask >> (-diff);
      }
      mask |= rtp_ulpfec_packet_mask_from_seqnum (seq, seq_base, TRUE);
    } else {
      seq_base = seq;
      mask = rtp_ulpfec_packet_mask_from_seqnum (seq, seq_base, TRUE);
    }
  }

  *dst_start = start;
  *dst_end = end;
  *dst_mask = mask;
  *dst_seq_base = seq_base;
}

static GstBuffer *
gst_rtp_ulpfec_enc_stream_ctx_protect (GstRtpUlpFecEncStreamCtx * ctx,
    guint8 pt, guint16 seq, guint32 timestamp, guint32 ssrc)
{
  guint end = 0;
  guint start = 0;
  guint64 fec_mask = 0;
  guint16 seq_base = 0;
  GstBuffer *ret;
  guint64 tmp_mask;
  gboolean fec_mask_long;

  if (ctx->fec_packet_idx >= ctx->fec_packets)
    return NULL;

  g_array_set_size (ctx->scratch_buf, 0);
  gst_rtp_ulpfec_enc_stream_ctx_get_protection_parameters (ctx, &seq_base,
      &fec_mask, &start, &end);

  tmp_mask = fec_mask;
  fec_mask_long = rtp_ulpfec_mask_is_long (fec_mask);
  for (guint i = start; i <= end; ++i) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (ctx, i);
    guint64 packet_mask =
        rtp_ulpfec_packet_mask_from_seqnum (gst_rtp_buffer_get_seq (&info->rtp),
        seq_base,
        TRUE);

    if (tmp_mask & packet_mask) {
      tmp_mask ^= packet_mask;
      rtp_buffer_to_ulpfec_bitstring (&info->rtp, ctx->scratch_buf, FALSE,
          fec_mask_long);
    }
  }

  g_assert (tmp_mask == 0ULL);
  ret =
      rtp_ulpfec_bitstring_to_fec_rtp_buffer (ctx->scratch_buf, seq_base,
      fec_mask_long, fec_mask, FALSE, pt, seq, timestamp, ssrc);
  ++ctx->fec_packet_idx;
  return ret;
}

static void
gst_rtp_ulpfec_enc_stream_ctx_report_budget (GstRtpUlpFecEncStreamCtx * ctx)
{
  GST_TRACE_OBJECT (ctx->parent, "budget = %f budget_important = %f",
      ctx->budget, ctx->budget_important);
}

static void
gst_rtp_ulpfec_enc_stream_ctx_increment_budget (GstRtpUlpFecEncStreamCtx * ctx,
    GstBuffer * buffer)
{
  if (ctx->percentage == 0 && ctx->percentage_important == 0) {
    if (ctx->budget > 0) {
      ctx->budget = 0;
      ctx->budget_important = 0;
    }
    if (ctx->budget < 0)
      ctx->budget += ctx->budget_inc;

    return;
  }
  ctx->budget += ctx->budget_inc;

  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_NON_DROPPABLE)) {
    ctx->budget_important += ctx->budget_inc_important;
  }

  gst_rtp_ulpfec_enc_stream_ctx_report_budget (ctx);
}

static void
gst_rtp_ulpfec_enc_stream_ctx_decrement_budget (GstRtpUlpFecEncStreamCtx * ctx,
    guint fec_packets_num)
{
  if (ctx->budget_important >= 1.)
    ctx->budget_important -= fec_packets_num;
  ctx->budget -= fec_packets_num;

  gst_rtp_ulpfec_enc_stream_ctx_report_budget (ctx);
}

static guint
gst_rtp_ulpfec_enc_stream_ctx_get_fec_packets_num (GstRtpUlpFecEncStreamCtx *
    ctx)
{
  g_assert_cmpfloat (ctx->budget_important, >=, 0.);

  if (ctx->budget_important >= 1.)
    return ctx->budget_important;
  return ctx->budget > 0. ? (guint) ctx->budget : 0;
}

static void
gst_rtp_ulpfec_enc_stream_ctx_free_packets_buf (GstRtpUlpFecEncStreamCtx * ctx)
{
  while (ctx->packets_buf.length)
    gst_buffer_unref (g_queue_pop_tail (&ctx->packets_buf));
}

static void
gst_rtp_ulpfec_enc_stream_ctx_prepend_to_fec_buffer (GstRtpUlpFecEncStreamCtx *
    ctx, GstRTPBuffer * rtp, guint buf_max_size)
{
  GList *new_head;
  if (ctx->packets_buf.length == buf_max_size) {
    new_head = g_queue_pop_tail_link (&ctx->packets_buf);
  } else {
    new_head = g_list_alloc ();
  }

  gst_buffer_replace ((GstBuffer **) & new_head->data, rtp->buffer);
  g_queue_push_head_link (&ctx->packets_buf, new_head);

  g_assert_cmpint (ctx->packets_buf.length, <=, buf_max_size);
}

static GstFlowReturn
gst_rtp_ulpfec_enc_stream_ctx_push_fec_packets (GstRtpUlpFecEncStreamCtx * ctx,
    guint8 pt, guint16 seq, guint32 timestamp, guint32 ssrc)
{
  GstFlowReturn ret = GST_FLOW_OK;
  guint fec_packets_num =
      gst_rtp_ulpfec_enc_stream_ctx_get_fec_packets_num (ctx);

  if (fec_packets_num) {
    guint fec_packets_pushed = 0;
    GstBuffer *latest_packet = ctx->packets_buf.head->data;
    GstBuffer *fec = NULL;

    gst_rtp_ulpfec_enc_stream_ctx_start (ctx, &ctx->packets_buf,
        fec_packets_num);

    while (NULL != (fec =
            gst_rtp_ulpfec_enc_stream_ctx_protect (ctx, pt,
                seq + fec_packets_pushed, timestamp, ssrc))) {
      gst_buffer_copy_into (fec, latest_packet, GST_BUFFER_COPY_TIMESTAMPS, 0,
          -1);

      ret = gst_pad_push (ctx->srcpad, fec);
      if (GST_FLOW_OK == ret)
        ++fec_packets_pushed;
      else
        break;
    }

    gst_rtp_ulpfec_enc_stream_ctx_stop (ctx);

    g_assert_cmpint (fec_packets_pushed, <=, fec_packets_num);

    ctx->num_packets_protected += ctx->packets_buf.length;
    ctx->num_packets_fec += fec_packets_pushed;
    ctx->seqnum_offset += fec_packets_pushed;
    ctx->seqnum += fec_packets_pushed;
  }

  gst_rtp_ulpfec_enc_stream_ctx_decrement_budget (ctx, fec_packets_num);
  return ret;
}

static void
gst_rtp_ulpfec_enc_stream_ctx_cache_packet (GstRtpUlpFecEncStreamCtx * ctx,
    GstRTPBuffer * rtp, gboolean * dst_empty_packet_buffer,
    gboolean * dst_push_fec)
{
  if (ctx->multipacket) {
    gst_rtp_ulpfec_enc_stream_ctx_prepend_to_fec_buffer (ctx, rtp,
        PACKETS_BUF_MAX_LENGTH);
    gst_rtp_ulpfec_enc_stream_ctx_increment_budget (ctx, rtp->buffer);

    *dst_empty_packet_buffer = gst_rtp_buffer_get_marker (rtp);
    *dst_push_fec = *dst_empty_packet_buffer;
  } else {
    gboolean push_fec;

    gst_rtp_ulpfec_enc_stream_ctx_prepend_to_fec_buffer (ctx, rtp, 1);

    push_fec = ctx->fec_nth == 0 ? FALSE :
        0 == (ctx->num_packets_received % ctx->fec_nth);

    ctx->budget = push_fec ? 1 : 0;
    ctx->budget_important = 0;

    *dst_push_fec = push_fec;
    *dst_empty_packet_buffer = FALSE;
  }
}

static void
gst_rtp_ulpfec_enc_stream_ctx_configure (GstRtpUlpFecEncStreamCtx * ctx,
    guint pt, guint32 fec_ssrc,
    guint percentage, guint percentage_important, gboolean multipacket,
    gboolean mux_seq)
{
  ctx->pt = pt;
  ctx->fec_ssrc = fec_ssrc;
  ctx->percentage = percentage;
  ctx->percentage_important = percentage_important;
  ctx->multipacket = multipacket;
  ctx->mux_seq = mux_seq;

  ctx->fec_nth = percentage ? 100 / percentage : 0;
  if (percentage) {
    ctx->budget_inc = percentage / 100.;
    ctx->budget_inc_important = percentage > percentage_important ?
        ctx->budget_inc : percentage_important / 100.;
  }
/*
   else {
    ctx->budget_inc = 0.0;
  }
*/
  ctx->budget_inc_important = percentage > percentage_important ?
      ctx->budget_inc : percentage_important / 100.;
}

static GstRtpUlpFecEncStreamCtx *
gst_rtp_ulpfec_enc_stream_ctx_new (guint ssrc,
    GstElement * parent, GstPad * srcpad,
    guint pt, guint32 fec_ssrc,
    guint percentage, guint percentage_important, gboolean multipacket,
    gboolean mux_seq)
{
  GstRtpUlpFecEncStreamCtx *ctx = g_new0 (GstRtpUlpFecEncStreamCtx, 1);

  ctx->ssrc = ssrc;
  ctx->parent = parent;
  ctx->srcpad = srcpad;

  ctx->seqnum = g_random_int_range (0, G_MAXUINT16 / 2);

  ctx->info_arr = g_array_new (FALSE, TRUE, sizeof (RtpUlpFecMapInfo));
  g_array_set_clear_func (ctx->info_arr,
      (GDestroyNotify) rtp_ulpfec_map_info_unmap);
  ctx->parent = parent;
  ctx->scratch_buf = g_array_new (FALSE, TRUE, sizeof (guint8));
  gst_rtp_ulpfec_enc_stream_ctx_configure (ctx, pt, fec_ssrc,
      percentage, percentage_important, multipacket, mux_seq);

  return ctx;
}

static void
gst_rtp_ulpfec_enc_stream_ctx_free (GstRtpUlpFecEncStreamCtx * ctx)
{
  if (ctx->num_packets_received) {
    GST_INFO_OBJECT (ctx->parent, "Actual FEC overhead is %4.2f%% (%u/%u)\n",
        ctx->num_packets_fec * (double) 100. / ctx->num_packets_received,
        ctx->num_packets_fec, ctx->num_packets_received);
  }
  gst_rtp_ulpfec_enc_stream_ctx_free_packets_buf (ctx);

  g_assert (0 == ctx->info_arr->len);
  g_array_free (ctx->info_arr, TRUE);
  g_array_free (ctx->scratch_buf, TRUE);
  g_slice_free1 (sizeof (GstRtpUlpFecEncStreamCtx), ctx);
}

static GstFlowReturn
gst_rtp_ulpfec_enc_stream_ctx_process (GstRtpUlpFecEncStreamCtx * ctx,
    GstBuffer * buffer)
{
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  GstFlowReturn ret;
  gboolean push_fec = FALSE;
  gboolean empty_packet_buffer = FALSE;

  ctx->num_packets_received++;

  if (ctx->mux_seq && ctx->seqnum_offset > 0) {
    buffer = gst_buffer_make_writable (buffer);
    if (!gst_rtp_buffer_map (buffer,
            GST_MAP_READWRITE | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtp))
      g_assert_not_reached ();
    gst_rtp_buffer_set_seq (&rtp,
        gst_rtp_buffer_get_seq (&rtp) + ctx->seqnum_offset);
  } else {
    if (!gst_rtp_buffer_map (buffer,
            GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtp))
      g_assert_not_reached ();
  }

  gst_rtp_ulpfec_enc_stream_ctx_cache_packet (ctx, &rtp, &empty_packet_buffer,
      &push_fec);

  if (push_fec) {
    guint32 fec_timestamp = gst_rtp_buffer_get_timestamp (&rtp);
    guint32 fec_ssrc =
        ctx->fec_ssrc ==
        UNDEF_SSRC ? gst_rtp_buffer_get_ssrc (&rtp) : ctx->fec_ssrc;
    guint16 fec_seq =
        ctx->mux_seq ? gst_rtp_buffer_get_seq (&rtp) + 1 : ctx->seqnum;

    gst_rtp_buffer_unmap (&rtp);

    ret = gst_pad_push (ctx->srcpad, buffer);
    if (GST_FLOW_OK == ret)
      ret =
          gst_rtp_ulpfec_enc_stream_ctx_push_fec_packets (ctx, ctx->pt, fec_seq,
          fec_timestamp, fec_ssrc);
  } else {
    gst_rtp_buffer_unmap (&rtp);
    ret = gst_pad_push (ctx->srcpad, buffer);
  }

  if (empty_packet_buffer)
    gst_rtp_ulpfec_enc_stream_ctx_free_packets_buf (ctx);

  return ret;
}

static GstRtpUlpFecEncStreamCtx *
gst_rtp_ulpfec_enc_aquire_ctx (GstRtpUlpFecEnc * fec, guint ssrc)
{
  GstRtpUlpFecEncStreamCtx *ctx;

  GST_OBJECT_LOCK (fec);
  ctx = g_hash_table_lookup (fec->ssrc_to_ctx, GUINT_TO_POINTER (ssrc));
  if (ctx == NULL) {
    ctx =
        gst_rtp_ulpfec_enc_stream_ctx_new (ssrc, GST_ELEMENT_CAST (fec),
        fec->srcpad, fec->pt, fec->ssrc, fec->percentage,
        fec->percentage_important, fec->multipacket, fec->mux_seq);
    g_hash_table_insert (fec->ssrc_to_ctx, GUINT_TO_POINTER (ssrc), ctx);
  }
  GST_OBJECT_UNLOCK (fec);

  return ctx;
}

static GstFlowReturn
gst_rtp_ulpfec_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
{
  GstRtpUlpFecEnc *fec = GST_RTP_ULPFEC_ENC (parent);
  GstRTPBuffer rtp = GST_RTP_BUFFER_INIT;
  GstFlowReturn ret;
  guint ssrc = 0;
  GstRtpUlpFecEncStreamCtx *ctx;

  if (fec->pt == UNDEF_PT)
    return gst_pad_push (fec->srcpad, buffer);

  /* FIXME: avoid this additional mapping of the buffer to get the
     ssrc! */
  if (!gst_rtp_buffer_map (buffer,
          GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtp)) {
    g_assert_not_reached ();
  }
  ssrc = gst_rtp_buffer_get_ssrc (&rtp);
  gst_rtp_buffer_unmap (&rtp);

  ctx = gst_rtp_ulpfec_enc_aquire_ctx (fec, ssrc);

  ret = gst_rtp_ulpfec_enc_stream_ctx_process (ctx, buffer);

  /* FIXME: does not work for mulitple ssrcs */
  fec->num_packets_protected = ctx->num_packets_protected;

  return ret;
}

static void
gst_rtp_ulpfec_enc_configure_ctx (gpointer key, gpointer value,
    gpointer user_data)
{
  GstRtpUlpFecEnc *fec = user_data;
  GstRtpUlpFecEncStreamCtx *ctx = value;

  gst_rtp_ulpfec_enc_stream_ctx_configure (ctx, fec->pt, fec->ssrc,
      fec->percentage, fec->percentage_important,
      fec->multipacket, fec->mux_seq);
}

static void
gst_rtp_ulpfec_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpUlpFecEnc *fec = GST_RTP_ULPFEC_ENC (object);

  switch (prop_id) {
    case PROP_PT:
      fec->pt = g_value_get_uint (value);
      break;
    case PROP_SSRC:
      fec->ssrc = g_value_get_uint (value);
      break;
    case PROP_MULTIPACKET:
      fec->multipacket = g_value_get_boolean (value);
      break;
    case PROP_PERCENTAGE:
      fec->percentage = g_value_get_uint (value);
      break;
    case PROP_PERCENTAGE_IMPORTANT:
      fec->percentage_important = g_value_get_uint (value);
      break;
    case PROP_MUX_SEQ:
      fec->mux_seq = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_LOCK (fec);
  g_hash_table_foreach (fec->ssrc_to_ctx, gst_rtp_ulpfec_enc_configure_ctx,
      fec);
  GST_OBJECT_UNLOCK (fec);
}

static void
gst_rtp_ulpfec_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpUlpFecEnc *fec = GST_RTP_ULPFEC_ENC (object);
  switch (prop_id) {
    case PROP_PT:
      g_value_set_uint (value, fec->pt);
      break;
    case PROP_SSRC:
      g_value_set_uint (value, fec->ssrc);
      break;
    case PROP_PROTECTED:
      g_value_set_uint (value, fec->num_packets_protected);
      break;
    case PROP_PERCENTAGE:
      g_value_set_uint (value, fec->percentage);
      break;
    case PROP_PERCENTAGE_IMPORTANT:
      g_value_set_uint (value, fec->percentage_important);
      break;
    case PROP_MULTIPACKET:
      g_value_set_boolean (value, fec->multipacket);
      break;
    case PROP_MUX_SEQ:
      g_value_set_boolean (value, fec->mux_seq);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_ulpfec_enc_dispose (GObject * obj)
{
  GstRtpUlpFecEnc *fec = GST_RTP_ULPFEC_ENC (obj);

  g_hash_table_destroy (fec->ssrc_to_ctx);

  G_OBJECT_CLASS (gst_rtp_ulpfec_enc_parent_class)->dispose (obj);
}

static void
gst_rtp_ulpfec_enc_init (GstRtpUlpFecEnc * fec)
{
  fec->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
  gst_element_add_pad (GST_ELEMENT (fec), fec->srcpad);

  fec->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
  GST_PAD_SET_PROXY_CAPS (fec->sinkpad);
  GST_PAD_SET_PROXY_ALLOCATION (fec->sinkpad);
  gst_pad_set_chain_function (fec->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_enc_chain));
  gst_element_add_pad (GST_ELEMENT (fec), fec->sinkpad);

  fec->ssrc_to_ctx = g_hash_table_new_full (NULL, NULL, NULL,
      (GDestroyNotify) gst_rtp_ulpfec_enc_stream_ctx_free);
}

static void
gst_rtp_ulpfec_enc_class_init (GstRtpUlpFecEncClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_rtp_ulpfec_enc_debug, "rtpulpfecenc", 0,
      "FEC encoder element");

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&srctemplate));
  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&sinktemplate));

  gst_element_class_set_static_metadata (element_class,
      "RTP FEC Encoder",
      "Codec/Payloader/Network/RTP",
      "Encodes RTP FEC (RFC5109)", "Mikhail Fludkov <misha@pexip.com>");

  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_enc_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_enc_get_property);
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_enc_dispose);

  g_object_class_install_property (gobject_class, PROP_SSRC,
      g_param_spec_uint ("ssrc", "SSRC",
          "The SSRC to use on FEC'd packets", 0, G_MAXUINT32, DEFAULT_SSRC,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PT,
      g_param_spec_uint ("pt", "payload type",
          "The payload type of FEC packets", 0, 255, DEFAULT_PT,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MULTIPACKET,
      g_param_spec_boolean ("multipacket", "Multipacket",
          "Apply FEC on multiple packets", DEFAULT_MULTIPACKET,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_MUX_SEQ,
      g_param_spec_boolean ("mux-seq", "Mux seq",
          "Mux seqnum for media and fec packets in same seqnum space",
          DEFAULT_MUX_SEQ,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PERCENTAGE,
      g_param_spec_uint ("percentage", "Percentage",
          "FEC overhead percentage for the whole stream", 0, 100, DEFAULT_PCT,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PERCENTAGE_IMPORTANT,
      g_param_spec_uint ("percentage-important", "Percentage important",
          "FEC overhead percentage for important packets",
          0, 100, DEFAULT_PCT_IMPORTANT,
          G_PARAM_CONSTRUCT | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class, PROP_PROTECTED,
      g_param_spec_uint ("protected", "Protected",
          "Count of protected packets", 0, G_MAXUINT32, 0,
          G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
}
