From 1ff24ddc31cb017a3d843d8b8c13d3c40a8fddc2 Mon Sep 17 00:00:00 2001 From: Kevin Mihelich Date: Sun, 14 Jan 2018 16:27:26 +0000 Subject: [PATCH] extra/gst-plugins-bad to 1.12.4-2 --- extra/gst-plugins-bad/PKGBUILD | 12 +- .../srtp-Support-libsrtp2.patch | 832 ++++++++++++++++++ 2 files changed, 841 insertions(+), 3 deletions(-) create mode 100644 extra/gst-plugins-bad/srtp-Support-libsrtp2.patch diff --git a/extra/gst-plugins-bad/PKGBUILD b/extra/gst-plugins-bad/PKGBUILD index db4a0ddb0..54914fb3a 100644 --- a/extra/gst-plugins-bad/PKGBUILD +++ b/extra/gst-plugins-bad/PKGBUILD @@ -8,7 +8,7 @@ pkgname=gst-plugins-bad pkgver=1.12.4 -pkgrel=1 +pkgrel=2 pkgdesc="GStreamer Multimedia Framework Bad Plugins" url="https://gstreamer.freedesktop.org/" arch=(x86_64) @@ -23,9 +23,11 @@ makedepends=(python gobject-introspection gtk-doc git autoconf-archive vulkan-he fluidsynth lilv opencv openexr) _commit=cbdbd8d4f6893e6042dbf7b8258e23a8d2aaf081 # tags/1.12.4^0 source=("git+https://anongit.freedesktop.org/git/gstreamer/gst-plugins-bad#commit=$_commit" - "gst-common::git+https://anongit.freedesktop.org/git/gstreamer/common") + "gst-common::git+https://anongit.freedesktop.org/git/gstreamer/common" + srtp-Support-libsrtp2.patch) sha256sums=('SKIP' - 'SKIP') + 'SKIP' + '12cb72b5972dcfbffa28176c5db9d701ebdbfb9dd8f26acf5500cc541abc87e7') pkgver() { cd $pkgname @@ -39,6 +41,10 @@ prepare() { git config --local submodule.common.url "$srcdir/gst-common" git submodule update + # libsrtp2 + git cherry-pick -n 029e01743f 17121ebc57 + patch -Np1 -i ../srtp-Support-libsrtp2.patch + sed -i 's/cmu_us_kal/&16/g' configure.ac ext/flite/gstflitetestsrc.c NOCONFIGURE=1 ./autogen.sh diff --git a/extra/gst-plugins-bad/srtp-Support-libsrtp2.patch b/extra/gst-plugins-bad/srtp-Support-libsrtp2.patch new file mode 100644 index 000000000..d9101a37a --- /dev/null +++ b/extra/gst-plugins-bad/srtp-Support-libsrtp2.patch @@ -0,0 +1,832 @@ +From 25713711519864ae2f666802d05b136772c3b84b Mon Sep 17 00:00:00 2001 +Message-Id: <25713711519864ae2f666802d05b136772c3b84b.1515749240.git.jsteffens@make.tv> +From: "Jan Alexander Steffens (heftig)" +Date: Thu, 11 Jan 2018 16:06:24 +0100 +Subject: [PATCH] srtp: Support libsrtp2 + +For libsrtp 1, add defines that translate the new namespaced identifiers +to the old unnamespaced ones. Also move the code for setting and getting +a stream's ROC into two compat functions that match libsrtp2's API. + +It seems that libsrtp2 properly supports changing the ROC without having +to touch the sequence numbers afterwards, given that srtp_set_stream_roc +sets a pending_roc field, so the entire roc_changed dance should not be +needed anymore. The compat functions for libsrtp 1 just contain our +preexisting hacks, however, so it's still needed there. + +libsrtp2 has no means of discovering the streams in the session, so to +create the stats structure we need to iterate over our own set of SSRCs. +For this we also need to re-add the previously removed ssrcs_set to the +encoder. + +https://bugzilla.gnome.org/show_bug.cgi?id=776901 +--- + configure.ac | 12 ++++++--- + ext/srtp/gstsrtp.c | 58 +++++++++++++++++++++++++++++------------- + ext/srtp/gstsrtp.h | 35 ++++++++++++++++++++++++-- + ext/srtp/gstsrtpdec.c | 70 ++++++++++++++++++++++++++++----------------------- + ext/srtp/gstsrtpdec.h | 5 ++-- + ext/srtp/gstsrtpenc.c | 65 ++++++++++++++++++++++++++++------------------- + ext/srtp/gstsrtpenc.h | 5 ++-- + ext/srtp/meson.build | 15 ++++++++--- + 8 files changed, 178 insertions(+), 87 deletions(-) + +diff --git a/configure.ac b/configure.ac +index fc15bfd8a..7a8714360 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -2470,9 +2470,15 @@ AC_SUBST(LIBMMS_LIBS) + dnl *** libsrtp *** + translit(dnm, m, l) AM_CONDITIONAL(USE_SRTP, true) + AG_GST_CHECK_FEATURE(SRTP, [srtp library], srtp, [ +- PKG_CHECK_MODULES(SRTP, libsrtp, HAVE_SRTP="yes", +- AG_GST_CHECK_LIBHEADER(SRTP, srtp, srtp_init, , srtp/srtp.h, SRTP_LIBS="-lsrtp") +- ) ++ HAVE_SRTP="no" ++ AG_GST_PKG_CHECK_MODULES(SRTP, libsrtp2) ++ if test x"$HAVE_SRTP" = x"yes"; then ++ AC_DEFINE([HAVE_SRTP2], 1, [Define if libsrtp2 is used]) ++ else ++ PKG_CHECK_MODULES(SRTP, libsrtp, HAVE_SRTP="yes", ++ AG_GST_CHECK_LIBHEADER(SRTP, srtp, srtp_init, , srtp/srtp.h, SRTP_LIBS="-lsrtp") ++ ) ++ fi + AC_SUBST(SRTP_LIBS) + AC_SUBST(SRTP_CFLAGS) + ]) +diff --git a/ext/srtp/gstsrtp.c b/ext/srtp/gstsrtp.c +index 1f2d3015c..0c1e235ab 100644 +--- a/ext/srtp/gstsrtp.c ++++ b/ext/srtp/gstsrtp.c +@@ -21,21 +21,46 @@ + * Boston, MA 02111-1307, USA. + */ + +-#ifdef HAVE_CONFIG_H +-#include "config.h" +-#endif + + #define GLIB_DISABLE_DEPRECATION_WARNINGS + + #include "gstsrtp.h" + +-#include +- + #include + + #include "gstsrtpenc.h" + #include "gstsrtpdec.h" + ++#ifndef HAVE_SRTP2 ++srtp_err_status_t ++srtp_set_stream_roc (srtp_t session, guint32 ssrc, guint32 roc) ++{ ++ srtp_stream_t stream; ++ ++ stream = srtp_get_stream (session, htonl (ssrc)); ++ if (stream == NULL) { ++ return srtp_err_status_bad_param; ++ } ++ ++ rdbx_set_roc (&stream->rtp_rdbx, roc); ++ return srtp_err_status_ok; ++} ++ ++srtp_err_status_t ++srtp_get_stream_roc (srtp_t session, guint32 ssrc, guint32 * roc) ++{ ++ srtp_stream_t stream; ++ ++ stream = srtp_get_stream (session, htonl (ssrc)); ++ if (stream == NULL) { ++ return srtp_err_status_bad_param; ++ } ++ ++ *roc = stream->rtp_rdbx.index >> 16; ++ return srtp_err_status_ok; ++} ++#endif ++ + static void free_reporter_data (gpointer data); + + GPrivate current_callback = G_PRIVATE_INIT (free_reporter_data); +@@ -185,64 +210,63 @@ rtcp_buffer_get_ssrc (GstBuffer * buf, guint32 * ssrc) + + void + set_crypto_policy_cipher_auth (GstSrtpCipherType cipher, +- GstSrtpAuthType auth, crypto_policy_t * policy) ++ GstSrtpAuthType auth, srtp_crypto_policy_t * policy) + { + switch (cipher) { + case GST_SRTP_CIPHER_AES_128_ICM: +- policy->cipher_type = AES_ICM; +- policy->cipher_key_len = 30; ++ policy->cipher_type = SRTP_AES_ICM_128; + break; + case GST_SRTP_CIPHER_AES_256_ICM: +- policy->cipher_type = AES_ICM; +- policy->cipher_key_len = 46; ++ policy->cipher_type = SRTP_AES_ICM_256; + break; + case GST_SRTP_CIPHER_NULL: +- policy->cipher_type = NULL_CIPHER; +- policy->cipher_key_len = 0; ++ policy->cipher_type = SRTP_NULL_CIPHER; + break; + default: + g_assert_not_reached (); + } + ++ policy->cipher_key_len = cipher_key_size (cipher); ++ + switch (auth) { + case GST_SRTP_AUTH_HMAC_SHA1_80: +- policy->auth_type = HMAC_SHA1; ++ policy->auth_type = SRTP_HMAC_SHA1; + policy->auth_key_len = 20; + policy->auth_tag_len = 10; + break; + case GST_SRTP_AUTH_HMAC_SHA1_32: +- policy->auth_type = HMAC_SHA1; ++ policy->auth_type = SRTP_HMAC_SHA1; + policy->auth_key_len = 20; + policy->auth_tag_len = 4; + break; + case GST_SRTP_AUTH_NULL: +- policy->auth_type = NULL_AUTH; ++ policy->auth_type = SRTP_NULL_AUTH; + policy->auth_key_len = 0; + policy->auth_tag_len = 0; + break; + } + + if (cipher == GST_SRTP_CIPHER_NULL && auth == GST_SRTP_AUTH_NULL) + policy->sec_serv = sec_serv_none; + else if (cipher == GST_SRTP_CIPHER_NULL) + policy->sec_serv = sec_serv_auth; + else if (auth == GST_SRTP_AUTH_NULL) + policy->sec_serv = sec_serv_conf; + else + policy->sec_serv = sec_serv_conf_and_auth; + } + + guint + cipher_key_size (GstSrtpCipherType cipher) + { + guint size = 0; + + switch (cipher) { + case GST_SRTP_CIPHER_AES_128_ICM: +- size = 30; ++ size = SRTP_AES_ICM_128_KEY_LEN_WSALT; + break; + case GST_SRTP_CIPHER_AES_256_ICM: +- size = 46; ++ size = SRTP_AES_ICM_256_KEY_LEN_WSALT; + break; + case GST_SRTP_CIPHER_NULL: + size = 0; +diff --git a/ext/srtp/gstsrtp.h b/ext/srtp/gstsrtp.h +index 6bc4fb943..8ea1cf9dc 100644 +--- a/ext/srtp/gstsrtp.h ++++ b/ext/srtp/gstsrtp.h +@@ -45,34 +45,65 @@ + #ifndef __GST_SRTP_H__ + #define __GST_SRTP_H__ + ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ + #include + +-#include ++#ifdef HAVE_SRTP2 ++# include ++# include ++#else ++# include ++# include ++ ++# define srtp_crypto_policy_t crypto_policy_t ++# define SRTP_AES_ICM_128 AES_ICM ++# define SRTP_AES_ICM_256 AES_ICM ++# define SRTP_NULL_CIPHER NULL_CIPHER ++# define SRTP_AES_ICM_128_KEY_LEN_WSALT 30 ++# define SRTP_AES_ICM_256_KEY_LEN_WSALT 46 ++# define SRTP_HMAC_SHA1 HMAC_SHA1 ++# define SRTP_NULL_AUTH NULL_AUTH ++# define srtp_err_status_t err_status_t ++# define srtp_err_status_ok err_status_ok ++# define srtp_err_status_bad_param err_status_bad_param ++# define srtp_err_status_key_expired err_status_key_expired ++# define srtp_err_status_auth_fail err_status_auth_fail ++# define srtp_err_status_cipher_fail err_status_cipher_fail ++# define srtp_err_status_fail err_status_fail ++ ++srtp_err_status_t srtp_set_stream_roc (srtp_t session, guint32 ssrc, ++ guint32 roc); ++srtp_err_status_t srtp_get_stream_roc (srtp_t session, guint32 ssrc, ++ guint32 * roc); ++#endif + + typedef enum + { + GST_SRTP_CIPHER_NULL, + GST_SRTP_CIPHER_AES_128_ICM, + GST_SRTP_CIPHER_AES_256_ICM + } GstSrtpCipherType; + + typedef enum + { + GST_SRTP_AUTH_NULL, + GST_SRTP_AUTH_HMAC_SHA1_32, + GST_SRTP_AUTH_HMAC_SHA1_80 + } GstSrtpAuthType; + + void gst_srtp_init_event_reporter (void); + gboolean gst_srtp_get_soft_limit_reached (void); + + gboolean rtcp_buffer_get_ssrc (GstBuffer * buf, guint32 * ssrc); + + const gchar *enum_nick_from_value (GType enum_gtype, gint value); + gint enum_value_from_nick (GType enum_gtype, const gchar *nick); + + void set_crypto_policy_cipher_auth (GstSrtpCipherType cipher, +- GstSrtpAuthType auth, crypto_policy_t * policy); ++ GstSrtpAuthType auth, srtp_crypto_policy_t * policy); + + guint cipher_key_size (GstSrtpCipherType cipher); + +diff --git a/ext/srtp/gstsrtpdec.c b/ext/srtp/gstsrtpdec.c +index 4ad989fb2..ae47704f0 100644 +--- a/ext/srtp/gstsrtpdec.c ++++ b/ext/srtp/gstsrtpdec.c +@@ -108,21 +108,13 @@ + * + */ + +-#ifdef HAVE_CONFIG_H +-#include +-#endif ++#include "gstsrtpdec.h" + +-#include + #include + #include + +-#include "gstsrtp.h" + #include "gstsrtp-enumtypes.h" + +-#include "gstsrtpdec.h" +- +-#include +- + GST_DEBUG_CATEGORY_STATIC (gst_srtp_dec_debug); + #define GST_CAT_DEFAULT gst_srtp_dec_debug + +@@ -409,35 +401,45 @@ gst_srtp_dec_init (GstSrtpDec * filter) + gst_element_add_pad (GST_ELEMENT (filter), filter->rtcp_srcpad); + + filter->first_session = TRUE; ++ ++#ifndef HAVE_SRTP2 + filter->roc_changed = FALSE; ++#endif + } + + static GstStructure * + gst_srtp_dec_create_stats (GstSrtpDec * filter) + { + GstStructure *s; + GValue va = G_VALUE_INIT; + GValue v = G_VALUE_INIT; + + s = gst_structure_new_empty ("application/x-srtp-decoder-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) { ++ GHashTableIter iter; ++ gpointer key; ++ ++ g_hash_table_iter_init (&iter, filter->streams); ++ while (g_hash_table_iter_next (&iter, &key, NULL)) { + GstStructure *ss; +- guint32 ssrc = GUINT32_FROM_BE (stream->ssrc); +- guint32 roc = stream->rtp_rdbx.index >> 16; ++ guint32 ssrc = GPOINTER_TO_UINT (key); ++ srtp_err_status_t status; ++ guint32 roc; ++ ++ status = srtp_get_stream_roc (filter->session, ssrc, &roc); ++ if (status != srtp_err_status_ok) { ++ continue; ++ } + + 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; + } + } + +@@ -556,7 +558,8 @@ get_stream_from_caps (GstSrtpDec * filter, GstCaps * caps, guint32 ssrc) + goto error; + } + +- if (stream->rtcp_cipher != NULL_CIPHER && stream->rtcp_auth == NULL_AUTH) { ++ if (stream->rtcp_cipher != SRTP_NULL_CIPHER && ++ stream->rtcp_auth == SRTP_NULL_AUTH) { + GST_WARNING_OBJECT (filter, + "Cannot have SRTP NULL authentication with a not-NULL encryption" + " cipher."); +@@ -594,19 +597,19 @@ signal_get_srtp_params (GstSrtpDec * filter, guint32 ssrc, gint signal) + + /* Create a stream in the session + */ +-static err_status_t ++static srtp_err_status_t + init_session_stream (GstSrtpDec * filter, guint32 ssrc, + GstSrtpDecSsrcStream * stream) + { +- err_status_t ret; ++ srtp_err_status_t ret; + srtp_policy_t policy; + GstMapInfo map; + guchar tmp[1]; + + memset (&policy, 0, sizeof (srtp_policy_t)); + + if (!stream) +- return err_status_bad_param; ++ return srtp_err_status_bad_param; + + GST_INFO_OBJECT (filter, "Setting RTP policy..."); + set_crypto_policy_cipher_auth (stream->rtp_cipher, stream->rtp_auth, +@@ -638,17 +641,20 @@ init_session_stream (GstSrtpDec * filter, guint32 ssrc, + if (stream->key) + gst_buffer_unmap (stream->key, &map); + +- if (ret == err_status_ok) { +- srtp_stream_t srtp_stream; ++ if (ret == srtp_err_status_ok) { ++ srtp_err_status_t status; + +- srtp_stream = srtp_get_stream (filter->session, htonl (ssrc)); +- if (srtp_stream) { ++ status = srtp_set_stream_roc (filter->session, ssrc, stream->roc); ++#ifdef HAVE_SRTP2 ++ (void) status; /* Ignore unused variable */ ++#else ++ if (status == srtp_err_status_ok) { + /* Here, we just set the ROC, but we also need to set the initial + * RTP sequence number later, otherwise libsrtp will not be able + * to get the right packet index. */ +- rdbx_set_roc (&srtp_stream->rtp_rdbx, stream->roc); + filter->roc_changed = TRUE; + } ++#endif + + filter->first_session = FALSE; + g_hash_table_insert (filter->streams, GUINT_TO_POINTER (stream->ssrc), +@@ -713,7 +719,7 @@ update_session_stream_from_caps (GstSrtpDec * filter, guint32 ssrc, + { + GstSrtpDecSsrcStream *stream = NULL; + GstSrtpDecSsrcStream *old_stream = NULL; +- err_status_t err; ++ srtp_err_status_t err; + + g_return_val_if_fail (GST_IS_SRTP_DEC (filter), NULL); + g_return_val_if_fail (GST_IS_CAPS (caps), NULL); +@@ -751,7 +757,7 @@ update_session_stream_from_caps (GstSrtpDec * filter, guint32 ssrc, + /* Create new session stream */ + err = init_session_stream (filter, ssrc, stream); + +- if (err != err_status_ok) { ++ if (err != srtp_err_status_ok) { + if (stream->key) + gst_buffer_unref (stream->key); + g_slice_free (GstSrtpDecSsrcStream, stream); +@@ -1139,83 +1145,85 @@ gst_srtp_dec_decode_buffer (GstSrtpDec * filter, GstPad * pad, GstBuffer * buf, + gboolean is_rtcp, guint32 ssrc) + { + GstMapInfo map; +- err_status_t err; ++ srtp_err_status_t err; + gint size; + + GST_LOG_OBJECT (pad, "Received %s buffer of size %" G_GSIZE_FORMAT + " with SSRC = %u", is_rtcp ? "RTCP" : "RTP", gst_buffer_get_size (buf), + ssrc); + + /* Change buffer to remove protection */ + buf = gst_buffer_make_writable (buf); + + gst_buffer_map (buf, &map, GST_MAP_READWRITE); + size = map.size; + + unprotect: + + gst_srtp_init_event_reporter (); + + if (is_rtcp) + err = srtp_unprotect_rtcp (filter->session, map.data, &size); + else { ++#ifndef HAVE_SRTP2 + /* If ROC has changed, we know we need to set the initial RTP + * sequence number too. */ + if (filter->roc_changed) { + srtp_stream_t stream; + + stream = srtp_get_stream (filter->session, htonl (ssrc)); + + if (stream) { + guint16 seqnum = 0; + GstRTPBuffer rtpbuf = GST_RTP_BUFFER_INIT; + + gst_rtp_buffer_map (buf, + GST_MAP_READ | GST_RTP_BUFFER_MAP_FLAG_SKIP_PADDING, &rtpbuf); + seqnum = gst_rtp_buffer_get_seq (&rtpbuf); + gst_rtp_buffer_unmap (&rtpbuf); + + /* We finally add the RTP sequence number to the current + * rollover counter. */ + stream->rtp_rdbx.index &= ~0xFFFF; + stream->rtp_rdbx.index |= seqnum; + } + + filter->roc_changed = FALSE; + } ++#endif + err = srtp_unprotect (filter->session, map.data, &size); + } + + GST_OBJECT_UNLOCK (filter); + +- if (err != err_status_ok) { ++ if (err != srtp_err_status_ok) { + GST_WARNING_OBJECT (pad, + "Unable to unprotect buffer (unprotect failed code %d)", err); + + /* Signal user depending on type of error */ + switch (err) { +- case err_status_key_expired: ++ case srtp_err_status_key_expired: + GST_OBJECT_LOCK (filter); + + /* Update stream */ + if (find_stream_by_ssrc (filter, ssrc)) { + GST_OBJECT_UNLOCK (filter); + if (request_key_with_signal (filter, ssrc, SIGNAL_HARD_LIMIT)) { + GST_OBJECT_LOCK (filter); + goto unprotect; + } else { + GST_WARNING_OBJECT (filter, "Hard limit reached, no new key, " + "dropping"); + } + } else { + GST_WARNING_OBJECT (filter, "Could not find matching stream, " + "dropping"); + } + break; +- case err_status_auth_fail: ++ case srtp_err_status_auth_fail: + GST_WARNING_OBJECT (filter, "Error authentication packet, dropping"); + break; +- case err_status_cipher_fail: ++ case srtp_err_status_cipher_fail: + GST_WARNING_OBJECT (filter, "Error while decrypting packet, dropping"); + break; + default: +diff --git a/ext/srtp/gstsrtpdec.h b/ext/srtp/gstsrtpdec.h +index 644092a50..f26435a43 100644 +--- a/ext/srtp/gstsrtpdec.h ++++ b/ext/srtp/gstsrtpdec.h +@@ -47,8 +47,7 @@ + #ifndef __GST_SRTPDEC_H__ + #define __GST_SRTPDEC_H__ + +-#include +-#include ++#include "gstsrtp.h" + + G_BEGIN_DECLS + +@@ -84,7 +83,9 @@ struct _GstSrtpDec + gboolean rtp_has_segment; + gboolean rtcp_has_segment; + ++#ifndef HAVE_SRTP2 + gboolean roc_changed; ++#endif + }; + + struct _GstSrtpDecClass +diff --git a/ext/srtp/gstsrtpenc.c b/ext/srtp/gstsrtpenc.c +index 893ece8be..c5884da40 100644 +--- a/ext/srtp/gstsrtpenc.c ++++ b/ext/srtp/gstsrtpenc.c +@@ -102,22 +102,15 @@ + * while to other clients. + */ + +-#ifdef HAVE_CONFIG_H +-#include +-#endif ++#include "gstsrtpenc.h" + +-#include + #include + #include + #include ++#include + +-#include "gstsrtpenc.h" +- +-#include "gstsrtp.h" + #include "gstsrtp-enumtypes.h" + +-#include +- + GST_DEBUG_CATEGORY_STATIC (gst_srtp_enc_debug); + #define GST_CAT_DEFAULT gst_srtp_enc_debug + +@@ -355,57 +348,58 @@ gst_srtp_enc_init (GstSrtpEnc * filter) + filter->rtcp_auth = DEFAULT_RTCP_AUTH; + filter->replay_window_size = DEFAULT_REPLAY_WINDOW_SIZE; + filter->allow_repeat_tx = DEFAULT_ALLOW_REPEAT_TX; ++ filter->ssrcs_set = g_hash_table_new (g_direct_hash, g_direct_equal); + } + + 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 ++static srtp_err_status_t + gst_srtp_enc_create_session (GstSrtpEnc * filter) + { +- err_status_t ret; ++ srtp_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; ++ return srtp_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; ++ return srtp_err_status_fail; + } + } + +@@ -450,6 +444,8 @@ gst_srtp_enc_reset_no_lock (GstSrtpEnc * filter) + if (!filter->first_session) { + srtp_dealloc (filter->session); + filter->session = NULL; ++ ++ g_hash_table_remove_all (filter->ssrcs_set); + } + + filter->first_session = TRUE; +@@ -604,35 +600,46 @@ gst_srtp_enc_dispose (GObject * object) + gst_buffer_unref (filter->key); + filter->key = NULL; + ++ if (filter->ssrcs_set) ++ g_hash_table_unref (filter->ssrcs_set); ++ filter->ssrcs_set = 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) { ++ GHashTableIter iter; ++ gpointer key; ++ ++ g_hash_table_iter_init (&iter, filter->ssrcs_set); ++ while (g_hash_table_iter_next (&iter, &key, NULL)) { + GstStructure *ss; +- guint32 ssrc = GUINT32_FROM_BE (stream->ssrc); +- guint32 roc = stream->rtp_rdbx.index >> 16; ++ guint32 ssrc = GPOINTER_TO_UINT (key); ++ srtp_err_status_t status; ++ guint32 roc; ++ ++ status = srtp_get_stream_roc (filter->session, ssrc, &roc); ++ if (status != srtp_err_status_ok) { ++ continue; ++ } + + 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; + } + } + +@@ -801,6 +808,12 @@ gst_srtp_enc_sink_setcaps (GstPad * pad, GstSrtpEnc * filter, + + GST_OBJECT_LOCK (filter); + ++ if (gst_structure_has_field_typed (ps, "ssrc", G_TYPE_UINT)) { ++ guint ssrc; ++ gst_structure_get_uint (ps, "ssrc", &ssrc); ++ g_hash_table_add (filter->ssrcs_set, GUINT_TO_POINTER (ssrc)); ++ } ++ + if (HAS_CRYPTO (filter)) + gst_structure_set (ps, "srtp-key", GST_TYPE_BUFFER, filter->key, NULL); + +@@ -990,9 +1003,9 @@ gst_srtp_enc_check_set_caps (GstSrtpEnc * filter, GstPad * pad, + } + + if (filter->first_session) { +- err_status_t status = gst_srtp_enc_create_session (filter); ++ srtp_err_status_t status = gst_srtp_enc_create_session (filter); + +- if (status != err_status_ok) { ++ if (status != srtp_err_status_ok) { + GST_OBJECT_UNLOCK (filter); + GST_ELEMENT_ERROR (filter, LIBRARY, INIT, + ("Could not initialize SRTP encoder"), +@@ -1025,39 +1038,39 @@ gst_srtp_enc_process_buffer (GstSrtpEnc * filter, GstPad * pad, + gint size_max, size; + GstBuffer *bufout = NULL; + GstMapInfo mapout; +- err_status_t err; ++ srtp_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) { ++ if (err == srtp_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) { ++ } else if (err == srtp_err_status_key_expired) { + + GST_ELEMENT_ERROR (GST_ELEMENT_CAST (filter), STREAM, ENCODE, + ("Key usage limit has been reached"), +@@ -1278,8 +1291,8 @@ gst_srtp_enc_change_state (GstElement * element, GstStateChange transition) + } + } + } +- if ((filter->rtcp_cipher != NULL_CIPHER) +- && (filter->rtcp_auth == NULL_AUTH)) { ++ if ((filter->rtcp_cipher != SRTP_NULL_CIPHER) ++ && (filter->rtcp_auth == SRTP_NULL_AUTH)) { + GST_ERROR_OBJECT (filter, + "RTCP authentication can't be NULL if encryption is not NULL."); + return GST_STATE_CHANGE_FAILURE; +diff --git a/ext/srtp/gstsrtpenc.h b/ext/srtp/gstsrtpenc.h +index 842c56f54..5c64e0b3e 100644 +--- a/ext/srtp/gstsrtpenc.h ++++ b/ext/srtp/gstsrtpenc.h +@@ -47,8 +47,7 @@ + #ifndef __GST_SRTPENC_H__ + #define __GST_SRTPENC_H__ + +-#include +-#include ++#include "gstsrtp.h" + + G_BEGIN_DECLS + +@@ -84,6 +83,8 @@ struct _GstSrtpEnc + + guint replay_window_size; + gboolean allow_repeat_tx; ++ ++ GHashTable *ssrcs_set; + }; + + struct _GstSrtpEncClass +diff --git a/ext/srtp/meson.build b/ext/srtp/meson.build +index 09f511118..3fb508703 100644 +--- a/ext/srtp/meson.build ++++ b/ext/srtp/meson.build +@@ -4,27 +4,34 @@ srtp_sources = [ + 'gstsrtpenc.c', + ] + +-srtp_dep = dependency('libsrtp', required : false) +-if not srtp_dep.found() and cc.has_header_symbol('srtp/srtp.h', 'srtp_init') +- srtp_dep = cc.find_library('srtp', required : false) ++srtp_cargs = [] ++ ++srtp_dep = dependency('libsrtp2', required : false) ++if srtp_dep.found() ++ srtp_cargs += ['-DHAVE_SRTP2'] ++else ++ srtp_dep = dependency('libsrtp', required : false) ++ if not srtp_dep.found() and cc.has_header_symbol('srtp/srtp.h', 'srtp_init') ++ srtp_dep = cc.find_library('srtp', required : false) ++ endif + endif + + if srtp_dep.found() + mkenums = find_program('srtp_mkenum.py') + gstsrtp_h = custom_target('gstsrtpenum_h', + output : 'gstsrtp-enumtypes.h', + input : 'gstsrtp.h', + command : [mkenums, glib_mkenums, '@OUTPUT@', '@INPUT@']) + + gstsrtp_c = custom_target('gstsrtpenum_c', + output : 'gstsrtp-enumtypes.c', + input : 'gstsrtp.h', + depends : [gstsrtp_h], + command : [mkenums, glib_mkenums, '@OUTPUT@', '@INPUT@']) + + gstsrtp = library('gstsrtp', + srtp_sources, gstsrtp_c, gstsrtp_h, +- c_args : gst_plugins_bad_args, ++ c_args : gst_plugins_bad_args + srtp_cargs, + link_args : noseh_link_args, + include_directories : [configinc], + dependencies : [gstrtp_dep, gstvideo_dep, srtp_dep], +-- +2.15.1 \ No newline at end of file