[asterisk-commits] kpfleming: trunk r175508 - in /trunk: channels/ formats/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Feb 13 07:35:24 CST 2009


Author: kpfleming
Date: Fri Feb 13 07:35:24 2009
New Revision: 175508

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=175508
Log:
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/


Added:
    trunk/formats/format_siren14.c   (with props)
    trunk/formats/format_siren7.c   (with props)
Modified:
    trunk/channels/chan_h323.c
    trunk/channels/chan_sip.c
    trunk/include/asterisk/frame.h
    trunk/include/asterisk/rtp.h
    trunk/main/frame.c
    trunk/main/rtp.c

Modified: trunk/channels/chan_h323.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/channels/chan_h323.c?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/channels/chan_h323.c (original)
+++ trunk/channels/chan_h323.c Fri Feb 13 07:35:24 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: trunk/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Feb 13 07:35:24 2009
@@ -2286,10 +2286,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);
@@ -7671,21 +7671,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 */
@@ -7706,21 +7701,29 @@
 			if (breakout)	/* We have a match, skip to next header */
 				continue;
 		}
+
 		if (!strcasecmp(a, "sendonly")) {
 			if (sendonly == -1)
 				sendonly = 1;
 			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);
@@ -7744,8 +7747,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);
@@ -7757,15 +7761,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;
@@ -7787,11 +7835,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;
@@ -8895,7 +8944,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)
 {
@@ -8915,18 +8964,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))
@@ -8939,7 +9001,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)
 {
@@ -8956,12 +9018,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)
 {
@@ -8978,11 +9041,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));
@@ -9107,7 +9171,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)
 {
@@ -9120,8 +9184,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);
 }
@@ -9161,13 +9225,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 
 
@@ -9340,9 +9397,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;
 	}
 
@@ -9359,9 +9414,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;
 	}
 
@@ -9374,14 +9427,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 */
@@ -9389,7 +9439,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");

Added: trunk/formats/format_siren14.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/formats/format_siren14.c?view=auto&rev=175508
==============================================================================
--- trunk/formats/format_siren14.c (added)
+++ trunk/formats/format_siren14.c Fri Feb 13 07:35:24 2009
@@ -1,0 +1,139 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Anthony Minessale and Digium, Inc.
+ * Anthony Minessale (anthmct at yahoo.com)
+ * Kevin P. Fleming <kpfleming at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief ITU G.722.1 Annex C (Siren14, licensed from Polycom) format, 48kbps bitrate only
+ * \arg File name extensions: siren14
+ * \ingroup formats
+ */
+ 
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/mod_format.h"
+#include "asterisk/module.h"
+#include "asterisk/endian.h"
+
+#define BUF_SIZE	120		/* 20 milliseconds == 120 bytes, 640 samples */
+#define SAMPLES_TO_BYTES(x)	((typeof(x)) x / ((float) 640 / 120))
+#define BYTES_TO_SAMPLES(x)	((typeof(x)) x * ((float) 640 / 120))
+
+static struct ast_frame *siren14read(struct ast_filestream *s, int *whennext)
+{
+	int res;
+	/* Send a frame from the file to the appropriate channel */
+
+	s->fr.frametype = AST_FRAME_VOICE;
+	s->fr.subclass = AST_FORMAT_SIREN14;
+	s->fr.mallocd = 0;
+	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
+	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
+		if (res)
+			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
+		return NULL;
+	}
+	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
+	ast_log(LOG_DEBUG, "Read frame of %d bytes and %d samples\n", res, s->fr.samples);
+	return &s->fr;
+}
+
+static int siren14write(struct ast_filestream *fs, struct ast_frame *f)
+{
+	int res;
+
+	if (f->frametype != AST_FRAME_VOICE) {
+		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
+		return -1;
+	}
+	if (f->subclass != AST_FORMAT_SIREN14) {
+		ast_log(LOG_WARNING, "Asked to write non-Siren14 frame (%d)!\n", f->subclass);
+		return -1;
+	}
+	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
+		ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+static int siren14seek(struct ast_filestream *fs, off_t sample_offset, int whence)
+{
+	off_t offset = 0, min = 0, cur, max;
+
+	sample_offset = SAMPLES_TO_BYTES(sample_offset);
+
+	cur = ftello(fs->f);
+
+	fseeko(fs->f, 0, SEEK_END);
+
+	max = ftello(fs->f);
+
+	if (whence == SEEK_SET)
+		offset = sample_offset;
+	else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
+		offset = sample_offset + cur;
+	else if (whence == SEEK_END)
+		offset = max - sample_offset;
+
+	if (whence != SEEK_FORCECUR)
+		offset = (offset > max) ? max : offset;
+
+	/* always protect against seeking past begining. */
+	offset = (offset < min) ? min : offset;
+
+	return fseeko(fs->f, offset, SEEK_SET);
+}
+
+static int siren14trunc(struct ast_filestream *fs)
+{
+	return ftruncate(fileno(fs->f), ftello(fs->f));
+}
+
+static off_t siren14tell(struct ast_filestream *fs)
+{
+	return BYTES_TO_SAMPLES(ftello(fs->f));
+}
+
+static const struct ast_format siren14_f = {
+	.name = "siren14",
+	.exts = "siren14",
+	.format = AST_FORMAT_SIREN14,
+	.write = siren14write,
+	.seek = siren14seek,
+	.trunc = siren14trunc,
+	.tell = siren14tell,
+	.read = siren14read,
+	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
+};
+
+static int load_module(void)
+{
+	if (ast_format_register(&siren14_f))
+		return AST_MODULE_LOAD_DECLINE;
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	return ast_format_unregister(siren14_f.name);
+}	
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ITU G.722.1 Annex C (Siren14, licensed from Polycom)");

Propchange: trunk/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: trunk/formats/format_siren7.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/formats/format_siren7.c?view=auto&rev=175508
==============================================================================
--- trunk/formats/format_siren7.c (added)
+++ trunk/formats/format_siren7.c Fri Feb 13 07:35:24 2009
@@ -1,0 +1,138 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 1999 - 2008, Anthony Minessale and Digium, Inc.
+ * Anthony Minessale (anthmct at yahoo.com)
+ * Kevin P. Fleming <kpfleming at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief ITU G.722.1 (Siren7, licensed from Polycom) format, 32kbps bitrate only
+ * \arg File name extensions: siren7
+ * \ingroup formats
+ */
+ 
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/mod_format.h"
+#include "asterisk/module.h"
+#include "asterisk/endian.h"
+
+#define BUF_SIZE	80		/* 20 milliseconds == 80 bytes, 320 samples */
+#define SAMPLES_TO_BYTES(x)	x / (320 / 80)
+#define BYTES_TO_SAMPLES(x)	x * (320 / 80)
+
+static struct ast_frame *siren7read(struct ast_filestream *s, int *whennext)
+{
+	int res;
+	/* Send a frame from the file to the appropriate channel */
+
+	s->fr.frametype = AST_FRAME_VOICE;
+	s->fr.subclass = AST_FORMAT_SIREN7;
+	s->fr.mallocd = 0;
+	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
+	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
+		if (res)
+			ast_log(LOG_WARNING, "Short read (%d) (%s)!\n", res, strerror(errno));
+		return NULL;
+	}
+	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
+	return &s->fr;
+}
+
+static int siren7write(struct ast_filestream *fs, struct ast_frame *f)
+{
+	int res;
+
+	if (f->frametype != AST_FRAME_VOICE) {
+		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
+		return -1;
+	}
+	if (f->subclass != AST_FORMAT_SIREN7) {
+		ast_log(LOG_WARNING, "Asked to write non-Siren7 frame (%d)!\n", f->subclass);
+		return -1;
+	}
+	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
+		ast_log(LOG_WARNING, "Bad write (%d/%d): %s\n", res, f->datalen, strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+static int siren7seek(struct ast_filestream *fs, off_t sample_offset, int whence)
+{
+	off_t offset = 0, min = 0, cur, max;
+
+	sample_offset = SAMPLES_TO_BYTES(sample_offset);
+
+	cur = ftello(fs->f);
+
+	fseeko(fs->f, 0, SEEK_END);
+
+	max = ftello(fs->f);
+
+	if (whence == SEEK_SET)
+		offset = sample_offset;
+	else if (whence == SEEK_CUR || whence == SEEK_FORCECUR)
+		offset = sample_offset + cur;
+	else if (whence == SEEK_END)
+		offset = max - sample_offset;
+
+	if (whence != SEEK_FORCECUR)
+		offset = (offset > max) ? max : offset;
+
+	/* always protect against seeking past begining. */
+	offset = (offset < min) ? min : offset;
+
+	return fseeko(fs->f, offset, SEEK_SET);
+}
+
+static int siren7trunc(struct ast_filestream *fs)
+{
+	return ftruncate(fileno(fs->f), ftello(fs->f));
+}
+
+static off_t siren7tell(struct ast_filestream *fs)
+{
+	return BYTES_TO_SAMPLES(ftello(fs->f));
+}
+
+static const struct ast_format siren7_f = {
+	.name = "siren7",
+	.exts = "siren7",
+	.format = AST_FORMAT_SIREN7,
+	.write = siren7write,
+	.seek = siren7seek,
+	.trunc = siren7trunc,
+	.tell = siren7tell,
+	.read = siren7read,
+	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
+};
+
+static int load_module(void)
+{
+	if (ast_format_register(&siren7_f))
+		return AST_MODULE_LOAD_DECLINE;
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+static int unload_module(void)
+{
+	return ast_format_unregister(siren7_f.name);
+}	
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ITU G.722.1 (Siren7, licensed from Polycom)");

Propchange: trunk/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/include/asterisk/frame.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/frame.h?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/include/asterisk/frame.h (original)
+++ trunk/include/asterisk/frame.h Fri Feb 13 07:35:24 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: trunk/include/asterisk/rtp.h
URL: http://svn.digium.com/svn-view/asterisk/trunk/include/asterisk/rtp.h?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/include/asterisk/rtp.h (original)
+++ trunk/include/asterisk/rtp.h Fri Feb 13 07:35:24 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 
 */
@@ -136,7 +142,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);
 
@@ -150,7 +156,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);
 
@@ -209,21 +215,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: trunk/main/frame.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/frame.c?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/main/frame.c (original)
+++ trunk/main/frame.c Fri Feb 13 07:35:24 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: trunk/main/rtp.c
URL: http://svn.digium.com/svn-view/asterisk/trunk/main/rtp.c?view=diff&rev=175508&r1=175507&r2=175508
==============================================================================
--- trunk/main/rtp.c (original)
+++ trunk/main/rtp.c Fri Feb 13 07:35:24 2009
@@ -97,12 +97,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 {
@@ -1832,7 +1826,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)
@@ -1863,40 +1857,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},
 };
 
 /*! 
@@ -1909,7 +1909,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... */
@@ -1935,6 +1935,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) */
@@ -1942,6 +1943,7 @@

[... 118 lines stripped ...]



More information about the asterisk-commits mailing list