1、VoiceEngine Codec数据结构

WebRTC中,用一个结构体struct CodecInst表示特定的音频编解码器对象:

  1. struct CodecInst
  2. {
  3. int pltype;      //payload type负载类型
  4. char plname[32]; //payload name负载名称,32个字符表示
  5. int plfreq;      //payload frequence负载频率
  6. int pacsize;     //packet size包大小
  7. int channels;    //声道
  8. int rate;        //速率或自适应
  9. };

参数详细说明:

1、 pltype范围在1~126之间才是有效值;

pltype的值是否有效可以通过调用下面ValidPayloadType(int payload_type)方法来判断,在...\src\modules\audio_coding\main\source\acm_codec_database.cc定义

  1. // Checks if the payload type is in the valid range.
  2. bool ACMCodecDB::ValidPayloadType(int payload_type) {
  3. if ((payload_type < 0) || (payload_type > 127)) {
  4. return false;
  5. }
  6. return true;
  7. }

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定义

  1. ACMGenericCodec* ACMCodecDB::CreateCodecInstance(const CodecInst* codec_inst) {
  2. // All we have support for right now.
  3. if (!STR_CASE_CMP(codec_inst->plname, "ISAC")) {
  4. #if (defined(WEBRTC_CODEC_ISAC) || defined(WEBRTC_CODEC_ISACFX))
  5. return new ACMISAC(kISAC);
  6. #endif
  7. } else if (!STR_CASE_CMP(codec_inst->plname, "PCMU")) {
  8. return new ACMPCMU(kPCMU);
  9. } else if (!STR_CASE_CMP(codec_inst->plname, "PCMA")) {
  10. return new ACMPCMA(kPCMA);
  11. } else if (!STR_CASE_CMP(codec_inst->plname, "ILBC")) {
  12. #ifdef WEBRTC_CODEC_ILBC
  13. return new ACMILBC(kILBC);
  14. #endif
  15. } else if (!STR_CASE_CMP(codec_inst->plname, "AMR")) {
  16. #ifdef WEBRTC_CODEC_AMR
  17. return new ACMAMR(kGSMAMR);
  18. #endif
  19. } else if (!STR_CASE_CMP(codec_inst->plname, "AMR-WB")) {
  20. #ifdef WEBRTC_CODEC_AMRWB
  21. return new ACMAMRwb(kGSMAMRWB);
  22. #endif
  23. } else if (!STR_CASE_CMP(codec_inst->plname, "G722")) {
  24. #ifdef WEBRTC_CODEC_G722
  25. return new ACMG722(kG722);
  26. #endif
  27. } else if (!STR_CASE_CMP(codec_inst->plname, "G7221")) {
  28. switch (codec_inst->plfreq) {
  29. case 16000: {
  30. #ifdef WEBRTC_CODEC_G722_1
  31. int codec_id;
  32. switch (codec_inst->rate) {
  33. case 16000 : {
  34. codec_id = kG722_1_16;
  35. break;
  36. }
  37. case 24000 : {
  38. codec_id = kG722_1_24;
  39. break;
  40. }
  41. case 32000 : {
  42. codec_id = kG722_1_32;
  43. break;
  44. }
  45. default: {
  46. return NULL;
  47. }
  48. return new ACMG722_1(codec_id);
  49. }
  50. #endif
  51. }
  52. case 32000: {
  53. #ifdef WEBRTC_CODEC_G722_1C
  54. int codec_id;
  55. switch (codec_inst->rate) {
  56. case 24000 : {
  57. codec_id = kG722_1C_24;
  58. break;
  59. }
  60. case 32000 : {
  61. codec_id = kG722_1C_32;
  62. break;
  63. }
  64. case 48000 : {
  65. codec_id = kG722_1C_48;
  66. break;
  67. }
  68. default: {
  69. return NULL;
  70. }
  71. return new ACMG722_1C(codec_id);
  72. }
  73. #endif
  74. }
  75. }
  76. } else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
  77. // For CN we need to check sampling frequency to know what codec to create.
  78. int codec_id;
  79. switch (codec_inst->plfreq) {
  80. case 8000: {
  81. codec_id = kCNNB;
  82. break;
  83. }
  84. case 16000: {
  85. codec_id = kCNWB;
  86. break;
  87. }
  88. case 32000: {
  89. codec_id = kCNSWB;
  90. break;
  91. }
  92. default: {
  93. return NULL;
  94. }
  95. }
  96. return new ACMCNG(codec_id);
  97. } else if (!STR_CASE_CMP(codec_inst->plname, "G729")) {
  98. #ifdef WEBRTC_CODEC_G729
  99. return new ACMG729(kG729);
  100. #endif
  101. } else if (!STR_CASE_CMP(codec_inst->plname, "G7291")) {
  102. #ifdef WEBRTC_CODEC_G729_1
  103. return new ACMG729_1(kG729_1);
  104. #endif
  105. } else if (!STR_CASE_CMP(codec_inst->plname, "speex")) {
  106. #ifdef WEBRTC_CODEC_SPEEX
  107. int codec_id;
  108. switch (codec_inst->plfreq) {
  109. case 8000: {
  110. codec_id = kSPEEX8;
  111. break;
  112. }
  113. case 16000: {
  114. codec_id = kSPEEX16;
  115. break;
  116. }
  117. default: {
  118. return NULL;
  119. }
  120. }
  121. return new ACMSPEEX(codec_id);
  122. #endif
  123. } else if (!STR_CASE_CMP(codec_inst->plname, "CN")) {
  124. // For CN we need to check sampling frequency to know what codec to create.
  125. int codec_id;
  126. switch (codec_inst->plfreq) {
  127. case 8000: {
  128. codec_id = kCNNB;
  129. break;
  130. }
  131. case 16000: {
  132. codec_id = kCNWB;
  133. break;
  134. }
  135. case 32000: {
  136. codec_id = kCNSWB;
  137. break;
  138. }
  139. default: {
  140. return NULL;
  141. }
  142. }
  143. return new ACMCNG(codec_id);
  144. } else if (!STR_CASE_CMP(codec_inst->plname, "L16")) {
  145. #ifdef WEBRTC_CODEC_PCM16
  146. // For L16 we need to check sampling frequency to know what codec to create.
  147. int codec_id;
  148. switch (codec_inst->plfreq) {
  149. case 8000: {
  150. codec_id = kPCM16B;
  151. break;
  152. }
  153. case 16000: {
  154. codec_id =kPCM16Bwb;
  155. break;
  156. }
  157. case 32000: {
  158. codec_id = kPCM16Bswb32kHz;
  159. break;
  160. }
  161. default: {
  162. return NULL;
  163. }
  164. }
  165. return new ACMPCM16B(codec_id);
  166. #endif
  167. } else if (!STR_CASE_CMP(codec_inst->plname, "telephone-event")) {
  168. #ifdef WEBRTC_CODEC_AVT
  169. return new ACMDTMFPlayout(kAVT);
  170. #endif
  171. } else if (!STR_CASE_CMP(codec_inst->plname, "red")) {
  172. #ifdef WEBRTC_CODEC_RED
  173. return new ACMRED(kRED);
  174. #endif
  175. }
  176. return NULL;
  177. }

3、 plfreq一般取如下值(在common_types.h定义);

  1. //负载频率值
  2. enum PayloadFrequencies
  3. {
  4. kFreq8000Hz  = 8000,
  5. kFreq16000Hz = 16000,
  6. kFreq32000Hz = 32000
  7. };

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信息示例代码

  1. //列出(获得)引擎支持的所有编解码器信息
  2. //支持平台:Windows, Mac OS X, Linux
  3. #include "voe_base.h"
  4. #include "voe_codec.h"
  5. VoiceEngine* ve = VoiceEngine::Create();
  6. VoECodec* codec = VoECodec::GetInterface(ve);
  7. for (int = 0; i < codec->NumOfCodecs(); i++)
  8. {
  9. CodecInst cinst;
  10. codec->GetCodec(i, cinst);
  11. DISPLAY_CODEC_INFO(i, cinst);
  12. }
  13. // 释放sub-API
  14. codec->Release();
  15. //删除引擎
  16. VoiceEngine::Delete(ve);

3、初始化VoiceEngine Codec示例代码

    1. //初始化VoiceEngine Codec示例代码
    2. //支持平台:Windows, Mac OS X, Linux
    3. #include "voe_codec.h"
    4. CodecInst cinst;
    5. //初始化iSAC编解码器参数
    6. strcpy(cinst.plname, "ISAC");
    7. cinst.plfreq   = 16000; // iSAC宽带模式取样频率
    8. cinst.pltype   = 103;
    9. cinst.pacsize  = 480;   //使用30ms packet size,480kbps
    10. cinst.channels = 1;     // 单声道
    11. cinst.rate     = -1;    // 信道自适应模式
    12. //初始化完成
    13. //在ID为0的channel激活已初始化的iSAC
    14. codec->SetSendCodec(0, cinst);

WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置的更多相关文章

  1. WebRTC音视频引擎研究(1)--整体架构分析

    WebRTC技术交流群:234795279 原文地址:http://blog.csdn.net/temotemo/article/details/7530504     1.WebRTC目的     ...

  2. 转: WebRTC音视频引擎研究(1)--整体架构分析

    转自: http://blog.csdn.net/temotemo/article/details/7530504   目录(?)[+]   WebRTC技术交流群:234795279 原文地址:ht ...

  3. Android WebRTC 音视频开发总结

    www.cnblogs.com/lingyunhu/p/3621057.html 前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC. ...

  4. WebRTC 音视频开发

    WebRTC 音视频开发 webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...

  5. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  6. Android IOS WebRTC 音视频开发总结(六)-- iOS开发之含泪经验

    前段时间在搞webrtc iOS开发,所以将标题改为了Android IOS WebRTC 音视频开发总结, 下面都是开发过程中的经验总结,转载请说明出处(博客园RTC.Blacker): 1. IO ...

  7. Android WebRTC 音视频开发总结(三)-- 信令服务和媒体服务

    前面介绍了WebRTCDemo的基本结构,本节主要介绍WebRTC音视频服务端的处理,,转载请说明出处(博客园RTC.Blacker). 通过前面的例子我们知道运行WebRTCDemo即可看到P2P的 ...

  8. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  9. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

随机推荐

  1. Bessie Goes Moo

    Bessie Goes Moo 题目描述 Farmer John and Bessie the cow love to exchange math puzzles in their free time ...

  2. PAT (Advanced Level) 1003. Emergency (25)

    最短路+dfs 先找出可能在最短路上的边,这些边会构成一个DAG,然后在这个DAG上dfs一次就可以得到两个答案了. 也可以对DAG进行拓扑排序,然后DP求解. #include<iostrea ...

  3. CodeForces 609A USB Flash Drives

    水题 #include<cstdio> #include<cmath> #include<algorithm> using namespace std; +; in ...

  4. vector 的用法(c++)

    vertor是向量类型,它是一个对象实体.它作为容器可以容纳不同的实体,如int,flout,double,还有类类型. 1.包含头文件 #include <vector> 2.声明:ve ...

  5. HDU 5616 Jam's balance

    背包.dp[i]=1表示i这种差值能被组合出来,差值有负数,所以用sum表示0,0表示-sum,2*sum表示sum. 询问X的时候,只需看dp[sum+X]或者dp[sum-X]是否有一个为1,注意 ...

  6. 全文搜索之 Elasticsearch

    概述 Elasticsearch (ES)是一个基于 Lucene 的开源搜索引擎,它不但稳定.可靠.快速,而且也具有良好的水平扩展能力,是专门为分布式环境设计的. 特性 安装方便:没有其他依赖,下载 ...

  7. java工程师联通XX面试题目

    什么是“长连接”和“短连接”? 所谓短连接指建立SOCKET连接后发送后接收完数据后马上断开连接,一般银行都使用短连接解释2长连接就是指在基于tcp的通讯中,一直保持连接,不管当前是否发送或者接收数据 ...

  8. Linux程序设计中的curses.h编译报错,无法找到curses.h和ncurses.h

    源程序screen.c如下: #include <stdio.h> #include <term.h> #include <curses.h> #include & ...

  9. Jsoup使用教程

    一.解析和遍历一个HTML文档1.解析Html及Url链接 String html = "<html><head><title>First parse&l ...

  10. HDU 3903 Trigonometric Function

    这题真难,并不会推理... #include<cstdio> #include<cstring> #include<cmath> #include<algor ...