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->InitPlayout
auto* 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::InitPlayout
int32_t result = audio_device_->InitPlayout();
RTC_LOG(INFO) << "output: " << result;
RTC_HISTOGRAM_BOOLEAN("WebRTC.Audio.InitPlayoutSuccess",
static_cast<int>(result == 0));
return result;
}