/* 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>
 */

/**
 * SECTION:element-rtpulpfecdec
 * @short_description: Generic RTP Forward Error Correction (FEC) decoder
 * @title: rtpulpfecdec
 *
 * Generic Forward Error Correction (FEC) decoder for Uneven Level
 * Protection (ULP) as described in RFC 5109.
 *
 * This element will work in combination with an upstream #GstRtpStorage
 * element and attempt to recover packets declared lost through custom
 * 'GstRTPPacketLost' events, usually emitted by #GstRtpJitterBuffer.
 *
 * As such, this element cannot be usefully used from the command line,
 * because a reference to the upstream storage object needs to be
 * provided to it through its #GstRtpUlpFecDec:storage property, example
 * programs are available at
 * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecserver.rs>
 * and
 * <https://github.com/sdroege/gstreamer-rs/blob/master/examples/src/bin/rtpfecclient.rs>.
 *
 * Additionally, the payload types of the protection packets *must* be
 * provided to this element via its #GstRtpUlpFecDec:pt property.
 *
 * When using #GstRtpBin, this element should be inserted through the
 * #GstRtpBin::request-fec-decoder signal.
 *
 * See also: #GstRtpUlpFecEnc, #GstRtpBin, #GstRtpStorage
 * Since: 1.14
 */

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

#include "rtpulpfeccommon.h"
#include "gstrtpulpfecdec.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")
    );

enum
{
  PROP_0,
  PROP_PT,
  PROP_STORAGE,
  PROP_RECOVERED,
  PROP_UNRECOVERED,
  N_PROPERTIES
};

#define DEFAULT_FEC_PT 0

static GParamSpec *klass_properties[N_PROPERTIES] = { NULL, };

GST_DEBUG_CATEGORY (gst_rtp_ulpfec_dec_debug);
#define GST_CAT_DEFAULT (gst_rtp_ulpfec_dec_debug)

G_DEFINE_TYPE (GstRtpUlpFecDec, gst_rtp_ulpfec_dec, GST_TYPE_ELEMENT);

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

static gint
_compare_fec_map_info (gconstpointer a, gconstpointer b, gpointer userdata)
{
  guint16 aseq =
      gst_rtp_buffer_get_seq (&RTP_FEC_MAP_INFO_NTH (userdata, a)->rtp);
  guint16 bseq =
      gst_rtp_buffer_get_seq (&RTP_FEC_MAP_INFO_NTH (userdata, b)->rtp);
  return gst_rtp_buffer_compare_seqnum (bseq, aseq);
}

static void
gst_rtp_ulpfec_dec_start (GstRtpUlpFecDec * self, GstBufferList * buflist,
    guint8 fec_pt, guint16 lost_seq)
{
  guint fec_packets = 0;

  g_assert (NULL == self->info_media);
  g_assert (0 == self->info_fec->len);
  g_assert (0 == self->info_arr->len);

  g_array_set_size (self->info_arr, gst_buffer_list_length (buflist));

  for (gsize i = 0;
      i < gst_buffer_list_length (buflist) && !self->lost_packet_from_storage;
      ++i) {
    GstBuffer *buffer = gst_buffer_list_get (buflist, i);
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self, i);

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

    if (fec_pt == gst_rtp_buffer_get_payload_type (&info->rtp)) {
      GST_DEBUG_RTP_PACKET (self, "rtp header (fec)", &info->rtp);

      ++fec_packets;
      if (rtp_ulpfec_buffer_is_valid (&info->rtp)) {
        GST_DEBUG_FEC_PACKET (self, &info->rtp);
        g_ptr_array_add (self->info_fec, GUINT_TO_POINTER (i));
      }
    } else {
      GST_LOG_RTP_PACKET (self, "rtp header (incoming)", &info->rtp);

      if (lost_seq == gst_rtp_buffer_get_seq (&info->rtp)) {
        GST_DEBUG_OBJECT (self, "Received lost packet from from the storage");
        g_list_free (self->info_media);
        self->info_media = NULL;
        self->lost_packet_from_storage = TRUE;
      }
      self->info_media =
          g_list_insert_sorted_with_data (self->info_media,
          GUINT_TO_POINTER (i), _compare_fec_map_info, self);
    }
  }
  if (!self->lost_packet_from_storage) {
    self->fec_packets_received += fec_packets;
    self->fec_packets_rejected += fec_packets - self->info_fec->len;
  }
}

static void
gst_rtp_ulpfec_dec_stop (GstRtpUlpFecDec * self)
{
  g_array_set_size (self->info_arr, 0);
  g_ptr_array_set_size (self->info_fec, 0);
  g_list_free (self->info_media);
  self->info_media = NULL;
  self->lost_packet_from_storage = FALSE;
  self->lost_packet_returned = FALSE;
}

static guint64
gst_rtp_ulpfec_dec_get_media_buffers_mask (GstRtpUlpFecDec * self,
    guint16 fec_seq_base)
{
  guint64 mask = 0;
  for (GList * it = self->info_media; it; it = it->next) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self, it->data);
    mask |=
        rtp_ulpfec_packet_mask_from_seqnum (gst_rtp_buffer_get_seq (&info->rtp),
        fec_seq_base, TRUE);
  }
  return mask;
}

static gboolean
gst_rtp_ulpfec_dec_is_recovered_pt_valid (GstRtpUlpFecDec * self, gint media_pt,
    guint8 recovered_pt)
{
  if (media_pt == recovered_pt)
    return TRUE;

  for (GList * it = self->info_media; it; it = it->next) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self, it->data);
    if (gst_rtp_buffer_get_payload_type (&info->rtp) == recovered_pt)
      return TRUE;
  }
  return FALSE;
}

static GstBuffer *
gst_rtp_ulpfec_dec_recover_from_fec (GstRtpUlpFecDec * self,
    RtpUlpFecMapInfo * info_fec, guint32 ssrc, gint media_pt, guint16 seq,
    guint8 * dst_pt)
{
  guint64 fec_mask = rtp_ulpfec_buffer_get_mask (&info_fec->rtp);
  gboolean fec_mask_long = rtp_ulpfec_buffer_get_fechdr (&info_fec->rtp)->L;
  guint16 fec_seq_base = rtp_ulpfec_buffer_get_seq_base (&info_fec->rtp);
  GstBuffer *ret;

  g_array_set_size (self->scratch_buf, 0);
  rtp_buffer_to_ulpfec_bitstring (&info_fec->rtp, self->scratch_buf, TRUE,
      fec_mask_long);

  for (GList * it = self->info_media; it; it = it->next) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self, it->data);
    guint64 packet_mask =
        rtp_ulpfec_packet_mask_from_seqnum (gst_rtp_buffer_get_seq (&info->rtp),
        fec_seq_base, TRUE);

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

  ret =
      rtp_ulpfec_bitstring_to_media_rtp_buffer (self->scratch_buf,
      fec_mask_long, ssrc, seq);
  if (ret) {
    /* We are about to put recovered packet back in self->info_media to be able
     * to reuse it later for recovery of other packets
     **/
    gint i = self->info_arr->len;
    RtpUlpFecMapInfo *info;
    guint8 recovered_pt;

    g_array_set_size (self->info_arr, self->info_arr->len + 1);
    info = RTP_FEC_MAP_INFO_NTH (self, i);

    if (!rtp_ulpfec_map_info_map (gst_buffer_ref (ret), info)) {
      GST_WARNING_OBJECT (self, "Invalid recovered packet");
      goto recovered_packet_invalid;
    }

    recovered_pt = gst_rtp_buffer_get_payload_type (&info->rtp);
    if (!gst_rtp_ulpfec_dec_is_recovered_pt_valid (self, media_pt,
            recovered_pt)) {
      GST_WARNING_OBJECT (self,
          "Recovered packet has unexpected payload type (%u)", recovered_pt);
      goto recovered_packet_invalid;
    }

    GST_DEBUG_RTP_PACKET (self, "rtp header (recovered)", &info->rtp);
    self->info_media =
        g_list_insert_sorted_with_data (self->info_media, GUINT_TO_POINTER (i),
        _compare_fec_map_info, self);
    *dst_pt = recovered_pt;
  }
  return ret;

recovered_packet_invalid:
  g_array_set_size (self->info_arr, self->info_arr->len - 1);
  gst_buffer_unref (ret);
  return NULL;
}

static GstBuffer *
gst_rtp_ulpfec_dec_recover_from_storage (GstRtpUlpFecDec * self,
    guint8 * dst_pt, guint16 * dst_seq)
{
  RtpUlpFecMapInfo *info;

  if (self->lost_packet_returned)
    return NULL;

  g_assert (g_list_length (self->info_media) == 1);

  info = RTP_FEC_MAP_INFO_NTH (self, self->info_media->data);
  *dst_seq = gst_rtp_buffer_get_seq (&info->rtp);
  *dst_pt = gst_rtp_buffer_get_payload_type (&info->rtp);
  self->lost_packet_returned = TRUE;
  GST_DEBUG_RTP_PACKET (self, "rtp header (recovered)", &info->rtp);
  return gst_buffer_ref (info->rtp.buffer);
}

static GstBuffer *
gst_rtp_ulpfec_dec_recover (GstRtpUlpFecDec * self, guint32 ssrc, gint media_pt,
    guint8 * dst_pt, guint16 * dst_seq)
{
  guint64 media_mask = 0;
  gint media_mask_seq_base = -1;

  if (self->lost_packet_from_storage)
    return gst_rtp_ulpfec_dec_recover_from_storage (self, dst_pt, dst_seq);

  /* Looking for a FEC packet which can be used for recovery */
  for (gsize i = 0; i < self->info_fec->len; ++i) {
    RtpUlpFecMapInfo *info = RTP_FEC_MAP_INFO_NTH (self,
        g_ptr_array_index (self->info_fec, i));
    guint16 seq_base = rtp_ulpfec_buffer_get_seq_base (&info->rtp);
    guint64 fec_mask = rtp_ulpfec_buffer_get_mask (&info->rtp);
    guint64 missing_packets_mask;

    if (media_mask_seq_base != (gint) seq_base) {
      media_mask_seq_base = seq_base;
      media_mask = gst_rtp_ulpfec_dec_get_media_buffers_mask (self, seq_base);
    }

    /* media_mask has 1s if packet exist.
     * fec_mask is the mask of protected packets
     * The statement below excludes existing packets from the protected. So
     * we are left with 1s only for missing packets which can be recovered
     * by this FEC packet. */
    missing_packets_mask = fec_mask & (~media_mask);

    /* Do we have any 1s? Checking if current FEC packet can be used for recovery */
    if (0 != missing_packets_mask) {
      guint trailing_zeros = __builtin_ctzll (missing_packets_mask);

      /* Is it the only 1 in the mask? Checking if we lacking single packet in
       * that case FEC packet can be used for recovery */
      if (missing_packets_mask == (1ULL << trailing_zeros)) {
        GstBuffer *ret;

        *dst_seq =
            seq_base + (RTP_ULPFEC_SEQ_BASE_OFFSET_MAX (TRUE) - trailing_zeros);
        ret =
            gst_rtp_ulpfec_dec_recover_from_fec (self, info, ssrc, media_pt,
            *dst_seq, dst_pt);
        if (ret)
          return ret;
      }
    }
  }
  return NULL;
}

static GstFlowReturn
gst_rtp_ulpfec_dec_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (parent);

  if (G_LIKELY (GST_FLOW_OK == self->chain_return_val)) {
    if (G_UNLIKELY (self->unset_discont_flag)) {
      self->unset_discont_flag = FALSE;
      buf = gst_buffer_make_writable (buf);
      GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
    }
    return gst_pad_push (self->srcpad, buf);
  }

  gst_buffer_unref (buf);
  return self->chain_return_val;
}

static gboolean
gst_rtp_ulpfec_dec_handle_packet_loss (GstRtpUlpFecDec * self, guint16 seqnum,
    GstClockTime timestamp, GstClockTime duration)
{
  gint caps_pt = self->have_caps_pt ? self->caps_pt : -1;
  gboolean ret = TRUE;
  GstBufferList *buflist =
      rtp_storage_get_packets_for_recovery (self->storage, self->fec_pt,
      self->caps_ssrc, seqnum);

  if (buflist) {
    GstBuffer *recovered_buffer = NULL;
    guint16 recovered_seq = 0;
    guint8 recovered_pt = 0;

    gst_rtp_ulpfec_dec_start (self, buflist, self->fec_pt, seqnum);

    while (NULL != (recovered_buffer =
            gst_rtp_ulpfec_dec_recover (self, self->caps_ssrc, caps_pt,
                &recovered_pt, &recovered_seq))) {
      if (seqnum == recovered_seq) {
        recovered_buffer = gst_buffer_make_writable (recovered_buffer);
        GST_BUFFER_PTS (recovered_buffer) = timestamp;
        /* GST_BUFFER_DURATION (recovered_buffer) = duration;
         * JB does not set the duration, so we will not too */

        if (!self->lost_packet_from_storage)
          rtp_storage_put_recovered_packet (self->storage,
              gst_buffer_ref (recovered_buffer), recovered_pt, self->caps_ssrc,
              recovered_seq);

        GST_DEBUG_OBJECT (self,
            "Pushing recovered packet ssrc=0x%08x seq=%u %" GST_PTR_FORMAT,
            self->caps_ssrc, seqnum, recovered_buffer);

        ret = FALSE;
        self->unset_discont_flag = TRUE;
        self->chain_return_val = gst_pad_push (self->srcpad, recovered_buffer);
        break;
      }

      rtp_storage_put_recovered_packet (self->storage,
          recovered_buffer, recovered_pt, self->caps_ssrc, recovered_seq);
    }

    gst_rtp_ulpfec_dec_stop (self);
    gst_buffer_list_unref (buflist);
  }

  GST_DEBUG_OBJECT (self, "Packet lost ssrc=0x%08x seq=%u", self->caps_ssrc,
      seqnum);

  return ret;
}

static gboolean
gst_rtp_ulpfec_dec_handle_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (parent);
  gboolean forward = TRUE;

  GST_LOG_OBJECT (self, "Received event %" GST_PTR_FORMAT, event);

  if (GST_FLOW_OK == self->chain_return_val &&
      GST_EVENT_CUSTOM_DOWNSTREAM == GST_EVENT_TYPE (event) &&
      gst_event_has_name (event, "GstRTPPacketLost")) {
    guint seqnum;
    GstClockTime timestamp, duration;

    g_assert (self->have_caps_ssrc);
    g_assert (self->storage);

    if (!gst_structure_get (gst_event_get_structure (event),
            "seqnum", G_TYPE_UINT, &seqnum,
            "timestamp", G_TYPE_UINT64, &timestamp,
            "duration", G_TYPE_UINT64, &duration, NULL))
      g_assert_not_reached ();

    forward =
        gst_rtp_ulpfec_dec_handle_packet_loss (self, seqnum, timestamp,
        duration);
    if (forward)
      ++self->packets_unrecovered;
    else
      ++self->packets_recovered;
    GST_DEBUG_OBJECT (self, "Unrecovered / Recovered: %lu / %lu",
        (gulong) self->packets_unrecovered, (gulong) self->packets_recovered);
  } else if (GST_EVENT_CAPS == GST_EVENT_TYPE (event)) {
    GstCaps *caps;
    gboolean have_caps_pt = FALSE;
    gboolean have_caps_ssrc = FALSE;
    guint caps_ssrc = 0;
    gint caps_pt = 0;

    gst_event_parse_caps (event, &caps);
    have_caps_ssrc =
        gst_structure_get_uint (gst_caps_get_structure (caps, 0), "ssrc",
        &caps_ssrc);
    have_caps_pt =
        gst_structure_get_int (gst_caps_get_structure (caps, 0), "payload",
        &caps_pt);

    if (self->have_caps_ssrc != have_caps_ssrc || self->caps_ssrc != caps_ssrc)
      GST_DEBUG_OBJECT (self, "SSRC changed %u, 0x%08x -> %u, 0x%08x",
          self->have_caps_ssrc, self->caps_ssrc, have_caps_ssrc, caps_ssrc);
    if (self->have_caps_pt != have_caps_pt || self->caps_pt != caps_pt)
      GST_DEBUG_OBJECT (self, "PT changed %u, %u -> %u, %u",
          self->have_caps_pt, self->caps_pt, have_caps_pt, caps_pt);

    self->have_caps_ssrc = have_caps_ssrc;
    self->have_caps_pt = have_caps_pt;
    self->caps_ssrc = caps_ssrc;
    self->caps_pt = caps_pt;
  }

  if (forward)
    return gst_pad_push_event (self->srcpad, event);
  gst_event_unref (event);
  return TRUE;
}

static void
gst_rtp_ulpfec_dec_init (GstRtpUlpFecDec * self)
{
  self->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
  self->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
  GST_PAD_SET_PROXY_CAPS (self->sinkpad);
  GST_PAD_SET_PROXY_ALLOCATION (self->sinkpad);
  gst_pad_set_chain_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_dec_chain));
  gst_pad_set_event_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_dec_handle_sink_event));

  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

  self->fec_pt = DEFAULT_FEC_PT;

  self->chain_return_val = GST_FLOW_OK;
  self->have_caps_ssrc = FALSE;
  self->caps_ssrc = 0;
  self->info_fec = g_ptr_array_new ();
  self->info_arr = g_array_new (FALSE, TRUE, sizeof (RtpUlpFecMapInfo));
  g_array_set_clear_func (self->info_arr,
      (GDestroyNotify) rtp_ulpfec_map_info_unmap);
  self->scratch_buf = g_array_new (FALSE, TRUE, sizeof (guint8));
}

static void
gst_rtp_ulpfec_dec_dispose (GObject * obj)
{
  GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (obj);

  GST_INFO_OBJECT (self,
      " ssrc=0x%08x pt=%u"
      " packets_recovered=%" G_GSIZE_FORMAT
      " packets_unrecovered=%" G_GSIZE_FORMAT,
      self->caps_ssrc, self->caps_pt,
      self->packets_recovered, self->packets_unrecovered);

  if (self->storage)
    g_object_unref (self->storage);

  g_assert (NULL == self->info_media);
  g_assert (0 == self->info_fec->len);
  g_assert (0 == self->info_arr->len);

  if (self->fec_packets_received) {
    GST_INFO_OBJECT (self,
        " fec_packets_received=%" G_GSIZE_FORMAT
        " fec_packets_rejected=%" G_GSIZE_FORMAT
        " packets_rejected=%" G_GSIZE_FORMAT,
        self->fec_packets_received,
        self->fec_packets_rejected, self->packets_rejected);
  }

  g_ptr_array_free (self->info_fec, TRUE);
  g_array_free (self->info_arr, TRUE);
  g_array_free (self->scratch_buf, TRUE);

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

static void
gst_rtp_ulpfec_dec_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (object);

  switch (prop_id) {
    case PROP_PT:
      self->fec_pt = g_value_get_uint (value);
      break;
    case PROP_STORAGE:
      if (self->storage)
        g_object_unref (self->storage);
      self->storage = g_value_get_object (value);
      if (self->storage)
        g_object_ref (self->storage);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_ulpfec_dec_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpUlpFecDec *self = GST_RTP_ULPFEC_DEC (object);

  switch (prop_id) {
    case PROP_PT:
      g_value_set_uint (value, self->fec_pt);
      break;
    case PROP_STORAGE:
      g_value_set_object (value, self->storage);
      break;
    case PROP_RECOVERED:
      g_value_set_uint (value, (guint) self->packets_recovered);
      break;
    case PROP_UNRECOVERED:
      g_value_set_uint (value, (guint) self->packets_unrecovered);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_ulpfec_dec_class_init (GstRtpUlpFecDecClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_rtp_ulpfec_dec_debug,
      "rtpulpfecdec", 0, "RTP FEC Decoder");

  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 Decoder",
      "Codec/Depayloader/Network/RTP",
      "Decodes RTP FEC (RFC5109)", "Mikhail Fludkov <misha@pexip.com>");

  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_dec_set_property);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_dec_get_property);
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_rtp_ulpfec_dec_dispose);

  klass_properties[PROP_PT] = g_param_spec_uint ("pt", "pt",
      "FEC packets payload type", 0, 127,
      DEFAULT_FEC_PT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
  klass_properties[PROP_STORAGE] =
      g_param_spec_object ("storage", "RTP storage", "RTP storage",
      G_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
  klass_properties[PROP_RECOVERED] =
      g_param_spec_uint ("recovered", "recovered",
      "The number of recovered packets", 0, G_MAXUINT, 0,
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
  klass_properties[PROP_UNRECOVERED] =
      g_param_spec_uint ("unrecovered", "unrecovered",
      "The number of unrecovered packets", 0, G_MAXUINT, 0,
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, N_PROPERTIES,
      klass_properties);
}
