WebRtc中VoiceEngine可以完成大部分的VOIP相关人物,包括采集、自动增益、噪声消除、回声抑制、编解码、RTP传输。下边我们通过代码来解析Voe中处理流程;
创建VoiceEngine和VoEBase
[cpp]
- VoiceEngine* _vePtr = VoiceEngine::Create();
- VoEBase* _veBasePtr = VoEBase::GetInterface(_vePtr);
-
- _veBasePtr->Init()
-
- VoiceEngine* _vePtr = VoiceEngine::Create();
- VoEBase* _veBasePtr = VoEBase::GetInterface(_vePtr);
- _veBasePtr->Init()
重点就在_veBasePtr->Init() 它会创建voe线程,线程负责采集、数字信号处理、编码、rtp传输。
[cpp]
- int VoEBaseImpl::Init(AudioDeviceModule* external_adm,
- AudioProcessing* audioproc)
- {
- _shared->process_thread();
- _shared->process_thread()->Start();
- _shared->audio_device()->Init();
- }
-
- int VoEBaseImpl::Init(AudioDeviceModule* external_adm,
- AudioProcessing* audioproc)
- {
- _shared->process_thread();
- _shared->process_thread()->Start();
- _shared->audio_device()->Init();
- }
audio_device()->Init()重载了int32_t AudioDeviceWindowsWave::Init()(windowns平台),别的平台是别的函数,基本差不多,在这个Init中,创建了 ThreadProcess线程,ThreadProcess线程负责所有的音频流程,从设备获取音频数据包。
[cpp]
- bool AudioDeviceWindowsWave::ThreadProcess()
- {
- while ((nRecordedBytes = RecProc(recTime)) > 0);
- }
-
- bool AudioDeviceWindowsWave::ThreadProcess()
- {
- while ((nRecordedBytes = RecProc(recTime)) > 0);
- }
处理过程在RecProc
[cpp]
- int32_t AudioDeviceWindowsWave::RecProc(LONGLONG& consumedTime)
- {
- _ptrAudioBuffer->DeliverRecordedData();
- }
-
- int32_t AudioDeviceWindowsWave::RecProc(LONGLONG& consumedTime)
- {
- _ptrAudioBuffer->DeliverRecordedData();
- }
- int32_t AudioDeviceBuffer::DeliverRecordedData()
- {
- _ptrCbAudioTransport->RecordedDataIsAvailable();
- }
-
- int32_t AudioDeviceBuffer::DeliverRecordedData()
- {
- _ptrCbAudioTransport->RecordedDataIsAvailable();
- }
RecordedDataIsAvailable是虚函数,被VoeBase重载
[cpp]
- 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();
- }
-
- 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;
[cpp]
- TransmitMixer::DemuxAndMix()
- {
- Channel* channelPtr = sc.GetFirstChannel(iterator);
- while (channelPtr != NULL)
- {
- if (channelPtr->InputIsOnHold())
- {
- channelPtr->UpdateLocalTimeStamp();
- } else if (channelPtr->Sending())
- {
-
- channelPtr->Demultiplex(_audioFrame);
- channelPtr->PrepareEncodeAndSend(_audioFrame.sample_rate_hz_);
- }
- channelPtr = sc.GetNextChannel(iterator);
- }
- }
-
- TransmitMixer::DemuxAndMix()
- {
- Channel* channelPtr = sc.GetFirstChannel(iterator);
- while (channelPtr != NULL)
- {
- if (channelPtr->InputIsOnHold())
- {
- channelPtr->UpdateLocalTimeStamp();
- } else if (channelPtr->Sending())
- {
-
- 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()
[cpp]
- Channel::PrepareEncodeAndSend(int mixingFrequency)
- {
- if (_inputFilePlaying)
- {
- MixOrReplaceAudioWithFile(mixingFrequency);
-
- }
-
- if (_mute)
- {
- AudioFrameOperations::Mute(_audioFrame);
- }
- if (_inputExternalMedia)
- {
- _inputExternalMediaCallbackPtr->Process();
-
- }
- InsertInbandDtmfTone();
- _rtpAudioProc->ProcessStream(&_audioFrame);
-
- }
-
- Channel::PrepareEncodeAndSend(int mixingFrequency)
- {
- if (_inputFilePlaying)
- {
- MixOrReplaceAudioWithFile(mixingFrequency);
-
- }
-
- if (_mute)
- {
- AudioFrameOperations::Mute(_audioFrame);
-
- }
- if (_inputExternalMedia)
- {
- _inputExternalMediaCallbackPtr->Process();
-
- }
- InsertInbandDtmfTone();
-
- _rtpAudioProc->ProcessStream(&_audioFrame);
-
- }
int AudioProcessingImpl::ProcessStream(AudioFrame* frame) 就是上述调用的_rtpAudioProc->ProcessStream();
以上是DemuxAndMix()过程,之后就是EncodeAndSend()过程,至此整个voe数据处理流程分析结束;
关于Audio Process则是另外一个大话题;
总结一下几点:
1. VoeBase提供大部分的对外接口
2. Channel:继承了大部分的音频功能;
(tastesweet) |