webrtc 接收音频逻辑走向
PlayThreadProcess
需要一个线程定时执行adm 方法,然后到 AudioDeviceGeneric 的一个方法,我这里是PlayThreadProcess里面调用接下来两个核心子方法
1. _ptrAudioBuffer->RequestPlayoutData
调用成员变量_ptrAudioBuffer(class AudioDeviceBuffer) 的 RequestPlayoutData 方法。后调用到:
audio_device_buffer.cc :: AudioDeviceBuffer :: RequestPlayoutData()
- 1.1 根据一些音频参数,对比检查数据长度
- 1.2 调用audio_transport_cb_对象的NeedMorePlayData 方法
audio_transport_cb_类型是 AudioTransport的实现类AudioTransportImpl-
1.2.1 mixer_->Mix
audio_mixer_impl.cc的AudioMixerImpl类的Mix方法
将混流后的数据,输入到audio_frame_for_mixing 里面。这里还有一个终端,里面有一个GetAudioFromSources方法的调用,最终会达到把接收的数据输出到每一个track的sink里面。后面详细介绍这一段, 1.2.2 ProcessReverseStream
对mixed_frame_音频数据做一些后处理。1.2.3 Resample
如果有采样率等问题,做一次重采样
-
2. _ptrAudioBuffer->GetPlayoutData
这一步比较简单,就是吧上面操作的数据,拷贝出来。
3. AudioMixerImpl 的 Mix 方法详细介绍
void AudioMixerImpl::Mix(size_t number_of_channels,
AudioFrame* audio_frame_for_mixing) {
RTC_DCHECK(number_of_channels >= 1);
RTC_DCHECK_RUNS_SERIALIZED(&race_checker_);
CalculateOutputFrequency();
{
rtc::CritScope lock(&crit_);
const size_t number_of_streams = audio_source_list_.size();
frame_combiner_.Combine(GetAudioFromSources(), number_of_channels,
OutputFrequency(), number_of_streams,
audio_frame_for_mixing);
}
return;
}
- GetAudioFromSources()
首先会调用GetAudioFromSources() 方法,这个方法里面遍历了 audio_source_list_ 数组
audio_source_list_ 里面存放的是SourceStatus类型
struct SourceStatus {
SourceStatus(Source* audio_source, bool is_mixed, float gain)
: audio_source(audio_source), is_mixed(is_mixed), gain(gain) {}
Source* audio_source = nullptr;
bool is_mixed = false;
float gain = 0.0f;
// A frame that will be passed to audio_source->GetAudioFrameWithInfo.
AudioFrame audio_frame;
};
这个里面存放了一个Source对象,循环遍历的时候,会调用这个source 的 GetAudioFrameWithInfo() 方法
接下来的走向是这样的
- file:audio_receive_stream.cc,class:AudioReceiveStream,fun:GetAudioFrameWithInfo
-
- file:channel_receive.cc,class:ChannelReceive,fun:GetAudioFrameWithInfo
- 首先从adm模块里面获取10ms音频pcm数据
audio_coding_->PlayoutData10Ms
- 首先从adm模块里面获取10ms音频pcm数据
- 调用sink的OnData 方法
audio_sink_->OnData(data);
- 调用sink的OnData 方法
- 跳转到 file:remote_audio_source.cc,class:RemoteAudioSource::AudioDataProxy,fun:OnData
- 继续跳转到 file:remote_audio_source.cc,class:RemoteAudioSource,fun:OnData
这里的sink 就是我们在拿到AudioTrack的时候,往里面添加的sink,这样就达到了,抓取某路流的数据的效果。
- 继续跳转到 file:remote_audio_source.cc,class:RemoteAudioSource,fun:OnData