diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-05-19 15:58:13 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-05-19 15:58:13 +0000 |
commit | 1c28ac165c9a24bc00ae6563fd87dcb05f8524b3 (patch) | |
tree | f8d03e735436381996fb2c0e5be02a83052e2699 /pjmedia/src/pjmedia-codec/gsm.c | |
parent | bf8079559cb3435731580d57b243f12a68863a05 (diff) |
Install VAD in g711, gsm, and speex, and add the DTX support in stream.c. Also changed the way the silence detector works, and changed default speex quality/complexity to 10
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@457 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia/src/pjmedia-codec/gsm.c')
-rw-r--r-- | pjmedia/src/pjmedia-codec/gsm.c | 83 |
1 files changed, 79 insertions, 4 deletions
diff --git a/pjmedia/src/pjmedia-codec/gsm.c b/pjmedia/src/pjmedia-codec/gsm.c index 8689960f..48e8ae13 100644 --- a/pjmedia/src/pjmedia-codec/gsm.c +++ b/pjmedia/src/pjmedia-codec/gsm.c @@ -20,7 +20,9 @@ #include <pjmedia/codec.h> #include <pjmedia/errno.h> #include <pjmedia/endpoint.h> +#include <pjmedia/plc.h> #include <pjmedia/port.h> +#include <pjmedia/silencedet.h> #include <pj/assert.h> #include <pj/pool.h> #include <pj/string.h> @@ -68,6 +70,9 @@ static pj_status_t gsm_codec_decode( pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output); +static pj_status_t gsm_codec_recover(pjmedia_codec *codec, + unsigned output_buf_len, + struct pjmedia_frame *output); /* Definition for GSM codec operations. */ static pjmedia_codec_op gsm_op = @@ -77,7 +82,8 @@ static pjmedia_codec_op gsm_op = &gsm_codec_close, &gsm_codec_parse, &gsm_codec_encode, - &gsm_codec_decode + &gsm_codec_decode, + &gsm_codec_recover }; /* Definition for GSM codec factory operations. */ @@ -100,11 +106,16 @@ static struct gsm_codec_factory pjmedia_codec codec_list; } gsm_codec_factory; + /* GSM codec private data. */ struct gsm_data { - void *encoder; - void *decoder; + void *encoder; + void *decoder; + pj_bool_t plc_enabled; + pjmedia_plc *plc; + pj_bool_t vad_enabled; + pjmedia_silence_det *vad; }; @@ -239,8 +250,10 @@ static pj_status_t gsm_default_attr (pjmedia_codec_factory *factory, attr->info.pt = PJMEDIA_RTP_PT_GSM; attr->setting.frm_per_pkt = 1; + attr->setting.vad = 1; + attr->setting.plc = 1; - /* Default all flag bits disabled. */ + /* Default all other flag bits disabled. */ return PJ_SUCCESS; } @@ -276,6 +289,7 @@ static pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory, { pjmedia_codec *codec; struct gsm_data *gsm_data; + pj_status_t status; PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL); PJ_ASSERT_RETURN(factory == &gsm_codec_factory.base, PJ_EINVAL); @@ -297,6 +311,23 @@ static pj_status_t gsm_alloc_codec( pjmedia_codec_factory *factory, gsm_data = pj_pool_zalloc(gsm_codec_factory.pool, sizeof(struct gsm_data)); codec->codec_data = gsm_data; + + /* Create PLC */ + status = pjmedia_plc_create(gsm_codec_factory.pool, 8000, + 160, 0, &gsm_data->plc); + if (status != PJ_SUCCESS) { + pj_mutex_unlock(gsm_codec_factory.mutex); + return status; + } + + /* Create silence detector */ + status = pjmedia_silence_det_create(gsm_codec_factory.pool, + 8000, 160, + &gsm_data->vad); + if (status != PJ_SUCCESS) { + pj_mutex_unlock(gsm_codec_factory.mutex); + return status; + } } pj_mutex_unlock(gsm_codec_factory.mutex); @@ -361,6 +392,9 @@ static pj_status_t gsm_codec_open( pjmedia_codec *codec, if (!gsm_data->decoder) return PJMEDIA_CODEC_EFAILED; + gsm_data->vad_enabled = (attr->setting.vad != 0); + gsm_data->plc_enabled = (attr->setting.plc != 0); + return PJ_SUCCESS; } @@ -437,6 +471,24 @@ static pj_status_t gsm_codec_encode( pjmedia_codec *codec, if (input->size < 320) return PJMEDIA_CODEC_EPCMTOOSHORT; + /* Detect silence */ + if (gsm_data->vad_enabled) { + pj_bool_t is_silence; + + is_silence = pjmedia_silence_det_detect(gsm_data->vad, + input->buf, + input->size / 2, + NULL); + if (is_silence) { + output->type = PJMEDIA_FRAME_TYPE_NONE; + output->buf = NULL; + output->size = 0; + output->timestamp.u64 = input->timestamp.u64; + return PJ_SUCCESS; + } + } + + /* Encode */ gsm_encode(gsm_data->encoder, (short*)input->buf, (unsigned char*)output->buf); @@ -472,6 +524,29 @@ static pj_status_t gsm_codec_decode( pjmedia_codec *codec, output->size = 320; output->type = PJMEDIA_FRAME_TYPE_AUDIO; + if (gsm_data->plc_enabled) + pjmedia_plc_save( gsm_data->plc, output->buf); + + return PJ_SUCCESS; +} + + +/* + * Recover lost frame. + */ +static pj_status_t gsm_codec_recover(pjmedia_codec *codec, + unsigned output_buf_len, + struct pjmedia_frame *output) +{ + struct gsm_data *gsm_data = codec->codec_data; + + PJ_ASSERT_RETURN(gsm_data->plc_enabled, PJ_EINVALIDOP); + + PJ_ASSERT_RETURN(output_buf_len >= 320, PJMEDIA_CODEC_EPCMTOOSHORT); + + pjmedia_plc_generate(gsm_data->plc, output->buf); + output->size = 320; + return PJ_SUCCESS; } |