/*
 * 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 ValidateBufferItData
{
  GstSrtpEnc *filter;
  gboolean is_rtcp;
} ValidateBufferItData;

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 gboolean
gst_srtp_enc_check_buffer (GstSrtpEnc * filter, GstBuffer * buf,
    gboolean is_rtcp)
{
  if (!is_rtcp) {
    GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT;

    if (!gst_rtp_buffer_map (buf, GST_MAP_READ, &rtpbuf)) {
      GST_ELEMENT_ERROR (filter, STREAM, WRONG_TYPE, (NULL),
          ("Could not map RTP buffer"));
      return FALSE;
    }

    gst_rtp_buffer_unmap (&rtpbuf);
  } else {
    GstRTCPBuffer rtcpbuf = GST_RTCP_BUFFER_INIT;

    if (!gst_rtcp_buffer_map (buf, GST_MAP_READ, &rtcpbuf)) {
      GST_ELEMENT_ERROR (filter, STREAM, WRONG_TYPE, (NULL),
          ("Could not map RTCP buffer"));
      return FALSE;
    }
    gst_rtcp_buffer_unmap (&rtcpbuf);
  }

  return 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 (!gst_srtp_enc_check_buffer (filter, buf, is_rtcp)) {
    goto fail;
  }

  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
validate_buffer_it (GstBuffer ** buffer, guint index, gpointer user_data)
{
  ValidateBufferItData *data = user_data;

  if (!gst_srtp_enc_check_buffer (data->filter, *buffer, data->is_rtcp)) {
    GST_WARNING_OBJECT (data->filter, "Invalid buffer, dropping");
    gst_buffer_replace (buffer, NULL);
  }

  return TRUE;
}

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;
  ValidateBufferItData validate_data;
  ProcessBufferItData process_data;

  validate_data.filter = filter;
  validate_data.is_rtcp = is_rtcp;

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

  gst_buffer_list_foreach (buf_list, validate_buffer_it, &validate_data);

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