From: Hyunjun Ko Date: Wed, 7 Oct 2015 09:53:01 +0000 (+0900) Subject: sdp: replace duplicated codes to call new base sdp apis X-Git-Tag: 1.19.3~495^2~566 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=924f914172795fa714725b890f773d8b2ecffda2;p=platform%2Fupstream%2Fgstreamer.git sdp: replace duplicated codes to call new base sdp apis https://bugzilla.gnome.org/show_bug.cgi?id=745880 --- diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index ae590bb..4013813 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -3206,490 +3206,6 @@ no_setup_sdp: } } -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: - * - * /[/] - */ -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: /[/] - * a=framesize: - - * a=fmtp: [=];... - */ -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 [=];... */ - PARSE_INT (p, " ", payload); - if (payload != -1 && payload == pt) { - gchar **pairs; - gint i; - - /* [=] 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 ;.. is translated into =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 - */ - 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) { @@ -3756,7 +3272,7 @@ 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; @@ -3764,9 +3280,9 @@ default_handle_sdp (GstRTSPMedia * media, GstSDPMessage * sdp) /* 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); diff --git a/gst/rtsp-server/rtsp-sdp.c b/gst/rtsp-server/rtsp-sdp.c index 393b099..74ea340 100644 --- a/gst/rtsp-server/rtsp-sdp.c +++ b/gst/rtsp-server/rtsp-sdp.c @@ -30,12 +30,6 @@ #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) { @@ -78,60 +72,27 @@ update_sdp_from_tags (GstRTSPStream * stream, GstSDPMedia * stream_media) 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); @@ -185,201 +146,27 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPMedia * media, 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); @@ -394,6 +181,16 @@ make_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPMedia * media, "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); @@ -424,6 +221,12 @@ no_multicast: 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; + } } /** @@ -456,7 +259,6 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info, for (i = 0; i < n_streams; i++) { GstRTSPStream *stream; GstCaps *caps; - GstStructure *s; GstRTSPProfile profiles; guint mask; @@ -468,13 +270,6 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info, 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; @@ -482,7 +277,7 @@ gst_rtsp_sdp_from_media (GstSDPMessage * sdp, GstSDPInfo * info, GstRTSPProfile prof = profiles & mask; if (prof) - make_media (sdp, info, media, stream, s, prof); + make_media (sdp, info, media, stream, caps, prof); mask <<= 1; }