123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include "precompile.h"
- #include "audiocodec.h"
- #include "audiocontext.h"
- #include "other/wsola.h"
- #include "codec/codecmgr.h"
- #include "codec/g711codec.h"
- #ifdef _WIN32
- #include "codec/g729acodec.h"
- #endif // _WIN32
- #include <assert.h>
- static apr_status_t read_frame(void *self, audioframe_t *frame)
- {
- audiocodec_t *codec = CONTAINING_RECORD(self, audiocodec_t, base);
- codec_t *private_codec = codec->private_codec;
- apr_status_t status;
- if (codec->base.downstream == NULL) {
- if (codec->flag & AUDIO_CODEC_OPT_DECODE_READ) {
- frame->size = codec->ptime * 2 * codec->clock / 1000;
- memset(frame->buffer, 0, frame->size);
- return APR_SUCCESS;
- } else {
- return APR_EGENERAL;
- }
- }
- codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
- status = codec->base.downstream->vtbl->read_frame(codec->base.downstream,
- &codec->tmp_frame);
- if (status != APR_SUCCESS) {
- if (codec->flag & AUDIO_CODEC_OPT_DECODE_READ) {
- if (codec->flag&AUDIO_CODEC_OPT_PLC && codec->last_plc) {
- wsola_generate(codec->plc_state, (short*)frame->buffer);
- frame->size = codec->ptime * 2 * codec->clock / 1000;
- codec->last_plc--;
- } else {
- frame->size = codec->ptime * 2 * codec->clock / 1000;
- memset(frame->buffer, 0, frame->size);
- }
- return APR_SUCCESS;
- }
- } else {
- if (codec->flag & AUDIO_CODEC_OPT_ENCODE_READ) {
- status = private_codec->factory->encode(private_codec,
- codec->tmp_frame.buffer, codec->tmp_frame.size,
- frame->buffer, &frame->size);
- if (status != APR_SUCCESS || frame->size == 0) {
- frame->size = codec->ptime * 2 * codec->clock / 1000;
- memset(frame->buffer, 0, frame->size);
- status = APR_SUCCESS;
- }
- } else {
- status = private_codec->factory->decode(private_codec,
- codec->tmp_frame.buffer, codec->tmp_frame.size,
- frame->buffer, &frame->size);
- if (status != APR_SUCCESS || frame->size == 0) {
- frame->size = codec->ptime * 2 * codec->clock / 1000;
- memset(frame->buffer, 0, frame->size);
- status = APR_SUCCESS;
- }
- if (status == APR_SUCCESS && codec->flag&AUDIO_CODEC_OPT_PLC) {
- wsola_save(codec->plc_state, (short*)frame->buffer, 0);
- codec->last_plc = 1;
- }
- }
- }
- return status;
- }
- static apr_status_t write_frame(void *self, const audioframe_t *frame)
- {
- audiocodec_t *codec = CONTAINING_RECORD(self, audiocodec_t, base);
- codec_t *private_codec = codec->private_codec;
- apr_status_t status;
- if (codec->base.downstream == NULL)
- return APR_EGENERAL;
- codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
- codec->tmp_frame.dtmf = frame->dtmf;
- if (codec->flag & AUDIO_CODEC_OPT_ENCODE_READ) {
- status = private_codec->factory->decode(private_codec,
- frame->buffer, frame->size,
- codec->tmp_frame.buffer, &codec->tmp_frame.size);
- } else {
- status = private_codec->factory->encode(private_codec,
- frame->buffer, frame->size,
- codec->tmp_frame.buffer, &codec->tmp_frame.size);
- }
- if (status == APR_SUCCESS) {
- status = codec->base.downstream->vtbl->write_frame(codec->base.downstream,
- &codec->tmp_frame);
- }
- return status;
- }
- static audiostream_vtbl_t g_stream_vtbl = {
- &read_frame,
- &write_frame,
- };
- apr_status_t audiocodec_create(apr_pool_t *pool,
- audioengine_t *engine,
- const char *name,
- int clock,
- int ptime,
- int flag,
- audiocodec_t**p_codec)
- {
- audiocodec_t *codec;
- codec_factory_t *factory;
- factory = codec_factory_find(name);
- if (!factory)
- return APR_NOTFOUND;
- codec = apr_palloc(pool, sizeof(audiocodec_t));
- codec->private_codec = factory->create(pool, clock, ptime);
- if (!codec->private_codec) {
- return APR_EGENERAL;
- }
- codec->ptime = ptime;
- codec->clock = clock;
- audiostream_init(engine, &g_stream_vtbl, &codec->base);
- codec->base.direction = STREAM_DIR_BOTH;
- codec->tmp_frame.size = SUGGEST_FRAME_SIZE;
- codec->tmp_frame.buffer = apr_palloc(pool, SUGGEST_FRAME_SIZE);
- codec->tmp_frame.dtmf = 0;
- codec->flag = flag;
- codec->last_plc = 0;
- wsola_create(clock, ptime * clock / 1000, 1, WSOLA_NO_FADING, (wsola_t**)&codec->plc_state);
- *p_codec = codec;
- return APR_SUCCESS;
- }
- apr_status_t audiocodec_set_param(audiocodec_t *codec, const char *key, const char *value)
- {
- codec_t *private_codec = codec->private_codec;
- return private_codec->factory->set_param(private_codec, key, value);
- }
- apr_status_t audiocodec_get_param(audiocodec_t *codec, const char *key, char *value)
- {
- codec_t *private_codec = codec->private_codec;
- return private_codec->factory->get_param(private_codec, key, value);
- }
- apr_status_t audiocodec_init(audiocodec_t *codec)
- {
- codec_t *private_codec = codec->private_codec;
- return private_codec->factory->init(private_codec);
- }
- apr_status_t audiocodec_term(audiocodec_t *codec)
- {
- codec_t *private_codec = codec->private_codec;
- return private_codec->factory->term(private_codec);
- }
- void audiocodec_destroy(audiocodec_t *codec)
- {
- codec_t *private_codec = codec->private_codec;
- private_codec->factory->destroy(private_codec);
- wsola_destroy(codec->plc_state);
- codec->plc_state = NULL;
- }
- apr_status_t audiocodec_pcma_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
- {
- return pcma_codec_decode(inbuf, insize, outbuf, outsize);
- }
- apr_status_t audiocodec_pcmu_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
- {
- return pcmu_codec_decode(inbuf, insize, outbuf, outsize);
- }
- apr_status_t audiocodec_g729a_decode(const void *inbuf,int insize,void *outbuf,int *outsize)
- {
- #ifdef _WIN32
- return audio_g729a_codec_decode(inbuf, insize, outbuf, outsize);
- #else
- return 0;
- #endif // _WIN32
-
- }
|