Make sure SetSsrc clears non-empty encodings and degradation_preference This regressed in https://webrtc-review.googlesource.com/c/src/+/442922 Bug: webrtc:500993975 Change-Id: I6400b3bc1f5fbc8f5d809c6cecc4d52e11274669 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/462527 Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Reviewed-by: Per Kjellander <perkj@webrtc.org> Cr-Commit-Position: refs/heads/main@{#47405}
diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc index 3edc511..ca1400b 100644 --- a/pc/rtp_sender.cc +++ b/pc/rtp_sender.cc
@@ -740,41 +740,49 @@ AddTrackToStats(); } - const bool update_parameters = - (ssrc_ != 0 && (!init_parameters_.encodings.empty() || - init_parameters_.degradation_preference.has_value())); RtpParameters current_parameters; bool params_modified = false; worker_thread_->BlockingCall([&, ssrc = ssrc_] { RTC_DCHECK_RUN_ON(worker_thread_); - if (update_parameters) { - RTC_DCHECK(media_channel_); - // Get the current parameters, which are constructed from the SDP. The - // number of layers in the SDP is currently authoritative to support SDP - // munging for Plan-B simulcast with "a=ssrc-group:SIM <ssrc-id>..." lines - // as described in RFC 5576. All fields should be default constructed and - // the SSRC field set, which we need to copy. - current_parameters = media_channel_->GetRtpSendParameters(ssrc); - // SSRC 0 has special meaning as "no stream". In this case, - // current_parameters may have size 0. - RTC_CHECK_GE(current_parameters.encodings.size(), - init_parameters_.encodings.size()); - for (size_t i = 0; i < init_parameters_.encodings.size(); ++i) { - init_parameters_.encodings[i].ssrc = - current_parameters.encodings[i].ssrc; - init_parameters_.encodings[i].rid = current_parameters.encodings[i].rid; - current_parameters.encodings[i] = init_parameters_.encodings[i]; - } - current_parameters.degradation_preference = - init_parameters_.degradation_preference; - params_modified = - media_channel_ - ->SetRtpSendParameters(ssrc, current_parameters, nullptr) - .ok(); - if (params_modified) { - // The parameters may change as they're applied. + if (!init_parameters_.encodings.empty() || + init_parameters_.degradation_preference.has_value()) { + if (ssrc != 0) { + RTC_DCHECK(media_channel_); + // Get the current parameters, which are constructed from the SDP. The + // number of layers in the SDP is currently authoritative to support SDP + // munging for Plan-B simulcast with "a=ssrc-group:SIM <ssrc-id>..." + // lines as described in RFC 5576. All fields should be default + // constructed and the SSRC field set, which we need to copy. current_parameters = media_channel_->GetRtpSendParameters(ssrc); + // SSRC 0 has special meaning as "no stream". In this case, + // current_parameters may have size 0. + RTC_CHECK_GE(current_parameters.encodings.size(), + init_parameters_.encodings.size()); + for (size_t i = 0; i < init_parameters_.encodings.size(); ++i) { + init_parameters_.encodings[i].ssrc = + current_parameters.encodings[i].ssrc; + init_parameters_.encodings[i].rid = + current_parameters.encodings[i].rid; + current_parameters.encodings[i] = init_parameters_.encodings[i]; + } + current_parameters.degradation_preference = + init_parameters_.degradation_preference; + params_modified = + media_channel_ + ->SetRtpSendParameters(ssrc, current_parameters, nullptr) + .ok(); + if (params_modified) { + // The parameters may change as they're applied. + current_parameters = media_channel_->GetRtpSendParameters(ssrc); + } } + // Clear the `init_parameters_` after they have been applied to the + // media channel. This prevents stale values from being used in + // subsequent calls to `SetSsrc`, which could happen if `SetSsrc` is + // called multiple times on the same sender. See + // https://issues.webrtc.org/issues/500993975 for details. + init_parameters_.encodings.clear(); + init_parameters_.degradation_preference = std::nullopt; } // While we're on the worker thread, attach the frame decryptor, transformer