[asterisk-commits] twilson: branch group/srtp r175584 - in /team/group/srtp: ./ channels/ format...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Feb 13 11:34:16 CST 2009


Author: twilson
Date: Fri Feb 13 11:34:16 2009
New Revision: 175584

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=175584
Log:
Merged revisions 175508,175512 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/trunk

........
  r175508 | kpfleming | 2009-02-13 07:35:24 -0600 (Fri, 13 Feb 2009) | 15 lines
  
  Add basic (passthrough, playback, record) support for ITU G.722.1 and G.722.1C (also known as Siren7 and Siren14)
  
  This patch adds passthrough, file recording and file playback support for the codecs listed above, with negotiation over SIP/SDP supported. Due to Asterisk's current limitation of treating a codec/bitrate combination as a unique codec, only G.722.1 at 32 kbps and G.722.1C at 48 kbps are supported.
  
  Along the way, some related work was done:
  
  1) The rtpPayloadType structure definition, used as a return result for an API call in rtp.h, was moved from rtp.c to rtp.h so that the API call was actually usable. The only previous used of the API all was chan_h323.c, which had a duplicate of the structure definition instead of doing it the right way.
  
  2) The hardcoded SDP sample rates for various codecs in chan_sip.c were removed, in favor of storing these sample rates in rtp.c along with the codec definitions there. A new API call was added to allow retrieval of the sample rate for a given codec.
  
  3) Some basic 'a=fmtp' parsing for SDP was added to chan_sip, because chan_sip *must* decline any media streams offered for these codecs that are not at the bitrates that we support (otherwise Bad Things (TM) would result).
  
  Review: http://reviewboard.digium.com/r/158/
........
  r175512 | kpfleming | 2009-02-13 07:41:52 -0600 (Fri, 13 Feb 2009) | 3 lines
  
  document G.722.1/.1C support
........

Added:
    team/group/srtp/formats/format_siren14.c
      - copied unchanged from r175512, trunk/formats/format_siren14.c
    team/group/srtp/formats/format_siren7.c
      - copied unchanged from r175512, trunk/formats/format_siren7.c
Modified:
    team/group/srtp/   (props changed)
    team/group/srtp/CHANGES
    team/group/srtp/channels/chan_h323.c
    team/group/srtp/channels/chan_sip.c
    team/group/srtp/include/asterisk/frame.h
    team/group/srtp/include/asterisk/rtp.h
    team/group/srtp/main/frame.c
    team/group/srtp/main/rtp.c

Propchange: team/group/srtp/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Feb 13 11:34:16 2009
@@ -1,1 +1,1 @@
-/trunk:1-175486
+/trunk:1-175547

Modified: team/group/srtp/CHANGES
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/CHANGES?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/CHANGES (original)
+++ team/group/srtp/CHANGES Fri Feb 13 11:34:16 2009
@@ -48,6 +48,7 @@
    first INVITE is generated - SIPRemoveHeader()
  * Channel variables set with setvar= in a device configuration is now 
    set both for inbound and outbound calls.
+ * Added support for ITU G.722.1 and G.722.1C (Siren7 and Siren14) media streams.
 
 Skinny Changes
 --------------
@@ -135,6 +136,8 @@
  * The contrib/scripts/ directory now has a script called sip_nat_settings that will
    give you the correct output for an asterisk box behind nat. It will give you the
    externhost and localnet settings.
+ * The Asterisk core now supports ITU G.722.1 and G.722.1C media streams, and
+   can connect calls in passthrough mode, as well as record and play back files.
 
 Asterisk Manager Interface
 --------------------------

Modified: team/group/srtp/channels/chan_h323.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/channels/chan_h323.c?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/channels/chan_h323.c (original)
+++ team/group/srtp/channels/chan_h323.c Fri Feb 13 11:34:16 2009
@@ -1922,15 +1922,6 @@
 	return info;
 }
 
-/* 
- * Definition taken from rtp.c for rtpPayloadType because we need it here.
- */
-
-struct rtpPayloadType {
-	int isAstFormat;	/* whether the following code is an AST_FORMAT */
-	int code;
-};
-
 /*! \brief
   * Call-back function passing remote ip/port information from H.323 to asterisk
   *

Modified: team/group/srtp/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/channels/chan_sip.c?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/channels/chan_sip.c (original)
+++ team/group/srtp/channels/chan_sip.c Fri Feb 13 11:34:16 2009
@@ -2291,10 +2291,10 @@
 static const char *get_sdp(struct sip_request *req, const char *name);
 static int find_sdp(struct sip_request *req);
 static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action);
-static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
+static void add_codec_to_sdp(const struct sip_pvt *p, int codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size);
-static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
+static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
 				struct ast_str **m_buf, struct ast_str **a_buf,
 				int debug);
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp);
@@ -7720,21 +7720,16 @@
 	iterator = req->sdp_start;
 	while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
 		char mimeSubtype[128];
+		char fmtp_string[64];
+		unsigned int sample_rate;
+
 		if (option_debug > 1) {
 			int breakout = FALSE;
-		
+
 			/* If we're debugging, check for unsupported sdp options */
 			if (!strncasecmp(a, "rtcp:", (size_t) 5)) {
 				if (debug)
 					ast_verbose("Got unsupported a:rtcp in SDP offer \n");
-				breakout = TRUE;
-			} else if (!strncasecmp(a, "fmtp:", (size_t) 5)) {
-				/* Format parameters:  Not supported */
-				/* Note: This is used for codec parameters, like bitrate for
-					G722 and video formats for H263 and H264 
-					See RFC2327 for an example */
-				if (debug)
-					ast_verbose("Got unsupported a:fmtp in SDP offer \n");
 				breakout = TRUE;
 			} else if (!strncasecmp(a, "framerate:", (size_t) 10)) {
 				/* Video stuff:  Not supported */
@@ -7750,6 +7745,7 @@
 			if (breakout)	/* We have a match, skip to next header */
 				continue;
 		}
+
 		if (!strcasecmp(a, "sendonly")) {
 			if (sendonly == -1)
 				sendonly = 1;
@@ -7760,17 +7756,24 @@
 		} else if (!strncasecmp(a, "key-mgmt:mikey ", (size_t) 15)) {
 			ast_log(LOG_NOTICE, "Asterisk currently does not support MIKEY key negotiation\n");
 			continue;
-		} else if (!strcasecmp(a, "inactive")) {
+		}
+
+		if (!strcasecmp(a, "inactive")) {
 			if (sendonly == -1)
 				sendonly = 2;
 			continue;
-		}  else if (!strcasecmp(a, "sendrecv")) {
+		}
+
+		if (!strcasecmp(a, "sendrecv")) {
 			if (sendonly == -1)
 				sendonly = 0;
 			continue;
-		} else if (strlen(a) > 5 && !strncasecmp(a, "ptime", 5)) {
+		}
+
+		if (!strncasecmp(a, "ptime", 5)) {
 			char *tmp = strrchr(a, ':');
 			long int framing = 0;
+
 			if (tmp) {
 				tmp++;
 				framing = strtol(tmp, NULL, 10);
@@ -7794,8 +7797,9 @@
 				ast_rtp_codec_setpref(p->rtp, pref);
 			}
 			continue;
-			
-		} else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
+		}
+
+		if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
 			/* count numbers of generations in fmtp */
 			red_cp = &red_fmtp[strlen(red_fmtp)];
 			strncpy(red_fmtp, a, 100);
@@ -7807,15 +7811,59 @@
 				red_cp = strtok(NULL, "/");
 			}
 			red_cp = red_fmtp;
-
-		} else if (sscanf(a, "rtpmap: %u %127[^/]/", &codec, mimeSubtype) == 2) {
+			continue;
+		}
+
+		if (sscanf(a, "fmtp: %u %63s", &codec, fmtp_string) == 2) {
+			struct rtpPayloadType payload;
+			unsigned int handled = 0;
+
+			payload = ast_rtp_lookup_pt(newaudiortp, codec);
+			if (!payload.code) {
+				/* it wasn't found, try the video rtp */
+				payload = ast_rtp_lookup_pt(newvideortp, codec);
+			}
+			if (payload.code && payload.isAstFormat) {
+				unsigned int bit_rate;
+
+				switch (payload.code) {
+				case AST_FORMAT_SIREN7:
+					if (sscanf(fmtp_string, "bitrate=%u", &bit_rate) == 1) {
+						if (bit_rate != 32000) {
+							ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate);
+							ast_rtp_unset_m_type(newaudiortp, codec);
+						} else {
+							handled = 1;
+						}
+					}
+					break;
+				case AST_FORMAT_SIREN14:
+					if (sscanf(fmtp_string, "bitrate=%u", &bit_rate) == 1) {
+						if (bit_rate != 48000) {
+							ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate);
+							ast_rtp_unset_m_type(newaudiortp, codec);
+						} else {
+							handled = 1;
+						}
+					}
+					break;
+				}
+			}
+
+			if (!handled) {
+				ast_debug(1, "Got unsupported a:%s in SDP offer\n", a);
+			}
+			continue;
+		}
+
+		if (sscanf(a, "rtpmap: %u %127[^/]/%u", &codec, mimeSubtype, &sample_rate) == 3) {
 			/* We have a rtpmap to handle */
 
 			if (last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
-				/* Note: should really look at the 'freq' and '#chans' params too */
+				/* Note: should really look at the '#chans' params too */
 				/* Note: This should all be done in the context of the m= above */
 				if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {         /* Video */
-					if(ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) {
+					if (ast_rtp_set_rtpmap_type_rate(newvideortp, codec, "video", mimeSubtype, 0, sample_rate) != -1) {
 						if (debug)
 							ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
 						found_rtpmap_codecs[last_rtpmap_codec] = codec;
@@ -7837,11 +7885,12 @@
 						sprintf(red_fmtp, "fmtp:%d ", red_pt); 
 
 						if (debug)
-							ast_verbose("Red submimetype has payload type: %d\n", red_pt);
+							ast_verbose("RED submimetype has payload type: %d\n", red_pt);
 					}
 				} else {                                          /* Must be audio?? */
-					if(ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
-								   ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) {
+					if (ast_rtp_set_rtpmap_type_rate(newaudiortp, codec, "audio", mimeSubtype,
+									 ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0,
+									 sample_rate) != -1) {
 						if (debug)
 							ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
 						found_rtpmap_codecs[last_rtpmap_codec] = codec;
@@ -8965,7 +9014,7 @@
 }
 
 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
+static void add_codec_to_sdp(const struct sip_pvt *p, int codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -8985,18 +9034,31 @@
 		return;
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-			 ast_rtp_lookup_mime_subtype(1, codec,
-						     ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
-			 sample_rate);
-	if (codec == AST_FORMAT_G729A) {
+		       ast_rtp_lookup_mime_subtype(1, codec,
+						   ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
+		       ast_rtp_lookup_sample_rate(1, codec));
+
+	switch (codec) {
+	case AST_FORMAT_G729A:
 		/* Indicate that we don't support VAD (G.729 annex B) */
 		ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
-	} else if (codec == AST_FORMAT_G723_1) {
+		break;
+	case AST_FORMAT_G723_1:
 		/* Indicate that we don't support VAD (G.723.1 annex A) */
 		ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
-	} else if (codec == AST_FORMAT_ILBC) {
+		break;
+	case AST_FORMAT_ILBC:
 		/* Add information about us using only 20/30 ms packetization */
 		ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
+		break;
+	case AST_FORMAT_SIREN7:
+		/* Indicate that we only expect 32Kbps */
+		ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=32000\r\n", rtp_code);
+		break;
+	case AST_FORMAT_SIREN14:
+		/* Indicate that we only expect 48Kbps */
+		ast_str_append(a_buf, 0, "a=fmtp:%d bitrate=48000\r\n", rtp_code);
+		break;
 	}
 
 	if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
@@ -9009,7 +9071,7 @@
 
 /*! \brief Add video codec offer to SDP offer/answer body in INVITE or 200 OK */
 /* This is different to the audio one now so we can add more caps later */
-static void add_vcodec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
+static void add_vcodec_to_sdp(const struct sip_pvt *p, int codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -9026,12 +9088,13 @@
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-			 ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate);
+		       ast_rtp_lookup_mime_subtype(1, codec, 0),
+		       ast_rtp_lookup_sample_rate(1, codec));
 	/* Add fmtp code here */
 }
 
 /*! \brief Add text codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_tcodec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
+static void add_tcodec_to_sdp(const struct sip_pvt *p, int codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -9048,11 +9111,12 @@
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-			 ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate);
+		       ast_rtp_lookup_mime_subtype(1, codec, 0),
+		       ast_rtp_lookup_sample_rate(1, codec));
 	/* Add fmtp code here */
 
 	if (codec == AST_FORMAT_T140RED) {
-		ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 
+		ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
 			 ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140),
 			 ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140),
 			 ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140));
@@ -9177,7 +9241,7 @@
 
 
 /*! \brief Add RFC 2833 DTMF offer to SDP */
-static void add_noncodec_to_sdp(const struct sip_pvt *p, int format, int sample_rate,
+static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
 				struct ast_str **m_buf, struct ast_str **a_buf,
 				int debug)
 {
@@ -9190,8 +9254,8 @@
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-			 ast_rtp_lookup_mime_subtype(0, format, 0),
-			 sample_rate);
+		       ast_rtp_lookup_mime_subtype(0, format, 0),
+		       ast_rtp_lookup_sample_rate(0, format));
 	if (format == AST_RTP_DTMF)	/* Indicate we support DTMF and FLASH... */
 		ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
 }
@@ -9231,13 +9295,6 @@
 	}
 
 }
-
-/*!
- * \note G.722 actually is supposed to specified as 8 kHz, even though it is
- * really 16 kHz.  Update this macro for other formats as they are added in
- * the future.
- */
-#define SDP_SAMPLE_RATE(x) 8000
 
 /*! \brief Add Session Description Protocol message 
 
@@ -9436,9 +9493,7 @@
 	if (capability & p->prefcodec) {
 		int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
 
-		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
-				 &m_audio, &a_audio,
-				 debug, &min_audio_packet_size);
+		add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
 		alreadysent |= codec;
 	}
 
@@ -9455,9 +9510,7 @@
 		if (alreadysent & codec)
 			continue;
 
-		add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
-				 &m_audio, &a_audio,
-				 debug, &min_audio_packet_size);
+		add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
 		alreadysent |= codec;
 	}
 
@@ -9470,14 +9523,11 @@
 			continue;
 
 		if (x & AST_FORMAT_AUDIO_MASK)
-			add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
-				 &m_audio, &a_audio, debug, &min_audio_packet_size);
-		else if (x & AST_FORMAT_VIDEO_MASK) 
-			add_vcodec_to_sdp(p, x, 90000,
-				 &m_video, &a_video, debug, &min_video_packet_size);
+			add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size);
+		else if (x & AST_FORMAT_VIDEO_MASK)
+			add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size);
 		else if (x & AST_FORMAT_TEXT_MASK)
-			add_tcodec_to_sdp(p, x, 1000,
-				 &m_text, &a_text, debug, &min_text_packet_size);
+			add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size);
 	}
 
 	/* Now add DTMF RFC2833 telephony-event as a codec */
@@ -9485,7 +9535,7 @@
 		if (!(p->jointnoncodeccapability & x))
 			continue;
 
-		add_noncodec_to_sdp(p, x, 8000, &m_audio, &a_audio, debug);
+		add_noncodec_to_sdp(p, x, &m_audio, &a_audio, debug);
 	}
 
 	ast_debug(3, "-- Done with adding codecs to SDP\n");

Modified: team/group/srtp/include/asterisk/frame.h
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/include/asterisk/frame.h?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/include/asterisk/frame.h (original)
+++ team/group/srtp/include/asterisk/frame.h Fri Feb 13 11:34:16 2009
@@ -259,6 +259,10 @@
 #define AST_FORMAT_G726		(1 << 11)
 /*! G.722 */
 #define AST_FORMAT_G722		(1 << 12)
+/*! G.722.1 (also known as Siren7, 32kbps assumed) */
+#define AST_FORMAT_SIREN7	(1 << 13)
+/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
+#define AST_FORMAT_SIREN14	(1 << 14)
 /*! Raw 16-bit Signed Linear (16000 Hz) PCM */
 #define AST_FORMAT_SLINEAR16	(1 << 15)
 /*! Maximum audio mask */
@@ -523,8 +527,8 @@
 #endif
 /*@} Doxygen marker */
 
-struct ast_format_list *ast_get_format_list_index(int index);
-struct ast_format_list *ast_get_format_list(size_t *size);
+const struct ast_format_list *ast_get_format_list_index(int index);
+const struct ast_format_list *ast_get_format_list(size_t *size);
 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix);
 
 /*! \page AudioCodecPref Audio Codec Preferences
@@ -630,10 +634,16 @@
  */
 static force_inline int ast_format_rate(int format)
 {
-	if (format == AST_FORMAT_G722 || format == AST_FORMAT_SLINEAR16)
+	switch (format) {
+	case AST_FORMAT_G722:
+	case AST_FORMAT_SLINEAR16:
+	case AST_FORMAT_SIREN7:
 		return 16000;
-
-	return 8000;
+	case AST_FORMAT_SIREN14:
+		return 32000;
+	default:
+		return 8000;
+	}
 }
 
 #if defined(__cplusplus) || defined(c_plusplus)

Modified: team/group/srtp/include/asterisk/rtp.h
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/include/asterisk/rtp.h?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/include/asterisk/rtp.h (original)
+++ team/group/srtp/include/asterisk/rtp.h Fri Feb 13 11:34:16 2009
@@ -83,6 +83,12 @@
 struct ast_rtp;
 /*! T.140 Redundancy structure*/
 struct rtp_red;
+
+/*! \brief The value of each payload format mapping: */
+struct rtpPayloadType {
+	int isAstFormat;		/*!< whether the following code is an AST_FORMAT */
+	int code;
+};
 
 /*! \brief This is the structure that binds a channel (SIP/Jingle/H.323) to the RTP subsystem 
 */
@@ -169,7 +175,7 @@
  * \param io
  * \param rtcpenable
  * \param callbackmode
- * \returns A representation (structure) of an RTP session.
+ * \return A representation (structure) of an RTP session.
  */
 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode);
 
@@ -183,7 +189,7 @@
  * \param rtcpenable
  * \param callbackmode
  * \param in
- * \returns A representation (structure) of an RTP session.
+ * \return A representation (structure) of an RTP session.
  */
 struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in);
 
@@ -242,21 +248,65 @@
 /*! \brief clear payload type */
 void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt);
 
-/*! \brief Initiate payload type to a known MIME media type for a codec */
+/*! \brief Set payload type to a known MIME media type for a codec
+ *
+ * \param rtp RTP structure to modify
+ * \param pt Payload type entry to modify
+ * \param mimeType top-level MIME type of media stream (typically "audio", "video", "text", etc.)
+ * \param mimeSubtype MIME subtype of media stream (typically a codec name)
+ * \param options Zero or more flags from the ast_rtp_options enum
+ *
+ * This function 'fills in' an entry in the list of possible formats for
+ * a media stream associated with an RTP structure.
+ *
+ * \retval 0 on success
+ * \retval -1 if the payload type is out of range
+ * \retval -2 if the mimeType/mimeSubtype combination was not found
+ */
 int ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
 			     char *mimeType, char *mimeSubtype,
 			     enum ast_rtp_options options);
 
+/*! \brief Set payload type to a known MIME media type for a codec with a specific sample rate
+ *
+ * \param rtp RTP structure to modify
+ * \param pt Payload type entry to modify
+ * \param mimeType top-level MIME type of media stream (typically "audio", "video", "text", etc.)
+ * \param mimeSubtype MIME subtype of media stream (typically a codec name)
+ * \param options Zero or more flags from the ast_rtp_options enum
+ * \param sample_rate The sample rate of the media stream
+ *
+ * This function 'fills in' an entry in the list of possible formats for
+ * a media stream associated with an RTP structure.
+ *
+ * \retval 0 on success
+ * \retval -1 if the payload type is out of range
+ * \retval -2 if the mimeType/mimeSubtype combination was not found
+ */
+int ast_rtp_set_rtpmap_type_rate(struct ast_rtp* rtp, int pt,
+				 char *mimeType, char *mimeSubtype,
+				 enum ast_rtp_options options,
+				 unsigned int sample_rate);
+
 /*! \brief  Mapping between RTP payload format codes and Asterisk codes: */
 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
 
 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
-			     int* astFormats, int* nonAstFormats);
+				 int* astFormats, int* nonAstFormats);
 
 /*! \brief  Mapping an Asterisk code into a MIME subtype (string): */
 const char *ast_rtp_lookup_mime_subtype(int isAstFormat, int code,
 					enum ast_rtp_options options);
+
+/*! \brief Get the sample rate associated with known RTP payload types
+ *
+ * \param isAstFormat True if the value in the 'code' parameter is an AST_FORMAT value
+ * \param code Format code, either from AST_FORMAT list or from AST_RTP list
+ *
+ * \return the sample rate if the format was found, zero if it was not found
+ */
+unsigned int ast_rtp_lookup_sample_rate(int isAstFormat, int code);
 
 /*! \brief Build a string of MIME subtype names from a capability list */
 char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,

Modified: team/group/srtp/main/frame.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/main/frame.c?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/main/frame.c (original)
+++ team/group/srtp/main/frame.c Fri Feb 13 11:34:16 2009
@@ -98,7 +98,7 @@
 };
 
 /*! \brief Definition of supported media formats (codecs) */
-static struct ast_format_list AST_FORMAT_LIST[] = {
+static const struct ast_format_list AST_FORMAT_LIST[] = {
 	{ AST_FORMAT_G723_1 , "g723", 8000, "G.723.1", 20, 30, 300, 30, 30 },                                  /*!< G723.1 */
 	{ AST_FORMAT_GSM, "gsm", 8000, "GSM", 33, 20, 300, 20, 20 },                                           /*!< codec_gsm.c */
 	{ AST_FORMAT_ULAW, "ulaw", 8000, "G.711 u-law", 80, 10, 150, 10, 20 },                                 /*!< codec_ulaw.c */
@@ -120,8 +120,10 @@
 	{ AST_FORMAT_H263_PLUS, "h263p", 0, "H.263+ Video" },                                                  /*!< H.263plus passthrough support See format_h263.c */
 	{ AST_FORMAT_H264, "h264", 0, "H.264 Video" },                                                         /*!< Passthrough support, see format_h263.c */
 	{ AST_FORMAT_MP4_VIDEO, "mpeg4", 0, "MPEG4 Video" },                                                   /*!< Passthrough support for MPEG4 */
-	{ AST_FORMAT_T140RED, "red", 1, "T.140 Realtime Text with redundancy"},                                 /*!< Redundant T.140 Realtime Text */
+	{ AST_FORMAT_T140RED, "red", 1, "T.140 Realtime Text with redundancy"},                                /*!< Redundant T.140 Realtime Text */
 	{ AST_FORMAT_T140, "t140", 0, "Passthrough T.140 Realtime Text" },                                     /*!< Passthrough support for T.140 Realtime Text */
+	{ AST_FORMAT_SIREN7, "siren7", 16000, "ITU G.722.1 (Siren7, licensed from Polycom)", 80, 20, 80, 20, 20 },			/*!< Binary commercial distribution */
+	{ AST_FORMAT_SIREN14, "siren14", 32000, "ITU G.722.1 Annex C, (Siren14, licensed from Polycom)", 120, 20, 80, 20, 20 },	/*!< Binary commercial distribution */
 };
 
 struct ast_frame ast_null_frame = { AST_FRAME_NULL, };
@@ -505,12 +507,12 @@
 }
 
 
-struct ast_format_list *ast_get_format_list_index(int idx) 
+const struct ast_format_list *ast_get_format_list_index(int idx) 
 {
 	return &AST_FORMAT_LIST[idx];
 }
 
-struct ast_format_list *ast_get_format_list(size_t *size) 
+const struct ast_format_list *ast_get_format_list(size_t *size) 
 {
 	*size = ARRAY_LEN(AST_FORMAT_LIST);
 	return AST_FORMAT_LIST;
@@ -564,6 +566,8 @@
 	{ "slinear", "slin"},
 	{ "slinear16", "slin16"},
 	{ "g723.1", "g723"},
+	{ "g722.1", "siren7"},
+	{ "g722.1c", "siren14"},
 };
 
 static const char *ast_expand_codec_alias(const char *in)
@@ -1407,7 +1411,8 @@
 
 int ast_codec_get_samples(struct ast_frame *f)
 {
-	int samples=0;
+	int samples = 0;
+
 	switch(f->subclass) {
 	case AST_FORMAT_SPEEX:
 		samples = speex_samples(f->data.ptr, f->datalen);
@@ -1443,6 +1448,14 @@
 	case AST_FORMAT_G726_AAL2:
 		samples = f->datalen * 2;
 		break;
+	case AST_FORMAT_SIREN7:
+		/* 16,000 samples per second at 32kbps is 4,000 bytes per second */
+		samples = f->datalen * (16000 / 4000);
+		break;
+	case AST_FORMAT_SIREN14:
+		/* 32,000 samples per second at 48kbps is 6,000 bytes per second */
+		samples = (int) f->datalen * ((float) 32000 / 6000);
+		break;
 	default:
 		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
 	}
@@ -1453,7 +1466,7 @@
 {
 	int len = 0;
 
-	/* XXX Still need speex, g723, and lpc10 XXX */	
+	/* XXX Still need speex, and lpc10 XXX */	
 	switch(format) {
 	case AST_FORMAT_G723_1:
 		len = (samples / 240) * 20;
@@ -1481,6 +1494,14 @@
 	case AST_FORMAT_G726_AAL2:
 		len = samples / 2;
 		break;
+	case AST_FORMAT_SIREN7:
+		/* 16,000 samples per second at 32kbps is 4,000 bytes per second */
+		len = samples / (16000 / 4000);
+		break;
+	case AST_FORMAT_SIREN14:
+		/* 32,000 samples per second at 48kbps is 6,000 bytes per second */
+		len = (int) samples / ((float) 32000 / 6000);
+		break;
 	default:
 		ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
 	}

Modified: team/group/srtp/main/rtp.c
URL: http://svn.digium.com/svn-view/asterisk/team/group/srtp/main/rtp.c?view=diff&rev=175584&r1=175583&r2=175584
==============================================================================
--- team/group/srtp/main/rtp.c (original)
+++ team/group/srtp/main/rtp.c Fri Feb 13 11:34:16 2009
@@ -100,11 +100,6 @@
  * RTP session is defined on page 9 of RFC 3550: "An association among a set of participants communicating with RTP.  A participant may be involved in multiple RTP sessions at the same time [...]"
  *
  */
-/*! \brief The value of each payload format mapping: */
-struct rtpPayloadType {
-	int isAstFormat; 	/*!< whether the following code is an AST_FORMAT */
-	int code;
-};
 
 /*! \brief RTP session description */
 struct ast_rtp {
@@ -1986,7 +1981,7 @@
 		/* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
 		ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
 		rtp->f.ts = timestamp / 8;
-		rtp->f.len = rtp->f.samples / ( (ast_format_rate(rtp->f.subclass) == 16000) ? 16 : 8 );
+		rtp->f.len = rtp->f.samples / ((ast_format_rate(rtp->f.subclass) / 1000));
 	} else if (rtp->f.subclass & AST_FORMAT_VIDEO_MASK) {
 		/* Video -- samples is # of samples vs. 90000 */
 		if (!rtp->lastividtimestamp)
@@ -2017,40 +2012,46 @@
 
 /* The following array defines the MIME Media type (and subtype) for each
    of our codecs, or RTP-specific data type. */
-static struct {
+static const struct mimeType {
 	struct rtpPayloadType payloadType;
-	char* type;
-	char* subtype;
+	char *type;
+	char *subtype;
+	unsigned int sample_rate;
 } mimeTypes[] = {
-	{{1, AST_FORMAT_G723_1}, "audio", "G723"},
-	{{1, AST_FORMAT_GSM}, "audio", "GSM"},
-	{{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
-	{{1, AST_FORMAT_ULAW}, "audio", "G711U"},
-	{{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
-	{{1, AST_FORMAT_ALAW}, "audio", "G711A"},
-	{{1, AST_FORMAT_G726}, "audio", "G726-32"},
-	{{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
-	{{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
-	{{1, AST_FORMAT_LPC10}, "audio", "LPC"},
-	{{1, AST_FORMAT_G729A}, "audio", "G729"},
-	{{1, AST_FORMAT_G729A}, "audio", "G729A"},
-	{{1, AST_FORMAT_G729A}, "audio", "G.729"},
-	{{1, AST_FORMAT_SPEEX}, "audio", "speex"},
-	{{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
-	{{1, AST_FORMAT_G722}, "audio", "G722"},
-	{{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"},
-	{{0, AST_RTP_DTMF}, "audio", "telephone-event"},
-	{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
-	{{0, AST_RTP_CN}, "audio", "CN"},
-	{{1, AST_FORMAT_JPEG}, "video", "JPEG"},
-	{{1, AST_FORMAT_PNG}, "video", "PNG"},
-	{{1, AST_FORMAT_H261}, "video", "H261"},
-	{{1, AST_FORMAT_H263}, "video", "H263"},
-	{{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"},
-	{{1, AST_FORMAT_H264}, "video", "H264"},
-	{{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES"},
-	{{1, AST_FORMAT_T140RED}, "text", "RED"},
-	{{1, AST_FORMAT_T140}, "text", "T140"},
+	{{1, AST_FORMAT_G723_1}, "audio", "G723", 8000},
+	{{1, AST_FORMAT_GSM}, "audio", "GSM", 8000},
+	{{1, AST_FORMAT_ULAW}, "audio", "PCMU", 8000},
+	{{1, AST_FORMAT_ULAW}, "audio", "G711U", 8000},
+	{{1, AST_FORMAT_ALAW}, "audio", "PCMA", 8000},
+	{{1, AST_FORMAT_ALAW}, "audio", "G711A", 8000},
+	{{1, AST_FORMAT_G726}, "audio", "G726-32", 8000},
+	{{1, AST_FORMAT_ADPCM}, "audio", "DVI4", 8000},
+	{{1, AST_FORMAT_SLINEAR}, "audio", "L16", 8000},
+	{{1, AST_FORMAT_LPC10}, "audio", "LPC", 8000},
+	{{1, AST_FORMAT_G729A}, "audio", "G729", 8000},
+	{{1, AST_FORMAT_G729A}, "audio", "G729A", 8000},
+	{{1, AST_FORMAT_G729A}, "audio", "G.729", 8000},
+	{{1, AST_FORMAT_SPEEX}, "audio", "speex", 8000},
+	{{1, AST_FORMAT_ILBC}, "audio", "iLBC", 8000},
+	/* this is the sample rate listed in the RTP profile for the G.722
+	   codec, *NOT* the actual sample rate of the media stream
+	*/
+	{{1, AST_FORMAT_G722}, "audio", "G722", 8000},
+	{{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32", 8000},
+	{{0, AST_RTP_DTMF}, "audio", "telephone-event", 8000},
+	{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event", 8000},
+	{{0, AST_RTP_CN}, "audio", "CN", 8000},
+	{{1, AST_FORMAT_JPEG}, "video", "JPEG", 90000},
+	{{1, AST_FORMAT_PNG}, "video", "PNG", 90000},
+	{{1, AST_FORMAT_H261}, "video", "H261", 90000},
+	{{1, AST_FORMAT_H263}, "video", "H263", 90000},
+	{{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998", 90000},
+	{{1, AST_FORMAT_H264}, "video", "H264", 90000},
+	{{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES", 90000},
+	{{1, AST_FORMAT_T140RED}, "text", "RED", 1000},
+	{{1, AST_FORMAT_T140}, "text", "T140", 1000},
+	{{1, AST_FORMAT_SIREN7}, "audio", "G7221", 16000},
+	{{1, AST_FORMAT_SIREN14}, "audio", "G7221", 32000},
 };
 
 /*! 
@@ -2063,7 +2064,7 @@
  * See http://www.iana.org/assignments/rtp-parameters for a list of
  * assigned values
  */
-static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
+static const struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
 	[0] = {1, AST_FORMAT_ULAW},
 #ifdef USE_DEPRECATED_G726
 	[2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
@@ -2089,6 +2090,7 @@
 	[98] = {1, AST_FORMAT_H263_PLUS},
 	[99] = {1, AST_FORMAT_H264},
 	[101] = {0, AST_RTP_DTMF},
+	[102] = {1, AST_FORMAT_SIREN7},
 	[103] = {1, AST_FORMAT_H263_PLUS},
 	[104] = {1, AST_FORMAT_MP4_VIDEO},
 	[105] = {1, AST_FORMAT_T140RED},	/* Real time text chat (with redundancy encoding) */
@@ -2096,6 +2098,7 @@
 	[110] = {1, AST_FORMAT_SPEEX},
 	[111] = {1, AST_FORMAT_G726},
 	[112] = {1, AST_FORMAT_G726_AAL2},
+	[115] = {1, AST_FORMAT_SIREN14},
 	[121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
 };
 
@@ -2365,35 +2368,61 @@
  * an SDP "a=rtpmap:" line.
  * \return 0 if the MIME type was found and set, -1 if it wasn't found
  */
-int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
-			     char *mimeType, char *mimeSubtype,
-			     enum ast_rtp_options options)
+int ast_rtp_set_rtpmap_type_rate(struct ast_rtp *rtp, int pt,
+				 char *mimeType, char *mimeSubtype,
+				 enum ast_rtp_options options,
+				 unsigned int sample_rate)
 {
 	unsigned int i;
 	int found = 0;
 
-	if (pt < 0 || pt > MAX_RTP_PT) 
+	if (pt < 0 || pt > MAX_RTP_PT)
 		return -1; /* bogus payload type */
-	
+
 	rtp_bridge_lock(rtp);
 
 	for (i = 0; i < ARRAY_LEN(mimeTypes); ++i) {
-		if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
-		    strcasecmp(mimeType, mimeTypes[i].type) == 0) {
-			found = 1;
-			rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
-			if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) &&
-			    mimeTypes[i].payloadType.isAstFormat &&
-			    (options & AST_RTP_OPT_G726_NONSTANDARD))
-				rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
-			break;
-		}
+		const struct mimeType *t = &mimeTypes[i];
+
+		if (strcasecmp(mimeSubtype, t->subtype)) {
+			continue;
+		}
+
+		if (strcasecmp(mimeType, t->type)) {
+			continue;
+		}
+
+		/* if both sample rates have been supplied, and they don't match,
+		   then this not a match; if one has not been supplied, then the
+		   rates are not compared */
+		if (sample_rate && t->sample_rate &&
+		    (sample_rate != t->sample_rate)) {
+			continue;
+		}
+
+		found = 1;
+		rtp->current_RTP_PT[pt] = t->payloadType;
+
+		if ((t->payloadType.code == AST_FORMAT_G726) &&
+		    t->payloadType.isAstFormat &&
+		    (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+			rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
+		}
+
+		break;
 	}
 
 	rtp_bridge_unlock(rtp);
 
-	return (found ? 0 : -1);
-} 
+	return (found ? 0 : -2);
+}
+
+int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
+			    char *mimeType, char *mimeSubtype,
+			    enum ast_rtp_options options)
+{
+	return ast_rtp_set_rtpmap_type_rate(rtp, pt, mimeType, mimeSubtype, options, 0);
+}
 
 /*! \brief Return the union of all of the codecs that were set by rtp_set...() calls 
  * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
@@ -2496,6 +2525,19 @@
 	}
 
 	return "";
+}
+
+unsigned int ast_rtp_lookup_sample_rate(int isAstFormat, int code)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_LEN(mimeTypes); ++i) {
+		if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) {
+			return mimeTypes[i].sample_rate;
+		}
+	}
+
+	return 0;
 }
 
 char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
@@ -4934,9 +4976,8 @@
 {
 	if (f->datalen > -1) {
 		struct rtp_red *red = rtp->red;
-		memcpy(&red->buf_data[red->t140.datalen], f->data.ptr, f->datalen); 
+		memcpy(&red->buf_data[red->t140.datalen], f->data.ptr, f->datalen);
 		red->t140.datalen += f->datalen;
 		red->t140.ts = f->ts;
 	}
 }
-




More information about the asterisk-commits mailing list