[asterisk-commits] kpfleming: branch kpfleming/siren_passthrough r175253 - in /team/kpfleming/si...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 12 12:55:57 CST 2009


Author: kpfleming
Date: Thu Feb 12 12:55:56 2009
New Revision: 175253

URL: http://svn.digium.com/svn-view/asterisk?view=rev&rev=175253
Log:
put this work into a branch for review and merging


Added:
    team/kpfleming/siren_passthrough/
      - copied from r175252, trunk/
    team/kpfleming/siren_passthrough/formats/format_siren14.c   (contents, props changed)
      - copied, changed from r174705, trunk/formats/format_sln16.c
    team/kpfleming/siren_passthrough/formats/format_siren7.c   (contents, props changed)
      - copied, changed from r174705, trunk/formats/format_sln16.c
Modified:
    team/kpfleming/siren_passthrough/channels/chan_h323.c
    team/kpfleming/siren_passthrough/channels/chan_sip.c
    team/kpfleming/siren_passthrough/include/asterisk/frame.h
    team/kpfleming/siren_passthrough/include/asterisk/rtp.h
    team/kpfleming/siren_passthrough/main/frame.c
    team/kpfleming/siren_passthrough/main/rtp.c

Modified: team/kpfleming/siren_passthrough/channels/chan_h323.c
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/channels/chan_h323.c?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/channels/chan_h323.c (original)
+++ team/kpfleming/siren_passthrough/channels/chan_h323.c Thu Feb 12 12:55:56 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/kpfleming/siren_passthrough/channels/chan_sip.c
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/channels/chan_sip.c?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/channels/chan_sip.c (original)
+++ team/kpfleming/siren_passthrough/channels/chan_sip.c Thu Feb 12 12:55:56 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);
@@ -7670,7 +7670,10 @@
 	/* XXX This needs to be done per media stream, since it's media stream specific */
 	iterator = req->sdp_start;
 	while ((a = get_sdp_iterate(&iterator, req, "a"))[0] != '\0') {
-		char* mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
+		char *mimeSubtype = ast_strdupa(a); /* ensures we have enough space */
+		char *fmtp_string = ast_strdupa(a); /* ensures we have enough space */
+		unsigned int sample_rate;
+
 		if (option_debug > 1) {
 			int breakout = FALSE;
 		
@@ -7678,14 +7681,6 @@
 			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 %[^/]/", &codec, mimeSubtype) == 2) {
+			continue;
+		}
+
+		if (sscanf(a, "fmtp: %u %s", &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 %[^/]/%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,7 +9041,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(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) {
@@ -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);
+			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, 90000,
-				 &m_video, &a_video, debug, &min_video_packet_size);
+			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");

Copied: team/kpfleming/siren_passthrough/formats/format_siren14.c (from r174705, trunk/formats/format_sln16.c)
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/formats/format_siren14.c?view=diff&rev=175253&p1=trunk/formats/format_sln16.c&r1=174705&p2=team/kpfleming/siren_passthrough/formats/format_siren14.c&r2=175253
==============================================================================
--- trunk/formats/format_sln16.c (original)
+++ team/kpfleming/siren_passthrough/formats/format_siren14.c Thu Feb 12 12:55:56 2009
@@ -18,8 +18,8 @@
 
 /*! \file
  *
- * \brief RAW SLINEAR 16 Format
- * \arg File name extensions: sln16
+ * \brief ITU G.722.1 Annex C (Siren14, licensed from Polycom) format, 48kbps bitrate only
+ * \arg File name extensions: siren14
  * \ingroup formats
  */
  
@@ -31,29 +31,30 @@
 #include "asterisk/module.h"
 #include "asterisk/endian.h"
 
-#define BUF_SIZE	640		/* 640 bytes, 320 samples */
-#define	SLIN_SAMPLES	320
+#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 *slinear_read(struct ast_filestream *s, int *whennext)
+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_SLINEAR16;
+	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)) < 1) {
+	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 = res/2;
-	s->fr.datalen = res;
+	*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 slinear_write(struct ast_filestream *fs, struct ast_frame *f)
+static int siren14write(struct ast_filestream *fs, struct ast_frame *f)
 {
 	int res;
 
@@ -61,8 +62,8 @@
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass != AST_FORMAT_SLINEAR16) {
-		ast_log(LOG_WARNING, "Asked to write non-slinear16 frame (%d)!\n", f->subclass);
+	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) {
@@ -72,11 +73,11 @@
 	return 0;
 }
 
-static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
+static int siren14seek(struct ast_filestream *fs, off_t sample_offset, int whence)
 {
 	off_t offset = 0, min = 0, cur, max;
 
-	sample_offset <<= 1;
+	sample_offset = SAMPLES_TO_BYTES(sample_offset);
 
 	cur = ftello(fs->f);
 
@@ -100,31 +101,31 @@
 	return fseeko(fs->f, offset, SEEK_SET);
 }
 
-static int slinear_trunc(struct ast_filestream *fs)
+static int siren14trunc(struct ast_filestream *fs)
 {
 	return ftruncate(fileno(fs->f), ftello(fs->f));
 }
 
-static off_t slinear_tell(struct ast_filestream *fs)
+static off_t siren14tell(struct ast_filestream *fs)
 {
-	return ftello(fs->f) / 2;
+	return BYTES_TO_SAMPLES(ftello(fs->f));
 }
 
-static const struct ast_format slin_f = {
-	.name = "sln16",
-	.exts = "sln16",
-	.format = AST_FORMAT_SLINEAR16,
-	.write = slinear_write,
-	.seek = slinear_seek,
-	.trunc = slinear_trunc,
-	.tell = slinear_tell,
-	.read = slinear_read,
+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(&slin_f))
+	if (ast_format_register(&siren14_f))
 		return AST_MODULE_LOAD_FAILURE;
 
 	return AST_MODULE_LOAD_SUCCESS;
@@ -132,7 +133,7 @@
 
 static int unload_module(void)
 {
-	return ast_format_unregister(slin_f.name);
+	return ast_format_unregister(siren14_f.name);
 }	
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw Signed Linear 16KHz Audio support (SLN16)");
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ITU G.722.1 Annex C (Siren14, licensed from Polycom)");

Propchange: team/kpfleming/siren_passthrough/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kpfleming/siren_passthrough/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kpfleming/siren_passthrough/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:mergeinfo = 

Propchange: team/kpfleming/siren_passthrough/formats/format_siren14.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Copied: team/kpfleming/siren_passthrough/formats/format_siren7.c (from r174705, trunk/formats/format_sln16.c)
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/formats/format_siren7.c?view=diff&rev=175253&p1=trunk/formats/format_sln16.c&r1=174705&p2=team/kpfleming/siren_passthrough/formats/format_siren7.c&r2=175253
==============================================================================
--- trunk/formats/format_sln16.c (original)
+++ team/kpfleming/siren_passthrough/formats/format_siren7.c Thu Feb 12 12:55:56 2009
@@ -18,8 +18,8 @@
 
 /*! \file
  *
- * \brief RAW SLINEAR 16 Format
- * \arg File name extensions: sln16
+ * \brief ITU G.722.1 (Siren7, licensed from Polycom) format, 32kbps bitrate only
+ * \arg File name extensions: siren7
  * \ingroup formats
  */
  
@@ -31,29 +31,29 @@
 #include "asterisk/module.h"
 #include "asterisk/endian.h"
 
-#define BUF_SIZE	640		/* 640 bytes, 320 samples */
-#define	SLIN_SAMPLES	320
+#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 *slinear_read(struct ast_filestream *s, int *whennext)
+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_SLINEAR16;
+	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)) < 1) {
+	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 = res/2;
-	s->fr.datalen = res;
+	*whennext = s->fr.samples = BYTES_TO_SAMPLES(res);
 	return &s->fr;
 }
 
-static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
+static int siren7write(struct ast_filestream *fs, struct ast_frame *f)
 {
 	int res;
 
@@ -61,8 +61,8 @@
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass != AST_FORMAT_SLINEAR16) {
-		ast_log(LOG_WARNING, "Asked to write non-slinear16 frame (%d)!\n", f->subclass);
+	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) {
@@ -72,11 +72,11 @@
 	return 0;
 }
 
-static int slinear_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
+static int siren7seek(struct ast_filestream *fs, off_t sample_offset, int whence)
 {
 	off_t offset = 0, min = 0, cur, max;
 
-	sample_offset <<= 1;
+	sample_offset = SAMPLES_TO_BYTES(sample_offset);
 
 	cur = ftello(fs->f);
 
@@ -100,31 +100,31 @@
 	return fseeko(fs->f, offset, SEEK_SET);
 }
 
-static int slinear_trunc(struct ast_filestream *fs)
+static int siren7trunc(struct ast_filestream *fs)
 {
 	return ftruncate(fileno(fs->f), ftello(fs->f));
 }
 
-static off_t slinear_tell(struct ast_filestream *fs)
+static off_t siren7tell(struct ast_filestream *fs)
 {
-	return ftello(fs->f) / 2;
+	return BYTES_TO_SAMPLES(ftello(fs->f));
 }
 
-static const struct ast_format slin_f = {
-	.name = "sln16",
-	.exts = "sln16",
-	.format = AST_FORMAT_SLINEAR16,
-	.write = slinear_write,
-	.seek = slinear_seek,
-	.trunc = slinear_trunc,
-	.tell = slinear_tell,
-	.read = slinear_read,
+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(&slin_f))
+	if (ast_format_register(&siren7_f))
 		return AST_MODULE_LOAD_FAILURE;
 
 	return AST_MODULE_LOAD_SUCCESS;
@@ -132,7 +132,7 @@
 
 static int unload_module(void)
 {
-	return ast_format_unregister(slin_f.name);
+	return ast_format_unregister(siren7_f.name);
 }	
 
-AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Raw Signed Linear 16KHz Audio support (SLN16)");
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ITU G.722.1 (Siren7, licensed from Polycom)");

Propchange: team/kpfleming/siren_passthrough/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: team/kpfleming/siren_passthrough/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: team/kpfleming/siren_passthrough/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:mergeinfo = 

Propchange: team/kpfleming/siren_passthrough/formats/format_siren7.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: team/kpfleming/siren_passthrough/include/asterisk/frame.h
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/include/asterisk/frame.h?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/include/asterisk/frame.h (original)
+++ team/kpfleming/siren_passthrough/include/asterisk/frame.h Thu Feb 12 12:55:56 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/kpfleming/siren_passthrough/include/asterisk/rtp.h
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/include/asterisk/rtp.h?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/include/asterisk/rtp.h (original)
+++ team/kpfleming/siren_passthrough/include/asterisk/rtp.h Thu Feb 12 12:55:56 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 
 */
@@ -214,16 +220,24 @@
 			     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 */
+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);
+
+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/kpfleming/siren_passthrough/main/frame.c
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/main/frame.c?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/main/frame.c (original)
+++ team/kpfleming/siren_passthrough/main/frame.c Thu Feb 12 12:55:56 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)
@@ -1443,6 +1447,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 = f->datalen * (32000 / 6000);
+		break;
 	default:
 		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(f->subclass));
 	}
@@ -1453,7 +1465,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 +1493,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 = samples / (32000 / 6000);
+		break;
 	default:
 		ast_log(LOG_WARNING, "Unable to calculate sample length for format %s\n", ast_getformatname(format));
 	}

Modified: team/kpfleming/siren_passthrough/main/rtp.c
URL: http://svn.digium.com/svn-view/asterisk/team/kpfleming/siren_passthrough/main/rtp.c?view=diff&rev=175253&r1=175252&r2=175253
==============================================================================
--- team/kpfleming/siren_passthrough/main/rtp.c (original)
+++ team/kpfleming/siren_passthrough/main/rtp.c Thu Feb 12 12:55:56 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 @@
 	[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 */
 };
 
@@ -2211,9 +2213,10 @@
  * 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;
@@ -2224,22 +2227,47 @@
 	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);
 } 
+
+int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
+			    char *mimeType, char *mimeSubtype,

[... 33 lines stripped ...]



More information about the asterisk-commits mailing list