/* 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-rtpstorage
 * @short_description: RTP storage for forward error correction (FEC) in rtpbin
 * @title: rtpstorage
 *
 * Helper element for storing packets to aid later packet recovery from packet
 * loss using RED/FEC (Forward Error Correction).
 *
 * This element is used internally by rtpbin and is usually created
 * automatically.
 *
 * Since: 1.14
 */

#include "gstrtpstorage.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_SIZE_TIME,
  PROP_INTERNAL_STORAGE,
  N_PROPERTIES
};

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

#define DEFAULT_SIZE_TIME (0)

GST_DEBUG_CATEGORY_STATIC (gst_rtp_storage_debug);
#define GST_CAT_DEFAULT (gst_rtp_storage_debug)

G_DEFINE_TYPE (GstRtpStorage, gst_rtp_storage, GST_TYPE_ELEMENT);

static GstFlowReturn
gst_rtp_storage_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  GstRtpStorage *self = GST_RTP_STORAGE (parent);;

  if (rtp_storage_append_buffer (self->storage, buf))
    return gst_pad_push (self->srcpad, buf);
  return GST_FLOW_OK;
}

static void
gst_rtp_storage_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpStorage *self = GST_RTP_STORAGE (object);

  switch (prop_id) {
    case PROP_SIZE_TIME:
      rtp_storage_set_size (self->storage, g_value_get_uint64 (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_storage_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpStorage *self = GST_RTP_STORAGE (object);
  switch (prop_id) {
    case PROP_SIZE_TIME:
      g_value_set_uint64 (value, rtp_storage_get_size (self->storage));
      break;
    case PROP_INTERNAL_STORAGE:
    {
      g_value_set_object (value, self->storage);
      break;
    }
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_storage_init (GstRtpStorage * 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_rtp_storage_chain);

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

  self->storage = rtp_storage_new ();
}

static void
gst_rtp_storage_dispose (GObject * obj)
{
  GstRtpStorage *self = GST_RTP_STORAGE (obj);
  g_object_unref (self->storage);
  G_OBJECT_CLASS (gst_rtp_storage_parent_class)->dispose (obj);
}

static void
gst_rtp_storage_class_init (GstRtpStorageClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (gst_rtp_storage_debug,
      "rtpstorage", 0, "RTP Storage");

  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 storage",
      "Analyzer/RTP",
      "Helper element for various purposes "
      "(ex. recovering from packet loss using RED/FEC). "
      "Saves given number of RTP packets. "
      "Should be instantiated before jitterbuffer",
      "Mikhail Fludkov <misha@pexip.com>");

  gobject_class->set_property = gst_rtp_storage_set_property;
  gobject_class->get_property = gst_rtp_storage_get_property;
  gobject_class->dispose = gst_rtp_storage_dispose;

  klass_properties[PROP_SIZE_TIME] =
      g_param_spec_uint64 ("size-time", "Storage size (in ns)",
      "The amount of data to keep in the storage (in ns, 0-disable)", 0,
      G_MAXUINT64, DEFAULT_SIZE_TIME,
      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);

  klass_properties[PROP_INTERNAL_STORAGE] =
      g_param_spec_object ("internal-storage", "Internal storage",
      "Internal RtpStorage object", G_TYPE_OBJECT,
      G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);

  g_object_class_install_properties (gobject_class, N_PROPERTIES,
      klass_properties);
}
