WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置

http://blog.csdn.net/temotemo/article/details/7531711

 

        WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置       

        分类:            WebRTC 5337人阅读 评论(1) 收藏 举报
数据结构 引擎 codec null struct audio

目录(?)[+]

  1. VoiceEngine Codec数据结构
  2. 参数详细说明
    1. 查看VoiceEngine支持的所有Codec信息示例代码
    2. 初始化VoiceEngine Codec示例代码

WebRTC技术交流群:234795279


1、VoiceEngine Codec数据结构

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

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

参数详细说明:


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

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

[cpp] view plain copy print ?
  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


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


[cpp] view plain copy print ?
  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; 



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

[cpp] view plain copy print ?
  1. //负载频率值 
  2. enum PayloadFrequencies 
  3.     kFreq8000Hz  = 8000, 
  4.     kFreq16000Hz = 16000, 
  5.     kFreq32000Hz = 32000 
  6. }; 

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

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

3、初始化VoiceEngine Codec示例代码

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


欢迎指出不对之处:[email protected]

/==================================================================================================================/
   Author: zengxijin    [email protected]     欢迎转载,请注明出处
   原文地址: http://blog.csdn.net/temotemo
/==================================================================================================================/

 

你可能感兴趣的:(WebRTC)