diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-03-17 21:30:19 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2005-03-17 21:30:19 +0000 |
commit | 235a6486c3ca01b9bdac577774cc90fa4f06a58f (patch) | |
tree | 2ff53ca559c15101655e44ad4281225c8aae6685 /codecs | |
parent | 98aa637d27b5ac36a35fc85b596f00d1104398e3 (diff) |
Add PLC and jitter buffer and iax2 meta trunk with timestamps (bug #2532, #3400)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5192 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'codecs')
-rwxr-xr-x | codecs/codec_adpcm.c | 53 | ||||
-rwxr-xr-x | codecs/codec_alaw.c | 48 | ||||
-rwxr-xr-x | codecs/codec_g726.c | 47 | ||||
-rwxr-xr-x | codecs/codec_gsm.c | 48 | ||||
-rwxr-xr-x | codecs/codec_ilbc.c | 14 | ||||
-rwxr-xr-x | codecs/codec_lpc10.c | 47 | ||||
-rwxr-xr-x | codecs/codec_speex.c | 20 | ||||
-rwxr-xr-x | codecs/codec_ulaw.c | 48 |
8 files changed, 319 insertions, 6 deletions
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c index 703792649..7ec1571da 100755 --- a/codecs/codec_adpcm.c +++ b/codecs/codec_adpcm.c @@ -17,6 +17,8 @@ #include <asterisk/lock.h> #include <asterisk/logger.h> #include <asterisk/module.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/translate.h> #include <asterisk/channel.h> #include <fcntl.h> @@ -36,6 +38,8 @@ static int localusecnt = 0; static char *tdesc = "Adaptive Differential PCM Coder/Decoder"; +static int useplc = 0; + /* Sample frame data */ #include "slin_adpcm_ex.h" @@ -236,6 +240,7 @@ struct adpcm_decoder_pvt short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ struct adpcm_state state; int tail; + plc_state_t plc; }; /* @@ -258,6 +263,7 @@ adpcmtolin_new (void) { memset(tmp, 0, sizeof(*tmp)); tmp->tail = 0; + plc_init(&tmp->plc); localusecnt++; ast_update_use_count (); } @@ -292,8 +298,8 @@ lintoadpcm_new (void) /* * AdpcmToLin_FrameIn - * Fill an input buffer with packed 4-bit ADPCM values if there is room - * left. + * Take an input buffer with packed 4-bit ADPCM values and put decoded PCM in outbuf, + * if there is room left. * * Results: * Foo @@ -309,7 +315,19 @@ adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) int x; unsigned char *b; - if (f->datalen * 4 > sizeof(tmp->outbuf)) { + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) > sizeof(tmp->outbuf) / 2) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; + } + + if (f->datalen * 4 + tmp->tail * 2 > sizeof(tmp->outbuf)) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; } @@ -321,6 +339,8 @@ adpcmtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) tmp->outbuf[tmp->tail++] = decode(b[x] & 0x0f, &tmp->state); } + if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail-f->datalen*2, f->datalen*2); + return 0; } @@ -538,6 +558,32 @@ static struct ast_translator lintoadpcm = { lintoadpcm_sample }; +static void +parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int +reload(void) +{ + parse_config(); + return 0; +} + int unload_module (void) { @@ -556,6 +602,7 @@ int load_module (void) { int res; + parse_config(); res = ast_register_translator (&adpcmtolin); if (!res) res = ast_register_translator (&lintoadpcm); diff --git a/codecs/codec_alaw.c b/codecs/codec_alaw.c index 6ba4e1da9..6705dff21 100755 --- a/codecs/codec_alaw.c +++ b/codecs/codec_alaw.c @@ -13,6 +13,8 @@ #include <asterisk/lock.h> #include <asterisk/logger.h> #include <asterisk/module.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/translate.h> #include <asterisk/channel.h> #include <asterisk/alaw.h> @@ -30,6 +32,8 @@ static int localusecnt = 0; static char *tdesc = "A-law Coder/Decoder"; +static int useplc = 0; + /* Sample frame data (Mu data is okay) */ #include "slin_ulaw_ex.h" @@ -57,6 +61,7 @@ struct alaw_decoder_pvt char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ int tail; + plc_state_t plc; }; /* @@ -79,6 +84,7 @@ alawtolin_new (void) { memset(tmp, 0, sizeof(*tmp)); tmp->tail = 0; + plc_init(&tmp->plc); localusecnt++; ast_update_use_count (); } @@ -130,6 +136,18 @@ alawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) int x; unsigned char *b; + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) * 2 > sizeof(tmp->outbuf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; + } + if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; @@ -140,6 +158,8 @@ alawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) for (x=0;x<f->datalen;x++) tmp->outbuf[tmp->tail + x] = AST_ALAW(b[x]); + if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail, f->datalen); + tmp->tail += f->datalen; return 0; } @@ -327,6 +347,33 @@ static struct ast_translator lintoalaw = { lintoalaw_sample }; +static void +parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int +reload(void) +{ + parse_config(); + return 0; +} + int unload_module (void) { @@ -345,6 +392,7 @@ int load_module (void) { int res; + parse_config(); res = ast_register_translator (&alawtolin); if (!res) res = ast_register_translator (&lintoalaw); diff --git a/codecs/codec_g726.c b/codecs/codec_g726.c index 8ac405854..80d978c80 100755 --- a/codecs/codec_g726.c +++ b/codecs/codec_g726.c @@ -16,6 +16,8 @@ #include <asterisk/lock.h> #include <asterisk/logger.h> #include <asterisk/module.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/translate.h> #include <asterisk/channel.h> #include <fcntl.h> @@ -49,6 +51,8 @@ static int localusecnt = 0; static char *tdesc = "ITU G.726-32kbps G726 Transcoder"; +static int useplc = 0; + /* Sample frame data */ #include "slin_g726_ex.h" @@ -694,6 +698,7 @@ struct g726_decoder_pvt short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ struct g726_state g726; int tail; + plc_state_t plc; }; /* @@ -716,6 +721,7 @@ g726tolin_new (void) { memset(tmp, 0, sizeof(*tmp)); tmp->tail = 0; + plc_init(&tmp->plc); localusecnt++; g726_init_state(&tmp->g726); ast_update_use_count (); @@ -769,6 +775,18 @@ g726tolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) unsigned char *b; int x; + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) > BUFFER_SIZE) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; + } + b = f->data; for (x=0;x<f->datalen;x++) { if (tmp->tail >= BUFFER_SIZE) { @@ -783,6 +801,8 @@ g726tolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) tmp->outbuf[tmp->tail++] = g726_decode(b[x] & 0x0f, &tmp->g726); } + if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail-f->datalen*2, f->datalen*2); + return 0; } @@ -974,6 +994,32 @@ static struct ast_translator lintog726 = { lintog726_sample }; +static void +parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int +reload(void) +{ + parse_config(); + return 0; +} + int unload_module (void) { @@ -992,6 +1038,7 @@ int load_module (void) { int res; + parse_config(); res = ast_register_translator (&g726tolin); if (!res) res = ast_register_translator (&lintog726); diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c index 286dc4fb8..30dc2d498 100755 --- a/codecs/codec_gsm.c +++ b/codecs/codec_gsm.c @@ -21,6 +21,8 @@ #include <asterisk/lock.h> #include <asterisk/translate.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/module.h> #include <asterisk/logger.h> #include <asterisk/channel.h> @@ -43,6 +45,8 @@ static int localusecnt=0; static char *tdesc = "GSM/PCM16 (signed linear) Codec Translator"; +static int useplc = 0; + struct ast_translator_pvt { gsm gsm; struct ast_frame f; @@ -53,6 +57,7 @@ struct ast_translator_pvt { /* Enough to store a full second */ short buf[8000]; int tail; + plc_state_t plc; }; #define gsm_coder_pvt ast_translator_pvt @@ -67,6 +72,7 @@ static struct ast_translator_pvt *gsm_new(void) tmp = NULL; } tmp->tail = 0; + plc_init(&tmp->plc); localusecnt++; } return tmp; @@ -131,6 +137,18 @@ static int gsmtolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) unsigned char data[66]; int msgsm=0; + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) > sizeof(tmp->buf) / 2) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->buf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; + } + if ((f->datalen % 33) && (f->datalen % 65)) { ast_log(LOG_WARNING, "Huh? A GSM frame that isn't a multiple of 33 or 65 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; @@ -171,6 +189,10 @@ static int gsmtolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f) } } } + + /* just add the last 20ms frame; there must have been at least one */ + if(useplc) plc_rx(&tmp->plc, tmp->buf+tmp->tail-160, 160); + return 0; } @@ -249,6 +271,31 @@ static struct ast_translator lintogsm = lintogsm_sample }; + +static void parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int reload(void) +{ + parse_config(); + return 0; +} + int unload_module(void) { int res; @@ -265,6 +312,7 @@ int unload_module(void) int load_module(void) { int res; + parse_config(); res=ast_register_translator(&gsmtolin); if (!res) res=ast_register_translator(&lintogsm); diff --git a/codecs/codec_ilbc.c b/codecs/codec_ilbc.c index 4bbb28c49..1c7428e8f 100755 --- a/codecs/codec_ilbc.c +++ b/codecs/codec_ilbc.c @@ -141,7 +141,19 @@ static int ilbctolin_framein(struct ast_translator_pvt *tmp, struct ast_frame *f the tail location. Read in as many frames as there are */ int x,i; float tmpf[240]; - + + if (f->datalen == 0) { /* native PLC */ + if (tmp->tail + 240 < sizeof(tmp->buf)/2) { + iLBC_decode(tmpf, NULL, &tmp->dec, 0); + for (i=0;i<240;i++) + tmp->buf[tmp->tail + i] = tmpf[i]; + tmp->tail+=240; + } else { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + } + if (f->datalen % 50) { ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, f->datalen); return -1; diff --git a/codecs/codec_lpc10.c b/codecs/codec_lpc10.c index 4a6925949..904f0266a 100755 --- a/codecs/codec_lpc10.c +++ b/codecs/codec_lpc10.c @@ -19,6 +19,8 @@ #include <asterisk/lock.h> #include <asterisk/translate.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/module.h> #include <asterisk/logger.h> #include <asterisk/channel.h> @@ -47,6 +49,8 @@ static int localusecnt=0; static char *tdesc = "LPC10 2.4kbps (signed linear) Voice Coder"; +static int useplc = 0; + struct ast_translator_pvt { union { struct lpc10_encoder_state *enc; @@ -61,6 +65,7 @@ struct ast_translator_pvt { short buf[8000]; int tail; int longer; + plc_state_t plc; /* god only knows why I bothered to implement PLC for LPC10 :) */ }; #define lpc10_coder_pvt ast_translator_pvt @@ -92,6 +97,7 @@ static struct ast_translator_pvt *lpc10_dec_new(void) } tmp->tail = 0; tmp->longer = 0; + plc_init(&tmp->plc); localusecnt++; } return tmp; @@ -199,6 +205,19 @@ static int lpc10tolin_framein(struct ast_translator_pvt *tmp, struct ast_frame * float tmpbuf[LPC10_SAMPLES_PER_FRAME]; short *sd; INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; + + if(f->datalen == 0) { /* perform PLC with nominal framesize of LPC10_SAMPLES_PER_FRAME */ + if((tmp->tail + LPC10_SAMPLES_PER_FRAME) > sizeof(tmp->buf)/2) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->buf+tmp->tail, LPC10_SAMPLES_PER_FRAME); + tmp->tail += LPC10_SAMPLES_PER_FRAME; + } + return 0; + } + while(len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) { if (tmp->tail + LPC10_SAMPLES_PER_FRAME < sizeof(tmp->buf)/2) { sd = tmp->buf + tmp->tail; @@ -211,6 +230,8 @@ static int lpc10tolin_framein(struct ast_translator_pvt *tmp, struct ast_frame * /* Convert to a real between -1.0 and 1.0 */ sd[x] = 32768.0 * tmpbuf[x]; } + + if(useplc) plc_rx(&tmp->plc, tmp->buf + tmp->tail, LPC10_SAMPLES_PER_FRAME); tmp->tail+=LPC10_SAMPLES_PER_FRAME; } else { @@ -326,6 +347,31 @@ static struct ast_translator lintolpc10 = lintolpc10_sample }; +static void parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int reload(void) +{ + parse_config(); + return 0; +} + + int unload_module(void) { int res; @@ -342,6 +388,7 @@ int unload_module(void) int load_module(void) { int res; + parse_config(); res=ast_register_translator(&lpc10tolin); if (!res) res=ast_register_translator(&lintolpc10); diff --git a/codecs/codec_speex.c b/codecs/codec_speex.c index 0f7bdd6c7..d59a849b4 100755 --- a/codecs/codec_speex.c +++ b/codecs/codec_speex.c @@ -181,6 +181,21 @@ static int speextolin_framein(struct ast_translator_pvt *tmp, struct ast_frame * int x; int res; float fout[1024]; + + if(f->datalen == 0) { /* Native PLC interpolation */ + if(tmp->tail + tmp->framesize > sizeof(tmp->buf) / 2) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + speex_decode(tmp->speex, NULL, fout); + for (x=0;x<tmp->framesize;x++) { + tmp->buf[tmp->tail + x] = fout[x]; + } + tmp->tail += tmp->framesize; + return 0; + } + + /* Read in bits */ speex_bits_read_from(&tmp->bits, f->data, f->datalen); for(;;) { @@ -357,11 +372,12 @@ static void parse_config(void) ast_mutex_unlock(&localuser_lock); } else if (!strcasecmp(var->name, "abr")) { res = abs(atoi(var->value)); - if (option_verbose > 2) + if (option_verbose > 2) { if(res > 0) ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Setting ABR target bitrate to %d\n",res); else - ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Disabling ABR\n",res); + ast_verbose(VERBOSE_PREFIX_3 "CODEC SPEEX: Disabling ABR\n"); + } if (res >= 0) { ast_mutex_lock(&localuser_lock); abr = res; diff --git a/codecs/codec_ulaw.c b/codecs/codec_ulaw.c index 698733a3c..4f2b24c7d 100755 --- a/codecs/codec_ulaw.c +++ b/codecs/codec_ulaw.c @@ -13,6 +13,8 @@ #include <asterisk/lock.h> #include <asterisk/logger.h> #include <asterisk/module.h> +#include <asterisk/config.h> +#include <asterisk/options.h> #include <asterisk/translate.h> #include <asterisk/channel.h> #include <asterisk/ulaw.h> @@ -30,6 +32,8 @@ static int localusecnt = 0; static char *tdesc = "Mu-law Coder/Decoder"; +static int useplc = 0; + /* Sample frame data */ #include "slin_ulaw_ex.h" @@ -57,6 +61,7 @@ struct ulaw_decoder_pvt char offset[AST_FRIENDLY_OFFSET]; /* Space to build offset */ short outbuf[BUFFER_SIZE]; /* Decoded signed linear values */ int tail; + plc_state_t plc; }; /* @@ -79,6 +84,7 @@ ulawtolin_new (void) { memset(tmp, 0, sizeof(*tmp)); tmp->tail = 0; + plc_init(&tmp->plc); localusecnt++; ast_update_use_count (); } @@ -130,6 +136,18 @@ ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) int x; unsigned char *b; + if(f->datalen == 0) { /* perform PLC with nominal framesize of 20ms/160 samples */ + if((tmp->tail + 160) * 2 > sizeof(tmp->outbuf)) { + ast_log(LOG_WARNING, "Out of buffer space\n"); + return -1; + } + if(useplc) { + plc_fillin(&tmp->plc, tmp->outbuf+tmp->tail, 160); + tmp->tail += 160; + } + return 0; + } + if ((tmp->tail + f->datalen) * 2 > sizeof(tmp->outbuf)) { ast_log(LOG_WARNING, "Out of buffer space\n"); return -1; @@ -140,6 +158,8 @@ ulawtolin_framein (struct ast_translator_pvt *pvt, struct ast_frame *f) for (x=0;x<f->datalen;x++) tmp->outbuf[tmp->tail + x] = AST_MULAW(b[x]); + if(useplc) plc_rx(&tmp->plc, tmp->outbuf+tmp->tail, f->datalen); + tmp->tail += f->datalen; return 0; } @@ -327,6 +347,33 @@ static struct ast_translator lintoulaw = { lintoulaw_sample }; +static void +parse_config(void) +{ + struct ast_config *cfg; + struct ast_variable *var; + if ((cfg = ast_config_load("codecs.conf"))) { + if ((var = ast_variable_browse(cfg, "plc"))) { + while (var) { + if (!strcasecmp(var->name, "genericplc")) { + useplc = ast_true(var->value) ? 1 : 0; + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "CODEC ULAW: %susing generic PLC\n", useplc ? "" : "not "); + } + var = var->next; + } + } + } +} + +int +reload(void) +{ + parse_config(); + return 0; +} + + int unload_module (void) { @@ -345,6 +392,7 @@ int load_module (void) { int res; + parse_config(); res = ast_register_translator (&ulawtolin); if (!res) res = ast_register_translator (&lintoulaw); |