编解码器类关系图

Add10MsData 用于向编码器输入数据
PlayoutData10Ms 用于从解码器获取数据
IncomingPacket用于从网络获取音频包,数据是没有rtp头的
创建音频编码器的步骤
创建音频编码器的函数调用过程

右边的第一步走完后,才会执行第二步。
最后调用SetEncoder将构造好的AudioEncoderOpusImpl赋值给创建好的AudioCodingModuleImpl。
音频编码器的选择
代码分析
ChannelSend::ChannelSend
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\audio\channel_send.cc
ChannelSend::ChannelSend(Clock* clock,TaskQueueFactory* task_queue_factory,ProcessThread* module_process_thread,Transport* rtp_transport,RtcpRttStats* rtcp_rtt_stats,RtcEventLog* rtc_event_log,FrameEncryptorInterface* frame_encryptor,const webrtc::CryptoOptions& crypto_options,bool extmap_allow_mixed,int rtcp_report_interval_ms,uint32_t ssrc,rtc::scoped_refptr<FrameTransformerInterface> frame_transformer,TransportFeedbackObserver* feedback_observer): event_log_(rtc_event_log),_timeStamp(0), // This is just an offset, RTP module will add it's own// random offset_moduleProcessThreadPtr(module_process_thread),input_mute_(false),previous_frame_muted_(false),_includeAudioLevelIndication(false),rtcp_observer_(new VoERtcpObserver(this)),feedback_observer_(feedback_observer),rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()),retransmission_rate_limiter_(new RateLimiter(clock, kMaxRetransmissionWindowMs)),frame_encryptor_(frame_encryptor),crypto_options_(crypto_options),encoder_queue_(task_queue_factory->CreateTaskQueue("AudioEncoder",TaskQueueFactory::Priority::NORMAL)),fixing_timestamp_stall_(!field_trial::IsDisabled("WebRTC-Audio-FixTimestampStall")) {RTC_DCHECK(module_process_thread);module_process_thread_checker_.Detach();// 创建音频编码器audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));RtpRtcpInterface::Configuration configuration;configuration.bandwidth_callback = rtcp_observer_.get();configuration.transport_feedback_callback = feedback_observer_;configuration.clock = (clock ? clock : Clock::GetRealTimeClock());configuration.audio = true;configuration.outgoing_transport = rtp_transport;configuration.paced_sender = rtp_packet_pacer_proxy_.get();configuration.event_log = event_log_;configuration.rtt_stats = rtcp_rtt_stats;configuration.retransmission_rate_limiter =retransmission_rate_limiter_.get();configuration.extmap_allow_mixed = extmap_allow_mixed;configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;configuration.local_media_ssrc = ssrc;// 创建ModuleRtpRtcpImpl2rtp_rtcp_ = ModuleRtpRtcpImpl2::Create(configuration);rtp_rtcp_->SetSendingMediaStatus(false);rtp_sender_audio_ = std::make_unique<RTPSenderAudio>(configuration.clock,rtp_rtcp_->RtpSender());_moduleProcessThreadPtr->RegisterModule(rtp_rtcp_.get(), RTC_FROM_HERE);// Ensure that RTCP is enabled by default for the created channel.rtp_rtcp_->SetRTCPStatus(RtcpMode::kCompound);int error = audio_coding_->RegisterTransportCallback(this);RTC_DCHECK_EQ(0, error);if (frame_transformer)InitFrameTransformerDelegate(std::move(frame_transformer));}
WebRtcVoiceMediaChannel::SetSendCodecs
// Utility function called from SetSendParameters() to extract current send// codec settings from the given list of codecs (originally from SDP). Both send// and receive streams may be reconfigured based on the new settings.bool WebRtcVoiceMediaChannel::SetSendCodecs(const std::vector<AudioCodec>& codecs) {RTC_DCHECK_RUN_ON(worker_thread_);dtmf_payload_type_ = absl::nullopt;dtmf_payload_freq_ = -1;// Validate supplied codecs list.for (const AudioCodec& codec : codecs) {// TODO(solenberg): Validate more aspects of input - that payload types// don't overlap, remove redundant/unsupported codecs etc -// the same way it is done for RtpHeaderExtensions.if (codec.id < kMinPayloadType || codec.id > kMaxPayloadType) {RTC_LOG(LS_WARNING) << "Codec payload type out of range: "<< ToString(codec);return false;}}// Find PT of telephone-event codec with lowest clockrate, as a fallback, in// case we don't have a DTMF codec with a rate matching the send codec's, or// if this function returns early.std::vector<AudioCodec> dtmf_codecs;for (const AudioCodec& codec : codecs) {if (IsCodec(codec, kDtmfCodecName)) {dtmf_codecs.push_back(codec);if (!dtmf_payload_type_ || codec.clockrate < dtmf_payload_freq_) {dtmf_payload_type_ = codec.id;dtmf_payload_freq_ = codec.clockrate;}}}// Scan through the list to figure out the codec to use for sending.absl::optional<webrtc::AudioSendStream::Config::SendCodecSpec>send_codec_spec;webrtc::BitrateConstraints bitrate_config;absl::optional<webrtc::AudioCodecInfo> voice_codec_info;size_t send_codec_position = 0;for (const AudioCodec& voice_codec : codecs) {if (!(IsCodec(voice_codec, kCnCodecName) ||IsCodec(voice_codec, kDtmfCodecName) ||IsCodec(voice_codec, kRedCodecName))) {webrtc::SdpAudioFormat format(voice_codec.name, voice_codec.clockrate,voice_codec.channels, voice_codec.params);voice_codec_info = engine()->encoder_factory_->QueryAudioEncoder(format);if (!voice_codec_info) {RTC_LOG(LS_WARNING) << "Unknown codec " << ToString(voice_codec);continue;}send_codec_spec = webrtc::AudioSendStream::Config::SendCodecSpec(voice_codec.id, format);if (voice_codec.bitrate > 0) {send_codec_spec->target_bitrate_bps = voice_codec.bitrate;}send_codec_spec->transport_cc_enabled = HasTransportCc(voice_codec);send_codec_spec->nack_enabled = HasNack(voice_codec);bitrate_config = GetBitrateConfigForCodec(voice_codec);break;}send_codec_position++;}if (!send_codec_spec) {return false;}RTC_DCHECK(voice_codec_info);if (voice_codec_info->allow_comfort_noise) {// Loop through the codecs list again to find the CN codec.// TODO(solenberg): Break out into a separate function?for (const AudioCodec& cn_codec : codecs) {if (IsCodec(cn_codec, kCnCodecName) &&cn_codec.clockrate == send_codec_spec->format.clockrate_hz &&cn_codec.channels == voice_codec_info->num_channels) {if (cn_codec.channels != 1) {RTC_LOG(LS_WARNING)<< "CN #channels " << cn_codec.channels << " not supported.";} else if (cn_codec.clockrate != 8000 && cn_codec.clockrate != 16000 &&cn_codec.clockrate != 32000) {RTC_LOG(LS_WARNING)<< "CN frequency " << cn_codec.clockrate << " not supported.";} else {send_codec_spec->cng_payload_type = cn_codec.id;}break;}}// Find the telephone-event PT exactly matching the preferred send codec.for (const AudioCodec& dtmf_codec : dtmf_codecs) {if (dtmf_codec.clockrate == send_codec_spec->format.clockrate_hz) {dtmf_payload_type_ = dtmf_codec.id;dtmf_payload_freq_ = dtmf_codec.clockrate;break;}}}if (audio_red_for_opus_trial_enabled_) {// Loop through the codecs to find the RED codec that matches opus// with respect to clockrate and number of channels.size_t red_codec_position = 0;for (const AudioCodec& red_codec : codecs) {if (red_codec_position < send_codec_position &&IsCodec(red_codec, kRedCodecName) &&red_codec.clockrate == send_codec_spec->format.clockrate_hz &&red_codec.channels == send_codec_spec->format.num_channels) {send_codec_spec->red_payload_type = red_codec.id;break;}red_codec_position++;}}if (send_codec_spec_ != send_codec_spec) {send_codec_spec_ = std::move(send_codec_spec);// Apply new settings to all streams.for (const auto& kv : send_streams_) {kv.second->SetSendCodecSpec(*send_codec_spec_);}} else {// If the codec isn't changing, set the start bitrate to -1 which means// "unchanged" so that BWE isn't affected.bitrate_config.start_bitrate_bps = -1;}call_->GetTransportControllerSend()->SetSdpBitrateParameters(bitrate_config);// Check if the transport cc feedback or NACK status has changed on the// preferred send codec, and in that case reconfigure all receive streams.if (recv_transport_cc_enabled_ != send_codec_spec_->transport_cc_enabled ||recv_nack_enabled_ != send_codec_spec_->nack_enabled) {RTC_LOG(LS_INFO) << "Recreate all the receive streams because the send ""codec has changed.";recv_transport_cc_enabled_ = send_codec_spec_->transport_cc_enabled;recv_nack_enabled_ = send_codec_spec_->nack_enabled;for (auto& kv : recv_streams_) {kv.second->SetUseTransportCcAndRecreateStream(recv_transport_cc_enabled_,recv_nack_enabled_);}}send_codecs_ = codecs;return true;}
总结

