Channel中的SetSendParameters

image.png

WebRtcVideoChannel::GetChangedSendParameters

image.png
negotiated_codecs:获取协商好的编码器,就是从本端获取跟远端匹配的视频编码器。

WebRtcVideoChannel::MapCodecs

  1. std::vector<WebRtcVideoChannel::VideoCodecSettings>
  2. WebRtcVideoChannel::MapCodecs(const std::vector<VideoCodec>& codecs) {
  3. if (codecs.empty()) {
  4. return {};
  5. }
  6. std::vector<VideoCodecSettings> video_codecs;
  7. std::map<int, VideoCodec::CodecType> payload_codec_type;
  8. // |rtx_mapping| maps video payload type to rtx payload type.
  9. std::map<int, int> rtx_mapping;
  10. webrtc::UlpfecConfig ulpfec_config;
  11. absl::optional<int> flexfec_payload_type;
  12. for (const VideoCodec& in_codec : codecs) {
  13. const int payload_type = in_codec.id;
  14. if (payload_codec_type.find(payload_type) != payload_codec_type.end()) {
  15. RTC_LOG(LS_ERROR) << "Payload type already registered: "
  16. << in_codec.ToString();
  17. return {};
  18. }
  19. payload_codec_type[payload_type] = in_codec.GetCodecType();
  20. switch (in_codec.GetCodecType()) {
  21. ****
  22. case VideoCodec::CODEC_VIDEO: {
  23. video_codecs.emplace_back();
  24. video_codecs.back().codec = in_codec;
  25. break;
  26. }
  27. }
  28. }
  29. // One of these codecs should have been a video codec. Only having FEC
  30. // parameters into this code is a logic error.
  31. RTC_DCHECK(!video_codecs.empty());
  32. *****
  33. for (VideoCodecSettings& codec_settings : video_codecs) {
  34. const int payload_type = codec_settings.codec.id;
  35. codec_settings.ulpfec = ulpfec_config;
  36. codec_settings.flexfec_payload_type = flexfec_payload_type.value_or(-1);
  37. auto it = rtx_mapping.find(payload_type);
  38. if (it != rtx_mapping.end()) {
  39. const int rtx_payload_type = it->second;
  40. codec_settings.rtx_payload_type = rtx_payload_type;
  41. }
  42. }
  43. return video_codecs;
  44. }

WebRtcVideoChannel::SelectSendVideoCodecs

  1. std::vector<WebRtcVideoChannel::VideoCodecSettings>
  2. WebRtcVideoChannel::SelectSendVideoCodecs(
  3. const std::vector<VideoCodecSettings>& remote_mapped_codecs) const {
  4. std::vector<webrtc::SdpVideoFormat> sdp_formats =
  5. encoder_factory_ ? encoder_factory_->GetImplementations()
  6. : std::vector<webrtc::SdpVideoFormat>();
  7. // The returned vector holds the VideoCodecSettings in term of preference.
  8. // They are orderd by receive codec preference first and local implementation
  9. // preference second.
  10. std::vector<VideoCodecSettings> encoders;
  11. for (const VideoCodecSettings& remote_codec : remote_mapped_codecs) {
  12. for (auto format_it = sdp_formats.begin();
  13. format_it != sdp_formats.end();) {
  14. // For H264, we will limit the encode level to the remote offered level
  15. // regardless if level asymmetry is allowed or not. This is strictly not
  16. // following the spec in https://tools.ietf.org/html/rfc6184#section-8.2.2
  17. // since we should limit the encode level to the lower of local and remote
  18. // level when level asymmetry is not allowed.
  19. if (IsSameCodec(format_it->name, format_it->parameters,
  20. remote_codec.codec.name, remote_codec.codec.params)) {
  21. encoders.push_back(remote_codec);
  22. // To allow the VideoEncoderFactory to keep information about which
  23. // implementation to instantitate when CreateEncoder is called the two
  24. // parmeter sets are merged.
  25. encoders.back().codec.params.insert(format_it->parameters.begin(),
  26. format_it->parameters.end());
  27. format_it = sdp_formats.erase(format_it);
  28. } else {
  29. ++format_it;
  30. }
  31. }
  32. }
  33. return encoders;
  34. }

image.png
image.png
对比结果
image.png
发现都支持输入的4个编码器。后面会使用第一个作为视频编码器设置。
image.png

Stream中的SetSendParameters

image.png