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

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,
  PROP_LAST
};

#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;
    if (rtpgstpay->stream_id)
      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_buffer_append (outbuf, paybuf);

    GST_BUFFER_TIMESTAMP (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) {
        if (rtpgstpay->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_TIMESTAMP (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);
}
