前言
编解码器信息收集的步骤
收集音频编解码器的时机
将编解码器信息与SDP建立联系

代码分析
Conductor::InitializePeerConnection ->webrtc::CreatePeerConnectionFactory
peer_connection_factory_ = webrtc::CreatePeerConnectionFactory(nullptr /* network_thread */, nullptr /* worker_thread */,nullptr /* signaling_thread */, nullptr /* default_adm */,webrtc::CreateBuiltinAudioEncoderFactory(),webrtc::CreateBuiltinAudioDecoderFactory(),webrtc::CreateBuiltinVideoEncoderFactory(),webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */,nullptr /* audio_processing */);
webrtc::CreateBuiltinAudioEncoderFactory(),
->
CreateAudioEncoderFactory 可变参数模板
->
audio_encoder_factory_template_impl::AudioEncoderFactoryT
->
class AudioEncoderFactoryT : public AudioEncoderFactory {
public:
std::vector
std::vector
Helper
return specs;
}
ChannelManager::Init
cricket::ChannelManager::Init() 行 123 C++webrtc::ConnectionContext::Create(webrtc::PeerConnectionFactoryDependencies * dependencies) 行 79 C++webrtc::PeerConnectionFactory::Create(webrtc::PeerConnectionFactoryDependencies dependencies) 行 84 C++webrtc::CreateModularPeerConnectionFactory(webrtc::PeerConnectionFactoryDependencies dependencies) 行 70 C++webrtc::CreatePeerConnectionFactory(rtc::Thread * network_thread, rtc::Thread * worker_thread, rtc::Thread * signaling_thread, rtc::scoped_refptr<webrtc::AudioDeviceModule> default_adm, rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory, rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory, std::__1::unique_ptr<webrtc::VideoEncoderFactory,std::default_delete<webrtc::VideoEncoderFactory>> video_encoder_factory, std::__1::unique_ptr<webrtc::VideoDecoderFactory,std::default_delete<webrtc::VideoDecoderFactory>> video_decoder_factory, rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing, webrtc::AudioFrameProcessor * audio_frame_processor) 行 71 C++Conductor::InitializePeerConnection() 行 133 C++Conductor::ConnectToPeer(int peer_id) 行 450 C++MainWnd::OnDefaultAction() 行 348 C++MainWnd::OnMessage(unsigned int msg, unsigned __int64 wp, __int64 lp, __int64 * result) 行 392 C++MainWnd::WndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wp, __int64 lp) 行 419 C++
bool ChannelManager::Init() {RTC_DCHECK(!initialized_);if (initialized_) {return false;}RTC_DCHECK(network_thread_);RTC_DCHECK(worker_thread_);if (!network_thread_->IsCurrent()) {// Do not allow invoking calls to other threads on the network thread.network_thread_->Invoke<void>(RTC_FROM_HERE, [&] { network_thread_->DisallowBlockingCalls(); });}if (media_engine_) {initialized_ = worker_thread_->Invoke<bool>(RTC_FROM_HERE, [&] { return media_engine_->Init(); });RTC_DCHECK(initialized_);} else {initialized_ = true;}return initialized_;}
WebRtcVoiceEngine::Init

cricket::WebRtcVoiceEngine::Init() 行 287 C++cricket::CompositeMediaEngine::Init() 行 182 C++cricket::ChannelManager::Init() 行 123 C++webrtc::ConnectionContext::Create(webrtc::PeerConnectionFactoryDependencies * dependencies) 行 79 C++webrtc::PeerConnectionFactory::Create(webrtc::PeerConnectionFactoryDependencies dependencies) 行 84 C++webrtc::CreateModularPeerConnectionFactory(webrtc::PeerConnectionFactoryDependencies dependencies) 行 70 C++webrtc::CreatePeerConnectionFactory(rtc::Thread * network_thread, rtc::Thread * worker_thread, rtc::Thread * signaling_thread, rtc::scoped_refptr<webrtc::AudioDeviceModule> default_adm, rtc::scoped_refptr<webrtc::AudioEncoderFactory> audio_encoder_factory, rtc::scoped_refptr<webrtc::AudioDecoderFactory> audio_decoder_factory, std::__1::unique_ptr<webrtc::VideoEncoderFactory,std::default_delete<webrtc::VideoEncoderFactory>> video_encoder_factory, std::__1::unique_ptr<webrtc::VideoDecoderFactory,std::default_delete<webrtc::VideoDecoderFactory>> video_decoder_factory, rtc::scoped_refptr<webrtc::AudioMixer> audio_mixer, rtc::scoped_refptr<webrtc::AudioProcessing> audio_processing, webrtc::AudioFrameProcessor * audio_frame_processor) 行 71 C++Conductor::InitializePeerConnection() 行 133 C++Conductor::ConnectToPeer(int peer_id) 行 450 C++MainWnd::OnDefaultAction() 行 348 C++MainWnd::OnMessage(unsigned int msg, unsigned __int64 wp, __int64 lp, __int64 * result) 行 392 C++MainWnd::WndProc(HWND__ * hwnd, unsigned int msg, unsigned __int64 wp, __int64 lp) 行 419 C++
void WebRtcVoiceEngine::Init() {RTC_DCHECK_RUN_ON(&worker_thread_checker_);RTC_LOG(LS_INFO) << "WebRtcVoiceEngine::Init";// 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)));// Load our audio codec lists.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);}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);*************}
CollectCodecs(encoderfactory->GetSupportedEncoders());
AudioEncoderOpusImpl::AppendSupportedEncoders
H:\webrtc-20210315\webrtc-20210315\webrtc\webrtc-checkout\src\modules\audio_coding\codecs\opus\audio_encoder_opus.cc
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.absl::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;}
PayloadTypeMapper::PayloadTypeMapper
保存类型信息
PayloadTypeMapper::PayloadTypeMapper()// RFC 3551 reserves payload type numbers in the range 96-127 exclusively// for dynamic assignment. Once those are used up, it is recommended that// payload types unassigned by the RFC are used for dynamic payload type// mapping, before any static payload ids. At this point, we only support// mapping within the exclusive range.: next_unused_payload_type_(96),max_payload_type_(127),mappings_({// Static payload type assignments according to RFC 3551.{{kPcmuCodecName, 8000, 1}, 0},{{"GSM", 8000, 1}, 3},{{"G723", 8000, 1}, 4},{{"DVI4", 8000, 1}, 5},{{"DVI4", 16000, 1}, 6},{{"LPC", 8000, 1}, 7},{{kPcmaCodecName, 8000, 1}, 8},{{kG722CodecName, 8000, 1}, 9},{{kL16CodecName, 44100, 2}, 10},{{kL16CodecName, 44100, 1}, 11},{{"QCELP", 8000, 1}, 12},{{kCnCodecName, 8000, 1}, 13},// RFC 4566 is a bit ambiguous on the contents of the "encoding// parameters" field, which, for audio, encodes the number of// channels. It is "optional and may be omitted if the number of// channels is one". Does that necessarily imply that an omitted// encoding parameter means one channel? Since RFC 3551 doesn't// specify a value for this parameter for MPA, I've included both 0// and 1 here, to increase the chances it will be correctly used if// someone implements an MPEG audio encoder/decoder.{{"MPA", 90000, 0}, 14},{{"MPA", 90000, 1}, 14},{{"G728", 8000, 1}, 15},{{"DVI4", 11025, 1}, 16},{{"DVI4", 22050, 1}, 17},{{"G729", 8000, 1}, 18},// Payload type assignments currently used by WebRTC.// Includes data to reduce collisions (and thus reassignments){{kGoogleRtpDataCodecName, 0, 0}, kGoogleRtpDataCodecPlType},{{kIlbcCodecName, 8000, 1}, 102},{{kIsacCodecName, 16000, 1}, 103},{{kIsacCodecName, 32000, 1}, 104},{{kCnCodecName, 16000, 1}, 105},{{kCnCodecName, 32000, 1}, 106},{{kOpusCodecName,48000,2,{{kCodecParamMinPTime, "10"},{kCodecParamUseInbandFec, kParamValueTrue}}},111},// TODO(solenberg): Remove the hard coded 16k,32k,48k DTMF once we// assign payload types dynamically for send side as well.{{kDtmfCodecName, 48000, 1}, 110},{{kDtmfCodecName, 32000, 1}, 112},{{kDtmfCodecName, 16000, 1}, 113},{{kDtmfCodecName, 8000, 1}, 126}}) {// TODO(ossu): Try to keep this as change-proof as possible until we're able// to remove the payload type constants from everywhere in the code.for (const auto& mapping : mappings_) {used_payload_types_.insert(mapping.second);}}
小结

