[asterisk-commits] kharwell: branch kharwell/pimp_my_sip r384748 - in /team/kharwell/pimp_my_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Apr 4 11:40:26 CDT 2013


Author: kharwell
Date: Thu Apr  4 11:40:23 2013
New Revision: 384748

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=384748
Log:
SIP video support.

Adding in video support and capabilities.  This addition handles negotiation
of video streams, including attribute negotiation, and also the video source
update control frame (initiates a fast video update request - RFC 5168).

Since there was similar functionality between the audio and video these
modifications also merged the handling of the two media types into a single
file, res_sip_sdp_rtp.c

(issue ASTERISK-21077)
........

Merged revisions 384736 from http://svn.asterisk.org/svn/asterisk/team/group/pimp_my_sip

Added:
    team/kharwell/pimp_my_sip/res/res_sip_sdp_rtp.c
      - copied unchanged from r384736, team/group/pimp_my_sip/res/res_sip_sdp_rtp.c
Removed:
    team/kharwell/pimp_my_sip/res/res_sip_sdp_audio.c
Modified:
    team/kharwell/pimp_my_sip/   (props changed)
    team/kharwell/pimp_my_sip/channels/chan_gulp.c
    team/kharwell/pimp_my_sip/include/asterisk/res_sip_session.h
    team/kharwell/pimp_my_sip/res/res_sip_session.c

Propchange: team/kharwell/pimp_my_sip/
------------------------------------------------------------------------------
    automerge = *

Propchange: team/kharwell/pimp_my_sip/
------------------------------------------------------------------------------
--- pimp_my_sip-integrated (original)
+++ pimp_my_sip-integrated Thu Apr  4 11:40:23 2013
@@ -1,1 +1,1 @@
-/team/group/pimp_my_sip:1-384713
+/team/group/pimp_my_sip:1-384747

Modified: team/kharwell/pimp_my_sip/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/channels/chan_gulp.c?view=diff&rev=384748&r1=384747&r2=384748
==============================================================================
--- team/kharwell/pimp_my_sip/channels/chan_gulp.c (original)
+++ team/kharwell/pimp_my_sip/channels/chan_gulp.c Thu Apr  4 11:40:23 2013
@@ -268,6 +268,21 @@
 	return AST_RTP_GLUE_RESULT_LOCAL;
 }
 
+/*! \brief Function called by RTP engine to get local video RTP peer */
+static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **instance)
+{
+	struct gulp_pvt *pvt = ast_channel_tech_pvt(chan);
+
+	if (!pvt || !pvt->session || !pvt->media[SIP_MEDIA_VIDEO]->rtp) {
+		return AST_RTP_GLUE_RESULT_FORBID;
+	}
+
+	*instance = pvt->media[SIP_MEDIA_VIDEO]->rtp;
+	ao2_ref(*instance, +1);
+
+	return AST_RTP_GLUE_RESULT_LOCAL;
+}
+
 /*! \brief Function called by RTP engine to get peer capabilities */
 static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
@@ -384,6 +399,7 @@
 static struct ast_rtp_glue gulp_rtp_glue = {
 	.type = "Gulp",
 	.get_rtp_info = gulp_get_rtp_peer,
+	.get_vrtp_info = gulp_get_vrtp_peer,
 	.get_codec = gulp_get_codec,
 	.update_peer = gulp_set_rtp_peer,
 };
@@ -416,9 +432,13 @@
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
 	ast_channel_tech_pvt_set(chan, pvt);
 
-	ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
-	ast_codec_choose(&session->endpoint->prefs, session->endpoint->codecs, 1, &fmt);
-
+	if (ast_format_cap_is_empty(session->req_caps)) {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
+	} else {
+		ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps);
+	}
+
+	ast_codec_choose(&session->endpoint->prefs, ast_channel_nativeformats(chan), 1, &fmt);
 	ast_format_copy(ast_channel_writeformat(chan), &fmt);
 	ast_format_copy(ast_channel_rawwriteformat(chan), &fmt);
 	ast_format_copy(ast_channel_readformat(chan), &fmt);
@@ -477,22 +497,32 @@
 {
 	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
 	struct ast_frame *f;
-	struct ast_sip_session_media *media = pvt->media[SIP_MEDIA_AUDIO];
-
-	if (!media) {
+	struct ast_sip_session_media *media = NULL;
+	int rtcp = 0;
+	int fdno = ast_channel_fdno(ast);
+
+	switch (fdno) {
+	case 0:
+		media = pvt->media[SIP_MEDIA_AUDIO];
+		break;
+	case 1:
+		media = pvt->media[SIP_MEDIA_AUDIO];
+		rtcp = 1;
+		break;
+	case 2:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		break;
+	case 3:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		rtcp = 1;
+		break;
+	}
+
+	if (!media || !media->rtp) {
 		return &ast_null_frame;
 	}
 
-	switch (ast_channel_fdno(ast)) {
-	case 0:
-		f = ast_rtp_instance_read(media->rtp, 0);
-		break;
-	case 1:
-		f = ast_rtp_instance_read(media->rtp, 1);
-		break;
-	default:
-		f = &ast_null_frame;
-	}
+	f = ast_rtp_instance_read(media->rtp, rtcp);
 
 	if (f && f->frametype == AST_FRAME_VOICE) {
 		if (!(ast_format_cap_iscompatible(ast_channel_nativeformats(ast), &f->subclass.format))) {
@@ -535,6 +565,11 @@
 			res = ast_rtp_instance_write(media->rtp, frame);
 		}
 		break;
+	case AST_FRAME_VIDEO:
+		if ((media = pvt->media[SIP_MEDIA_VIDEO]) && media->rtp) {
+			res = ast_rtp_instance_write(media->rtp, frame);
+		}
+		break;
 	default:
 		ast_log(LOG_WARNING, "Can't send %d type frames with Gulp\n", frame->frametype);
 		break;
@@ -627,12 +662,40 @@
 	return 0;
 }
 
+/*! \brief Send SIP INFO with video update request */
+static int transmit_info_with_vidupdate(void *data)
+{
+	const char * xml =
+		"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
+		" <media_control>\r\n"
+		"  <vc_primitive>\r\n"
+		"   <to_encoder>\r\n"
+		"    <picture_fast_update/>\r\n"
+		"   </to_encoder>\r\n"
+		"  </vc_primitive>\r\n"
+		" </media_control>\r\n";
+
+	const struct ast_sip_body body = {
+		.type = "application",
+		.subtype = "media_control+xml",
+		.body_text = xml
+	};
+
+	struct ast_sip_session *session = data;
+	if (ast_sip_send_request("INFO", &body, session->inv_session->dlg, NULL) != PJ_SUCCESS) {
+		ast_log(LOG_ERROR, "Could not send text video update INFO request\n");
+	}
+
+	return 0;
+}
+
 /*! \brief Function called by core to ask the channel to indicate some sort of condition */
 static int gulp_indicate(struct ast_channel *ast, int condition, const void *data, size_t datalen)
 {
 	int res = 0;
 	struct gulp_pvt *pvt = ast_channel_tech_pvt(ast);
 	struct ast_sip_session *session = pvt->session;
+	struct ast_sip_session_media *media;
 	int response_code = 0;
 
 	switch (condition) {
@@ -679,6 +742,12 @@
 		}
 		break;
 	case AST_CONTROL_VIDUPDATE:
+		media = pvt->media[SIP_MEDIA_VIDEO];
+		if (media && media->rtp) {
+			ast_sip_push_task(session->serializer, transmit_info_with_vidupdate, session);
+		} else
+			res = -1;
+		break;
 	case AST_CONTROL_UPDATE_RTP_PEER:
 	case AST_CONTROL_PVT_CAUSE_CODE:
 		break;
@@ -930,6 +999,7 @@
 
 struct request_data {
 	struct ast_sip_session *session;
+	struct ast_format_cap *caps;
 	const char *dest;
 	int cause;
 };
@@ -970,12 +1040,13 @@
 		return -1;
 	}
 
-	if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user))) {
+	if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user, req_data->caps))) {
 		req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
 		return -1;
 	}
 
 	req_data->session = session;
+
 	return 0;
 }
 
@@ -985,6 +1056,7 @@
 	struct request_data req_data;
 	struct ast_sip_session *session;
 
+	req_data.caps = cap;
 	req_data.dest = data;
 
 	if (ast_sip_push_task_synchronous(NULL, request, &req_data)) {

Modified: team/kharwell/pimp_my_sip/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/include/asterisk/res_sip_session.h?view=diff&rev=384748&r1=384747&r2=384748
==============================================================================
--- team/kharwell/pimp_my_sip/include/asterisk/res_sip_session.h (original)
+++ team/kharwell/pimp_my_sip/include/asterisk/res_sip_session.h Thu Apr  4 11:40:23 2013
@@ -97,6 +97,8 @@
 	pj_timer_entry rescheduled_reinvite;
 	/* Format capabilities pertaining to direct media */
 	struct ast_format_cap *direct_media_cap;
+	/* Requested capabilities */
+	struct ast_format_cap *req_caps;
 };
 
 typedef int (*ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata);
@@ -266,8 +268,9 @@
  * \param endpoint The endpoint that this session uses for settings
  * \param location Optional name of the location to call, be it named location or explicit URI
  * \param request_user Optional request user to place in the request URI if permitted
- */
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user);
+ * \param req_caps The requested capabilities
+ */
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *req_caps);
 
 /*!
  * \brief Register an SDP handler

Modified: team/kharwell/pimp_my_sip/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_my_sip/res/res_sip_session.c?view=diff&rev=384748&r1=384747&r2=384748
==============================================================================
--- team/kharwell/pimp_my_sip/res/res_sip_session.c (original)
+++ team/kharwell/pimp_my_sip/res/res_sip_session.c Thu Apr  4 11:40:23 2013
@@ -27,7 +27,6 @@
 #include <pjsip.h>
 #include <pjsip_ua.h>
 #include <pjlib.h>
-#include "pjsua-lib/pjsua.h"
 
 #include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
@@ -872,6 +871,7 @@
 		ast_free(delay);
 	}
 	ao2_cleanup(session->endpoint);
+	ast_format_cap_destroy(session->req_caps);
 }
 
 static int add_supplements(struct ast_sip_session *session)
@@ -934,6 +934,8 @@
 	inv_session->mod_data[session_module.id] = session;
 	session->endpoint = endpoint;
 	session->inv_session = inv_session;
+	session->req_caps = ast_format_cap_alloc_nolock();
+
 	if (add_supplements(session)) {
 		return NULL;
 	}
@@ -954,7 +956,7 @@
 	return CMP_MATCH | CMP_STOP;
 }
 
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user)
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *req_caps)
 {
 	char *aor_name, *rest;
 	const char *uri = NULL;
@@ -1012,9 +1014,14 @@
 	timer.sess_expires = endpoint->sess_expires;
 	pjsip_timer_init_session(inv_session, &timer);
 
-	if (!(session = ast_sip_session_alloc(endpoint, inv_session)) ||
-		(pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) ||
-		!(offer = create_local_sdp(inv_session, session, NULL))) {
+	if (!(session = ast_sip_session_alloc(endpoint, inv_session))) {
+		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		return NULL;
+	}
+
+	ast_format_cap_copy(session->req_caps, req_caps);
+	if ((pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) ||
+	    !(offer = create_local_sdp(inv_session, session, NULL))) {
 		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		return NULL;
 	}
@@ -1209,7 +1216,6 @@
 	}
 	return PJ_FALSE;
 }
-
 /*!
  * \brief Called when a new SIP request comes into PJSIP
  *




More information about the asterisk-commits mailing list