[asterisk-commits] kharwell: branch kharwell/pimp_sip_video r383516 - in /team/kharwell/pimp_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Mar 21 11:40:55 CDT 2013


Author: kharwell
Date: Thu Mar 21 11:40:51 2013
New Revision: 383516

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383516
Log:
addressing some issues found during initial review: adding caps to audio, using push_task to handle video update INFO, a few coding guideline fixes, etc...

Modified:
    team/kharwell/pimp_sip_video/channels/chan_gulp.c
    team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c
    team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c

Modified: team/kharwell/pimp_sip_video/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/channels/chan_gulp.c?view=diff&rev=383516&r1=383515&r2=383516
==============================================================================
--- team/kharwell/pimp_sip_video/channels/chan_gulp.c (original)
+++ team/kharwell/pimp_sip_video/channels/chan_gulp.c Thu Mar 21 11:40:51 2013
@@ -538,8 +538,9 @@
 }
 
 /*! \brief Send SIP INFO with video update request */
-static int transmit_info_with_vidupdate(struct ast_sip_session *session)
-{
+static int transmit_info_with_vidupdate(void *data)
+{
+	struct ast_sip_session *session = data;
 	pjsip_tx_data *packet;
 
 	const pj_str_t type = pj_str("application");
@@ -555,11 +556,9 @@
 		"  </vc_primitive>\r\n"
 		" </media_control>\r\n");
 
-	if (pjsip_inv_invite(session->inv_session, &packet) != PJ_SUCCESS) {
-		return -1;
-	}
-
-	packet->msg->body = pjsip_msg_body_create(packet->pool, &type, &subtype, &xml);
+	/* TODO: create and send in-dialog INFO request */
+	/* packet->msg->body = pjsip_msg_body_create(packet->pool, &type, &subtype, &xml); */
+
 	return 0;
 }
 
@@ -618,8 +617,7 @@
 	case AST_CONTROL_VIDUPDATE:
 		media = pvt->media[SIP_MEDIA_VIDEO];
 		if (media && media->rtp) {
-			transmit_info_with_vidupdate(session);
-			response_code = 200;
+			ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session);
 		} else
 			res = -1;
 		break;

Modified: team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c?view=diff&rev=383516&r1=383515&r2=383516
==============================================================================
--- team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c (original)
+++ team/kharwell/pimp_sip_video/res/res_sip_sdp_audio.c Thu Mar 21 11:40:51 2013
@@ -50,6 +50,8 @@
 #include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
 
+static const char STR_AUDIO[] = "audio";
+
 /*! \brief Scheduler for RTCP purposes */
 static struct ast_sched_context *sched;
 
@@ -101,6 +103,135 @@
 	return 0;
 }
 
+static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream,
+		       struct ast_rtp_codecs* codecs, const char *type)
+{
+	pjmedia_sdp_attr *attr;
+	pjmedia_sdp_rtpmap *rtpmap;
+	pjmedia_sdp_fmtp fmtp;
+	struct ast_format *format;
+	int i, num = 0;
+	char name[32];
+
+	ast_rtp_codecs_payloads_initialize(codecs);
+
+	/* Iterate through provided formats */
+	for (i = 0; i < stream->desc.fmt_count; ++i) {
+		/* The payload is kept as a string for things like t38 but for video it is always numerical */
+		ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
+		/* Look for the optional rtpmap attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
+			continue;
+		}
+
+		/* Interpret the attribute as an rtpmap */
+		if (!(pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
+			continue;
+		}
+
+		ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
+		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
+							     (char*)type, name, 0, rtpmap->clock_rate);
+		/* Look for an optional associated fmtp attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
+			continue;
+		}
+
+		if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
+			sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
+			if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
+				ast_format_sdp_parse(format, pj_strbuf(&fmtp.fmt_param));
+			}
+		}
+	}
+}
+
+static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+		    const struct pjmedia_sdp_media *stream, enum ast_format_type type, const char *type_desc)
+{
+	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
+	struct ast_rtp_codecs codecs;
+	struct ast_format fmt;
+	int fmts = 0;
+
+	if (!(caps = ast_format_cap_alloc_nolock()) ||
+	    !(peer = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type_desc);
+		return -1;
+	}
+
+	/* get the endpoint capabilities */
+	ast_format_cap_copy(caps, session->endpoint->codecs);
+	ast_format_cap_remove_bytype(caps, AST_FORMAT_TYPE_VIDEO);
+
+	/* get the capabilities on the peer */
+	get_codecs(session, stream, &codecs, type_desc);
+	ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
+
+	/* get the joint capabilities between peer and endpoint */
+	if (!(joint = ast_format_cap_joint(caps, peer))) {
+		char usbuf[64], thembuf[64];
+
+		ast_rtp_codecs_payloads_destroy(&codecs);
+		if (session->channel) {
+			ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+		}
+
+		ast_getformatname_multiple(usbuf, sizeof(usbuf), caps);
+		ast_getformatname_multiple(thembuf, sizeof(thembuf), peer);
+		ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
+		return -1;
+	}
+
+	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
+				     session_media->rtp);
+
+	ast_format_cap_copy(caps, session->caps);
+	ast_format_cap_remove_bytype(caps, type);
+	ast_format_cap_append(caps, joint);
+	ast_format_cap_append(session->caps, joint);
+
+	if (session->channel) {
+		/* Apply the new formats to the channel, potentially changing read/write formats while doing so */
+		ast_format_cap_append(ast_channel_nativeformats(session->channel), session->caps);
+		ast_codec_choose(&session->endpoint->prefs, caps, 0, &fmt);
+		ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
+		ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
+		ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
+		ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+	}
+
+	ast_rtp_codecs_payloads_destroy(&codecs);
+	return 1;
+}
+
+static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
+{
+	struct ast_str *fmtp0 = ast_str_alloca(256);
+	pj_str_t fmtp1;
+	pjmedia_sdp_attr *attr = NULL;
+	char *tmp;
+
+	ast_format_sdp_generate(format, rtp_code, &fmtp0);
+	if (ast_str_strlen(fmtp0)) {
+		tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
+		/* remove any carriage return line feeds */
+		while (*tmp == '\r' || *tmp == '\n') --tmp;
+		*++tmp = '\0';
+		/* ast...generate gives us everything, just need value */
+		tmp = strchr(ast_str_buffer(fmtp0), ':');
+		if (tmp && tmp + 1) {
+			fmtp1 = pj_str(tmp + 1);
+		} else {
+			fmtp1 = pj_str(ast_str_buffer(fmtp0));
+		}
+		attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
+	}
+	return attr;
+}
+
 /*! \brief Function which negotiates an incoming 'audio' stream */
 static int audio_negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
 {
@@ -126,7 +257,7 @@
 	}
 
 	/* pjmedia takes care of the formats and such */
-	return 1;
+	return set_caps(session, session_media, stream, AST_FORMAT_TYPE_AUDIO, STR_AUDIO);
 }
 
 /*! \brief Function which adds ICE attributes to an 'audio' stream */
@@ -193,7 +324,6 @@
 static int audio_create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp)
 {
 	pj_pool_t *pool = session->inv_session->pool_active;
-	static const pj_str_t STR_AUDIO = { "audio", 5};
 	static const pj_str_t STR_IN = { "IN", 2 };
 	static const pj_str_t STR_IP4 = { "IP4", 3};
 	static const pj_str_t STR_IP6 = { "IP6", 3};
@@ -206,6 +336,10 @@
 	pj_str_t stmp;
 	pjmedia_sdp_attr *attr;
 	int index = 0, min_packet_size = 0, noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733) ? AST_RTP_DTMF : 0;
+	int rtp_code;
+	char rtp_code_str[32];
+	struct ast_format format;
+	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
 
 	if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_AUDIO)) {
 		/* If no audio formats are configured don't add a stream */
@@ -220,7 +354,7 @@
 	}
 
 	/* TODO: This should eventually support SRTP */
-	media->desc.media = STR_AUDIO;
+	media->desc.media = pj_str((char*)STR_AUDIO);
 	media->desc.transport = STR_RTP_AVP;
 
 	/* Add connection level details */
@@ -245,24 +379,30 @@
 	/* Add ICE attributes and candidates */
 	audio_add_ice_to_stream(session, session_media, pool, media);
 
-	/* Add formats */
-	for (index = 0; (index < AST_CODEC_PREF_SIZE); index++) {
-		struct ast_format format;
-		int rtp_code;
+	if (!(caps = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n");
+		return -1;
+	}
+	if (ast_format_cap_is_empty(session->caps)) {
+		ast_format_cap_copy(caps, session->endpoint->codecs);
+	} else {
+		ast_format_cap_copy(caps, session->caps);
+	}
+
+	ast_format_cap_iter_start(caps);
+	while (!(ast_format_cap_iter_next(caps, &format))) {
 		pjmedia_sdp_rtpmap rtpmap;
 		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
-
-		if (!ast_codec_pref_index(&session->endpoint->prefs, index, &format)) {
-			break;
-		} else if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) {
+		if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) {
 			continue;
-		} else if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp),
-								   1, &format, 0)) == -1) {
+		}
+
+		if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &format, 0)) == -1) {
 			return -1;
 		}
 
-		snprintf(tmp, sizeof(tmp), "%d", rtp_code);
-		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
+		snprintf(rtp_code_str, sizeof(rtp_code_str), "%d", rtp_code);
+		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], rtp_code_str);
 		rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
 		rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(1, &format, 0);
 		pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(1, &format, 0, 0));
@@ -270,6 +410,10 @@
 
 		pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
 		media->attr[media->attr_count++] = attr;
+
+		if ((attr = generate_fmtp_attr(pool, &format, rtp_code))) {
+			media->attr[media->attr_count++] = attr;
+		}
 
 		if (pref) {
 			struct ast_format_list fmt = ast_codec_pref_getsize(pref, &format);
@@ -278,6 +422,41 @@
 			}
 		}
 	}
+	ast_format_cap_iter_end(caps);
+
+	/* /\* Add formats *\/ */
+	/* for (index = 0; (index < AST_CODEC_PREF_SIZE); index++) { */
+	/* 	struct ast_format format; */
+	/* 	int rtp_code; */
+	/* 	pjmedia_sdp_rtpmap rtpmap; */
+	/* 	struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref; */
+
+	/* 	if (!ast_codec_pref_index(&session->endpoint->prefs, index, &format)) { */
+	/* 		break; */
+	/* 	} else if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) { */
+	/* 		continue; */
+	/* 	} else if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), */
+	/* 							   1, &format, 0)) == -1) { */
+	/* 		return -1; */
+	/* 	} */
+
+	/* 	snprintf(tmp, sizeof(tmp), "%d", rtp_code); */
+	/* 	pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp); */
+	/* 	rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1]; */
+	/* 	rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(1, &format, 0); */
+	/* 	pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(1, &format, 0, 0)); */
+	/* 	rtpmap.param.slen = 0; */
+
+	/* 	pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr); */
+	/* 	media->attr[media->attr_count++] = attr; */
+
+	/* 	if (pref) { */
+	/* 		struct ast_format_list fmt = ast_codec_pref_getsize(pref, &format); */
+	/* 		if (fmt.cur_ms && ((fmt.cur_ms < min_packet_size) || !min_packet_size)) { */
+	/* 			min_packet_size = fmt.cur_ms; */
+	/* 		} */
+	/* 	} */
+	/* } */
 
 	/* Add non-codec formats */
 	for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
@@ -406,15 +585,8 @@
 static int audio_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
 	const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
 {
-	int format, othercapability = 0;
 	char host[NI_MAXHOST];
 	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
-	struct ast_rtp_codecs codecs;
-	const pjmedia_sdp_attr *attr;
-	RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy);
-	RAII_VAR(struct ast_format_cap *, jointcap, NULL, ast_format_cap_destroy);
-	RAII_VAR(struct ast_format_cap *, peercap, NULL, ast_format_cap_destroy);
-	struct ast_format fmt;
 
 	if (!session->channel) {
 		return 1;
@@ -433,94 +605,13 @@
 		return -1;
 	}
 
-	/* To properly apply formats to the channel we need to keep track of capabilities */
-	if (!(cap = ast_format_cap_alloc_nolock()) ||
-		!(peercap = ast_format_cap_alloc_nolock())) {
-		ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n");
-		return -1;
-	}
-
 	/* Apply connection information to the RTP instance */
 	ast_sockaddr_set_port(addrs, remote_stream->desc.port);
 	ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
 
-	ast_rtp_codecs_payloads_initialize(&codecs);
-
-	/* Iterate through provided formats */
-	for (format = 0; format < local_stream->desc.fmt_count; format++) {
-		/* The payload is kept as a string for things like t38 but for audio it is always numerical */
-		ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]));
-
-		/* Look for the optional rtpmap attribute */
-		if ((attr = pjmedia_sdp_media_find_attr2(local_stream, "rtpmap", &local_stream->desc.fmt[format]))) {
-			pjmedia_sdp_rtpmap *rtpmap;
-
-			/* Interpret the attribute as an rtpmap */
-			if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
-				char name[32];
-
-				ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
-				ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]),
-										 "audio", name, 0, rtpmap->clock_rate);
-			}
-		}
-	}
-
-	ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
-
-	/* Apply packetization if available and configured to do so */
-	if (session->endpoint->use_ptime && (attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) {
-		pj_str_t value = attr->value;
-		unsigned long framing = pj_strtoul(pj_strltrim(&value));
-		int codec;
-		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
-
-		for (codec = 0; codec < AST_RTP_MAX_PT; codec++) {
-			struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(
-				session_media->rtp), codec);
-
-			if (!format.asterisk_format) {
-				continue;
-			}
-
-			ast_codec_pref_setsize(pref, &format.format, framing);
-		}
-
-		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp),
-			session_media->rtp, pref);
-	}
-
-	/* Using the configured codecs and the codecs in this SDP we determine the joint formats for *audio only* */
-	ast_format_cap_copy(cap, session->endpoint->codecs);
-	ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_VIDEO);
-
-	if (!(jointcap = ast_format_cap_joint(cap, peercap))) {
-		char usbuf[64], thembuf[64];
-
-		ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
-		ast_getformatname_multiple(usbuf, sizeof(usbuf), cap);
-		ast_getformatname_multiple(thembuf, sizeof(thembuf), peercap);
-		ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
-
-		ast_rtp_codecs_payloads_destroy(&codecs);
-		return -1;
-	}
-
-	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
-				     session_media->rtp);
-
-	/* Now that we have joint formats for audio remove the existing ones from the channel and add the new ones */
-	ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel));
-	ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
-	ast_format_cap_append(cap, jointcap);
-
-	/* Apply the new formats to the channel, potentially changing read/write formats while doing so */
-	ast_format_cap_copy(ast_channel_nativeformats(session->channel), cap);
-	ast_codec_choose(&session->endpoint->prefs, cap, 1, &fmt);
-	ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
-	ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
-	ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
-	ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+	if (set_caps(session, session_media, local_stream, AST_FORMAT_TYPE_AUDIO, STR_AUDIO) < 1) {
+		return -1;
+	}
 
 	ast_channel_set_fd(session->channel, 0, ast_rtp_instance_fd(session_media->rtp, 0));
 	ast_channel_set_fd(session->channel, 1, ast_rtp_instance_fd(session_media->rtp, 1));
@@ -546,9 +637,155 @@
 		ast_rtp_instance_activate(session_media->rtp);
 	}
 
-	ast_rtp_codecs_payloads_destroy(&codecs);
 	return 1;
 }
+
+/* static int audio_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream, */
+/* 	const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream) */
+/* { */
+/* 	int format, othercapability = 0; */
+/* 	char host[NI_MAXHOST]; */
+/* 	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr); */
+/* 	struct ast_rtp_codecs codecs; */
+/* 	const pjmedia_sdp_attr *attr; */
+/* 	RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy); */
+/* 	RAII_VAR(struct ast_format_cap *, jointcap, NULL, ast_format_cap_destroy); */
+/* 	RAII_VAR(struct ast_format_cap *, peercap, NULL, ast_format_cap_destroy); */
+/* 	struct ast_format fmt; */
+
+/* 	if (!session->channel) { */
+/* 		return 1; */
+/* 	} */
+
+/* 	/\* Create an RTP instance if need be *\/ */
+/* 	if (!session_media->rtp && audio_create_rtp(session, session_media, session->endpoint->rtp_ipv6)) { */
+/* 		return -1; */
+/* 	} */
+
+/* 	ast_copy_pj_str(host, remote_stream->conn ? &remote_stream->conn->addr : &remote->conn->addr, sizeof(host)); */
+
+/* 	/\* Ensure that the address provided is valid *\/ */
+/* 	if (ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC) <= 0) { */
+/* 		/\* The provided host was actually invalid so we error out this negotiation *\/ */
+/* 		return -1; */
+/* 	} */
+
+/* 	/\* To properly apply formats to the channel we need to keep track of capabilities *\/ */
+/* 	if (!(cap = ast_format_cap_alloc_nolock()) || */
+/* 		!(peercap = ast_format_cap_alloc_nolock())) { */
+/* 		ast_log(LOG_ERROR, "Failed to allocate audio capabilities\n"); */
+/* 		return -1; */
+/* 	} */
+
+/* 	/\* Apply connection information to the RTP instance *\/ */
+/* 	ast_sockaddr_set_port(addrs, remote_stream->desc.port); */
+/* 	ast_rtp_instance_set_remote_address(session_media->rtp, addrs); */
+
+/* 	ast_rtp_codecs_payloads_initialize(&codecs); */
+
+/* 	/\* Iterate through provided formats *\/ */
+/* 	for (format = 0; format < local_stream->desc.fmt_count; format++) { */
+/* 		/\* The payload is kept as a string for things like t38 but for audio it is always numerical *\/ */
+/* 		ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format])); */
+
+/* 		/\* Look for the optional rtpmap attribute *\/ */
+/* 		if ((attr = pjmedia_sdp_media_find_attr2(local_stream, "rtpmap", &local_stream->desc.fmt[format]))) { */
+/* 			pjmedia_sdp_rtpmap *rtpmap; */
+
+/* 			/\* Interpret the attribute as an rtpmap *\/ */
+/* 			if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) { */
+/* 				char name[32]; */
+
+/* 				ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name)); */
+/* 				ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]), */
+/* 										 "audio", name, 0, rtpmap->clock_rate); */
+/* 			} */
+/* 		} */
+/* 	} */
+
+/* 	ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability); */
+
+/* 	/\* Apply packetization if available and configured to do so *\/ */
+/* 	if (session->endpoint->use_ptime && (attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) { */
+/* 		pj_str_t value = attr->value; */
+/* 		unsigned long framing = pj_strtoul(pj_strltrim(&value)); */
+/* 		int codec; */
+/* 		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref; */
+
+/* 		for (codec = 0; codec < AST_RTP_MAX_PT; codec++) { */
+/* 			struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs( */
+/* 				session_media->rtp), codec); */
+
+/* 			if (!format.asterisk_format) { */
+/* 				continue; */
+/* 			} */
+
+/* 			ast_codec_pref_setsize(pref, &format.format, framing); */
+/* 		} */
+
+/* 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp), */
+/* 			session_media->rtp, pref); */
+/* 	} */
+
+/* 	/\* Using the configured codecs and the codecs in this SDP we determine the joint formats for *audio only* *\/ */
+/* 	ast_format_cap_copy(cap, session->endpoint->codecs); */
+/* 	ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_VIDEO); */
+
+/* 	if (!(jointcap = ast_format_cap_joint(cap, peercap))) { */
+/* 		char usbuf[64], thembuf[64]; */
+
+/* 		ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); */
+/* 		ast_getformatname_multiple(usbuf, sizeof(usbuf), cap); */
+/* 		ast_getformatname_multiple(thembuf, sizeof(thembuf), peercap); */
+/* 		ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf); */
+
+/* 		ast_rtp_codecs_payloads_destroy(&codecs); */
+/* 		return -1; */
+/* 	} */
+
+/* 	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp), */
+/* 				     session_media->rtp); */
+
+/* 	/\* Now that we have joint formats for audio remove the existing ones from the channel and add the new ones *\/ */
+/* 	ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel)); */
+/* 	ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO); */
+/* 	ast_format_cap_append(cap, jointcap); */
+
+/* 	/\* Apply the new formats to the channel, potentially changing read/write formats while doing so *\/ */
+/* 	ast_format_cap_copy(ast_channel_nativeformats(session->channel), cap); */
+/* 	ast_codec_choose(&session->endpoint->prefs, cap, 1, &fmt); */
+/* 	ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt); */
+/* 	ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt); */
+/* 	ast_set_read_format(session->channel, ast_channel_readformat(session->channel)); */
+/* 	ast_set_write_format(session->channel, ast_channel_writeformat(session->channel)); */
+
+/* 	ast_channel_set_fd(session->channel, 0, ast_rtp_instance_fd(session_media->rtp, 0)); */
+/* 	ast_channel_set_fd(session->channel, 1, ast_rtp_instance_fd(session_media->rtp, 1)); */
+
+/* 	/\* If ICE support is enabled find all the needed attributes *\/ */
+/* 	audio_process_ice_attributes(session, session_media, remote, remote_stream); */
+
+/* 	if (session_media->held && (!ast_sockaddr_isnull(addrs) || */
+/* 							  !pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL))) { */
+/* 		/\* The remote side has taken us off hold *\/ */
+/* 		ast_queue_control(session->channel, AST_CONTROL_UNHOLD); */
+/* 		ast_queue_frame(session->channel, &ast_null_frame); */
+/* 		session_media->held = 0; */
+/* 	} else if (ast_sockaddr_isnull(addrs) || ast_sockaddr_is_any(addrs) || pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) { */
+/* 		/\* The remote side has put us on hold *\/ */
+/* 		ast_queue_control_data(session->channel, AST_CONTROL_HOLD, S_OR(session->endpoint->mohsuggest, NULL), */
+/* 					   !ast_strlen_zero(session->endpoint->mohsuggest) ? strlen(session->endpoint->mohsuggest) + 1 : 0); */
+/* 		ast_rtp_instance_stop(session_media->rtp); */
+/* 		ast_queue_frame(session->channel, &ast_null_frame); */
+/* 		session_media->held = 1; */
+/* 	} else { */
+/* 		/\* The remote side has not changed state, but make sure the instance is active *\/ */
+/* 		ast_rtp_instance_activate(session_media->rtp); */
+/* 	} */
+
+/* 	ast_rtp_codecs_payloads_destroy(&codecs); */
+/* 	return 1; */
+/* } */
 
 /*! \brief Function which updates the media stream with external media address, if applicable */
 static void audio_change_outgoing_sdp_stream_media_address(pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)

Modified: team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c?view=diff&rev=383516&r1=383515&r2=383516
==============================================================================
--- team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c (original)
+++ team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c Thu Mar 21 11:40:51 2013
@@ -82,7 +82,11 @@
 		       struct ast_rtp_codecs* codecs, const char *type)
 {
 	pjmedia_sdp_attr *attr;
+	pjmedia_sdp_rtpmap *rtpmap;
+	pjmedia_sdp_fmtp fmtp;
+	struct ast_format *format;
 	int i, num = 0;
+	char name[32];
 
 	ast_rtp_codecs_payloads_initialize(codecs);
 
@@ -91,25 +95,27 @@
 		/* The payload is kept as a string for things like t38 but for video it is always numerical */
 		ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
 		/* Look for the optional rtpmap attribute */
-		if ((attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
-			pjmedia_sdp_rtpmap *rtpmap;
-			/* Interpret the attribute as an rtpmap */
-			if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
-				char name[32];
-				ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
-				ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
-									     (char*)type, name, 0, rtpmap->clock_rate);
-				/* Look for an optional associated fmtp attribute */
-				if ((attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
-					pjmedia_sdp_fmtp fmtp;
-					if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
-						struct ast_format *format;
-						sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
-						if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
-							ast_format_sdp_parse(format, pj_strbuf(&fmtp.fmt_param));
-						}
-					}
-				}
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
+			continue;
+		}
+
+		/* Interpret the attribute as an rtpmap */
+		if (!(pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
+			continue;
+		}
+
+		ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
+		ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
+							     (char*)type, name, 0, rtpmap->clock_rate);
+		/* Look for an optional associated fmtp attribute */
+		if (!(attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
+			continue;
+		}
+
+		if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
+			sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
+			if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
+				ast_format_sdp_parse(format, pj_strbuf(&fmtp.fmt_param));
 			}
 		}
 	}
@@ -191,8 +197,8 @@
 		*++tmp = '\0';
 		/* ast...generate gives us everything, just need value */
 		tmp = strchr(ast_str_buffer(fmtp0), ':');
-		if (tmp && tmp+1) {
-			fmtp1 = pj_str(tmp+1);
+		if (tmp && tmp + 1) {
+			fmtp1 = pj_str(tmp + 1);
 		} else {
 			fmtp1 = pj_str(ast_str_buffer(fmtp0));
 		}
@@ -241,12 +247,12 @@
 	pj_pool_t *pool = session->inv_session->pool_active;
 	pjmedia_sdp_media *media;
 	struct ast_sockaddr addr;
-	int rtp_code0;
-	char rtp_code1[32];
+	int rtp_code;
+	char rtp_code_str[32];
 	pjmedia_sdp_rtpmap rtpmap;
 	pjmedia_sdp_attr *attr;
 	struct ast_format format;
-	RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
 
 	if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_VIDEO)) {
 		/* If no video formats are configured don't add a stream */
@@ -274,28 +280,28 @@
 	media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
 	media->desc.port_count = 1;
 
-	if (!(joint = ast_format_cap_alloc_nolock())) {
+	if (!(caps = ast_format_cap_alloc_nolock())) {
 		ast_log(LOG_ERROR, "Failed to allocate video capabilities\n");
 		return -1;
 	}
 	if (ast_format_cap_is_empty(session->caps)) {
-		ast_format_cap_copy(joint, session->endpoint->codecs);
+		ast_format_cap_copy(caps, session->endpoint->codecs);
 	} else {
-		ast_format_cap_copy(joint, session->caps);
-	}
-
-	ast_format_cap_iter_start(joint);
-	while (!(ast_format_cap_iter_next(joint, &format))) {
+		ast_format_cap_copy(caps, session->caps);
+	}
+
+	ast_format_cap_iter_start(caps);
+	while (!(ast_format_cap_iter_next(caps, &format))) {
 		if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) {
 			continue;
 		}
 
-		if ((rtp_code0 = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &format, 0)) == -1) {
+		if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &format, 0)) == -1) {
 			return -1;
 		}
 
-		snprintf(rtp_code1, sizeof(rtp_code1), "%d", rtp_code0);
-		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], rtp_code1);
+		snprintf(rtp_code_str, sizeof(rtp_code_str), "%d", rtp_code);
+		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], rtp_code_str);
 		rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
 		rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(1, &format, 0);
 		pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(1, &format, 0, 0));
@@ -304,11 +310,11 @@
 		pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
 		media->attr[media->attr_count++] = attr;
 
-		if ((attr = generate_fmtp_attr(pool, &format, rtp_code0))) {
+		if ((attr = generate_fmtp_attr(pool, &format, rtp_code))) {
 			media->attr[media->attr_count++] = attr;
 		}
 	}
-	ast_format_cap_iter_end(joint);
+	ast_format_cap_iter_end(caps);
 
 	/* Add the sendrecv attribute - we purposely don't keep track because pjmedia-sdp will automatically change our offer for us */
 	attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
@@ -326,8 +332,6 @@
 {
 	char host[NI_MAXHOST];
 	RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
-
-	RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
 
 	/* Create an RTP instance if need be */
 	if (!session_media->rtp && video_create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
@@ -378,9 +382,15 @@
 
 static int incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
 {
+	pjsip_tx_data *tdata = NULL;
+
 	if (!pj_strcmp2(&rdata->msg_info.msg->body->content_type.type, "application") &&
 	    !pj_strcmp2(&rdata->msg_info.msg->body->content_type.subtype, "media_control+xml")) {
 		ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE);
+
+		if (pjsip_inv_answer(session->inv_session, 200, NULL, NULL, &tdata) == PJ_SUCCESS) {
+			ast_sip_session_send_response(session, tdata);
+		}
 	}
 
 	return 0;
@@ -397,8 +407,8 @@
  * Module loading including tests for configuration or dependencies.
  * This function can return AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_DECLINE,
  * or AST_MODULE_LOAD_SUCCESS. If a dependency or environment variable fails
- * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the 
- * configuration file or other non-critical problem return 
+ * tests return AST_MODULE_LOAD_FAILURE. If the module can not load the
+ * configuration file or other non-critical problem return
  * AST_MODULE_LOAD_DECLINE. On success return AST_MODULE_LOAD_SUCCESS.
  */
 static int load_module(void)




More information about the asterisk-commits mailing list