webrtc 接收音频逻辑走向

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() 方法
接下来的走向是这样的

    1. file:audio_receive_stream.cc,class:AudioReceiveStream,fun:GetAudioFrameWithInfo
    1. file:channel_receive.cc,class:ChannelReceive,fun:GetAudioFrameWithInfo
      1. 首先从adm模块里面获取10ms音频pcm数据
        audio_coding_->PlayoutData10Ms
      1. 调用sink的OnData 方法
        audio_sink_->OnData(data);
      1. 跳转到 file:remote_audio_source.cc,class:RemoteAudioSource::AudioDataProxy,fun:OnData
      1. 继续跳转到 file:remote_audio_source.cc,class:RemoteAudioSource,fun:OnData
        这里的sink 就是我们在拿到AudioTrack的时候,往里面添加的sink,这样就达到了,抓取某路流的数据的效果。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容