[asterisk-commits] file: branch group/pimp_my_sip r379269 - /team/group/pimp_my_sip/res/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 16 13:28:02 CST 2013


Author: file
Date: Wed Jan 16 13:27:59 2013
New Revision: 379269

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=379269
Log:
Enable RTCP and apply joint audio capabilities to the RTP instance and channel.

Modified:
    team/group/pimp_my_sip/res/res_sip_sdp_audio.c

Modified: team/group/pimp_my_sip/res/res_sip_sdp_audio.c
URL: http://svnview.digium.com/svn/asterisk/team/group/pimp_my_sip/res/res_sip_sdp_audio.c?view=diff&rev=379269&r1=379268&r2=379269
==============================================================================
--- team/group/pimp_my_sip/res/res_sip_sdp_audio.c (original)
+++ team/group/pimp_my_sip/res/res_sip_sdp_audio.c Wed Jan 16 13:27:59 2013
@@ -45,8 +45,13 @@
 #include "asterisk/netsock2.h"
 #include "asterisk/channel.h"
 #include "asterisk/causes.h"
-
+#include "asterisk/sched.h"
+
+#include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
+
+/*! \brief Scheduler for RTCP purposes */
+static struct ast_sched_context *sched;
 
 /*! \brief Forward declarations for SDP handler functions */
 static int audio_handle_incoming_sdp_stream_offer(struct ast_sip_session *session, struct pjmedia_sdp_media *stream);
@@ -67,14 +72,14 @@
 	/* TODO: Add support for IPv6 */
 	ast_sockaddr_parse(&tmp, "0.0.0.0", 0);
 
-	if (!(session->media.audio = ast_rtp_instance_new("asterisk", NULL, &tmp, NULL))) {
+	if (!(session->media.audio = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
 		return -1;
 	}
 
-	/* TODO: Create scheduler so RTCP can function */
-	ast_rtp_instance_set_prop(session->media.audio, AST_RTP_PROPERTY_RTCP, 0);
+	ast_rtp_instance_set_prop(session->media.audio, AST_RTP_PROPERTY_RTCP, 1);
 
 	ast_channel_set_fd(session->channel, 0, ast_rtp_instance_fd(session->media.audio, 0));
+	ast_channel_set_fd(session->channel, 1, ast_rtp_instance_fd(session->media.audio, 1));
 	
 	return 0;
 }
@@ -82,17 +87,20 @@
 /*! \brief Function which handles an incoming 'audio' stream */
 static int audio_handle_incoming_sdp_stream_offer(struct ast_sip_session *session, struct pjmedia_sdp_media *stream)
 {
+	int res = 0, addrs_cnt, format, othercapability = 0;
 	char host[NI_MAXHOST];
-	int addrs_cnt, format;
 	struct ast_sockaddr *addrs;
 	struct ast_rtp_codecs codecs;
 	const pjmedia_sdp_attr *attr;
+	struct ast_format_cap *cap, *jointcap = NULL, *peercap = NULL;
+	struct ast_format fmt;
 
 	/* If the stream has been rejected stop media if active */
 	if (!stream->desc.port) {
 		if (session->media.audio) {
 			ast_rtp_instance_stop(session->media.audio);
 		}
+
 		return 1;
 	}
 
@@ -111,6 +119,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())) {
+		res = -1;
+		goto cleanup;
+	}
+
 	/* Apply connection information to the RTP instance */
 	ast_sockaddr_set_port(addrs, stream->desc.port);
 	ast_rtp_instance_set_remote_address(session->media.audio, addrs);
@@ -136,7 +151,38 @@
 		}
 	}
 
-	return 0;
+	ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
+
+	/* 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))) {
+		ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+		res = -1;
+		goto cleanup;
+	}
+
+	ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session->media.audio), session->media.audio);
+
+	/* 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(NULL, cap, 1, &fmt);
+	ast_set_read_format(session->channel, &fmt);
+	ast_set_write_format(session->channel, &fmt);
+
+cleanup:
+	ast_format_cap_destroy(peercap);
+	ast_format_cap_destroy(jointcap);
+	ast_format_cap_destroy(cap);
+	ast_rtp_codecs_payloads_destroy(&codecs);
+
+	return res;
 }
 
 /*! \brief Function which creates an outgoing 'audio' stream */
@@ -157,13 +203,36 @@
  */
 static int load_module(void)
 {
-	return ast_sip_session_register_sdp_handler(&audio_sdp_handler, "audio") ? AST_MODULE_LOAD_FAILURE : AST_MODULE_LOAD_SUCCESS;
+	if (!(sched = ast_sched_context_create())) {
+		ast_log(LOG_ERROR, "Unable to create scheduler context.\n");
+		goto end;
+	}
+
+	if (ast_sched_start_thread(sched)) {
+		ast_log(LOG_ERROR, "Unable to create scheduler context thread.\n");
+		goto end;
+	}
+
+	if (ast_sip_session_register_sdp_handler(&audio_sdp_handler, "audio")) {
+		ast_log(LOG_ERROR, "Unable to register SDP handler for 'audio' stream type\n");
+		goto end;
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
+end:
+	if (sched) {
+		ast_sched_context_destroy(sched);
+	}
+
+
+	return AST_MODULE_LOAD_FAILURE;
 }
 
 /*! \brief Unload the Gulp channel from Asterisk */
 static int unload_module(void)
 {
 	ast_sip_session_unregister_sdp_handler(&audio_sdp_handler, "audio");
+	ast_sched_context_destroy(sched);
 	return 0;
 }
 




More information about the asterisk-commits mailing list