WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置
1、VoiceEngine Codec数据结构
WebRTC中,用一个结构体struct CodecInst表示特定的音频编解码器对象:
- struct CodecInst
- {
- int pltype; //payload type负载类型
- char plname[32]; //payload name负载名称,32个字符表示
- int plfreq; //payload frequence负载频率
- int pacsize; //packet size包大小
- int channels; //声道
- int rate; //速率或自适应
- };
参数详细说明:
1、 pltype范围在1~126之间才是有效值;
pltype的值是否有效可以通过调用下面ValidPayloadType(int payload_type)方法来判断,在...\src\modules\audio_coding\main\source\acm_codec_database.cc定义
- // Checks if the payload type is in the valid range.
- bool ACMCodecDB::ValidPayloadType(int payload_type) {
- if ((payload_type < 0) || (payload_type > 127)) {
- return false;
- }
- return true;
- }
2、 plname是编解码器的名称,可能的值在CreateCodecInstance已定义,如WebRTC默认的"ISAC"
VoiceEngine支持多个音频编解码器,具体支持的编解码器在CreateCodecInstance(const CodecInst* codec_inst)定义,比如ISAC\PCMU\PCMA\ILBC\AMR等等,在...\src\modules\audio_coding\main\source\acm_codec_database.cc定义
- ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
- // All we have support for right now.
- if (!STR_CASE_CMP(codec_inst->plname, "ISAC")) {
- #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
- return new ACMISAC(kISAC);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "PCMU")) {
- return new ACMPCMU(kPCMU);
- } else if (!STR_CASE_CMP(codec_inst->plname, "PCMA")) {
- return new ACMPCMA(kPCMA);
- } else if (!STR_CASE_CMP(codec_inst->plname, "ILBC")) {
- #ifdef WEBRTC_CODEC_ILBC
- return new ACMILBC(kILBC);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "AMR")) {
- #ifdef WEBRTC_CODEC_AMR
- return new ACMAMR(kGSMAMR);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "AMR-WB")) {
- #ifdef WEBRTC_CODEC_AMRWB
- return new ACMAMRwb(kGSMAMRWB);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "G722")) {
- #ifdef WEBRTC_CODEC_G722
- return new ACMG722(kG722);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "G7221")) {
- switch (codec_inst->plfreq) {
- case 16000: {
- #ifdef WEBRTC_CODEC_G722_1
- int codec_id;
- switch (codec_inst->rate) {
- case 16000 : {
- codec_id = kG722_1_16;
- break;
- }
- case 24000 : {
- codec_id = kG722_1_24;
- break;
- }
- case 32000 : {
- codec_id = kG722_1_32;
- break;
- }
- default: {
- return NULL;
- }
- return new ACMG722_1(codec_id);
- }
- #endif
- }
- case 32000: {
- #ifdef WEBRTC_CODEC_G722_1C
- int codec_id;
- switch (codec_inst->rate) {
- case 24000 : {
- codec_id = kG722_1C_24;
- break;
- }
- case 32000 : {
- codec_id = kG722_1C_32;
- break;
- }
- case 48000 : {
- codec_id = kG722_1C_48;
- break;
- }
- default: {
- return NULL;
- }
- return new ACMG722_1C(codec_id);
- }
- #endif
- }
- }
- } else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
- // For CN we need to check sampling frequency to know what codec to create.
- int codec_id;
- switch (codec_inst->plfreq) {
- case 8000: {
- codec_id = kCNNB;
- break;
- }
- case 16000: {
- codec_id = kCNWB;
- break;
- }
- case 32000: {
- codec_id = kCNSWB;
- break;
- }
- default: {
- return NULL;
- }
- }
- return new ACMCNG(codec_id);
- } else if (!STR_CASE_CMP(codec_inst->plname, "G729")) {
- #ifdef WEBRTC_CODEC_G729
- return new ACMG729(kG729);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "G7291")) {
- #ifdef WEBRTC_CODEC_G729_1
- return new ACMG729_1(kG729_1);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "speex")) {
- #ifdef WEBRTC_CODEC_SPEEX
- int codec_id;
- switch (codec_inst->plfreq) {
- case 8000: {
- codec_id = kSPEEX8;
- break;
- }
- case 16000: {
- codec_id = kSPEEX16;
- break;
- }
- default: {
- return NULL;
- }
- }
- return new ACMSPEEX(codec_id);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
- // For CN we need to check sampling frequency to know what codec to create.
- int codec_id;
- switch (codec_inst->plfreq) {
- case 8000: {
- codec_id = kCNNB;
- break;
- }
- case 16000: {
- codec_id = kCNWB;
- break;
- }
- case 32000: {
- codec_id = kCNSWB;
- break;
- }
- default: {
- return NULL;
- }
- }
- return new ACMCNG(codec_id);
- } else if (!STR_CASE_CMP(codec_inst->plname, "L16")) {
- #ifdef WEBRTC_CODEC_PCM16
- // For L16 we need to check sampling frequency to know what codec to create.
- int codec_id;
- switch (codec_inst->plfreq) {
- case 8000: {
- codec_id = kPCM16B;
- break;
- }
- case 16000: {
- codec_id =kPCM16Bwb;
- break;
- }
- case 32000: {
- codec_id = kPCM16Bswb32kHz;
- break;
- }
- default: {
- return NULL;
- }
- }
- return new ACMPCM16B(codec_id);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "telephone-event")) {
- #ifdef WEBRTC_CODEC_AVT
- return new ACMDTMFPlayout(kAVT);
- #endif
- } else if (!STR_CASE_CMP(codec_inst->plname, "red")) {
- #ifdef WEBRTC_CODEC_RED
- return new ACMRED(kRED);
- #endif
- }
- return NULL;
- }
3、 plfreq一般取如下值(在common_types.h定义);
- //负载频率值
- enum PayloadFrequencies
- {
- kFreq8000Hz = 8000,
- kFreq16000Hz = 16000,
- kFreq32000Hz = 32000
- };
4、 pacsize取值是与plfreq有关系的,单位为kbps,下面是计算公式
计算公式如下:
如果:plfreq = 16000(单位为hz)
如果我需要30ms(毫秒)的packet size
那么pacsize = (plfreq *30) /1000 = 480kbps;
也即是:要得到k ms的packet size,则可计算出
pacsize =( plfreq * k) / 1000
而如果plfreq = 32000;20ms的packet size,则pacsize = 640;
5、 channels取值
channels = 1 表示单声道
channels = 2 表示立体声道
注意:channels = -1时,表示此时只支持单声道模式
6、 rate取值,单位是bps
一般取rate = 16000,32000,48000这些16000整数倍的值,即16kbps,32kbps,48kpbs
注意:当rate = -1时,表示此时启动自适应信道速率
2、查看VoiceEngine支持的所有Codec信息示例代码
- //列出(获得)引擎支持的所有编解码器信息
- //支持平台:Windows, Mac OS X, Linux
- #include "voe_base.h"
- #include "voe_codec.h"
- VoiceEngine* ve = VoiceEngine::Create();
- VoECodec* codec = VoECodec::GetInterface(ve);
- for (int = 0; i < codec->NumOfCodecs(); i++)
- {
- CodecInst cinst;
- codec->GetCodec(i, cinst);
- DISPLAY_CODEC_INFO(i, cinst);
- }
- // 释放sub-API
- codec->Release();
- //删除引擎
- VoiceEngine::Delete(ve);
3、初始化VoiceEngine Codec示例代码
- //初始化VoiceEngine Codec示例代码
- //支持平台:Windows, Mac OS X, Linux
- #include "voe_codec.h"
- CodecInst cinst;
- //初始化iSAC编解码器参数
- strcpy(cinst.plname, "ISAC");
- cinst.plfreq = 16000; // iSAC宽带模式取样频率
- cinst.pltype = 103;
- cinst.pacsize = 480; //使用30ms packet size,480kbps
- cinst.channels = 1; // 单声道
- cinst.rate = -1; // 信道自适应模式
- //初始化完成
- //在ID为0的channel激活已初始化的iSAC
- codec->SetSendCodec(0, cinst);
WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置的更多相关文章
- WebRTC音视频引擎研究(1)--整体架构分析
WebRTC技术交流群:234795279 原文地址:http://blog.csdn.net/temotemo/article/details/7530504 1.WebRTC目的 ...
- 转: WebRTC音视频引擎研究(1)--整体架构分析
转自: http://blog.csdn.net/temotemo/article/details/7530504 目录(?)[+] WebRTC技术交流群:234795279 原文地址:ht ...
- Android WebRTC 音视频开发总结
www.cnblogs.com/lingyunhu/p/3621057.html 前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC. ...
- WebRTC 音视频开发
WebRTC 音视频开发 webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验
前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...
- Android WebRTC 音视频开发总结(三)-- 信令服务和媒体服务
前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC.Blacker). 通过前面的例子我们知道运行WebRTCDemo即可看到P2P的 ...
- Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
- Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)
本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...
随机推荐
- PAT1011
With the 2010 FIFA World Cup running, 随着2010世界杯的举行 football fans the world over were becoming increa ...
- MyBatis部分细节归档
1. xml中如果要使用到特殊的字符,比如> 或者< 等,使用 <![CDATA[<]> 进行包裹,避免解析XML的时候出错. 2. 后续还有内容,待总结.
- CSS盒模型和margin重叠
在 CSS 中,width 和 height 指的是内容区域的宽度和高度.增加内边距.边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸.(div的实际占用尺寸变打了) 但: 一旦为页面设置 ...
- css Loading 教程
http://www.cnblogs.com/lhb25/p/loading-spinners-animated-with-css3.html
- [Unity]背包效果-使用NGUI实现物品的拖拽效果Drag
背包效果-使用NGUI实现物品的拖拽效果Drag 效果实现如图 对象层级关系图 PacketCell - Right 对象作为单元格背景 PacketContainer 对象作为单元格容器 Packe ...
- POJ 3449 Geometric Shapes
判断两个多边形是否相交,只需判断边是否有相交. 编码量有点大,不过思路挺简单的. #include<cstdio> #include<cstring> #include< ...
- 前端教程&开发模块化/规范化/工程化/优化&工具/调试&值得关注的博客/Git&面试-资源汇总
内容精简 资源这么多,多看看多学习再总结肯定是好的.多读读就算看重了不算浪费时间,毕竟一千个读者就有一千个林黛玉,还有温故而知新,说不定多读一些内容,就发现惊喜了呢.不过,在此也精简一些内容,就1~2 ...
- SQL TOP分页
SQL TOP分页 2010-11-12 16:35:29| 分类: SQL | 标签: |字号大中小 订阅 1.分页方案一:(利用Not In和SELECT TOP分页) 语句形式: ...
- 单位冲击响应与频响以及FIR实现代码(C语言)(转)
源:FIR数字滤波器C语言 1.单位冲击响应与频响 就如同之前所说的一样,使用下图所示的单位冲击响应,所设计的滤波器,是无法实现的. 现在,让我们看看其这个滤波器的频响.所谓频响,就是计算其单位冲击响 ...
- listen函数里面backlog的意义以及各种情况
先看了这篇: http://www.cppblog.com/thisisbin/archive/2010/02/07/107444.html 里面说了会维护两个队列,established 和 syn ...