webrtc-sdk / libwebrtc

A C++ wrapper for binary release, mainly used for flutter-webrtc desktop (windows, linux, embedded).
MIT License
378 stars 77 forks source link

fix: fix setCodecPreferences not working #78

Closed netsy closed 1 year ago

netsy commented 1 year ago

The bug introduces the wrong value of channels for video codecs when calling getRtpSenderCapabilities() or getRtpReceiverCapabilities(). The default value for channels should be -1.

The bug then prevents setCodecPreferences() from being applied since the channels does not match the original one. https://github.com/flutter-webrtc/flutter-webrtc/blob/main/common/cpp/src/flutter_peerconnection.cc#L796

void FlutterPeerConnection::RtpTransceiverSetCodecPreferences()

    auto codecNumChannels = findInt(codecMap, "channels");

    if (codecNumChannels != -1)
      codecCapability->set_channels(codecNumChannels);
RTCError VerifyCodecPreferences(const std::vector<RtpCodecCapability>& codecs,
                                const std::vector<T>& send_codecs,
                                const std::vector<T>& recv_codecs) {
  // If the intersection between codecs and
  // RTCRtpSender.getCapabilities(kind).codecs or the intersection between
  // codecs and RTCRtpReceiver.getCapabilities(kind).codecs only contains RTX,
  // RED or FEC codecs or is an empty set, throw InvalidModificationError.
  // This ensures that we always have something to offer, regardless of
  // transceiver.direction.

  if (!absl::c_any_of(codecs, [&recv_codecs](const RtpCodecCapability& codec) {
        return codec.name != cricket::kRtxCodecName &&
               codec.name != cricket::kRedCodecName &&
               codec.name != cricket::kFlexfecCodecName &&
               absl::c_any_of(recv_codecs, [&codec](const T& recv_codec) {
                 return recv_codec.MatchesCapability(codec);
               });
      })) {
    return RTCError(RTCErrorType::INVALID_MODIFICATION,
                    "Invalid codec preferences: Missing codec from recv "
                    "codec capabilities.");
  }
bool Codec::MatchesCapability(
    const webrtc::RtpCodecCapability& codec_capability) const {
  webrtc::RtpCodecParameters codec_parameters = ToCodecParameters();

  return codec_parameters.name == codec_capability.name &&
         codec_parameters.kind == codec_capability.kind &&
         (codec_parameters.name == cricket::kRtxCodecName ||
          (codec_parameters.num_channels == codec_capability.num_channels &&
           codec_parameters.clock_rate == codec_capability.clock_rate &&
           codec_parameters.parameters == codec_capability.parameters));
}