/* GStreamer
 * Copyright (C) <2010> Wim Taymans <wim.taymans@gmail.com>
 *
 * 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.
 */

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

#include <string.h>

#include <gst/rtp/gstrtpbuffer.h>

#include "gstrtpgstpay.h"
#include "gstrtputils.h"

GST_DEBUG_CATEGORY_STATIC (gst_rtp_pay_debug);
#define GST_CAT_DEFAULT gst_rtp_pay_debug

/*
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |C| CV  |D|0|0|0|     ETYPE     |  MBZ                          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                          Frag_offset                          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 * C: caps inlined flag
 *   When C set, first part of payload contains caps definition. Caps definition
 *   starts with variable-length length prefix and then a string of that length.
 *   the length is encoded in big endian 7 bit chunks, the top 1 bit of a byte
 *   is the continuation marker and the 7 next bits the data. A continuation
 *   marker of 1 means that the next byte contains more data.
 *
 * CV: caps version, 0 = caps from SDP, 1 - 7 inlined caps
 * D: delta unit buffer
 * ETYPE: type of event. Payload contains the event, prefixed with a
 *        variable length field.
 *   0 = NO event
 *   1 = GST_EVENT_TAG
 *   2 = GST_EVENT_CUSTOM_DOWNSTREAM
 *   3 = GST_EVENT_CUSTOM_BOTH
 *   4 = GST_EVENT_STREAM_START
 */

static GstStaticPadTemplate gst_rtp_gst_pay_sink_template =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS_ANY);

static GstStaticPadTemplate gst_rtp_gst_pay_src_template =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("application/x-rtp, "
        "media = (string) \"application\", "
        "payload = (int) " GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
        "clock-rate = (int) 90000, " "encoding-name = (string) \"X-GST\"")
    );

enum
{
  PROP_0,
  PROP_CONFIG_INTERVAL
};

#define DEFAULT_CONFIG_INTERVAL		      0

static void gst_rtp_gst_pay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_rtp_gst_pay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);
static void gst_rtp_gst_pay_finalize (GObject * obj);
static GstStateChangeReturn gst_rtp_gst_pay_change_state (GstElement * element,
    GstStateChange transition);

static gboolean gst_rtp_gst_pay_setcaps (GstRTPBasePayload * payload,
    GstCaps * caps);
static GstFlowReturn gst_rtp_gst_pay_handle_buffer (GstRTPBasePayload * payload,
    GstBuffer * buffer);
static gboolean gst_rtp_gst_pay_sink_event (GstRTPBasePayload * payload,
    GstEvent * event);

#define gst_rtp_gst_pay_parent_class parent_class
G_DEFINE_TYPE (GstRtpGSTPay, gst_rtp_gst_pay, GST_TYPE_RTP_BASE_PAYLOAD);

static void
gst_rtp_gst_pay_class_init (GstRtpGSTPayClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstRTPBasePayloadClass *gstrtpbasepayload_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstrtpbasepayload_class = (GstRTPBasePayloadClass *) klass;

  gobject_class->set_property = gst_rtp_gst_pay_set_property;
  gobject_class->get_property = gst_rtp_gst_pay_get_property;
  gobject_class->finalize = gst_rtp_gst_pay_finalize;

  g_object_class_install_property (G_OBJECT_CLASS (klass),
      PROP_CONFIG_INTERVAL,
      g_param_spec_uint ("config-interval",
          "Caps/Tags Send Interval",
          "Interval for sending caps and TAG events in seconds (0 = disabled)",
          0, 3600, DEFAULT_CONFIG_INTERVAL,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)
      );

  gstelement_class->change_state = gst_rtp_gst_pay_change_state;

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_gst_pay_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&gst_rtp_gst_pay_sink_template));

  gst_element_class_set_static_metadata (gstelement_class,
      "RTP GStreamer payloader", "Codec/Payloader/Network/RTP",
      "Payload GStreamer buffers as RTP packets",
      "Wim Taymans <wim.taymans@gmail.com>");

  gstrtpbasepayload_class->set_caps = gst_rtp_gst_pay_setcaps;
  gstrtpbasepayload_class->handle_buffer = gst_rtp_gst_pay_handle_buffer;
  gstrtpbasepayload_class->sink_event = gst_rtp_gst_pay_sink_event;

  GST_DEBUG_CATEGORY_INIT (gst_rtp_pay_debug, "rtpgstpay", 0,
      "rtpgstpay element");
}

static void
gst_rtp_gst_pay_init (GstRtpGSTPay * rtpgstpay)
{
  rtpgstpay->adapter = gst_adapter_new ();
  rtpgstpay->pending_buffers = NULL;
  gst_rtp_base_payload_set_options (GST_RTP_BASE_PAYLOAD (rtpgstpay),
      "application", TRUE, "X-GST", 90000);
  rtpgstpay->last_config = GST_CLOCK_TIME_NONE;
  rtpgstpay->taglist = NULL;
  rtpgstpay->config_interval = DEFAULT_CONFIG_INTERVAL;
}

static void
gst_rtp_gst_pay_reset (GstRtpGSTPay * rtpgstpay, gboolean full)
{
  rtpgstpay->last_config = GST_CLOCK_TIME_NONE;
  gst_adapter_clear (rtpgstpay->adapter);
  rtpgstpay->flags &= 0x70;
  rtpgstpay->etype = 0;
  if (rtpgstpay->pending_buffers)
    g_list_free_full (rtpgstpay->pending_buffers,
        (GDestroyNotify) gst_buffer_list_unref);
  rtpgstpay->pending_buffers = NULL;
  if (full) {
    if (rtpgstpay->taglist)
      gst_tag_list_unref (rtpgstpay->taglist);
    rtpgstpay->taglist = NULL;
    g_free (rtpgstpay->stream_id);
    rtpgstpay->stream_id = NULL;
    rtpgstpay->current_CV = 0;
    rtpgstpay->next_CV = 0;
  }
}

static void
gst_rtp_gst_pay_finalize (GObject * obj)
{
  GstRtpGSTPay *rtpgstpay;

  rtpgstpay = GST_RTP_GST_PAY (obj);

  gst_rtp_gst_pay_reset (rtpgstpay, TRUE);

  g_object_unref (rtpgstpay->adapter);

  G_OBJECT_CLASS (parent_class)->finalize (obj);
}

static void
gst_rtp_gst_pay_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstRtpGSTPay *rtpgstpay;

  rtpgstpay = GST_RTP_GST_PAY (object);

  switch (prop_id) {
    case PROP_CONFIG_INTERVAL:
      rtpgstpay->config_interval = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_rtp_gst_pay_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstRtpGSTPay *rtpgstpay;

  rtpgstpay = GST_RTP_GST_PAY (object);

  switch (prop_id) {
    case PROP_CONFIG_INTERVAL:
      g_value_set_uint (value, rtpgstpay->config_interval);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstStateChangeReturn
gst_rtp_gst_pay_change_state (GstElement * element, GstStateChange transition)
{
  GstRtpGSTPay *rtpgstpay;
  GstStateChangeReturn ret;

  rtpgstpay = GST_RTP_GST_PAY (element);

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_rtp_gst_pay_reset (rtpgstpay, TRUE);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_rtp_gst_pay_reset (rtpgstpay, TRUE);
      break;
    default:
      break;
  }
  return ret;
}

#define RTP_HEADER_LEN 12

static gboolean
gst_rtp_gst_pay_create_from_adapter (GstRtpGSTPay * rtpgstpay,
    GstClockTime timestamp)
{
  guint avail, mtu;
  guint frag_offset;
  GstBufferList *list;

  avail = gst_adapter_available (rtpgstpay->adapter);
  if (avail == 0)
    return FALSE;

  mtu = GST_RTP_BASE_PAYLOAD_MTU (rtpgstpay);

  list = gst_buffer_list_new_sized ((avail / (mtu - (RTP_HEADER_LEN + 8))) + 1);
  frag_offset = 0;

  while (avail) {
    guint towrite;
    guint8 *payload;
    guint payload_len;
    guint packet_len;
    GstBuffer *outbuf;
    GstRTPBuffer rtp = { NULL };
    GstBuffer *paybuf;


    /* this will be the total lenght of the packet */
    packet_len = gst_rtp_buffer_calc_packet_len (8 + avail, 0, 0);

    /* fill one MTU or all available bytes */
    towrite = MIN (packet_len, mtu);

    /* this is the payload length */
    payload_len = gst_rtp_buffer_calc_payload_len (towrite, 0, 0);

    /* create buffer to hold the header */
    outbuf = gst_rtp_buffer_new_allocate (8, 0, 0);

    gst_rtp_buffer_map (outbuf, GST_MAP_WRITE, &rtp);
    payload = gst_rtp_buffer_get_payload (&rtp);

    GST_DEBUG_OBJECT (rtpgstpay, "new packet len %u, frag %u", packet_len,
        frag_offset);

    /*
     *  0                   1                   2                   3
     *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * |C| CV  |D|0|0|0|     ETYPE     |  MBZ                          |
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     * |                          Frag_offset                          |
     * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     */
    payload[0] = rtpgstpay->flags;
    payload[1] = rtpgstpay->etype;
    payload[2] = payload[3] = 0;
    payload[4] = frag_offset >> 24;
    payload[5] = frag_offset >> 16;
    payload[6] = frag_offset >> 8;
    payload[7] = frag_offset & 0xff;

    payload += 8;
    payload_len -= 8;

    frag_offset += payload_len;
    avail -= payload_len;

    if (avail == 0)
      gst_rtp_buffer_set_marker (&rtp, TRUE);

    gst_rtp_buffer_unmap (&rtp);

    /* create a new buf to hold the payload */
    GST_DEBUG_OBJECT (rtpgstpay, "take %u bytes from adapter", payload_len);
    paybuf = gst_adapter_take_buffer_fast (rtpgstpay->adapter, payload_len);

    /* create a new group to hold the rtp header and the payload */
    gst_rtp_copy_meta (GST_ELEMENT_CAST (rtpgstpay), outbuf, paybuf, 0);
    outbuf = gst_buffer_append (outbuf, paybuf);

    GST_BUFFER_PTS (outbuf) = timestamp;

    /* and add to list */
    gst_buffer_list_insert (list, -1, outbuf);
  }

  rtpgstpay->flags &= 0x70;
  rtpgstpay->etype = 0;
  rtpgstpay->pending_buffers = g_list_append (rtpgstpay->pending_buffers, list);

  return TRUE;
}

static GstFlowReturn
gst_rtp_gst_pay_flush (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp)
{
  GstFlowReturn ret = GST_FLOW_OK;
  GList *iter;

  gst_rtp_gst_pay_create_from_adapter (rtpgstpay, timestamp);

  iter = rtpgstpay->pending_buffers;
  while (iter) {
    GstBufferList *list = iter->data;

    rtpgstpay->pending_buffers = iter =
        g_list_delete_link (rtpgstpay->pending_buffers, iter);

    /* push the whole buffer list at once */
    ret = gst_rtp_base_payload_push_list (GST_RTP_BASE_PAYLOAD (rtpgstpay),
        list);
    if (ret != GST_FLOW_OK)
      break;
  }

  return ret;
}

static GstBuffer *
make_data_buffer (GstRtpGSTPay * rtpgstpay, gchar * data, guint size)
{
  guint plen;
  guint8 *ptr;
  GstBuffer *outbuf;
  GstMapInfo map;

  /* calculate length */
  plen = 1;
  while (size >> (7 * plen))
    plen++;

  outbuf = gst_buffer_new_allocate (NULL, plen + size, NULL);

  gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
  ptr = map.data;

  /* write length */
  while (plen) {
    plen--;
    *ptr++ = ((plen > 0) ? 0x80 : 0) | ((size >> (7 * plen)) & 0x7f);
  }
  /* copy data */
  memcpy (ptr, data, size);
  gst_buffer_unmap (outbuf, &map);

  return outbuf;
}

static void
gst_rtp_gst_pay_send_caps (GstRtpGSTPay * rtpgstpay, guint8 cv, GstCaps * caps)
{
  gchar *capsstr;
  guint capslen;
  GstBuffer *outbuf;

  if (rtpgstpay->flags & (1 << 7))
    return;

  capsstr = gst_caps_to_string (caps);
  capslen = strlen (capsstr);
  /* for 0 byte */
  capslen++;

  GST_DEBUG_OBJECT (rtpgstpay, "sending caps=%s", capsstr);

  /* make a data buffer of it */
  outbuf = make_data_buffer (rtpgstpay, capsstr, capslen);
  g_free (capsstr);

  /* store in adapter, we don't flush yet, buffer might follow */
  rtpgstpay->flags = (1 << 7) | (cv << 4);
  gst_adapter_push (rtpgstpay->adapter, outbuf);
}

static gboolean
gst_rtp_gst_pay_setcaps (GstRTPBasePayload * payload, GstCaps * caps)
{
  GstRtpGSTPay *rtpgstpay;
  gboolean res;
  gchar *capsstr, *capsenc, *capsver;
  guint capslen;

  rtpgstpay = GST_RTP_GST_PAY (payload);

  capsstr = gst_caps_to_string (caps);
  capslen = strlen (capsstr);

  /* encode without 0 byte */
  capsenc = g_base64_encode ((guchar *) capsstr, capslen);
  GST_DEBUG_OBJECT (payload, "caps=%s, caps(base64)=%s", capsstr, capsenc);
  g_free (capsstr);

  /* Send the new caps */
  rtpgstpay->current_CV = rtpgstpay->next_CV;
  rtpgstpay->next_CV = (rtpgstpay->next_CV + 1) & 0x7;
  gst_rtp_gst_pay_send_caps (rtpgstpay, rtpgstpay->current_CV, caps);

  /* make caps for SDP */
  capsver = g_strdup_printf ("%d", rtpgstpay->current_CV);
  res =
      gst_rtp_base_payload_set_outcaps (payload, "caps", G_TYPE_STRING, capsenc,
      "capsversion", G_TYPE_STRING, capsver, NULL);
  g_free (capsenc);
  g_free (capsver);

  return res;
}

static void
gst_rtp_gst_pay_send_event (GstRtpGSTPay * rtpgstpay, guint etype,
    GstEvent * event)
{
  const GstStructure *s;
  gchar *estr;
  guint elen;
  GstBuffer *outbuf;

  /* Create the standalone caps packet if an inlined caps was pending */
  gst_rtp_gst_pay_create_from_adapter (rtpgstpay, GST_CLOCK_TIME_NONE);

  s = gst_event_get_structure (event);

  estr = gst_structure_to_string (s);
  elen = strlen (estr);
  /* for 0 byte */
  elen++;
  outbuf = make_data_buffer (rtpgstpay, estr, elen);
  GST_DEBUG_OBJECT (rtpgstpay, "sending event=%s", estr);
  g_free (estr);

  rtpgstpay->etype = etype;
  gst_adapter_push (rtpgstpay->adapter, outbuf);
  /* Create the event packet now to avoid conflict with data/caps packets */
  gst_rtp_gst_pay_create_from_adapter (rtpgstpay, GST_CLOCK_TIME_NONE);
}

static gboolean
gst_rtp_gst_pay_sink_event (GstRTPBasePayload * payload, GstEvent * event)
{
  gboolean ret;
  GstRtpGSTPay *rtpgstpay;
  guint etype = 0;

  rtpgstpay = GST_RTP_GST_PAY (payload);

  ret =
      GST_RTP_BASE_PAYLOAD_CLASS (parent_class)->sink_event (payload,
      gst_event_ref (event));

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_rtp_gst_pay_reset (rtpgstpay, FALSE);
      break;
    case GST_EVENT_TAG:{
      GstTagList *tags;

      gst_event_parse_tag (event, &tags);

      if (gst_tag_list_get_scope (tags) == GST_TAG_SCOPE_STREAM) {
        GstTagList *old;

        GST_DEBUG_OBJECT (rtpgstpay, "storing stream tags %" GST_PTR_FORMAT,
            tags);
        if ((old = rtpgstpay->taglist))
          gst_tag_list_unref (old);
        rtpgstpay->taglist = gst_tag_list_ref (tags);
      }
      etype = 1;
      break;
    }
    case GST_EVENT_CUSTOM_DOWNSTREAM:
      etype = 2;
      break;
    case GST_EVENT_CUSTOM_BOTH:
      etype = 3;
      break;
    case GST_EVENT_STREAM_START:{
      const gchar *stream_id = NULL;

      if (rtpgstpay->taglist)
        gst_tag_list_unref (rtpgstpay->taglist);
      rtpgstpay->taglist = NULL;

      gst_event_parse_stream_start (event, &stream_id);
      if (stream_id) {
        g_free (rtpgstpay->stream_id);
        rtpgstpay->stream_id = g_strdup (stream_id);
      }
      etype = 4;
      break;
    }
    default:
      GST_LOG_OBJECT (rtpgstpay, "no event for %s",
          GST_EVENT_TYPE_NAME (event));
      break;
  }
  if (etype) {
    GST_DEBUG_OBJECT (rtpgstpay, "make event type %d for %s",
        etype, GST_EVENT_TYPE_NAME (event));
    gst_rtp_gst_pay_send_event (rtpgstpay, etype, event);
    /* Do not send stream-start right away since caps/new-segment were not yet
       sent, so our data would be considered invalid */
    if (etype != 4) {
      /* flush the adapter immediately */
      gst_rtp_gst_pay_flush (rtpgstpay, GST_CLOCK_TIME_NONE);
    }
  }

  gst_event_unref (event);

  return ret;
}

static void
gst_rtp_gst_pay_send_config (GstRtpGSTPay * rtpgstpay, GstClockTime timestamp)
{
  GstPad *pad = GST_RTP_BASE_PAYLOAD_SINKPAD (rtpgstpay);
  GstCaps *caps = NULL;
  GstEvent *tag = NULL;
  GstEvent *stream_start = NULL;

  GST_DEBUG_OBJECT (rtpgstpay, "time to send config");
  /* Send tags */
  if (rtpgstpay->taglist && !gst_tag_list_is_empty (rtpgstpay->taglist))
    tag = gst_event_new_tag (gst_tag_list_ref (rtpgstpay->taglist));
  if (tag) {
    /* Send start-stream to clear tags */
    if (rtpgstpay->stream_id)
      stream_start = gst_event_new_stream_start (rtpgstpay->stream_id);
    if (stream_start) {
      gst_rtp_gst_pay_send_event (rtpgstpay, 4, stream_start);
      gst_event_unref (stream_start);
    }
    gst_rtp_gst_pay_send_event (rtpgstpay, 1, tag);
    gst_event_unref (tag);
  }
  /* send caps */
  caps = gst_pad_get_current_caps (pad);
  if (caps) {
    gst_rtp_gst_pay_send_caps (rtpgstpay, rtpgstpay->current_CV, caps);
    gst_caps_unref (caps);
  }
  rtpgstpay->last_config = timestamp;
}

static GstFlowReturn
gst_rtp_gst_pay_handle_buffer (GstRTPBasePayload * basepayload,
    GstBuffer * buffer)
{
  GstFlowReturn ret;
  GstRtpGSTPay *rtpgstpay;
  GstClockTime timestamp;

  rtpgstpay = GST_RTP_GST_PAY (basepayload);

  timestamp = GST_BUFFER_PTS (buffer);

  /* check if we need to send the caps and taglist now */
  if (rtpgstpay->config_interval > 0) {
    GST_DEBUG_OBJECT (rtpgstpay,
        "timestamp %" GST_TIME_FORMAT ", last config %" GST_TIME_FORMAT,
        GST_TIME_ARGS (timestamp), GST_TIME_ARGS (rtpgstpay->last_config));

    if (timestamp != GST_CLOCK_TIME_NONE &&
        rtpgstpay->last_config != GST_CLOCK_TIME_NONE) {
      guint64 diff;

      /* calculate diff between last SPS/PPS in milliseconds */
      if (timestamp > rtpgstpay->last_config)
        diff = timestamp - rtpgstpay->last_config;
      else
        diff = 0;

      GST_DEBUG_OBJECT (rtpgstpay,
          "interval since last config %" GST_TIME_FORMAT, GST_TIME_ARGS (diff));

      /* bigger than interval, queue SPS/PPS */
      if (GST_TIME_AS_SECONDS (diff) >= rtpgstpay->config_interval)
        gst_rtp_gst_pay_send_config (rtpgstpay, timestamp);
    } else {
      gst_rtp_gst_pay_send_config (rtpgstpay, timestamp);
    }
  }

  /* caps always from SDP for now */
  if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
    rtpgstpay->flags |= (1 << 3);

  gst_adapter_push (rtpgstpay->adapter, buffer);
  ret = gst_rtp_gst_pay_flush (rtpgstpay, timestamp);

  return ret;
}

gboolean
gst_rtp_gst_pay_plugin_init (GstPlugin * plugin)
{
  return gst_element_register (plugin, "rtpgstpay",
      GST_RANK_NONE, GST_TYPE_RTP_GST_PAY);
}
