前言

代码分析
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\media\engine\webrtc_voice_engine.cc
WebRtcVoiceEngine::Init
void WebRtcVoiceEngine::Init() {RTC_DCHECK_RUN_ON(&worker_thread_checker_);RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::Init";//1、 TaskQueue expects to be created/destroyed on the same thread.low_priority_worker_queue_.reset(new rtc::TaskQueue(task_queue_factory_->CreateTaskQueue("rtc-low-prio", webrtc::TaskQueueFactory::Priority::LOW)));//2、 收集音频编码器RTC_LOG(LS_VERBOSE) << "Supported send codecs in order of preference:";send_codecs_ = CollectCodecs(encoder_factory_->GetSupportedEncoders());for (const AudioCodec& codec : send_codecs_) {RTC_LOG(LS_VERBOSE) << ToString(codec);}//3、 收集音频解码器RTC_LOG(LS_VERBOSE) << "Supported recv codecs in order of preference:";recv_codecs_ = CollectCodecs(decoder_factory_->GetSupportedDecoders());for (const AudioCodec& codec : recv_codecs_) {RTC_LOG(LS_VERBOSE) << ToString(codec);}// 4、创建ADM#if defined(WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICE)// No ADM supplied? Create a default one.if (!adm_) {adm_ = webrtc::AudioDeviceModule::Create(webrtc::AudioDeviceModule::kPlatformDefaultAudio, task_queue_factory_);}#endif // WEBRTC_INCLUDE_INTERNAL_AUDIO_DEVICERTC_CHECK(adm());// 5、 初始化admwebrtc::adm_helpers::Init(adm());//6、 Set up AudioState.{webrtc::AudioState::Config config;if (audio_mixer_) {config.audio_mixer = audio_mixer_;} else {config.audio_mixer = webrtc::AudioMixerImpl::Create();}config.audio_processing = apm_;config.audio_device_module = adm_;if (audio_frame_processor_)config.async_audio_processing_factory =new rtc::RefCountedObject<webrtc::AsyncAudioProcessing::Factory>(*audio_frame_processor_, *task_queue_factory_);audio_state_ = webrtc::AudioState::Create(config);}//7、 Connect the ADM to our audio path.adm()->RegisterAudioCallback(audio_state()->audio_transport());//8、 Set default engine options.{AudioOptions options;options.echo_cancellation = true;options.auto_gain_control = true;#if defined(WEBRTC_IOS)// On iOS, VPIO provides built-in NS.options.noise_suppression = false;options.typing_detection = false;#elseoptions.noise_suppression = true;options.typing_detection = true;#endifoptions.experimental_ns = false;options.highpass_filter = true;options.stereo_swapping = false;options.audio_jitter_buffer_max_packets = 200;options.audio_jitter_buffer_fast_accelerate = false;options.audio_jitter_buffer_min_delay_ms = 0;options.audio_jitter_buffer_enable_rtx_handling = false;options.experimental_agc = false;options.residual_echo_detector = true;bool error = ApplyOptions(options);RTC_DCHECK(error);}initialized_ = true;}
—》
sendcodecs = CollectCodecs(encoderfactory->GetSupportedEncoders());
recvcodecs = CollectCodecs(decoderfactory->GetSupportedDecoders());
WebRtcVoiceEngine::CollectCodecs
std::vector<AudioCodec> WebRtcVoiceEngine::CollectCodecs(const std::vector<webrtc::AudioCodecSpec>& specs) const {PayloadTypeMapper mapper;std::vector<AudioCodec> out;// Only generate CN payload types for these clockrates:std::map<int, bool, std::greater<int>> generate_cn = {{8000, false}, {16000, false}, {32000, false}};// Only generate telephone-event payload types for these clockrates:std::map<int, bool, std::greater<int>> generate_dtmf = {{8000, false}, {16000, false}, {32000, false}, {48000, false}};auto map_format = [&mapper](const webrtc::SdpAudioFormat& format,std::vector<AudioCodec>* out) {absl::optional<AudioCodec> opt_codec = mapper.ToAudioCodec(format);if (opt_codec) {if (out) {out->push_back(*opt_codec);}} else {RTC_LOG(LS_ERROR) << "Unable to assign payload type to format: "<< rtc::ToString(format);}return opt_codec;};for (const auto& spec : specs) {// We need to do some extra stuff before adding the main codecs to out.// 调用上面定义的map_format函数,来将format格式转为AudioCodecabsl::optional<AudioCodec> opt_codec = map_format(spec.format, nullptr);if (opt_codec) {AudioCodec& codec = *opt_codec;if (spec.info.supports_network_adaption) {codec.AddFeedbackParam(FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));}if (spec.info.allow_comfort_noise) {// Generate a CN entry if the decoder allows it and we support the// clockrate.auto cn = generate_cn.find(spec.format.clockrate_hz);if (cn != generate_cn.end()) {cn->second = true;}}// Generate a telephone-event entry if we support the clockrate.auto dtmf = generate_dtmf.find(spec.format.clockrate_hz);if (dtmf != generate_dtmf.end()) {dtmf->second = true;}out.push_back(codec);if (codec.name == kOpusCodecName && audio_red_for_opus_trial_enabled_) {map_format({kRedCodecName, 48000, 2}, &out);}}}// Add CN codecs after "proper" audio codecs.for (const auto& cn : generate_cn) {if (cn.second) {map_format({kCnCodecName, cn.first, 1}, &out);}}// Add telephone-event codecs last.for (const auto& dtmf : generate_dtmf) {if (dtmf.second) {map_format({kDtmfCodecName, dtmf.first, 1}, &out);}}return out;}

返回out的值,可以看到有14个编码器
