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

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);


static guint32
gst_srtp_enc_get_rollover_counter (GstSrtpEnc * filter, guint32 ssrc)
{
  guint32 roc = 0;
  srtp_stream_t stream;

  GST_OBJECT_LOCK (filter);

  GST_DEBUG_OBJECT (filter, "retrieving SRTP Rollover Counter, ssrc: %u", ssrc);

  if (filter->session) {
    stream = srtp_get_stream (filter->session, htonl (ssrc));
    if (stream)
      roc = stream->rtp_rdbx.index >> 16;
  }

  GST_OBJECT_UNLOCK (filter);

  return roc;
}

/* 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_pad_template (gstelement_class,
      gst_static_pad_template_get (&rtp_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&rtp_sink_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&rtcp_src_template));
  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&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));

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

  /**
   * GstSrtpEnc::get-rollover-counter:
   * @gstsrtpenc: the element on which the signal is emitted
   * @ssrc: The unique SSRC of the stream
   *
   * Request the SRTP rollover counter for the stream with @ssrc.
   */
  gst_srtp_enc_signals[SIGNAL_GET_ROLLOVER_COUNTER] =
      g_signal_new ("get-rollover-counter", G_TYPE_FROM_CLASS (klass),
      G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (GstSrtpEncClass,
          get_rollover_counter), NULL, NULL, g_cclosure_marshal_generic,
      G_TYPE_UINT, 1, G_TYPE_UINT);

  klass->get_rollover_counter =
      GST_DEBUG_FUNCPTR (gst_srtp_enc_get_rollover_counter);
}


/* 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_ELEMENT_ERROR (filter, LIBRARY, SETTINGS,
          ("Cipher is not NULL, key must be set"),
          ("Cipher is not NULL, key must be set"));
      return err_status_fail;
    }

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

    if (expected != keysize) {
      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));
      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 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;
    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);
}
