summaryrefslogtreecommitdiff
path: root/main/rtp.c
diff options
context:
space:
mode:
Diffstat (limited to 'main/rtp.c')
-rw-r--r--main/rtp.c156
1 files changed, 98 insertions, 58 deletions
diff --git a/main/rtp.c b/main/rtp.c
index a39fc10f2..8240a9fe3 100644
--- a/main/rtp.c
+++ b/main/rtp.c
@@ -97,12 +97,6 @@ enum strict_rtp_state {
* 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 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
/* 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 @@ struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
/* 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 @@ static struct {
* 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 @@ static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
[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 @@ static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
[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,35 +2213,61 @@ void ast_rtp_unset_m_type(struct ast_rtp* rtp, int pt)
* an SDP "a=rtpmap:" line.
* \return 0 if the MIME type was found and set, -1 if it wasn't found
*/
-int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
- char *mimeType, char *mimeSubtype,
- enum ast_rtp_options options)
+int ast_rtp_set_rtpmap_type_rate(struct ast_rtp *rtp, int pt,
+ char *mimeType, char *mimeSubtype,
+ enum ast_rtp_options options,
+ unsigned int sample_rate)
{
unsigned int i;
int found = 0;
- if (pt < 0 || pt > MAX_RTP_PT)
+ if (pt < 0 || pt > MAX_RTP_PT)
return -1; /* bogus payload type */
-
+
rtp_bridge_lock(rtp);
for (i = 0; i < ARRAY_LEN(mimeTypes); ++i) {
- if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
- strcasecmp(mimeType, mimeTypes[i].type) == 0) {
- found = 1;
- rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
- if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) &&
- mimeTypes[i].payloadType.isAstFormat &&
- (options & AST_RTP_OPT_G726_NONSTANDARD))
- rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
- break;
+ const struct mimeType *t = &mimeTypes[i];
+
+ if (strcasecmp(mimeSubtype, t->subtype)) {
+ continue;
+ }
+
+ if (strcasecmp(mimeType, t->type)) {
+ continue;
+ }
+
+ /* if both sample rates have been supplied, and they don't match,
+ then this not a match; if one has not been supplied, then the
+ rates are not compared */
+ if (sample_rate && t->sample_rate &&
+ (sample_rate != t->sample_rate)) {
+ continue;
+ }
+
+ found = 1;
+ rtp->current_RTP_PT[pt] = t->payloadType;
+
+ if ((t->payloadType.code == AST_FORMAT_G726) &&
+ t->payloadType.isAstFormat &&
+ (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+ rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
}
+
+ break;
}
rtp_bridge_unlock(rtp);
- return (found ? 0 : -1);
-}
+ return (found ? 0 : -2);
+}
+
+int ast_rtp_set_rtpmap_type(struct ast_rtp *rtp, int pt,
+ char *mimeType, char *mimeSubtype,
+ enum ast_rtp_options options)
+{
+ return ast_rtp_set_rtpmap_type_rate(rtp, pt, mimeType, mimeSubtype, options, 0);
+}
/*! \brief Return the union of all of the codecs that were set by rtp_set...() calls
* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
@@ -2344,6 +2372,19 @@ const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code,
return "";
}
+unsigned int ast_rtp_lookup_sample_rate(int isAstFormat, int code)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_LEN(mimeTypes); ++i) {
+ if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) {
+ return mimeTypes[i].sample_rate;
+ }
+ }
+
+ return 0;
+}
+
char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
const int isAstFormat, enum ast_rtp_options options)
{
@@ -4773,9 +4814,8 @@ void red_buffer_t140(struct ast_rtp *rtp, struct ast_frame *f)
{
if (f->datalen > -1) {
struct rtp_red *red = rtp->red;
- memcpy(&red->buf_data[red->t140.datalen], f->data.ptr, f->datalen);
+ memcpy(&red->buf_data[red->t140.datalen], f->data.ptr, f->datalen);
red->t140.datalen += f->datalen;
red->t140.ts = f->ts;
}
}
-