[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