调用栈
Channel中的SetRecvParameters

第一步,获取解码器变化的参数,然后获取最优解码器参数;
第二步,保存媒体协商时的接收到的解码器参数。
bool WebRtcVideoChannel::SetRecvParameters(const VideoRecvParameters& params) {RTC_DCHECK_RUN_ON(&thread_checker_);TRACE_EVENT0("webrtc", "WebRtcVideoChannel::SetRecvParameters");RTC_DLOG(LS_INFO) << "SetRecvParameters: " << params.ToString();ChangedRecvParameters changed_params;if (!GetChangedRecvParameters(params, &changed_params)) {return false;}if (changed_params.flexfec_payload_type) {RTC_DLOG(LS_INFO) << "Changing FlexFEC payload type (recv) from "<< recv_flexfec_payload_type_ << " to "<< *changed_params.flexfec_payload_type;recv_flexfec_payload_type_ = *changed_params.flexfec_payload_type;}if (changed_params.rtp_header_extensions) {recv_rtp_extensions_ = *changed_params.rtp_header_extensions;}if (changed_params.codec_settings) {RTC_DLOG(LS_INFO) << "Changing recv codecs from "<< CodecSettingsVectorToString(recv_codecs_) << " to "<< CodecSettingsVectorToString(*changed_params.codec_settings);recv_codecs_ = *changed_params.codec_settings;}for (auto& kv : receive_streams_) {kv.second->SetRecvParameters(changed_params);}recv_params_ = params;return true;}
WebRtcVideoChannel::GetChangedRecvParameters

就是通过对比接收到的解码器信息,和创建解码器时的信息,获取改变的参数,这里忽略flexfec的参数变化。
bool WebRtcVideoChannel::GetChangedRecvParameters(const VideoRecvParameters& params,ChangedRecvParameters* changed_params) const {if (!ValidateCodecFormats(params.codecs) ||!ValidateRtpExtensions(params.extensions)) {return false;}// Handle receive codecs.const std::vector<VideoCodecSettings> mapped_codecs =MapCodecs(params.codecs);if (mapped_codecs.empty()) {RTC_LOG(LS_ERROR)<< "GetChangedRecvParameters called without any video codecs.";return false;}// Verify that every mapped codec is supported locally.if (params.is_stream_active) {const std::vector<VideoCodec> local_supported_codecs =GetPayloadTypesAndDefaultCodecs(decoder_factory_,/*is_decoder_factory=*/true,call_->trials());for (const VideoCodecSettings& mapped_codec : mapped_codecs) {if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) {RTC_LOG(LS_ERROR)<< "GetChangedRecvParameters called with unsupported video codec: "<< mapped_codec.codec.ToString();return false;}}}if (NonFlexfecReceiveCodecsHaveChanged(recv_codecs_, mapped_codecs)) {changed_params->codec_settings =absl::optional<std::vector<VideoCodecSettings>>(mapped_codecs);}// Handle RTP header extensions.std::vector<webrtc::RtpExtension> filtered_extensions = FilterRtpExtensions(params.extensions, webrtc::RtpExtension::IsSupportedForVideo, false,call_->trials());if (filtered_extensions != recv_rtp_extensions_) {changed_params->rtp_header_extensions =absl::optional<std::vector<webrtc::RtpExtension>>(filtered_extensions);}int flexfec_payload_type = mapped_codecs.front().flexfec_payload_type;if (flexfec_payload_type != recv_flexfec_payload_type_) {changed_params->flexfec_payload_type = flexfec_payload_type;}return true;}
WebRtcVideoChannel中的recvcodecs参数

这里是指构造WebRtcVideoChannel对象时,它的recvcodecs参数是从encoderfactory编码工厂中获取到的,这时候获取的编码的payloadtype值还是不确定的。
协商后的这个值,是从MediaSessionDescriptionFactory对象后获得的,是最终确定的编码参数值。
WebRtcVideoChannel::WebRtcVideoChannel(webrtc::Call* call,const MediaConfig& config,const VideoOptions& options,const webrtc::CryptoOptions& crypto_options,webrtc::VideoEncoderFactory* encoder_factory,webrtc::VideoDecoderFactory* decoder_factory,webrtc::VideoBitrateAllocatorFactory* bitrate_allocator_factory): VideoMediaChannel(config),worker_thread_(rtc::Thread::Current()),call_(call),unsignalled_ssrc_handler_(&default_unsignalled_ssrc_handler_),video_config_(config.video),encoder_factory_(encoder_factory),decoder_factory_(decoder_factory),bitrate_allocator_factory_(bitrate_allocator_factory),default_send_options_(options),last_stats_log_ms_(-1),discard_unknown_ssrc_packets_(IsEnabled(call_->trials(),"WebRTC-Video-DiscardPacketsWithUnknownSsrc")),crypto_options_(crypto_options),unknown_ssrc_packet_buffer_(IsEnabled(call_->trials(),"WebRTC-Video-BufferPacketsWithUnknownSsrc")? new UnhandledPacketsBuffer(): nullptr) {RTC_DCHECK_RUN_ON(&thread_checker_);network_thread_checker_.Detach();rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc;sending_ = false;recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs(decoder_factory_, /*is_decoder_factory=*/true, call_->trials()));recv_flexfec_payload_type_ =recv_codecs_.empty() ? 0 : recv_codecs_.front().flexfec_payload_type;}
GetPayloadTypesAndDefaultCodecs
// This function will assign dynamic payload types (in the range [96, 127]) to// the input codecs, and also add ULPFEC, RED, FlexFEC, and associated RTX// codecs for recognized codecs (VP8, VP9, H264, and RED). It will also add// default feedback params to the codecs.// is_decoder_factory is needed to keep track of the implict assumption that any// H264 decoder also supports constrained base line profile.// Also, is_decoder_factory is used to decide whether FlexFEC video format// should be advertised as supported.// TODO(kron): Perhaps it is better to move the implicit knowledge to the place// where codecs are negotiated.template <class T>std::vector<VideoCodec> GetPayloadTypesAndDefaultCodecs(const T* factory,bool is_decoder_factory,const webrtc::WebRtcKeyValueConfig& trials) {if (!factory) {return {};}std::vector<webrtc::SdpVideoFormat> supported_formats =factory->GetSupportedFormats();if (is_decoder_factory) {AddH264ConstrainedBaselineProfileToSupportedFormats(&supported_formats);}if (supported_formats.empty())return std::vector<VideoCodec>();// Due to interoperability issues with old Chrome/WebRTC versions only use// the lower range for new codecs.static const int kFirstDynamicPayloadTypeLowerRange = 35;static const int kLastDynamicPayloadTypeLowerRange = 65;static const int kFirstDynamicPayloadTypeUpperRange = 96;static const int kLastDynamicPayloadTypeUpperRange = 127;int payload_type_upper = kFirstDynamicPayloadTypeUpperRange;int payload_type_lower = kFirstDynamicPayloadTypeLowerRange;supported_formats.push_back(webrtc::SdpVideoFormat(kRedCodecName));supported_formats.push_back(webrtc::SdpVideoFormat(kUlpfecCodecName));// flexfec-03 is supported as// - receive codec unless WebRTC-FlexFEC-03-Advertised is disabled// - send codec if WebRTC-FlexFEC-03-Advertised is enabledif ((is_decoder_factory &&!IsDisabled(trials, "WebRTC-FlexFEC-03-Advertised")) ||(!is_decoder_factory &&IsEnabled(trials, "WebRTC-FlexFEC-03-Advertised"))) {webrtc::SdpVideoFormat flexfec_format(kFlexfecCodecName);// This value is currently arbitrarily set to 10 seconds. (The unit// is microseconds.) This parameter MUST be present in the SDP, but// we never use the actual value anywhere in our code however.// TODO(brandtr): Consider honouring this value in the sender and receiver.flexfec_format.parameters = {{kFlexfecFmtpRepairWindow, "10000000"}};supported_formats.push_back(flexfec_format);}std::vector<VideoCodec> output_codecs;for (const webrtc::SdpVideoFormat& format : supported_formats) {VideoCodec codec(format);bool isCodecValidForLowerRange =absl::EqualsIgnoreCase(codec.name, kFlexfecCodecName) ||absl::EqualsIgnoreCase(codec.name, kAv1CodecName);if (!isCodecValidForLowerRange) {codec.id = payload_type_upper++;} else {codec.id = payload_type_lower++;}AddDefaultFeedbackParams(&codec, trials);output_codecs.push_back(codec);if (payload_type_upper > kLastDynamicPayloadTypeUpperRange) {RTC_LOG(LS_ERROR)<< "Out of dynamic payload types [96,127], skipping the rest.";// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12194):// continue in lower range.break;}if (payload_type_lower > kLastDynamicPayloadTypeLowerRange) {// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12248):// return an error.RTC_LOG(LS_ERROR)<< "Out of dynamic payload types [35,65], skipping the rest.";break;}// Add associated RTX codec for non-FEC codecs.if (!absl::EqualsIgnoreCase(codec.name, kUlpfecCodecName) &&!absl::EqualsIgnoreCase(codec.name, kFlexfecCodecName)) {if (!isCodecValidForLowerRange) {output_codecs.push_back(VideoCodec::CreateRtxCodec(payload_type_upper++, codec.id));} else {output_codecs.push_back(VideoCodec::CreateRtxCodec(payload_type_lower++, codec.id));}if (payload_type_upper > kLastDynamicPayloadTypeUpperRange) {RTC_LOG(LS_ERROR)<< "Out of dynamic payload types [96,127], skipping rtx.";// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12194):// continue in lower range.break;}if (payload_type_lower > kLastDynamicPayloadTypeLowerRange) {// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12248):// return an error.RTC_LOG(LS_ERROR)<< "Out of dynamic payload types [35,65], skipping rtx.";break;}}}return output_codecs;}

