GST_REQ=1.3.0.1
GSTPB_REQ=1.3.0.1
GSTPG_REQ=1.3.0.1
+GSTPD_REQ=1.3.0.1
dnl *** autotools stuff ****
AC_SUBST(GSTPG_PLUGINS_DIR)
AC_MSG_NOTICE(Using GStreamer Good Plugins in $GSTPG_PLUGINS_DIR)
+AG_GST_CHECK_GST_PLUGINS_BAD($GST_API_VERSION, [$GSTPD_REQ], [yes])
+GSTPD_PLUGINS_DIR=`$PKG_CONFIG gstreamer-plugins-bad-$GST_API_VERSION --variable pluginsdir`
+AC_SUBST(GSTPD_PLUGINS_DIR)
+AC_MSG_NOTICE(Using GStreamer Bad Plugins in $GSTPD_PLUGINS_DIR)
+
AG_GST_CHECK_GST_CHECK($GST_API_VERSION, [$GST_REQ], no)
AM_CONDITIONAL(HAVE_CHECK, test "x$HAVE_GST_CHECK" = "xyes")
gst_rtsp_media_factory_set_permissions (factory, permissions);
gst_rtsp_permissions_unref (permissions);
#endif
+ gst_rtsp_media_factory_set_profiles (factory, GST_RTSP_PROFILE_SAVP);
/* attach the test factory to the /test url */
gst_rtsp_mount_points_add_factory (mounts, "/test", factory);
#include <string.h>
+#include <gst/sdp/gstmikey.h>
+
#include "rtsp-sdp.h"
static gboolean
gst_sdp_media_add_attribute (smedia, "control", tmp);
g_free (tmp);
+
+ /* check for srtp */
+ do {
+ GstBuffer *srtpkey;
+ const GValue *val;
+ const gchar *srtpcipher, *srtpauth, *srtcpcipher, *srtcpauth;
+ GstMIKEYMessage *msg;
+ GstMIKEYPayload *payload;
+ GBytes *bytes;
+ GstMapInfo info;
+ const guint8 *data;
+ gsize size;
+ gchar *base64;
+ guint8 byte;
+ guint32 ssrc;
+
+ val = gst_structure_get_value (s, "srtp-key");
+ if (val == NULL)
+ break;
+
+ srtpkey = gst_value_get_buffer (val);
+ if (srtpkey == NULL)
+ break;
+
+ srtpcipher = gst_structure_get_string (s, "srtp-cipher");
+ srtpauth = gst_structure_get_string (s, "srtp-auth");
+ srtcpcipher = gst_structure_get_string (s, "srtcp-cipher");
+ srtcpauth = gst_structure_get_string (s, "srtcp-auth");
+
+ if (srtpcipher == NULL || srtpauth == NULL || srtcpcipher == NULL ||
+ srtcpauth == NULL)
+ break;
+
+ msg = gst_mikey_message_new ();
+ /* unencrypted MIKEY message, we send this over TLS so this is allowed */
+ gst_mikey_message_set_info (msg, GST_MIKEY_VERSION, GST_MIKEY_TYPE_PSK_INIT,
+ FALSE, GST_MIKEY_PRF_MIKEY_1, 0, GST_MIKEY_MAP_TYPE_SRTP);
+ /* add policy '0' for our SSRC */
+ gst_rtsp_stream_get_ssrc (stream, &ssrc);
+ gst_mikey_message_add_cs_srtp (msg, 0, ssrc, 0);
+ /* timestamp is now */
+ gst_mikey_message_add_t_now_ntp_utc (msg);
+ /* add some random data */
+ gst_mikey_message_add_rand_len (msg, 16);
+
+ /* the policy '0' is SRTP with the above discovered algorithms */
+ payload = gst_mikey_payload_new (GST_MIKEY_PT_SP);
+ gst_mikey_payload_sp_set (payload, 0, GST_MIKEY_SEC_PROTO_SRTP);
+
+ /* only AES-CM is supported */
+ byte = 1;
+ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_ALG, 1,
+ &byte);
+ /* only HMAC-SHA1 */
+ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
+ &byte);
+ /* we enable encryption on RTP and RTCP */
+ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_ENC, 1,
+ &byte);
+ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTCP_ENC, 1,
+ &byte);
+ /* we enable authentication on RTP and RTCP */
+ gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_SRTP_AUTH, 1,
+ &byte);
+ gst_mikey_message_add_payload (msg, payload);
+
+ /* add the key in KEMAC */
+ gst_buffer_map (srtpkey, &info, GST_MAP_READ);
+ gst_mikey_message_add_kemac (msg, GST_MIKEY_ENC_NULL, info.size, info.data,
+ GST_MIKEY_MAC_NULL, NULL);
+ gst_buffer_unmap (srtpkey, &info);
+
+ /* now serialize this to bytes */
+ bytes = gst_mikey_message_to_bytes (msg);
+ gst_mikey_message_free (msg);
+ /* and make it into base64 */
+ data = g_bytes_get_data (bytes, &size);
+ base64 = g_base64_encode (data, size);
+ g_bytes_unref (bytes);
+
+ tmp = g_strdup_printf ("mikey %s", base64);
+ g_free (base64);
+
+ gst_sdp_media_add_attribute (smedia, "key-mgmt", tmp);
+ g_free (tmp);
+ } while (FALSE);
+
/* collect all other properties and add them to fmtp or attributes */
fmtp = g_string_new ("");
g_string_append_printf (fmtp, "%d ", caps_pt);
continue;
if (!strcmp (fname, "seqnum-base"))
continue;
+ if (g_str_has_prefix (fname, "srtp-"))
+ continue;
+ if (g_str_has_prefix (fname, "srtcp-"))
+ continue;
if (g_str_has_prefix (fname, "a-")) {
/* attribute */
/* the RTPSession object */
GObject *session;
+ /* SRTP encoder/decoder */
+ GstElement *srtpenc;
+ GstElement *srtpdec;
+
/* sinks used for sending and receiving RTP and RTCP over ipv4, they share
* sockets */
GstElement *udpsrc_v4[2];
handle_new_sample,
};
+static GstElement *
+get_rtp_encoder (GstRTSPStream * stream, guint session)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+
+ if (priv->srtpenc == NULL) {
+ gchar *name;
+
+ name = g_strdup_printf ("srtpenc_%u", session);
+ priv->srtpenc = gst_element_factory_make ("srtpenc", name);
+ g_free (name);
+
+ g_object_set (priv->srtpenc, "random-key", TRUE, NULL);
+ }
+ return gst_object_ref (priv->srtpenc);
+}
+
+static GstElement *
+request_rtp_encoder (GstElement * rtpbin, guint session, GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+ GstElement *enc;
+ GstPad *pad;
+ gchar *name;
+
+ if (priv->idx != session)
+ return NULL;
+
+ GST_DEBUG_OBJECT (stream, "make RTP encoder for session %u", session);
+
+ enc = get_rtp_encoder (stream, session);
+ name = g_strdup_printf ("rtp_sink_%d", session);
+ pad = gst_element_get_request_pad (enc, name);
+ g_free (name);
+ gst_object_unref (pad);
+
+ return enc;
+}
+
+static GstElement *
+request_rtcp_encoder (GstElement * rtpbin, guint session,
+ GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+ GstElement *enc;
+ GstPad *pad;
+ gchar *name;
+
+ if (priv->idx != session)
+ return NULL;
+
+ GST_DEBUG_OBJECT (stream, "make RTCP encoder for session %u", session);
+
+ enc = get_rtp_encoder (stream, session);
+ name = g_strdup_printf ("rtcp_sink_%d", session);
+ pad = gst_element_get_request_pad (enc, name);
+ g_free (name);
+ gst_object_unref (pad);
+
+ return enc;
+}
+
+static GstElement *
+request_rtcp_decoder (GstElement * rtpbin, guint session,
+ GstRTSPStream * stream)
+{
+ GstRTSPStreamPrivate *priv = stream->priv;
+
+ if (priv->idx != session)
+ return NULL;
+
+ if (priv->srtpdec == NULL) {
+ gchar *name;
+
+ name = g_strdup_printf ("srtpdec_%u", session);
+ priv->srtpdec = gst_element_factory_make ("srtpdec", name);
+ g_free (name);
+ }
+ return gst_object_ref (priv->srtpdec);
+}
+
/**
* gst_rtsp_stream_join_bin:
* @stream: a #GstRTSPStream
/* update the dscp qos field in the sinks */
update_dscp_qos (stream);
+ if (priv->profiles & GST_RTSP_PROFILE_SAVP
+ || priv->profiles & GST_RTSP_PROFILE_SAVPF) {
+ /* For SRTP */
+ g_signal_connect (rtpbin, "request-rtp-encoder",
+ (GCallback) request_rtp_encoder, stream);
+ g_signal_connect (rtpbin, "request-rtcp-encoder",
+ (GCallback) request_rtcp_encoder, stream);
+#if 0
+ g_signal_connect (rtpbin, "request-rtp-decoder",
+ (GCallback) request_rtp_decoder, stream);
+#endif
+ g_signal_connect (rtpbin, "request-rtcp-decoder",
+ (GCallback) request_rtcp_decoder, stream);
+ }
+
/* get a pad for sending RTP */
name = g_strdup_printf ("send_rtp_sink_%u", idx);
priv->send_rtp_sink = gst_element_get_request_pad (rtpbin, name);
gst_caps_unref (priv->caps);
priv->caps = NULL;
+ if (priv->srtpenc)
+ gst_object_unref (priv->srtpenc);
+
priv->is_joined = FALSE;
g_mutex_unlock (&priv->lock);
GST_STATE_IGNORE_ELEMENTS="$(STATE_IGNORE_ELEMENTS)" \
$(REGISTRY_ENVIRONMENT) \
GST_PLUGIN_SYSTEM_PATH_1_0= \
- GST_PLUGIN_PATH_1_0=$(GST_PLUGINS_DIR):$(GSTPB_PLUGINS_DIR):$(GSTPG_PLUGINS_DIR) \
- GST_PLUGIN_LOADING_WHITELIST="gstreamer:gst-plugins-base:gst-plugins-good"
+ GST_PLUGIN_PATH_1_0=$(GST_PLUGINS_DIR):$(GSTPB_PLUGINS_DIR):$(GSTPG_PLUGINS_DIR):$(GSTPD_PLUGINS_DIR) \
+ GST_PLUGIN_LOADING_WHITELIST="gstreamer:gst-plugins-base:gst-plugins-good:gst-plugins-bad"
# ths core dumps of some machines have PIDs appended