WebRtc中VoiceEngine可以完成大部分的VOIP相关人物,包括采集、自动增益、噪声消除、回声抑制、编解码、RTP传输。下边我们通过代码来解析Voe中处理流程;
创建VoiceEngine和VoEBase
VoiceEngine* _vePtr = VoiceEngine::Create(); //创建VoiceEngine VoEBase* _veBasePtr = VoEBase::GetInterface(_vePtr); //创建VoeBase 所有Voe相关操作通过这个共有类 _veBasePtr->Init() //创建整个Voe处理线程
重点就在_veBasePtr->Init() 它会创建voe线程,线程负责采集、数字信号处理、编码、rtp传输。
int VoEBaseImpl::Init(AudioDeviceModule* external_adm, AudioProcessing* audioproc) { _shared->process_thread(); //创建voe线程 _shared->process_thread()->Start(); _shared->audio_device()->Init(); }
audio_device()->Init()重载了int32_t AudioDeviceWindowsWave::Init()(windowns平台),别的平台是别的函数,基本差不多,在这个Init中,创建了ThreadProcess线程,ThreadProcess线程负责所有的音频流程,从设备获取音频数据包。
bool AudioDeviceWindowsWave::ThreadProcess() { while ((nRecordedBytes = RecProc(recTime)) > 0); }
处理过程在RecProc
int32_t AudioDeviceWindowsWave::RecProc(LONGLONG& consumedTime) { _ptrAudioBuffer->DeliverRecordedData(); }
int32_t AudioDeviceBuffer::DeliverRecordedData() { _ptrCbAudioTransport->RecordedDataIsAvailable(); }
int32_t VoEBaseImpl::RecordedDataIsAvailable( const void* audioSamples, uint32_t nSamples, uint8_t nBytesPerSample, uint8_t nChannels, uint32_t samplesPerSec, uint32_t totalDelayMS, int32_t clockDrift, uint32_t currentMicLevel, bool keyPressed, uint32_t& newMicLevel) { _shared->transmit_mixer()->DemuxAndMix(); _shared->transmit_mixer()->EncodeAndSend(); }
DemuxAndMix() 从字面意思是分路与混合,这个函数,主要负责AudioProcess的所有过程,包括Aec,Aecm,AGC,DTMF,遍历所有channel;
TransmitMixer::DemuxAndMix() { Channel* channelPtr = sc.GetFirstChannel(iterator); while (channelPtr != NULL) { if (channelPtr->InputIsOnHold()) { channelPtr->UpdateLocalTimeStamp(); } else if (channelPtr->Sending()) { // Demultiplex makes a copy of its input. channelPtr->Demultiplex(_audioFrame); channelPtr->PrepareEncodeAndSend(_audioFrame.sample_rate_hz_); } channelPtr = sc.GetNextChannel(iterator); } }
Channel::Demutiplex(),基本上没有什么具体任务,就是把audioFrame里边的数据 拷贝到channel自身, webrtc是client解决方案,对于client只认为有一个audio source,但可以有多个channel,每个channel中都有audio process,所以需要把数据copy到每个channel.
只有就是数据处理 PrepareEncodeAndSend()
Channel::PrepareEncodeAndSend(int mixingFrequency) { if (_inputFilePlaying) { MixOrReplaceAudioWithFile(mixingFrequency); //如果使用了voeFile::PlayFileAsMic();则从文件读取10ms数据,并覆盖audio buffer } if (_mute) { AudioFrameOperations::Mute(_audioFrame);//当然如果设置mutex,则memset 0 } if (_inputExternalMedia) { _inputExternalMediaCallbackPtr->Process(); //所过设置了ExternalMedia,自己的audio处理过程,就是在这里调用的 } InsertInbandDtmfTone(); //添加DTMF音频 _rtpAudioProc->ProcessStream(&_audioFrame); // 真正的GIPS牛逼代码,audio process过程: Aec Aecm AGC }
int AudioProcessingImpl::ProcessStream(AudioFrame* frame) 就是上述调用的_rtpAudioProc->ProcessStream();
以上是DemuxAndMix()过程,之后就是EncodeAndSend()过程,至此整个voe数据处理流程分析结束;
关于Audio Process则是另外一个大话题;
总结一下几点:
1. VoeBase提供大部分的对外接口
2. Channel:继承了大部分的音频功能;
今天的文章 WebRtc VoiceEngine代码解析分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/4146.html