aboutsummaryrefslogtreecommitdiffstats
path: root/main/frame.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-13 13:35:24 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-13 13:35:24 +0000
commita46dd55034bbf45b2e45a62559f9b9a2c075e8c6 (patch)
tree51f8bb89740396001e20f9f64d9044733305193c /main/frame.c
parent01f6911d4a307b66ee955ad6c09a54c05ac27fa6 (diff)
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/ git-svn-id: http://svn.digium.com/svn/asterisk/trunk@175508 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/frame.c')
-rw-r--r--main/frame.c33
1 files changed, 27 insertions, 6 deletions
diff --git a/main/frame.c b/main/frame.c
index 84a2b0a5a..7d950d740 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -98,7 +98,7 @@ struct ast_smoother {
};
/*! \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 @@ static struct ast_format_list AST_FORMAT_LIST[] = {
{ 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 @@ void ast_swapcopy_samples(void *dst, const void *src, int samples)
}
-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 @@ static struct ast_codec_alias_table {
{ "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 @@ static int speex_samples(unsigned char *data, int len)
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 @@ int ast_codec_get_samples(struct ast_frame *f)
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 ast_codec_get_len(int format, int samples)
{
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 @@ int ast_codec_get_len(int format, int samples)
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));
}