/*
 * GStreamer - GStreamer SRTP encoder
 *
 * Copyright 2009-2011 Collabora Ltd.
 *  @author: Gabriel Millaire <gabriel.millaire@collabora.com>
 *  @author: Olivier Crete <olivier.crete@collabora.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gst-plugin-bad-plugins-srtpenc
 * @see_also: srtpdec
 *
 * gstrtpenc acts as an encoder that adds security to RTP and RTCP
 * packets in the form of encryption and authentication. It outs SRTP
 * and SRTCP.
 *
 * An application can request multiple RTP and RTCP pads to protect,
 * but every sink pad requested must receive packets from the same
 * source (identical SSRC). If a packet received contains a different
 * SSRC, a warning is emited and the valid SSRC is forced on the packet.
 *
 * This element uses libsrtp library. When receiving the first packet,
 * the library is initialized with a new stream (based on the SSRC). It
 * uses the default RTP and RTCP encryption and authentication mechanisms,
 * unless the user has set the relevant properties first. It also uses
 * a master key that MUST be set by property (key) at the beginning. The
 * master key must be of a maximum length of 46 characters (14 characters
 * for the salt plus the key). The encryption and authentication mecanisms
 * available are :
 *
 * Encryption (properties rtp-cipher and rtcp-cipher)
 * - AES_ICM 256 bits (maximum security)
 * - AES_ICM 128 bits (default)
 * - NULL
 *
 * Authentication (properties rtp-auth and rtcp-auth)
 * - HMAC_SHA1 80 bits (default, maximum protection)
 * - HMAC_SHA1 32 bits
 * - NULL
 *
 * Note that for SRTP protection, authentication is mandatory (non-null)
 * if encryption is used (non-null).
 *
 * When requested to create a sink pad, a linked source pad is created.
 * Each packet received is first analysed (checked for valid SSRC) then
 * its buffer is protected with libsrtp, then pushed on the source pad.
 * If protection failed or the stream could not be created, the buffer
 * is dropped and a warning is emitted. The packets pushed on the source
 * pad are of type 'application/x-srtp' or 'application/x-srtcp'.
 *
 * When the maximum usage of the master key is reached, a soft-limit
 * signal is sent to the user. The user must then set a new master key
 * by property. If the hard limit is reached, a flag is set and every
 * subsequent packet is dropped, until a new key is set and the stream
 * has been updated.
 *
 * If a stream is to be shared between multiple clients it is also
 * possible to request the internal SRTP rollover counter for a given
 * SSRC. The rollover counter should be then transmitted and used by the
 * clients to authenticate and decrypt the packets. Failing to do that
 * the clients will start with a rollover counter of 0 which will
 * probably be incorrect if the stream has been transmitted for a
 * while to other clients.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <gst/gst.h>
#include <gst/rtp/gstrtpbuffer.h>
#include <gst/rtp/gstrtcpbuffer.h>
#include <string.h>

#include "gstsrtpenc.h"

#include "gstsrtp.h"
#include "gstsrtp-enumtypes.h"

#include <srtp/srtp_priv.h>

GST_DEBUG_CATEGORY_STATIC (gst_srtp_enc_debug);
#define GST_CAT_DEFAULT gst_srtp_enc_debug

/* 128 bit key size: 14 (salt) + 16 */
#define MASTER_128_KEY_SIZE 30

/* 256 bit key size: 14 (salt) + 16 + 16 */
#define MASTER_256_KEY_SIZE 46

/* Properties default values */
#define DEFAULT_MASTER_KEY      NULL
#define DEFAULT_RTP_CIPHER      GST_SRTP_CIPHER_AES_128_ICM
#define DEFAULT_RTP_AUTH        GST_SRTP_AUTH_HMAC_SHA1_80
#define DEFAULT_RTCP_CIPHER     DEFAULT_RTP_CIPHER
#define DEFAULT_RTCP_AUTH       DEFAULT_RTP_AUTH
#define DEFAULT_RANDOM_KEY      FALSE
#define DEFAULT_REPLAY_WINDOW_SIZE 128
#define DEFAULT_ALLOW_REPEAT_TX FALSE

#define HAS_CRYPTO(filter) (filter->rtp_cipher != GST_SRTP_CIPHER_NULL || \
      filter->rtcp_cipher != GST_SRTP_CIPHER_NULL ||                      \
      filter->rtp_auth != GST_SRTP_AUTH_NULL ||                           \
      filter->rtcp_auth != GST_SRTP_AUTH_NULL)

/* Filter signals and args */
enum
{
  SIGNAL_SOFT_LIMIT,
  SIGNAL_GET_ROLLOVER_COUNTER,
  LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_MKEY,
  PROP_RTP_CIPHER,
  PROP_RTP_AUTH,
  PROP_RTCP_CIPHER,
  PROP_RTCP_AUTH,
  PROP_RANDOM_KEY,
  PROP_REPLAY_WINDOW_SIZE,
  PROP_ALLOW_REPEAT_TX,
  PROP_STATS
};

typedef struct ProcessBufferItData
{
  GstSrtpEnc *filter;
  GstPad *pad;
  GstBufferList *out_list;
  gboolean is_rtcp;
} ProcessBufferItData;

/* the capabilities of the inputs and outputs.
 *
 * describe the real formats here.
 */
static GstStaticPadTemplate rtp_sink_template =
GST_STATIC_PAD_TEMPLATE ("rtp_sink_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("application/x-rtp")
    );

static GstStaticPadTemplate rtp_src_template =
GST_STATIC_PAD_TEMPLATE ("rtp_src_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("application/x-srtp")
    );

static GstStaticPadTemplate rtcp_sink_template =
GST_STATIC_PAD_TEMPLATE ("rtcp_sink_%u",
    GST_PAD_SINK,
    GST_PAD_REQUEST,
    GST_STATIC_CAPS ("application/x-rtcp")
    );

static GstStaticPadTemplate rtcp_src_template =
GST_STATIC_PAD_TEMPLATE ("rtcp_src_%u",
    GST_PAD_SRC,
    GST_PAD_SOMETIMES,
    GST_STATIC_CAPS ("application/x-srtcp")
    );

G_DEFINE_TYPE (GstSrtpEnc, gst_srtp_enc, GST_TYPE_ELEMENT);

static guint gst_srtp_enc_signals[LAST_SIGNAL] = { 0 };

static void gst_srtp_enc_dispose (GObject * object);

static void gst_srtp_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_srtp_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_srtp_enc_sink_query_rtp (GstPad * pad, GstObject * parent,
    GstQuery * query);
static gboolean gst_srtp_enc_sink_query_rtcp (GstPad * pad, GstObject * parent,
    GstQuery * query);

static GstIterator *gst_srtp_enc_iterate_internal_links_rtp (GstPad * pad,
    GstObject * parent);
static GstIterator *gst_srtp_enc_iterate_internal_links_rtcp (GstPad * pad,
    GstObject * parent);

static GstFlowReturn gst_srtp_enc_chain_rtp (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static GstFlowReturn gst_srtp_enc_chain_rtcp (GstPad * pad, GstObject * parent,
    GstBuffer * buf);
static GstFlowReturn gst_srtp_enc_chain_list_rtp (GstPad * pad,
    GstObject * parent, GstBufferList * buf);
static GstFlowReturn gst_srtp_enc_chain_list_rtcp (GstPad * pad,
    GstObject * parent, GstBufferList * buf);

static gboolean gst_srtp_enc_sink_event_rtp (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_srtp_enc_sink_event_rtcp (GstPad * pad, GstObject * parent,
    GstEvent * event);

static GstStateChangeReturn gst_srtp_enc_change_state (GstElement * element,
    GstStateChange transition);

static GstPad *gst_srtp_enc_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);

static void gst_srtp_enc_release_pad (GstElement * element, GstPad * pad);


/* initialize the srtpenc's class
 */
static void
gst_srtp_enc_class_init (GstSrtpEncClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;

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

  gst_element_class_add_static_pad_template (gstelement_class,
      &rtp_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &rtp_sink_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &rtcp_src_template);
  gst_element_class_add_static_pad_template (gstelement_class,
      &rtcp_sink_template);

  gst_element_class_set_static_metadata (gstelement_class, "SRTP encoder",
      "Filter/Network/SRTP",
      "A SRTP and SRTCP encoder",
      "Gabriel Millaire <millaire.gabriel@collabora.com>");


  /* Install callbacks */
  gobject_class->set_property = gst_srtp_enc_set_property;
  gobject_class->get_property = gst_srtp_enc_get_property;
  gobject_class->dispose = gst_srtp_enc_dispose;
  gstelement_class->request_new_pad =
      GST_DEBUG_FUNCPTR (gst_srtp_enc_request_new_pad);
  gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_srtp_enc_release_pad);
  gstelement_class->change_state =
      GST_DEBUG_FUNCPTR (gst_srtp_enc_change_state);

  /* Install properties */
  g_object_class_install_property (gobject_class, PROP_MKEY,
      g_param_spec_boxed ("key", "Key", "Master key (minimum of "
          G_STRINGIFY (MASTER_128_KEY_SIZE) " and maximum of "
          G_STRINGIFY (MASTER_256_KEY_SIZE) " bytes)",
          GST_TYPE_BUFFER, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
          GST_PARAM_MUTABLE_PLAYING));
  g_object_class_install_property (gobject_class, PROP_RTP_CIPHER,
      g_param_spec_enum ("rtp-cipher", "RTP Cipher", "RTP Cipher",
          GST_TYPE_SRTP_CIPHER_TYPE, DEFAULT_RTP_CIPHER,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RTP_AUTH,
      g_param_spec_enum ("rtp-auth", "RTP Authentication",
          "RTP Authentication", GST_TYPE_SRTP_AUTH_TYPE, DEFAULT_RTP_AUTH,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RTCP_CIPHER,
      g_param_spec_enum ("rtcp-cipher", "RTCP Cipher",
          "RTCP Cipher", GST_TYPE_SRTP_CIPHER_TYPE, DEFAULT_RTCP_CIPHER,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RTCP_AUTH,
      g_param_spec_enum ("rtcp-auth", "RTCP Authentication",
          "RTCP Authentication", GST_TYPE_SRTP_AUTH_TYPE, DEFAULT_RTCP_AUTH,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_RANDOM_KEY,
      g_param_spec_boolean ("random-key", "Generate random key",
          "Generate a random key if TRUE",
          DEFAULT_RANDOM_KEY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_REPLAY_WINDOW_SIZE,
      g_param_spec_uint ("replay-window-size", "Replay window size",
          "Size of the replay protection window",
          64, 0x8000, DEFAULT_REPLAY_WINDOW_SIZE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_ALLOW_REPEAT_TX,
      g_param_spec_boolean ("allow-repeat-tx",
          "Allow repeat packets transmission",
          "Whether retransmissions of packets with the same sequence number are allowed"
          "(Note that such repeated transmissions must have the same RTP payload, "
          "or a severe security weakness is introduced!)",
          DEFAULT_ALLOW_REPEAT_TX, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
  g_object_class_install_property (gobject_class, PROP_STATS,
      g_param_spec_boxed ("stats", "Statistics", "Various statistics",
          GST_TYPE_STRUCTURE, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));

  /**
   * GstSrtpEnc::soft-limit:
   * @gstsrtpenc: the element on which the signal is emitted
   *
   * Signal emited when the stream with @ssrc has reached the soft
   * limit of utilisation of it's master encryption key. User should
   * provide a new key by setting the #GstSrtpEnc:key property.
   */
  gst_srtp_enc_signals[SIGNAL_SOFT_LIMIT] =
      g_signal_new ("soft-limit", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
}


/* initialize the new element
 */
static void
gst_srtp_enc_init (GstSrtpEnc * filter)
{
  filter->key_changed = TRUE;
  filter->first_session = TRUE;
  filter->key = DEFAULT_MASTER_KEY;
  filter->rtp_cipher = DEFAULT_RTP_CIPHER;
  filter->rtp_auth = DEFAULT_RTP_AUTH;
  filter->rtcp_cipher = DEFAULT_RTCP_CIPHER;
  filter->rtcp_auth = DEFAULT_RTCP_AUTH;
  filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE;
  filter->allow_repeat_tx = DEFAULT_ALLOW_REPEAT_TX;
}

static guint
max_cipher_key_size (GstSrtpEnc * filter)
{
  guint rtp_size, rtcp_size;

  rtp_size = cipher_key_size (filter->rtp_cipher);
  rtcp_size = cipher_key_size (filter->rtcp_cipher);

  return (rtp_size > rtcp_size) ? rtp_size : rtcp_size;
}

/* Create stream
 *
 * Should be called with the filter locked
 */
static err_status_t
gst_srtp_enc_create_session (GstSrtpEnc * filter)
{
  err_status_t ret;
  srtp_policy_t policy;
  GstMapInfo map;
  guchar tmp[1];

  memset (&policy, 0, sizeof (srtp_policy_t));

  if (HAS_CRYPTO (filter)) {
    guint expected;
    gsize keysize;

    if (filter->key == NULL) {
      GST_OBJECT_UNLOCK (filter);
      GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
          ("Cipher is not NULL, key must be set"),
          ("Cipher is not NULL, key must be set"));
      GST_OBJECT_LOCK (filter);
      return err_status_fail;
    }

    expected = max_cipher_key_size (filter);
    keysize = gst_buffer_get_size (filter->key);

    if (expected != keysize) {
      GST_OBJECT_UNLOCK (filter);
      GST_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
          ("Master key size is wrong"),
          ("Expected master key of %d bytes, but received %" G_GSIZE_FORMAT
              " bytes", expected, keysize));
      GST_OBJECT_LOCK (filter);
      return err_status_fail;
    }
  }

  GST_DEBUG_OBJECT (filter, "Setting RTP/RTCP policy to %d / %d",
      filter->rtp_cipher, filter->rtcp_cipher);
  set_crypto_policy_cipher_auth (filter->rtp_cipher, filter->rtp_auth,
      &policy.rtp);
  set_crypto_policy_cipher_auth (filter->rtcp_cipher, filter->rtcp_auth,
      &policy.rtcp);

  if (HAS_CRYPTO (filter)) {
    gst_buffer_map (filter->key, &map, GST_MAP_READ);
    policy.key = (guchar *) map.data;
  } else {
    policy.key = tmp;
  }

  policy.ssrc.value = 0;
  policy.ssrc.type = ssrc_any_outbound;
  policy.next = NULL;

  policy.window_size = filter->replay_window_size;
  policy.allow_repeat_tx = filter->allow_repeat_tx;

  /* If it is the first stream, create the session
   * If not, add the stream to the session
   */
  ret = srtp_create (&filter->session, &policy);
  filter->first_session = FALSE;

  if (HAS_CRYPTO (filter))
    gst_buffer_unmap (filter->key, &map);

  return ret;
}

/* Release ressources and set default values
 */
static void
gst_srtp_enc_reset_no_lock (GstSrtpEnc * filter)
{
  if (!filter->first_session)
    srtp_dealloc (filter->session);

  filter->first_session = TRUE;
  filter->key_changed = FALSE;
}

static void
gst_srtp_enc_reset (GstSrtpEnc * filter)
{
  GST_OBJECT_LOCK (filter);
  gst_srtp_enc_reset_no_lock (filter);
  GST_OBJECT_UNLOCK (filter);
}

/* Create sinkpad to receive RTP packets from encers
 * and a srcpad for the RTP packets
 */
static GstPad *
create_rtp_sink (GstSrtpEnc * filter, const gchar * name)
{
  GstPad *sinkpad, *srcpad;
  gchar *sinkpadname, *srcpadname;
  guint nb = 0;

  GST_DEBUG_OBJECT (filter, "creating RTP sink pad");
  sinkpad = gst_pad_new_from_static_template (&rtp_sink_template, name);

  sinkpadname = gst_pad_get_name (sinkpad);
  sscanf (sinkpadname, "rtp_sink_%u", &nb);
  srcpadname = g_strdup_printf ("rtp_src_%u", nb);

  GST_DEBUG_OBJECT (filter, "creating RTP source pad");
  srcpad = gst_pad_new_from_static_template (&rtp_src_template, srcpadname);
  g_free (srcpadname);
  g_free (sinkpadname);

  gst_pad_set_element_private (sinkpad, srcpad);
  gst_pad_set_element_private (srcpad, sinkpad);

  gst_pad_set_query_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_query_rtp));
  gst_pad_set_iterate_internal_links_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtp));
  gst_pad_set_chain_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_rtp));
  gst_pad_set_chain_list_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_list_rtp));
  gst_pad_set_event_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_event_rtp));
  gst_pad_set_active (sinkpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (filter), sinkpad);

  gst_pad_set_iterate_internal_links_function (srcpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtp));
  gst_pad_set_active (srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (filter), srcpad);

  return sinkpad;
}

/* Create sinkpad to receive RTCP packets from encers
 * and a srcpad for the RTCP packets
 */
static GstPad *
create_rtcp_sink (GstSrtpEnc * filter, const gchar * name)
{
  GstPad *srcpad, *sinkpad;
  gchar *sinkpadname, *srcpadname;
  guint nb = 0;

  GST_DEBUG_OBJECT (filter, "creating RTCP sink pad");
  sinkpad = gst_pad_new_from_static_template (&rtcp_sink_template, name);

  sinkpadname = gst_pad_get_name (sinkpad);
  sscanf (sinkpadname, "rtcp_sink_%u", &nb);
  srcpadname = g_strdup_printf ("rtcp_src_%u", nb);

  GST_DEBUG_OBJECT (filter, "creating RTCP source pad");
  srcpad = gst_pad_new_from_static_template (&rtcp_src_template, srcpadname);
  g_free (srcpadname);
  g_free (sinkpadname);

  gst_pad_set_element_private (sinkpad, srcpad);
  gst_pad_set_element_private (srcpad, sinkpad);

  gst_pad_set_query_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_query_rtcp));
  gst_pad_set_iterate_internal_links_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtcp));
  gst_pad_set_chain_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_rtcp));
  gst_pad_set_chain_list_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_chain_list_rtcp));
  gst_pad_set_event_function (sinkpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_sink_event_rtcp));
  gst_pad_set_active (sinkpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (filter), sinkpad);

  gst_pad_set_iterate_internal_links_function (srcpad,
      GST_DEBUG_FUNCPTR (gst_srtp_enc_iterate_internal_links_rtcp));
  gst_pad_set_active (srcpad, TRUE);
  gst_element_add_pad (GST_ELEMENT_CAST (filter), srcpad);

  return sinkpad;
}

/* Handling new pad request
 */
static GstPad *
gst_srtp_enc_request_new_pad (GstElement * element,
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
  GstElementClass *klass;
  GstSrtpEnc *filter;

  filter = GST_SRTP_ENC (element);
  klass = GST_ELEMENT_GET_CLASS (element);

  GST_INFO_OBJECT (element, "New pad requested");

  if (templ == gst_element_class_get_pad_template (klass, "rtp_sink_%u"))
    return create_rtp_sink (filter, name);

  if (templ == gst_element_class_get_pad_template (klass, "rtcp_sink_%u"))
    return create_rtcp_sink (filter, name);

  GST_ERROR_OBJECT (element, "Could not find specified template");
  return NULL;
}

/* Dispose
 */
static void
gst_srtp_enc_dispose (GObject * object)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (object);
  GstIterator *it;
  GValue val = { 0 };

  GST_DEBUG_OBJECT (object, "Dispose...");

  it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (object));
  while (gst_iterator_next (it, &val) == GST_ITERATOR_OK) {
    gst_srtp_enc_release_pad (GST_ELEMENT_CAST (object),
        g_value_get_object (&val));
    g_value_unset (&val);
    gst_iterator_resync (it);
  }
  gst_iterator_free (it);

  if (filter->key)
    gst_buffer_unref (filter->key);
  filter->key = NULL;

  G_OBJECT_CLASS (gst_srtp_enc_parent_class)->dispose (object);
}

static GstStructure *
gst_srtp_enc_create_stats (GstSrtpEnc * filter)
{
  GstStructure *s;
  GValue va = G_VALUE_INIT;
  GValue v = G_VALUE_INIT;

  s = gst_structure_new_empty ("application/x-srtp-encoder-stats");

  g_value_init (&va, GST_TYPE_ARRAY);
  g_value_init (&v, GST_TYPE_STRUCTURE);

  if (filter->session) {
    srtp_stream_t stream = filter->session->stream_list;
    while (stream) {
      GstStructure *ss;
      guint32 ssrc = GUINT32_FROM_BE (stream->ssrc);
      guint32 roc = stream->rtp_rdbx.index >> 16;

      ss = gst_structure_new ("application/x-srtp-stream",
          "ssrc", G_TYPE_UINT, ssrc, "roc", G_TYPE_UINT, roc, NULL);

      g_value_take_boxed (&v, ss);
      gst_value_array_append_value (&va, &v);

      stream = stream->next;
    }
  }

  gst_structure_take_value (s, "streams", &va);
  g_value_unset (&v);

  return s;
}

static void
gst_srtp_enc_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (object);

  GST_OBJECT_LOCK (filter);

  switch (prop_id) {
    case PROP_MKEY:
      if (filter->key)
        gst_buffer_unref (filter->key);
      filter->key = g_value_dup_boxed (value);
      filter->key_changed = TRUE;
      GST_INFO_OBJECT (object, "Set property: key=[%p]", filter->key);
      break;

    case PROP_RTP_CIPHER:
      filter->rtp_cipher = g_value_get_enum (value);
      GST_INFO_OBJECT (object, "Set property: rtp cipher=%d",
          filter->rtp_cipher);
      break;
    case PROP_RTP_AUTH:
      filter->rtp_auth = g_value_get_enum (value);
      GST_INFO_OBJECT (object, "Set property: rtp auth=%d", filter->rtp_auth);
      break;

    case PROP_RTCP_CIPHER:
      filter->rtcp_cipher = g_value_get_enum (value);
      GST_INFO_OBJECT (object, "Set property: rtcp cipher=%d",
          filter->rtcp_cipher);
      break;

    case PROP_RTCP_AUTH:
      filter->rtcp_auth = g_value_get_enum (value);
      GST_INFO_OBJECT (object, "Set property: rtcp auth=%d", filter->rtcp_auth);
      break;

    case PROP_RANDOM_KEY:
      filter->random_key = g_value_get_boolean (value);
      break;

    case PROP_REPLAY_WINDOW_SIZE:
      filter->replay_window_size = g_value_get_uint (value);
      break;

    case PROP_ALLOW_REPEAT_TX:
      filter->allow_repeat_tx = g_value_get_boolean (value);
      break;

    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (filter);
}

static void
gst_srtp_enc_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (object);
  GST_OBJECT_LOCK (filter);

  switch (prop_id) {
    case PROP_MKEY:
      if (filter->key)
        g_value_set_boxed (value, filter->key);
      break;
    case PROP_RTP_CIPHER:
      g_value_set_enum (value, filter->rtp_cipher);
      break;
    case PROP_RTCP_CIPHER:
      g_value_set_enum (value, filter->rtcp_cipher);
      break;
    case PROP_RTP_AUTH:
      g_value_set_enum (value, filter->rtp_auth);
      break;
    case PROP_RTCP_AUTH:
      g_value_set_enum (value, filter->rtcp_auth);
      break;
    case PROP_RANDOM_KEY:
      g_value_set_boolean (value, filter->random_key);
      break;
    case PROP_REPLAY_WINDOW_SIZE:
      g_value_set_uint (value, filter->replay_window_size);
      break;
    case PROP_ALLOW_REPEAT_TX:
      g_value_set_boolean (value, filter->allow_repeat_tx);
      break;
    case PROP_STATS:
      g_value_take_boxed (value, gst_srtp_enc_create_stats (filter));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }

  GST_OBJECT_UNLOCK (filter);
}

/* Returns the source pad linked with the sink pad
 */
static GstPad *
get_rtp_other_pad (GstPad * pad)
{
  return GST_PAD (gst_pad_get_element_private (pad));
}

/* Release a sink pad and it's linked source pad
 */
static void
gst_srtp_enc_release_pad (GstElement * element, GstPad * sinkpad)
{
  GstPad *srcpad;

  GST_INFO_OBJECT (element, "Releasing pad %s:%s",
      GST_DEBUG_PAD_NAME (sinkpad));

  srcpad = GST_PAD (gst_pad_get_element_private (sinkpad));
  gst_pad_set_element_private (sinkpad, NULL);
  gst_pad_set_element_private (srcpad, NULL);

  /* deactivate from source to sink */
  gst_pad_set_active (srcpad, FALSE);
  gst_pad_set_active (sinkpad, FALSE);

  /* remove pads */
  gst_element_remove_pad (element, srcpad);
  gst_element_remove_pad (element, sinkpad);
}

/* Common setcaps function
 * Handles the link with other elements
 */
static gboolean
gst_srtp_enc_sink_setcaps (GstPad * pad, GstSrtpEnc * filter,
    GstCaps * caps, gboolean is_rtcp)
{
  GstPad *otherpad = NULL;
  GstStructure *ps = NULL;
  gboolean ret = FALSE;

  g_return_val_if_fail (gst_caps_is_fixed (caps), FALSE);

  caps = gst_caps_copy (caps);

  ps = gst_caps_get_structure (caps, 0);

  GST_DEBUG_OBJECT (pad, "Sink caps: %" GST_PTR_FORMAT, caps);

  if (is_rtcp)
    gst_structure_set_name (ps, "application/x-srtcp");
  else
    gst_structure_set_name (ps, "application/x-srtp");

  GST_OBJECT_LOCK (filter);

  if (HAS_CRYPTO (filter))
    gst_structure_set (ps, "srtp-key", GST_TYPE_BUFFER, filter->key, NULL);

  /* Add srtp-specific params to source caps */
  gst_structure_set (ps,
      "srtp-cipher", G_TYPE_STRING,
      enum_nick_from_value (GST_TYPE_SRTP_CIPHER_TYPE, filter->rtp_cipher),
      "srtp-auth", G_TYPE_STRING,
      enum_nick_from_value (GST_TYPE_SRTP_AUTH_TYPE, filter->rtp_auth),
      "srtcp-cipher", G_TYPE_STRING,
      enum_nick_from_value (GST_TYPE_SRTP_CIPHER_TYPE, filter->rtcp_cipher),
      "srtcp-auth", G_TYPE_STRING,
      enum_nick_from_value (GST_TYPE_SRTP_AUTH_TYPE, filter->rtcp_auth), NULL);

  GST_OBJECT_UNLOCK (filter);

  GST_DEBUG_OBJECT (pad, "Source caps: %" GST_PTR_FORMAT, caps);

  /* Set caps on source pad */
  otherpad = get_rtp_other_pad (pad);

  ret = gst_pad_set_caps (otherpad, caps);

  gst_caps_unref (caps);

  return ret;
}

static gboolean
gst_srtp_enc_sink_query (GstPad * pad, GstObject * parent, GstQuery * query,
    gboolean is_rtcp)
{
  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_CAPS:
    {
      GstCaps *filter = NULL;
      GstCaps *other_filter = NULL;
      GstPad *otherpad;
      GstCaps *other_caps;
      GstCaps *ret;
      GstCaps *template_caps;
      int i;

      otherpad = get_rtp_other_pad (pad);

      gst_query_parse_caps (query, &filter);
      if (filter) {
        other_filter = gst_caps_copy (filter);

        for (i = 0; i < gst_caps_get_size (other_filter); i++) {
          GstStructure *ps = gst_caps_get_structure (other_filter, i);
          if (is_rtcp)
            gst_structure_set_name (ps, "application/x-srtcp");
          else
            gst_structure_set_name (ps, "application/x-srtp");
        }
      }

      other_caps = gst_pad_peer_query_caps (otherpad, other_filter);

      if (other_filter)
        gst_caps_unref (other_filter);

      if (!other_caps)
        goto return_template;

      template_caps = gst_pad_get_pad_template_caps (otherpad);
      ret = gst_caps_intersect_full (other_caps, template_caps,
          GST_CAPS_INTERSECT_FIRST);
      gst_caps_unref (other_caps);
      gst_caps_unref (template_caps);

      ret = gst_caps_make_writable (ret);

      for (i = 0; i < gst_caps_get_size (ret); i++) {
        GstStructure *ps = gst_caps_get_structure (ret, i);
        if (is_rtcp)
          gst_structure_set_name (ps, "application/x-rtcp");
        else
          gst_structure_set_name (ps, "application/x-rtp");
        gst_structure_remove_fields (ps, "srtp-key", "srtp-cipher", "srtp-auth",
            "srtcp-cipher", "srtcp-auth", NULL);
      }

      gst_query_set_caps_result (query, ret);
      gst_caps_unref (ret);
      return TRUE;
    return_template:

      ret = gst_pad_get_pad_template_caps (pad);
      gst_query_set_caps_result (query, ret);
      gst_caps_unref (ret);

      return TRUE;
    }
    default:
      return gst_pad_query_default (pad, parent, query);
  }
}

static gboolean
gst_srtp_enc_sink_query_rtp (GstPad * pad, GstObject * parent, GstQuery * query)
{
  return gst_srtp_enc_sink_query (pad, parent, query, FALSE);
}

static gboolean
gst_srtp_enc_sink_query_rtcp (GstPad * pad, GstObject * parent,
    GstQuery * query)
{
  return gst_srtp_enc_sink_query (pad, parent, query, TRUE);
}

static GstIterator *
gst_srtp_enc_iterate_internal_links (GstPad * pad, GstObject * parent,
    gboolean is_rtcp)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
  GstPad *otherpad = NULL;
  GstIterator *it = NULL;

  otherpad = get_rtp_other_pad (pad);

  if (otherpad) {
    GValue val = { 0 };

    g_value_init (&val, GST_TYPE_PAD);
    g_value_set_object (&val, otherpad);
    it = gst_iterator_new_single (GST_TYPE_PAD, &val);
    g_value_unset (&val);
  } else {
    GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), CORE, PAD, (NULL),
        ("Unable to get linked pad"));
  }

  return it;
}

static GstIterator *
gst_srtp_enc_iterate_internal_links_rtp (GstPad * pad, GstObject * parent)
{
  return gst_srtp_enc_iterate_internal_links (pad, parent, FALSE);
}

static GstIterator *
gst_srtp_enc_iterate_internal_links_rtcp (GstPad * pad, GstObject * parent)
{
  return gst_srtp_enc_iterate_internal_links (pad, parent, TRUE);
}


static void
gst_srtp_enc_replace_random_key (GstSrtpEnc * filter)
{
  guint i;
  guint key_size;
  GstMapInfo map;

  GST_DEBUG_OBJECT (filter, "Generating random key");

  if (filter->key)
    gst_buffer_unref (filter->key);

  key_size = max_cipher_key_size (filter);

  filter->key = gst_buffer_new_allocate (NULL, key_size, NULL);

  gst_buffer_map (filter->key, &map, GST_MAP_WRITE);
  for (i = 0; i < map.size; i += 4)
    GST_WRITE_UINT32_BE (map.data + i, g_random_int ());
  gst_buffer_unmap (filter->key, &map);

  filter->key_changed = TRUE;
}

static GstFlowReturn
gst_srtp_enc_check_set_caps (GstSrtpEnc * filter, GstPad * pad,
    gboolean is_rtcp)
{
  gboolean do_setcaps = FALSE;

  GST_OBJECT_LOCK (filter);

  if (filter->key_changed) {
    gst_srtp_enc_reset_no_lock (filter);
    do_setcaps = TRUE;
  }

  if (filter->first_session) {
    err_status_t status = gst_srtp_enc_create_session (filter);

    if (status != err_status_ok) {
      GST_OBJECT_UNLOCK (filter);
      GST_ELEMENT_ERROR (filter, LIBRARY, INIT,
          ("Could not initialize SRTP encoder"),
          ("Failed to add stream to SRTP encoder (err: %d)", status));
      return GST_FLOW_ERROR;
    }
  }

  GST_OBJECT_UNLOCK (filter);

  /* Update source caps if asked */
  if (do_setcaps) {
    GstCaps *caps;

    caps = gst_pad_get_current_caps (pad);
    if (!gst_srtp_enc_sink_setcaps (pad, filter, caps, is_rtcp)) {
      gst_caps_unref (caps);
      return GST_FLOW_NOT_NEGOTIATED;
    }
    gst_caps_unref (caps);
  }

  return GST_FLOW_OK;
}

static GstBuffer *
gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad,
    GstBuffer * buf, gboolean is_rtcp)
{
  gint size_max, size;
  GstBuffer *bufout = NULL;
  GstMapInfo mapout;
  err_status_t err;

  /* Create a bigger buffer to add protection */
  size = gst_buffer_get_size (buf);
  size_max = size + SRTP_MAX_TRAILER_LEN + 10;
  bufout = gst_buffer_new_allocate (NULL, size_max, NULL);

  gst_buffer_map (bufout, &mapout, GST_MAP_READWRITE);

  gst_buffer_extract (buf, 0, mapout.data, size);

  GST_OBJECT_LOCK (filter);

  gst_srtp_init_event_reporter ();

  if (is_rtcp)
    err = srtp_protect_rtcp (filter->session, mapout.data, &size);
  else
    err = srtp_protect (filter->session, mapout.data, &size);

  GST_OBJECT_UNLOCK (filter);

  gst_buffer_unmap (bufout, &mapout);

  if (err == err_status_ok) {
    /* Buffer protected */
    gst_buffer_set_size (bufout, size);
    gst_buffer_copy_into (bufout, buf, GST_BUFFER_COPY_METADATA, 0, -1);

    GST_LOG_OBJECT (pad, "Encoding %s buffer of size %d",
        is_rtcp ? "RTCP" : "RTP", size);

  } else if (err == err_status_key_expired) {

    GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE,
        ("Key usage limit has been reached"),
        ("Unable to protect buffer (hard key usage limit reached)"));
    goto fail;

  } else {
    /* srtp_protect failed */
    GST_ELEMENT_ERROR (filter, LIBRARY, FAILED, (NULL),
        ("Unable to protect buffer (protect failed) code %d", err));
    goto fail;
  }

  return bufout;

fail:
  gst_buffer_unref (bufout);
  return NULL;
}

static GstFlowReturn
gst_srtp_enc_chain (GstPad * pad, GstObject * parent, GstBuffer * buf,
    gboolean is_rtcp)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
  GstFlowReturn ret = GST_FLOW_OK;
  GstPad *otherpad;
  GstBuffer *bufout = NULL;

  if ((ret = gst_srtp_enc_check_set_caps (filter, pad, is_rtcp)) != GST_FLOW_OK) {
    goto out;
  }

  GST_OBJECT_LOCK (filter);

  if (!HAS_CRYPTO (filter)) {
    GST_OBJECT_UNLOCK (filter);
    otherpad = get_rtp_other_pad (pad);
    return gst_pad_push (otherpad, buf);
  }

  GST_OBJECT_UNLOCK (filter);

  if ((bufout = gst_srtp_enc_process_buffer (filter, pad, buf, is_rtcp))) {
    /* Push buffer to source pad */
    otherpad = get_rtp_other_pad (pad);
    ret = gst_pad_push (otherpad, bufout);
    bufout = NULL;

    if (ret != GST_FLOW_OK)
      goto out;
  } else {
    goto fail;
  }

  GST_OBJECT_LOCK (filter);

  if (gst_srtp_get_soft_limit_reached ()) {
    GST_OBJECT_UNLOCK (filter);
    g_signal_emit (filter, gst_srtp_enc_signals[SIGNAL_SOFT_LIMIT], 0);
    GST_OBJECT_LOCK (filter);
    if (filter->random_key && !filter->key_changed)
      gst_srtp_enc_replace_random_key (filter);
  }

  GST_OBJECT_UNLOCK (filter);

out:

  gst_buffer_unref (buf);

  return ret;

fail:
  ret = GST_FLOW_ERROR;
  goto out;
}

static gboolean
process_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
{
  ProcessBufferItData *data = user_data;
  GstBuffer *bufout;

  if ((bufout =
          gst_srtp_enc_process_buffer (data->filter, data->pad, *buffer,
              data->is_rtcp))) {
    gst_buffer_list_add (data->out_list, bufout);
  } else {
    GST_WARNING_OBJECT (data->filter, "Error encoding buffer, dropping");
  }

  return TRUE;
}

static GstFlowReturn
gst_srtp_enc_chain_list (GstPad * pad, GstObject * parent,
    GstBufferList * buf_list, gboolean is_rtcp)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
  GstFlowReturn ret = GST_FLOW_OK;
  GstPad *otherpad;
  GstBufferList *out_list = NULL;
  ProcessBufferItData process_data;

  GST_LOG_OBJECT (pad, "Buffer chain with list of %d",
      gst_buffer_list_length (buf_list));

  if (!gst_buffer_list_length (buf_list))
    goto out;

  if ((ret = gst_srtp_enc_check_set_caps (filter, pad, is_rtcp)) != GST_FLOW_OK)
    goto out;

  GST_OBJECT_LOCK (filter);

  if (!HAS_CRYPTO (filter)) {
    GST_OBJECT_UNLOCK (filter);
    otherpad = get_rtp_other_pad (pad);
    return gst_pad_push_list (otherpad, buf_list);
  }

  GST_OBJECT_UNLOCK (filter);

  out_list = gst_buffer_list_new ();

  process_data.filter = filter;
  process_data.pad = pad;
  process_data.is_rtcp = is_rtcp;
  process_data.out_list = out_list;

  gst_buffer_list_foreach (buf_list, process_buffer_it, &process_data);

  if (!gst_buffer_list_length (out_list)) {
    gst_buffer_list_unref (out_list);
    ret = GST_FLOW_OK;
    goto out;
  }

  /* Push buffer to source pad */
  otherpad = get_rtp_other_pad (pad);
  GST_LOG_OBJECT (pad, "Pushing buffer chain of %d",
      gst_buffer_list_length (buf_list));
  ret = gst_pad_push_list (otherpad, out_list);

  if (ret != GST_FLOW_OK) {
    goto out;
  }

  GST_OBJECT_LOCK (filter);

  if (gst_srtp_get_soft_limit_reached ()) {
    GST_OBJECT_UNLOCK (filter);
    g_signal_emit (filter, gst_srtp_enc_signals[SIGNAL_SOFT_LIMIT], 0);
    GST_OBJECT_LOCK (filter);
    if (filter->random_key && !filter->key_changed)
      gst_srtp_enc_replace_random_key (filter);
  }

  GST_OBJECT_UNLOCK (filter);

out:

  gst_buffer_list_unref (buf_list);

  return ret;
}

static GstFlowReturn
gst_srtp_enc_chain_rtp (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  return gst_srtp_enc_chain (pad, parent, buf, FALSE);
}

static GstFlowReturn
gst_srtp_enc_chain_rtcp (GstPad * pad, GstObject * parent, GstBuffer * buf)
{
  return gst_srtp_enc_chain (pad, parent, buf, TRUE);
}

static GstFlowReturn
gst_srtp_enc_chain_list_rtp (GstPad * pad, GstObject * parent,
    GstBufferList * buf_list)
{
  return gst_srtp_enc_chain_list (pad, parent, buf_list, FALSE);
}

static GstFlowReturn
gst_srtp_enc_chain_list_rtcp (GstPad * pad, GstObject * parent,
    GstBufferList * buf_list)
{
  return gst_srtp_enc_chain_list (pad, parent, buf_list, TRUE);
}


/* Change state
 */
static GstStateChangeReturn
gst_srtp_enc_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn res;
  GstSrtpEnc *filter;

  filter = GST_SRTP_ENC (element);

  switch (transition) {
    case GST_STATE_CHANGE_NULL_TO_READY:
      if (filter->rtp_cipher != GST_SRTP_CIPHER_NULL ||
          filter->rtcp_cipher != GST_SRTP_CIPHER_NULL ||
          filter->rtp_auth != GST_SRTP_AUTH_NULL ||
          filter->rtcp_auth != GST_SRTP_AUTH_NULL) {
        if (!filter->key) {
          if (filter->random_key) {
            gst_srtp_enc_replace_random_key (filter);
          } else {
            GST_ERROR_OBJECT (element, "Need a key to get to READY");
            return GST_STATE_CHANGE_FAILURE;
          }
        }
      }
      if ((filter->rtcp_cipher != NULL_CIPHER)
          && (filter->rtcp_auth == NULL_AUTH)) {
        GST_ERROR_OBJECT (filter,
            "RTCP authentication can't be NULL if encryption is not NULL.");
        return GST_STATE_CHANGE_FAILURE;
      }
      GST_OBJECT_LOCK (filter);
      if (!filter->first_session)
        gst_srtp_enc_reset_no_lock (filter);
      GST_OBJECT_UNLOCK (filter);
      break;
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
      break;
    default:
      break;
  }

  res = GST_ELEMENT_CLASS (gst_srtp_enc_parent_class)->change_state (element,
      transition);

  switch (transition) {
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
      break;
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_srtp_enc_reset (filter);
      break;
    case GST_STATE_CHANGE_READY_TO_NULL:
      break;
    default:
      break;
  }

  return res;
}

static gboolean
gst_srtp_enc_sink_event (GstPad * pad, GstObject * parent, GstEvent * event,
    gboolean is_rtcp)
{
  GstSrtpEnc *filter = GST_SRTP_ENC (parent);
  gboolean ret;
  GstPad *otherpad;

  otherpad = get_rtp_other_pad (pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      GST_DEBUG_OBJECT (pad, "Encing event Flush stop (%d)",
          GST_EVENT_TYPE (event));
      gst_srtp_enc_reset (filter);
      ret = gst_pad_push_event (otherpad, event);
      break;
    case GST_EVENT_CAPS:
    {
      GstCaps *caps;

      gst_event_parse_caps (event, &caps);
      ret = gst_srtp_enc_sink_setcaps (pad, filter, caps, is_rtcp);
      gst_event_unref (event);
      break;
    }
    default:
      GST_DEBUG_OBJECT (pad, "Encing event default (%d)",
          GST_EVENT_TYPE (event));
      ret = gst_pad_event_default (pad, parent, event);
      break;
  }

  return ret;
}

static gboolean
gst_srtp_enc_sink_event_rtp (GstPad * pad, GstObject * parent, GstEvent * event)
{
  return gst_srtp_enc_sink_event (pad, parent, event, FALSE);
}

static gboolean
gst_srtp_enc_sink_event_rtcp (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  return gst_srtp_enc_sink_event (pad, parent, event, TRUE);
}

/* entry point to initialize the plug-in
 * initialize the plug-in itself
 * register the element factories and other features
 */
gboolean
gst_srtp_enc_plugin_init (GstPlugin * srtpenc)
{
  GST_DEBUG_CATEGORY_INIT (gst_srtp_enc_debug, "srtpenc", 0, "SRTP Enc");

  return gst_element_register (srtpenc, "srtpenc", GST_RANK_NONE,
      GST_TYPE_SRTP_ENC);
}
