📄 ilbc.c
字号:
/* $Id: ilbc.c 974 2007-02-19 01:13:53Z bennylp $ *//* * Copyright (C)2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <pjmedia-codec/ilbc.h>#include <pjmedia-codec/types.h>#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/log.h>#include <pj/pool.h>#include <pj/string.h>#include <pj/os.h>#include "ilbc/iLBC_encode.h"#include "ilbc/iLBC_decode.h"/* * Only build this file if PJMEDIA_HAS_ILBC_CODEC != 0 */#if defined(PJMEDIA_HAS_ILBC_CODEC) && PJMEDIA_HAS_ILBC_CODEC != 0#define THIS_FILE "ilbc.c"#define CLOCK_RATE 8000#define DEFAULT_MODE 30/* Prototypes for iLBC factory */static pj_status_t ilbc_test_alloc(pjmedia_codec_factory *factory, const pjmedia_codec_info *id );static pj_status_t ilbc_default_attr(pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec_param *attr );static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, unsigned *count, pjmedia_codec_info codecs[]);static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec **p_codec);static pj_status_t ilbc_dealloc_codec(pjmedia_codec_factory *factory, pjmedia_codec *codec );/* Prototypes for iLBC implementation. */static pj_status_t ilbc_codec_init(pjmedia_codec *codec, pj_pool_t *pool );static pj_status_t ilbc_codec_open(pjmedia_codec *codec, pjmedia_codec_param *attr );static pj_status_t ilbc_codec_close(pjmedia_codec *codec );static pj_status_t ilbc_codec_modify(pjmedia_codec *codec, const pjmedia_codec_param *attr );static pj_status_t ilbc_codec_parse(pjmedia_codec *codec, void *pkt, pj_size_t pkt_size, const pj_timestamp *ts, unsigned *frame_cnt, pjmedia_frame frames[]);static pj_status_t ilbc_codec_encode(pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output);static pj_status_t ilbc_codec_decode(pjmedia_codec *codec, const struct pjmedia_frame *input, unsigned output_buf_len, struct pjmedia_frame *output);static pj_status_t ilbc_codec_recover(pjmedia_codec *codec, unsigned output_buf_len, struct pjmedia_frame *output);/* Definition for iLBC codec operations. */static pjmedia_codec_op ilbc_op = { &ilbc_codec_init, &ilbc_codec_open, &ilbc_codec_close, &ilbc_codec_modify, &ilbc_codec_parse, &ilbc_codec_encode, &ilbc_codec_decode, &ilbc_codec_recover};/* Definition for iLBC codec factory operations. */static pjmedia_codec_factory_op ilbc_factory_op ={ &ilbc_test_alloc, &ilbc_default_attr, &ilbc_enum_codecs, &ilbc_alloc_codec, &ilbc_dealloc_codec};/* iLBC factory */static struct ilbc_factory{ pjmedia_codec_factory base; pjmedia_endpt *endpt; int mode; int bps;} ilbc_factory;/* iLBC codec private data. */struct ilbc_codec{ pjmedia_codec base; pj_pool_t *pool; char obj_name[PJ_MAX_OBJ_NAME]; pjmedia_silence_det *vad; pj_bool_t vad_enabled; pj_bool_t plc_enabled; pj_timestamp last_tx; pj_bool_t enc_ready; iLBC_Enc_Inst_t enc; unsigned enc_frame_size; unsigned enc_samples_per_frame; float enc_block[BLOCKL_MAX]; pj_bool_t dec_ready; iLBC_Dec_Inst_t dec; unsigned dec_frame_size; unsigned dec_samples_per_frame; float dec_block[BLOCKL_MAX];};/* * Initialize and register iLBC codec factory to pjmedia endpoint. */PJ_DEF(pj_status_t) pjmedia_codec_ilbc_init( pjmedia_endpt *endpt, int mode ){ pjmedia_codec_mgr *codec_mgr; pj_status_t status; PJ_ASSERT_RETURN(endpt != NULL, PJ_EINVAL); PJ_ASSERT_RETURN(mode==0 || mode==20 || mode==30, PJ_EINVAL); /* Create iLBC codec factory. */ ilbc_factory.base.op = &ilbc_factory_op; ilbc_factory.base.factory_data = NULL; ilbc_factory.endpt = endpt; if (mode == 0) mode = DEFAULT_MODE; ilbc_factory.mode = mode; if (mode == 20) { ilbc_factory.bps = 15200; } else { ilbc_factory.bps = 13333; } /* Get the codec manager. */ codec_mgr = pjmedia_endpt_get_codec_mgr(endpt); if (!codec_mgr) return PJ_EINVALIDOP; /* Register codec factory to endpoint. */ status = pjmedia_codec_mgr_register_factory(codec_mgr, &ilbc_factory.base); if (status != PJ_SUCCESS) return status; /* Done. */ return PJ_SUCCESS;}/* * Unregister iLBC codec factory from pjmedia endpoint and deinitialize * the iLBC codec library. */PJ_DEF(pj_status_t) pjmedia_codec_ilbc_deinit(void){ pjmedia_codec_mgr *codec_mgr; pj_status_t status; /* Get the codec manager. */ codec_mgr = pjmedia_endpt_get_codec_mgr(ilbc_factory.endpt); if (!codec_mgr) return PJ_EINVALIDOP; /* Unregister iLBC codec factory. */ status = pjmedia_codec_mgr_unregister_factory(codec_mgr, &ilbc_factory.base); return status;}/* * Check if factory can allocate the specified codec. */static pj_status_t ilbc_test_alloc( pjmedia_codec_factory *factory, const pjmedia_codec_info *info ){ const pj_str_t ilbc_tag = { "iLBC", 4}; PJ_UNUSED_ARG(factory); PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL); /* Type MUST be audio. */ if (info->type != PJMEDIA_TYPE_AUDIO) return PJMEDIA_CODEC_EUNSUP; /* Check encoding name. */ if (pj_stricmp(&info->encoding_name, &ilbc_tag) != 0) return PJMEDIA_CODEC_EUNSUP; /* Check clock-rate */ if (info->clock_rate != CLOCK_RATE) return PJMEDIA_CODEC_EUNSUP; /* Channel count must be one */ if (info->channel_cnt != 1) return PJMEDIA_CODEC_EUNSUP; /* Yes, this should be iLBC! */ return PJ_SUCCESS;}/* * Generate default attribute. */static pj_status_t ilbc_default_attr (pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec_param *attr ){ PJ_UNUSED_ARG(factory); PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL); PJ_UNUSED_ARG(id); PJ_ASSERT_RETURN(pj_stricmp2(&id->encoding_name, "iLBC")==0, PJ_EINVAL); pj_bzero(attr, sizeof(pjmedia_codec_param)); attr->info.clock_rate = CLOCK_RATE; attr->info.channel_cnt = 1; attr->info.avg_bps = ilbc_factory.bps; attr->info.pcm_bits_per_sample = 16; attr->info.frm_ptime = (short)ilbc_factory.mode; attr->info.pt = PJMEDIA_RTP_PT_ILBC; attr->setting.frm_per_pkt = 1; attr->setting.vad = 1; attr->setting.plc = 1; attr->setting.penh = 1; attr->setting.dec_fmtp_mode = (pj_uint8_t)ilbc_factory.mode; return PJ_SUCCESS;}/* * Enum codecs supported by this factory (i.e. only iLBC!). */static pj_status_t ilbc_enum_codecs(pjmedia_codec_factory *factory, unsigned *count, pjmedia_codec_info codecs[]){ PJ_UNUSED_ARG(factory); PJ_ASSERT_RETURN(factory==&ilbc_factory.base, PJ_EINVAL); PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); pj_bzero(&codecs[0], sizeof(pjmedia_codec_info)); codecs[0].encoding_name = pj_str("iLBC"); codecs[0].pt = PJMEDIA_RTP_PT_ILBC; codecs[0].type = PJMEDIA_TYPE_AUDIO; codecs[0].clock_rate = 8000; codecs[0].channel_cnt = 1; *count = 1; return PJ_SUCCESS;}/* * Allocate a new iLBC codec instance. */static pj_status_t ilbc_alloc_codec(pjmedia_codec_factory *factory, const pjmedia_codec_info *id, pjmedia_codec **p_codec){ pj_pool_t *pool; struct ilbc_codec *codec; PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL); PJ_ASSERT_RETURN(factory == &ilbc_factory.base, PJ_EINVAL); pool = pjmedia_endpt_create_pool(ilbc_factory.endpt, "iLBC%p",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -