ADM与播放声音
播放声音的流程
重要流程

源码分析-音频播放流程
在h:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\media\engine\webrtc_voice_engine.cc
WebRtcVoiceMediaChannel::AddRecvStream 打断点调试
WebRtcVoiceMediaChannel::AddRecvStream
bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::AddRecvStream");RTC_DCHECK_RUN_ON(worker_thread_);***// Create a new channel for receiving audio data.// 创建一个新的通道去接收音频数据// 键值<ssrc, WebRtcAudioReceiveStream>recv_streams_.insert(std::make_pair(ssrc, new WebRtcAudioReceiveStream(ssrc, receiver_reports_ssrc_, recv_transport_cc_enabled_,recv_nack_enabled_, sp.stream_ids(), recv_rtp_extensions_,call_, this, engine()->decoder_factory_, decoder_map_,codec_pair_id_, engine()->audio_jitter_buffer_max_packets_,engine()->audio_jitter_buffer_fast_accelerate_,engine()->audio_jitter_buffer_min_delay_ms_,engine()->audio_jitter_buffer_enable_rtx_handling_,unsignaled_frame_decryptor_, crypto_options_, nullptr)));recv_streams_[ssrc]->SetPlayout(playout_);return true;}
调用堆栈

recvstreams[ssrc]->SetPlayout(playout_);
SetPlayout(bool playout)
void SetPlayout(bool playout) {RTC_DCHECK_RUN_ON(&worker_thread_checker_);RTC_DCHECK(stream_);if (playout) {stream_->Start();} else {stream_->Stop();}}
stream->Start();
stream->Stop();
AudioReceiveStream::Start
void AudioReceiveStream::Start() {RTC_DCHECK_RUN_ON(&worker_thread_checker_);if (playing_) {return;}channel_receive_->StartPlayout();playing_ = true;audio_state()->AddReceivingStream(this);}void AudioReceiveStream::Stop() {RTC_DCHECK_RUN_ON(&worker_thread_checker_);if (!playing_) {return;}channel_receive_->StopPlayout();playing_ = false;audio_state()->RemoveReceivingStream(this);}
audio_state()->AddReceivingStream(this);
AudioState::AddReceivingStream
void AudioState::AddReceivingStream(webrtc::AudioReceiveStream* stream) {RTC_DCHECK(thread_checker_.IsCurrent());RTC_DCHECK_EQ(0, receiving_streams_.count(stream));// 首先将该流插入到自己的管理中receiving_streams_.insert(stream);// 然后添加到audio_mixer的源中,后面就可以用它来进行混音了if (!config_.audio_mixer->AddSource(static_cast<internal::AudioReceiveStream*>(stream))) {RTC_DLOG(LS_ERROR) << "Failed to add source to mixer.";}// Make sure playback is initialized; start playing if enabled.UpdateNullAudioPollerState();// 判断是否正在播放,没有则调用adm->InitPlayoutauto* adm = config_.audio_device_module.get();if (!adm->Playing()) {if (adm->InitPlayout() == 0) {if (playout_enabled_) {adm->StartPlayout();}} else {RTC_DLOG_F(LS_ERROR) << "Failed to initialize playout.";}}}
AudioDeviceModuleImpl::InitPlayout
int32_t AudioDeviceModuleImpl::InitPlayout() {RTC_LOG(INFO) << __FUNCTION__;CHECKinitialized_();if (PlayoutIsInitialized()) {return 0;}// 又回到 AudioDeviceWindowsCore::InitPlayoutint32_t result = audio_device_->InitPlayout();RTC_LOG(INFO) << "output: " << result;RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",static_cast<int>(result == 0));return result;}

