}
}
-static const gchar *
-rtsp_get_attribute_for_pt (const GstSDPMedia * media, const gchar * name,
- gint pt)
-{
- guint i;
-
- for (i = 0;; i++) {
- const gchar *attr;
- gint val;
-
- if ((attr = gst_sdp_media_get_attribute_val_n (media, name, i)) == NULL)
- break;
-
- if (sscanf (attr, "%d ", &val) != 1)
- continue;
-
- if (val == pt)
- return attr;
- }
- return NULL;
-}
-
-#define PARSE_INT(p, del, res) \
-G_STMT_START { \
- gchar *t = p; \
- p = strstr (p, del); \
- if (p == NULL) \
- res = -1; \
- else { \
- *p = '\0'; \
- p++; \
- res = atoi (t); \
- } \
-} G_STMT_END
-
-#define PARSE_STRING(p, del, res) \
-G_STMT_START { \
- gchar *t = p; \
- p = strstr (p, del); \
- if (p == NULL) { \
- res = NULL; \
- p = t; \
- } \
- else { \
- *p = '\0'; \
- p++; \
- res = t; \
- } \
-} G_STMT_END
-
-#define SKIP_SPACES(p) \
- while (*p && g_ascii_isspace (*p)) \
- p++;
-
-/* rtpmap contains:
- *
- * <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
- */
-static gboolean
-parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
- gint * rate, gchar ** params)
-{
- gchar *p, *t;
-
- p = (gchar *) rtpmap;
-
- PARSE_INT (p, " ", *payload);
- if (*payload == -1)
- return FALSE;
-
- SKIP_SPACES (p);
- if (*p == '\0')
- return FALSE;
-
- PARSE_STRING (p, "/", *name);
- if (*name == NULL) {
- GST_DEBUG ("no rate, name %s", p);
- /* no rate, assume -1 then, this is not supposed to happen but RealMedia
- * streams seem to omit the rate. */
- *name = p;
- *rate = -1;
- return TRUE;
- }
-
- t = p;
- p = strstr (p, "/");
- if (p == NULL) {
- *rate = atoi (t);
- return TRUE;
- }
- *p = '\0';
- p++;
- *rate = atoi (t);
-
- t = p;
- if (*p == '\0')
- return TRUE;
- *params = t;
-
- return TRUE;
-}
-
-/*
- * Mapping of caps to and from SDP fields:
- *
- * a=rtpmap:<payload> <encoding_name>/<clock_rate>[/<encoding_params>]
- * a=framesize:<payload> <width>-<height>
- * a=fmtp:<payload> <param>[=<value>];...
- */
-static GstCaps *
-media_to_caps (gint pt, const GstSDPMedia * media)
-{
- GstCaps *caps;
- const gchar *rtpmap;
- const gchar *fmtp;
- const gchar *framesize;
- gchar *name = NULL;
- gint rate = -1;
- gchar *params = NULL;
- gchar *tmp;
- GstStructure *s;
- gint payload = 0;
- gboolean ret;
-
- /* get and parse rtpmap */
- rtpmap = rtsp_get_attribute_for_pt (media, "rtpmap", pt);
-
- if (rtpmap) {
- ret = parse_rtpmap (rtpmap, &payload, &name, &rate, ¶ms);
- if (!ret) {
- g_warning ("error parsing rtpmap, ignoring");
- rtpmap = NULL;
- }
- }
- /* dynamic payloads need rtpmap or we fail */
- if (rtpmap == NULL && pt >= 96)
- goto no_rtpmap;
-
- /* check if we have a rate, if not, we need to look up the rate from the
- * default rates based on the payload types. */
- if (rate == -1) {
- const GstRTPPayloadInfo *info;
-
- if (GST_RTP_PAYLOAD_IS_DYNAMIC (pt)) {
- /* dynamic types, use media and encoding_name */
- tmp = g_ascii_strdown (media->media, -1);
- info = gst_rtp_payload_info_for_name (tmp, name);
- g_free (tmp);
- } else {
- /* static types, use payload type */
- info = gst_rtp_payload_info_for_pt (pt);
- }
-
- if (info) {
- if ((rate = info->clock_rate) == 0)
- rate = -1;
- }
- /* we fail if we cannot find one */
- if (rate == -1)
- goto no_rate;
- }
-
- tmp = g_ascii_strdown (media->media, -1);
- caps = gst_caps_new_simple ("application/x-unknown",
- "media", G_TYPE_STRING, tmp, "payload", G_TYPE_INT, pt, NULL);
- g_free (tmp);
- s = gst_caps_get_structure (caps, 0);
-
- gst_structure_set (s, "clock-rate", G_TYPE_INT, rate, NULL);
-
- /* encoding name must be upper case */
- if (name != NULL) {
- tmp = g_ascii_strup (name, -1);
- gst_structure_set (s, "encoding-name", G_TYPE_STRING, tmp, NULL);
- g_free (tmp);
- }
-
- /* params must be lower case */
- if (params != NULL) {
- tmp = g_ascii_strdown (params, -1);
- gst_structure_set (s, "encoding-params", G_TYPE_STRING, tmp, NULL);
- g_free (tmp);
- }
-
- /* parse optional fmtp: field */
- if ((fmtp = rtsp_get_attribute_for_pt (media, "fmtp", pt))) {
- gchar *p;
- gint payload = 0;
-
- p = (gchar *) fmtp;
-
- /* p is now of the format <payload> <param>[=<value>];... */
- PARSE_INT (p, " ", payload);
- if (payload != -1 && payload == pt) {
- gchar **pairs;
- gint i;
-
- /* <param>[=<value>] are separated with ';' */
- pairs = g_strsplit (p, ";", 0);
- for (i = 0; pairs[i]; i++) {
- gchar *valpos;
- const gchar *val, *key;
- gint j;
- const gchar *reserved_keys[] =
- { "media", "payload", "clock-rate", "encoding-name",
- "encoding-params"
- };
-
- /* the key may not have a '=', the value can have other '='s */
- valpos = strstr (pairs[i], "=");
- if (valpos) {
- /* we have a '=' and thus a value, remove the '=' with \0 */
- *valpos = '\0';
- /* value is everything between '=' and ';'. We split the pairs at ;
- * boundaries so we can take the remainder of the value. Some servers
- * put spaces around the value which we strip off here. Alternatively
- * we could strip those spaces in the depayloaders should these spaces
- * actually carry any meaning in the future. */
- val = g_strstrip (valpos + 1);
- } else {
- /* simple <param>;.. is translated into <param>=1;... */
- val = "1";
- }
- /* strip the key of spaces, convert key to lowercase but not the value. */
- key = g_strstrip (pairs[i]);
-
- /* skip keys from the fmtp, which we already use ourselves for the
- * caps. Some software is adding random things like clock-rate into
- * the fmtp, and we would otherwise here set a string-typed clock-rate
- * in the caps... and thus fail to create valid RTP caps
- */
- for (j = 0; j < G_N_ELEMENTS (reserved_keys); j++) {
- if (g_ascii_strcasecmp (reserved_keys[j], key) == 0) {
- key = "";
- break;
- }
- }
-
- if (strlen (key) > 1) {
- tmp = g_ascii_strdown (key, -1);
- gst_structure_set (s, tmp, G_TYPE_STRING, val, NULL);
- g_free (tmp);
- }
- }
- g_strfreev (pairs);
- }
- }
-
- /* parse framesize: field */
- if ((framesize = gst_sdp_media_get_attribute_val (media, "framesize"))) {
- gchar *p;
-
- /* p is now of the format <payload> <width>-<height> */
- p = (gchar *) framesize;
-
- PARSE_INT (p, " ", payload);
- if (payload != -1 && payload == pt) {
- gst_structure_set (s, "a-framesize", G_TYPE_STRING, p, NULL);
- }
- }
- return caps;
-
- /* ERRORS */
-no_rtpmap:
- {
- g_warning ("rtpmap type not given for dynamic payload %d", pt);
- return NULL;
- }
-no_rate:
- {
- g_warning ("rate unknown for payload type %d", pt);
- return NULL;
- }
-}
-
-static gboolean
-parse_keymgmt (const gchar * keymgmt, GstCaps * caps)
-{
- gboolean res = FALSE;
- gsize size;
- guchar *data;
- GstMIKEYMessage *msg;
- const GstMIKEYPayload *payload;
- const gchar *srtp_cipher;
- const gchar *srtp_auth;
-
- {
- gchar *orig_value;
- gchar *p, *kmpid;
-
- p = orig_value = g_strdup (keymgmt);
-
- SKIP_SPACES (p);
- if (*p == '\0') {
- g_free (orig_value);
- return FALSE;
- }
-
- PARSE_STRING (p, " ", kmpid);
- if (kmpid == NULL || !g_str_equal (kmpid, "mikey")) {
- g_free (orig_value);
- return FALSE;
- }
- data = g_base64_decode (p, &size);
-
- g_free (orig_value); /* Don't need this any more */
- }
-
- if (data == NULL)
- return FALSE;
-
- msg = gst_mikey_message_new_from_data (data, size, NULL, NULL);
- g_free (data);
- if (msg == NULL)
- return FALSE;
-
- srtp_cipher = "aes-128-icm";
- srtp_auth = "hmac-sha1-80";
-
- /* check the Security policy if any */
- if ((payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_SP, 0))) {
- GstMIKEYPayloadSP *p = (GstMIKEYPayloadSP *) payload;
- guint len, i;
-
- if (p->proto != GST_MIKEY_SEC_PROTO_SRTP)
- goto done;
-
- len = gst_mikey_payload_sp_get_n_params (payload);
- for (i = 0; i < len; i++) {
- const GstMIKEYPayloadSPParam *param =
- gst_mikey_payload_sp_get_param (payload, i);
-
- switch (param->type) {
- case GST_MIKEY_SP_SRTP_ENC_ALG:
- switch (param->val[0]) {
- case 0:
- srtp_cipher = "null";
- break;
- case 2:
- case 1:
- srtp_cipher = "aes-128-icm";
- break;
- default:
- break;
- }
- break;
- case GST_MIKEY_SP_SRTP_ENC_KEY_LEN:
- switch (param->val[0]) {
- case AES_128_KEY_LEN:
- srtp_cipher = "aes-128-icm";
- break;
- case AES_256_KEY_LEN:
- srtp_cipher = "aes-256-icm";
- break;
- default:
- break;
- }
- break;
- case GST_MIKEY_SP_SRTP_AUTH_ALG:
- switch (param->val[0]) {
- case 0:
- srtp_auth = "null";
- break;
- case 2:
- case 1:
- srtp_auth = "hmac-sha1-80";
- break;
- default:
- break;
- }
- break;
- case GST_MIKEY_SP_SRTP_AUTH_KEY_LEN:
- switch (param->val[0]) {
- case HMAC_32_KEY_LEN:
- srtp_auth = "hmac-sha1-32";
- break;
- case HMAC_80_KEY_LEN:
- srtp_auth = "hmac-sha1-80";
- break;
- default:
- break;
- }
- break;
- case GST_MIKEY_SP_SRTP_SRTP_ENC:
- break;
- case GST_MIKEY_SP_SRTP_SRTCP_ENC:
- break;
- default:
- break;
- }
- }
- }
-
- if (!(payload = gst_mikey_message_find_payload (msg, GST_MIKEY_PT_KEMAC, 0)))
- goto done;
- else {
- GstMIKEYPayloadKEMAC *p = (GstMIKEYPayloadKEMAC *) payload;
- const GstMIKEYPayload *sub;
- GstMIKEYPayloadKeyData *pkd;
- GstBuffer *buf;
-
- if (p->enc_alg != GST_MIKEY_ENC_NULL || p->mac_alg != GST_MIKEY_MAC_NULL)
- goto done;
-
- if (!(sub = gst_mikey_payload_kemac_get_sub (payload, 0)))
- goto done;
-
- if (sub->type != GST_MIKEY_PT_KEY_DATA)
- goto done;
-
- pkd = (GstMIKEYPayloadKeyData *) sub;
- buf =
- gst_buffer_new_wrapped (g_memdup (pkd->key_data, pkd->key_len),
- pkd->key_len);
- gst_caps_set_simple (caps, "srtp-key", GST_TYPE_BUFFER, buf, NULL);
- }
-
- gst_caps_set_simple (caps,
- "srtp-cipher", G_TYPE_STRING, srtp_cipher,
- "srtp-auth", G_TYPE_STRING, srtp_auth,
- "srtcp-cipher", G_TYPE_STRING, srtp_cipher,
- "srtcp-auth", G_TYPE_STRING, srtp_auth, NULL);
-
- res = TRUE;
-done:
- gst_mikey_message_unref (msg);
-
- return res;
-}
-
-/*
- * Mapping SDP attributes to caps
- *
- * prepend 'a-' to IANA registered sdp attributes names
- * (ie: not prefixed with 'x-') in order to avoid
- * collision with gstreamer standard caps properties names
- */
-static void
-sdp_attributes_to_caps (GArray * attributes, GstCaps * caps)
-{
- if (attributes->len > 0) {
- GstStructure *s;
- guint i;
-
- s = gst_caps_get_structure (caps, 0);
-
- for (i = 0; i < attributes->len; i++) {
- GstSDPAttribute *attr = &g_array_index (attributes, GstSDPAttribute, i);
- gchar *tofree, *key;
-
- key = attr->key;
-
- /* skip some of the attribute we already handle */
- if (!strcmp (key, "fmtp"))
- continue;
- if (!strcmp (key, "rtpmap"))
- continue;
- if (!strcmp (key, "control"))
- continue;
- if (!strcmp (key, "range"))
- continue;
- if (!strcmp (key, "framesize"))
- continue;
- if (g_str_equal (key, "key-mgmt")) {
- parse_keymgmt (attr->value, caps);
- continue;
- }
-
- /* string must be valid UTF8 */
- if (!g_utf8_validate (attr->value, -1, NULL))
- continue;
-
- if (!g_str_has_prefix (key, "x-"))
- tofree = key = g_strdup_printf ("a-%s", key);
- else
- tofree = NULL;
-
- GST_DEBUG ("adding caps: %s=%s", key, attr->value);
- gst_structure_set (s, key, G_TYPE_STRING, attr->value, NULL);
- g_free (tofree);
- }
- }
-}
-
static gboolean
default_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp)
{
GST_DEBUG (" looking at %d pt: %d", j, pt);
/* convert caps */
- caps = media_to_caps (pt, sdp_media);
+ caps = gst_sdp_media_get_caps_from_media (sdp_media, pt);
if (caps == NULL) {
GST_WARNING (" skipping pt %d without caps", pt);
continue;
/* do some tweaks */
GST_DEBUG ("mapping sdp session level attributes to caps");
- sdp_attributes_to_caps (sdp->attributes, caps);
+ gst_sdp_message_attributes_to_caps (sdp, caps);
GST_DEBUG ("mapping sdp media level attributes to caps");
- sdp_attributes_to_caps (sdp_media->attributes, caps);
+ gst_sdp_media_attributes_to_caps (sdp_media, caps);
s = gst_caps_get_structure (caps, 0);
gst_structure_set_name (s, media_type);
#include "rtsp-sdp.h"
-#define AES_128_KEY_LEN 16
-#define AES_256_KEY_LEN 32
-
-#define HMAC_32_KEY_LEN 4
-#define HMAC_80_KEY_LEN 10
-
static gboolean
get_info_from_tags (GstPad * pad, GstEvent ** event, gpointer user_data)
{
gst_object_unref (src_pad);
}
-static guint8
-enc_key_length_from_cipher_name (const gchar * cipher)
-{
- if (g_strcmp0 (cipher, "aes-128-icm") == 0)
- return AES_128_KEY_LEN;
- else if (g_strcmp0 (cipher, "aes-256-icm") == 0)
- return AES_256_KEY_LEN;
- else {
- GST_ERROR ("encryption algorithm '%s' not supported", cipher);
- return 0;
- }
-}
-
-static guint8
-auth_key_length_from_auth_name (const gchar * auth)
-{
- if (g_strcmp0 (auth, "hmac-sha1-32") == 0)
- return HMAC_32_KEY_LEN;
- else if (g_strcmp0 (auth, "hmac-sha1-80") == 0)
- return HMAC_80_KEY_LEN;
- else {
- GST_ERROR ("authentication algorithm '%s' not supported", auth);
- return 0;
- }
-}
-
static void
make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPMedia * media,
- GstRTSPStream * stream, GstStructure * s, GstRTSPProfile profile)
+ GstRTSPStream * stream, GstCaps * caps, GstRTSPProfile profile)
{
GstSDPMedia *smedia;
- const gchar *caps_str, *caps_enc, *caps_params;
gchar *tmp;
- gint caps_pt, caps_rate;
- guint n_fields, j;
- gboolean first;
- GString *fmtp;
GstRTSPLowerTrans ltrans;
GSocketFamily family;
const gchar *addrtype, *proto;
gchar *address;
guint ttl;
GstClockTime rtx_time;
+ gchar *base64;
+ guint32 ssrc;
+ GstMIKEYMessage *mikey_msg;
gst_sdp_media_new (&smedia);
- /* get media type and payload for the m= line */
- caps_str = gst_structure_get_string (s, "media");
- gst_sdp_media_set_media (smedia, caps_str);
-
- gst_structure_get_int (s, "payload", &caps_pt);
- tmp = g_strdup_printf ("%d", caps_pt);
- gst_sdp_media_add_format (smedia, tmp);
- g_free (tmp);
+ if (gst_sdp_media_set_media_from_caps (caps, smedia) != GST_SDP_OK) {
+ goto error;
+ }
gst_sdp_media_set_port_info (smedia, 0, 1);
gst_sdp_media_add_connection (smedia, "IN", addrtype, address, ttl, 1);
g_free (address);
- /* get clock-rate, media type and params for the rtpmap attribute */
- gst_structure_get_int (s, "clock-rate", &caps_rate);
- caps_enc = gst_structure_get_string (s, "encoding-name");
- caps_params = gst_structure_get_string (s, "encoding-params");
-
- if (caps_enc) {
- if (caps_params)
- tmp = g_strdup_printf ("%d %s/%d/%s", caps_pt, caps_enc, caps_rate,
- caps_params);
- else
- tmp = g_strdup_printf ("%d %s/%d", caps_pt, caps_enc, caps_rate);
-
- gst_sdp_media_add_attribute (smedia, "rtpmap", tmp);
- g_free (tmp);
- }
-
/* the config uri */
tmp = gst_rtsp_stream_get_control (stream);
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, *pkd;
- 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 */
+ mikey_msg = gst_mikey_message_new_from_caps (caps);
+ if (mikey_msg) {
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);
- /* Encryption key length */
- byte = enc_key_length_from_cipher_name (srtpcipher);
- gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_ENC_KEY_LEN, 1,
- &byte);
- /* only HMAC-SHA1 */
- gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_ALG, 1,
- &byte);
- /* Authentication key length */
- byte = auth_key_length_from_auth_name (srtpauth);
- gst_mikey_payload_sp_add_param (payload, GST_MIKEY_SP_SRTP_AUTH_KEY_LEN, 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);
-
- /* make unencrypted KEMAC */
- payload = gst_mikey_payload_new (GST_MIKEY_PT_KEMAC);
- gst_mikey_payload_kemac_set (payload, GST_MIKEY_ENC_NULL,
- GST_MIKEY_MAC_NULL);
-
- /* add the key in key data */
- pkd = gst_mikey_payload_new (GST_MIKEY_PT_KEY_DATA);
- gst_buffer_map (srtpkey, &info, GST_MAP_READ);
- gst_mikey_payload_key_data_set_key (pkd, GST_MIKEY_KD_TEK, info.size,
- info.data);
- gst_buffer_unmap (srtpkey, &info);
- /* add key data to KEMAC */
- gst_mikey_payload_kemac_add_sub (payload, pkd);
- gst_mikey_message_add_payload (msg, payload);
-
- /* now serialize this to bytes */
- bytes = gst_mikey_message_to_bytes (msg, NULL, NULL);
- gst_mikey_message_unref (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);
- first = TRUE;
- n_fields = gst_structure_n_fields (s);
- for (j = 0; j < n_fields; j++) {
- const gchar *fname, *fval;
-
- fname = gst_structure_nth_field_name (s, j);
-
- /* filter out standard properties */
- if (!strcmp (fname, "media"))
- continue;
- if (!strcmp (fname, "payload"))
- continue;
- if (!strcmp (fname, "clock-rate"))
- continue;
- if (!strcmp (fname, "encoding-name"))
- continue;
- if (!strcmp (fname, "encoding-params"))
- continue;
- if (!strcmp (fname, "ssrc"))
- continue;
- if (!strcmp (fname, "timestamp-offset"))
- continue;
- if (!strcmp (fname, "seqnum-offset"))
- continue;
- if (g_str_has_prefix (fname, "srtp-"))
- continue;
- if (g_str_has_prefix (fname, "srtcp-"))
- continue;
- /* handled later */
- if (g_str_has_prefix (fname, "x-gst-rtsp-server-rtx-time"))
- continue;
-
- if (!strcmp (fname, "a-framesize")) {
- /* a-framesize attribute */
- if ((fval = gst_structure_get_string (s, fname))) {
- tmp = g_strdup_printf ("%d %s", caps_pt, fval);
- gst_sdp_media_add_attribute (smedia, fname + 2, tmp);
- g_free (tmp);
- }
- continue;
- }
-
- if (g_str_has_prefix (fname, "a-")) {
- /* attribute */
- if ((fval = gst_structure_get_string (s, fname)))
- gst_sdp_media_add_attribute (smedia, fname + 2, fval);
- continue;
- }
- if (g_str_has_prefix (fname, "x-")) {
- /* attribute */
- if ((fval = gst_structure_get_string (s, fname)))
- gst_sdp_media_add_attribute (smedia, fname, fval);
- continue;
- }
+ /* add policy '0' for our SSRC */
+ gst_mikey_message_add_cs_srtp (mikey_msg, 0, ssrc, 0);
- if ((fval = gst_structure_get_string (s, fname))) {
- g_string_append_printf (fmtp, "%s%s=%s", first ? "" : ";", fname, fval);
- first = FALSE;
+ base64 = gst_mikey_message_base64_encode (mikey_msg);
+ if (base64) {
+ tmp = g_strdup_printf ("mikey %s", base64);
+ g_free (base64);
+ gst_sdp_media_add_attribute (smedia, "key-mgmt", tmp);
+ g_free (tmp);
}
- }
- if (!first) {
- tmp = g_string_free (fmtp, FALSE);
- gst_sdp_media_add_attribute (smedia, "fmtp", tmp);
- g_free (tmp);
- } else {
- g_string_free (fmtp, TRUE);
+ gst_mikey_message_unref (mikey_msg);
}
update_sdp_from_tags (stream, smedia);
"Not adding retransmission");
} else {
gchar *tmp;
+ GstStructure *s;
+ gint caps_pt, caps_rate;
+
+ s = gst_caps_get_structure (caps, 0);
+ if (s == NULL)
+ goto error;
+
+ /* get payload type and clock rate */
+ gst_structure_get_int (s, "payload", &caps_pt);
+ gst_structure_get_int (s, "clock-rate", &caps_rate);
tmp = g_strdup_printf ("%d", rtx_pt);
gst_sdp_media_add_format (smedia, tmp);
gst_rtsp_stream_get_index (stream));
return;
}
+error:
+ {
+ gst_sdp_media_free (smedia);
+ g_warning ("ignoring stream %d", gst_rtsp_stream_get_index (stream));
+ return;
+ }
}
/**
for (i = 0; i < n_streams; i++) {
GstRTSPStream *stream;
GstCaps *caps;
- GstStructure *s;
GstRTSPProfile profiles;
guint mask;
continue;
}
- s = gst_caps_get_structure (caps, 0);
- if (s == NULL) {
- gst_caps_unref (caps);
- g_warning ("ignoring stream %d without media type", i);
- continue;
- }
-
/* make a new media for each profile */
profiles = gst_rtsp_stream_get_profiles (stream);
mask = 1;
GstRTSPProfile prof = profiles & mask;
if (prof)
- make_media (sdp, info, media, stream, s, prof);
+ make_media (sdp, info, media, stream, caps, prof);
mask <<= 1;
}