diff --git a/call/call.cc b/call/call.cc index ed5ee1bc18..fe2dbb628b 100644 --- a/call/call.cc +++ b/call/call.cc @@ -266,6 +266,10 @@ class Call final : public webrtc::Call, void OnLocalSsrcUpdated(webrtc::AudioReceiveStream& stream, uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(VideoReceiveStream& stream, + uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(FlexfecReceiveStream& stream, + uint32_t local_ssrc) override; void OnUpdateSyncGroup(webrtc::AudioReceiveStream& stream, const std::string& sync_group) override; @@ -415,6 +419,8 @@ class Call final : public webrtc::Call, RTC_GUARDED_BY(&receive_11993_checker_); // Audio and Video send streams are owned by the client that creates them. + // TODO(bugs.webrtc.org/11993): `audio_send_ssrcs_` and `video_send_ssrcs_` + // should be accessed on the network thread. std::map audio_send_ssrcs_ RTC_GUARDED_BY(worker_thread_); std::map video_send_ssrcs_ @@ -1386,6 +1392,17 @@ void Call::OnLocalSsrcUpdated(webrtc::AudioReceiveStream& stream, : nullptr); } +void Call::OnLocalSsrcUpdated(VideoReceiveStream& stream, uint32_t local_ssrc) { + RTC_DCHECK_RUN_ON(worker_thread_); + static_cast(stream).SetLocalSsrc(local_ssrc); +} + +void Call::OnLocalSsrcUpdated(FlexfecReceiveStream& stream, + uint32_t local_ssrc) { + RTC_DCHECK_RUN_ON(worker_thread_); + static_cast(stream).SetLocalSsrc(local_ssrc); +} + void Call::OnUpdateSyncGroup(webrtc::AudioReceiveStream& stream, const std::string& sync_group) { RTC_DCHECK_RUN_ON(worker_thread_); diff --git a/call/call.h b/call/call.h index 9d6d4ee11a..65bd5f2f23 100644 --- a/call/call.h +++ b/call/call.h @@ -165,6 +165,10 @@ class Call { // send streams needs to be updated. virtual void OnLocalSsrcUpdated(AudioReceiveStream& stream, uint32_t local_ssrc) = 0; + virtual void OnLocalSsrcUpdated(VideoReceiveStream& stream, + uint32_t local_ssrc) = 0; + virtual void OnLocalSsrcUpdated(FlexfecReceiveStream& stream, + uint32_t local_ssrc) = 0; virtual void OnUpdateSyncGroup(AudioReceiveStream& stream, const std::string& sync_group) = 0; diff --git a/call/degraded_call.cc b/call/degraded_call.cc index 3790c78927..e6dd3618e2 100644 --- a/call/degraded_call.cc +++ b/call/degraded_call.cc @@ -304,6 +304,16 @@ void DegradedCall::OnLocalSsrcUpdated(AudioReceiveStream& stream, call_->OnLocalSsrcUpdated(stream, local_ssrc); } +void DegradedCall::OnLocalSsrcUpdated(VideoReceiveStream& stream, + uint32_t local_ssrc) { + call_->OnLocalSsrcUpdated(stream, local_ssrc); +} + +void DegradedCall::OnLocalSsrcUpdated(FlexfecReceiveStream& stream, + uint32_t local_ssrc) { + call_->OnLocalSsrcUpdated(stream, local_ssrc); +} + void DegradedCall::OnUpdateSyncGroup(AudioReceiveStream& stream, const std::string& sync_group) { call_->OnUpdateSyncGroup(stream, sync_group); diff --git a/call/degraded_call.h b/call/degraded_call.h index 59f5236593..586bb91701 100644 --- a/call/degraded_call.h +++ b/call/degraded_call.h @@ -100,6 +100,10 @@ class DegradedCall : public Call, private PacketReceiver { int transport_overhead_per_packet) override; void OnLocalSsrcUpdated(AudioReceiveStream& stream, uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(VideoReceiveStream& stream, + uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(FlexfecReceiveStream& stream, + uint32_t local_ssrc) override; void OnUpdateSyncGroup(AudioReceiveStream& stream, const std::string& sync_group) override; void OnSentPacket(const rtc::SentPacket& sent_packet) override; diff --git a/call/flexfec_receive_stream_impl.cc b/call/flexfec_receive_stream_impl.cc index 6f2b5dcad7..59add821d1 100644 --- a/call/flexfec_receive_stream_impl.cc +++ b/call/flexfec_receive_stream_impl.cc @@ -213,4 +213,14 @@ RtpHeaderExtensionMap FlexfecReceiveStreamImpl::GetRtpExtensionMap() const { return extension_map_; } +void FlexfecReceiveStreamImpl::SetLocalSsrc(uint32_t local_ssrc) { + RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + if (local_ssrc == config_.rtp.local_ssrc) + return; + + auto& c = const_cast(config_); + c.rtp.local_ssrc = local_ssrc; + rtp_rtcp_->SetLocalSsrc(local_ssrc); +} + } // namespace webrtc diff --git a/call/flexfec_receive_stream_impl.h b/call/flexfec_receive_stream_impl.h index e25b7f09c2..857715a941 100644 --- a/call/flexfec_receive_stream_impl.h +++ b/call/flexfec_receive_stream_impl.h @@ -62,6 +62,10 @@ class FlexfecReceiveStreamImpl : public FlexfecReceiveStream { void SetRtpExtensions(std::vector extensions) override; RtpHeaderExtensionMap GetRtpExtensionMap() const override; + // Updates the `rtp_video_stream_receiver_`'s `local_ssrc` when the default + // sender has been created, changed or removed. + void SetLocalSsrc(uint32_t local_ssrc); + uint32_t remote_ssrc() const { return config_.rtp.remote_ssrc; } bool transport_cc() const override { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); @@ -73,8 +77,8 @@ class FlexfecReceiveStreamImpl : public FlexfecReceiveStream { RtpHeaderExtensionMap extension_map_; - // Config. Mostly const, header extensions may change, which is an exception - // case that's specifically handled in `SetRtpExtensions`, which must be + // Config. Mostly const, local_ssrc may change, which is an exception + // case that's specifically handled in `SetLocalSsrc`, which must be // called on the `packet_sequence_checker` thread. const Config config_; diff --git a/media/engine/fake_webrtc_call.cc b/media/engine/fake_webrtc_call.cc index 19a4ad2199..0cbbf7cf42 100644 --- a/media/engine/fake_webrtc_call.cc +++ b/media/engine/fake_webrtc_call.cc @@ -715,6 +715,18 @@ void FakeCall::OnLocalSsrcUpdated(webrtc::AudioReceiveStream& stream, fake_stream.SetLocalSsrc(local_ssrc); } +void FakeCall::OnLocalSsrcUpdated(webrtc::VideoReceiveStream& stream, + uint32_t local_ssrc) { + auto& fake_stream = static_cast(stream); + fake_stream.SetLocalSsrc(local_ssrc); +} + +void FakeCall::OnLocalSsrcUpdated(webrtc::FlexfecReceiveStream& stream, + uint32_t local_ssrc) { + auto& fake_stream = static_cast(stream); + fake_stream.SetLocalSsrc(local_ssrc); +} + void FakeCall::OnUpdateSyncGroup(webrtc::AudioReceiveStream& stream, const std::string& sync_group) { auto& fake_stream = static_cast(stream); diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h index c26f7b1ddf..8a3e22614f 100644 --- a/media/engine/fake_webrtc_call.h +++ b/media/engine/fake_webrtc_call.h @@ -250,6 +250,10 @@ class FakeVideoReceiveStream final : public webrtc::VideoReceiveStream { return base_mininum_playout_delay_ms_; } + void SetLocalSsrc(uint32_t local_ssrc) { + config_.rtp.local_ssrc = local_ssrc; + } + void SetFrameDecryptor(rtc::scoped_refptr frame_decryptor) override {} @@ -295,6 +299,10 @@ class FakeFlexfecReceiveStream final : public webrtc::FlexfecReceiveStream { explicit FakeFlexfecReceiveStream( const webrtc::FlexfecReceiveStream::Config config); + void SetLocalSsrc(uint32_t local_ssrc) { + config_.rtp.local_ssrc = local_ssrc; + } + void SetRtpExtensions(std::vector extensions) override; webrtc::RtpHeaderExtensionMap GetRtpExtensionMap() const override; bool transport_cc() const override { return config_.rtp.transport_cc; } @@ -411,6 +419,10 @@ class FakeCall final : public webrtc::Call, public webrtc::PacketReceiver { int transport_overhead_per_packet) override; void OnLocalSsrcUpdated(webrtc::AudioReceiveStream& stream, uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(webrtc::VideoReceiveStream& stream, + uint32_t local_ssrc) override; + void OnLocalSsrcUpdated(webrtc::FlexfecReceiveStream& stream, + uint32_t local_ssrc) override; void OnUpdateSyncGroup(webrtc::AudioReceiveStream& stream, const std::string& sync_group) override; void OnSentPacket(const rtc::SentPacket& sent_packet) override; diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index e29d1ea66e..4c19f9c666 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1241,6 +1241,20 @@ std::string WebRtcVideoChannel::CodecSettingsVectorToString( return out.Release(); } +// RTC_RUN_ON(&thread_checker_) +void WebRtcVideoChannel::SetReceiverReportSsrc(uint32_t ssrc) { + if (ssrc == rtcp_receiver_report_ssrc_) + return; + + rtcp_receiver_report_ssrc_ = ssrc; + for (auto& [unused, receive_stream] : receive_streams_) { + call_->OnLocalSsrcUpdated(receive_stream->stream(), ssrc); + webrtc::FlexfecReceiveStream* flex_fec = receive_stream->flexfec_stream(); + if (flex_fec) + call_->OnLocalSsrcUpdated(*flex_fec, ssrc); + } +} + bool WebRtcVideoChannel::GetSendCodec(VideoCodec* codec) { RTC_DCHECK_RUN_ON(&thread_checker_); if (!send_codec_) { @@ -1353,13 +1367,9 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) { send_streams_[ssrc] = stream; if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) { - rtcp_receiver_report_ssrc_ = ssrc; - RTC_LOG(LS_INFO) - << "SetLocalSsrc on all the receive streams because we added " - "a send stream."; - for (auto& kv : receive_streams_) - kv.second->SetLocalSsrc(ssrc); + SetReceiverReportSsrc(ssrc); } + if (sending_) { stream->SetSend(true); } @@ -1386,15 +1396,8 @@ bool WebRtcVideoChannel::RemoveSendStream(uint32_t ssrc) { // Switch receiver report SSRCs, the one in use is no longer valid. if (rtcp_receiver_report_ssrc_ == ssrc) { - rtcp_receiver_report_ssrc_ = send_streams_.empty() - ? kDefaultRtcpReceiverReportSsrc - : send_streams_.begin()->first; - RTC_LOG(LS_INFO) << "SetLocalSsrc on all the receive streams because the " - "previous local SSRC was removed."; - - for (auto& kv : receive_streams_) { - kv.second->SetLocalSsrc(rtcp_receiver_report_ssrc_); - } + SetReceiverReportSsrc(send_streams_.empty() ? kDefaultRtcpReceiverReportSsrc + : send_streams_.begin()->first); } delete removed_stream; @@ -2803,7 +2806,7 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::WebRtcVideoReceiveStream( config_.renderer = this; ConfigureCodecs(recv_codecs); flexfec_config_.payload_type = flexfec_config.payload_type; - RecreateWebRtcVideoStream(); + RecreateReceiveStream(); } WebRtcVideoChannel::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { @@ -2812,6 +2815,17 @@ WebRtcVideoChannel::WebRtcVideoReceiveStream::~WebRtcVideoReceiveStream() { call_->DestroyFlexfecReceiveStream(flexfec_stream_); } +webrtc::VideoReceiveStream& +WebRtcVideoChannel::WebRtcVideoReceiveStream::stream() { + RTC_DCHECK(stream_); + return *stream_; +} + +webrtc::FlexfecReceiveStream* +WebRtcVideoChannel::WebRtcVideoReceiveStream::flexfec_stream() { + return flexfec_stream_; +} + const std::vector& WebRtcVideoChannel::WebRtcVideoReceiveStream::GetSsrcs() const { return stream_params_.ssrcs; @@ -2921,27 +2935,6 @@ bool WebRtcVideoChannel::WebRtcVideoReceiveStream::ConfigureCodecs( return recreate_needed; } -void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetLocalSsrc( - uint32_t local_ssrc) { - // TODO(pbos): Consider turning this sanity check into a RTC_DCHECK. You - // should not be able to create a sender with the same SSRC as a receiver, but - // right now this can't be done due to unittests depending on receiving what - // they are sending from the same MediaChannel. - if (local_ssrc == config_.rtp.local_ssrc) { - RTC_DLOG(LS_INFO) << "Ignoring call to SetLocalSsrc because parameters are " - "unchanged; local_ssrc=" - << local_ssrc; - return; - } - - config_.rtp.local_ssrc = local_ssrc; - flexfec_config_.rtp.local_ssrc = local_ssrc; - RTC_LOG(LS_INFO) - << "RecreateWebRtcVideoStream (recv) because of SetLocalSsrc; local_ssrc=" - << local_ssrc; - RecreateWebRtcVideoStream(); -} - void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetFeedbackParameters( bool lntf_enabled, bool nack_enabled, @@ -2970,10 +2963,10 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetFeedbackParameters( // based on the rtcp-fb for the FlexFEC codec, not the media codec. flexfec_config_.rtp.transport_cc = config_.rtp.transport_cc; flexfec_config_.rtcp_mode = config_.rtp.rtcp_mode; - RTC_LOG(LS_INFO) << "RecreateWebRtcVideoStream (recv) because of " + RTC_LOG(LS_INFO) << "RecreateReceiveStream (recv) because of " "SetFeedbackParameters; nack=" << nack_enabled << ", transport_cc=" << transport_cc_enabled; - RecreateWebRtcVideoStream(); + RecreateReceiveStream(); } void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters( @@ -3012,11 +3005,11 @@ void WebRtcVideoChannel::WebRtcVideoReceiveStream::SetRecvParameters( video_needs_recreation = true; } if (video_needs_recreation) { - RecreateWebRtcVideoStream(); + RecreateReceiveStream(); } } -void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateWebRtcVideoStream() { +void WebRtcVideoChannel::WebRtcVideoReceiveStream::RecreateReceiveStream() { absl::optional base_minimum_playout_delay_ms; absl::optional recording_state; if (stream_) { diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index f70ebca334..62a2654615 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -316,6 +316,10 @@ class WebRtcVideoChannel : public VideoMediaChannel, static std::string CodecSettingsVectorToString( const std::vector& codecs); + // Called when the local ssrc changes. Sets `rtcp_receiver_report_ssrc_` and + // updates the receive streams. + void SetReceiverReportSsrc(uint32_t ssrc) RTC_RUN_ON(&thread_checker_); + // Wrapper for the sender part. class WebRtcVideoSendStream { public: @@ -438,6 +442,10 @@ class WebRtcVideoChannel : public VideoMediaChannel, const webrtc::FlexfecReceiveStream::Config& flexfec_config); ~WebRtcVideoReceiveStream(); + webrtc::VideoReceiveStream& stream(); + // Return value may be nullptr. + webrtc::FlexfecReceiveStream* flexfec_stream(); + const std::vector& GetSsrcs() const; std::vector GetSources(); @@ -445,7 +453,6 @@ class WebRtcVideoChannel : public VideoMediaChannel, // Does not return codecs, they are filled by the owning WebRtcVideoChannel. webrtc::RtpParameters GetRtpParameters() const; - void SetLocalSsrc(uint32_t local_ssrc); // TODO(deadbeef): Move these feedback parameters into the recv parameters. void SetFeedbackParameters(bool lntf_enabled, bool nack_enabled, @@ -478,7 +485,7 @@ class WebRtcVideoChannel : public VideoMediaChannel, frame_transformer); private: - void RecreateWebRtcVideoStream(); + void RecreateReceiveStream(); // Applies a new receive codecs configration to `config_`. Returns true // if the internal stream needs to be reconstructed, or false if no changes diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc index 886d1bdd6f..c4dd7c0818 100644 --- a/video/rtp_video_stream_receiver2.cc +++ b/video/rtp_video_stream_receiver2.cc @@ -923,6 +923,11 @@ void RtpVideoStreamReceiver2::UpdateRtt(int64_t max_rtt_ms) { nack_module_->UpdateRtt(max_rtt_ms); } +void RtpVideoStreamReceiver2::OnLocalSsrcChange(uint32_t local_ssrc) { + RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + rtp_rtcp_->SetLocalSsrc(local_ssrc); +} + absl::optional RtpVideoStreamReceiver2::LastReceivedPacketMs() const { RTC_DCHECK_RUN_ON(&packet_sequence_checker_); if (last_received_rtp_system_time_) { diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h index 4658401fa5..b0c7eab294 100644 --- a/video/rtp_video_stream_receiver2.h +++ b/video/rtp_video_stream_receiver2.h @@ -184,6 +184,9 @@ class RtpVideoStreamReceiver2 : public LossNotificationSender, // Called by VideoReceiveStream when stats are updated. void UpdateRtt(int64_t max_rtt_ms); + // Called when the local_ssrc is changed to match with a sender. + void OnLocalSsrcChange(uint32_t local_ssrc); + absl::optional LastReceivedPacketMs() const; absl::optional LastReceivedKeyframePacketMs() const; diff --git a/video/video_receive_stream2.cc b/video/video_receive_stream2.cc index 96c13a9b10..47c1634d8a 100644 --- a/video/video_receive_stream2.cc +++ b/video/video_receive_stream2.cc @@ -341,6 +341,16 @@ void VideoReceiveStream2::SetSync(Syncable* audio_syncable) { rtp_stream_sync_.ConfigureSync(audio_syncable); } +void VideoReceiveStream2::SetLocalSsrc(uint32_t local_ssrc) { + RTC_DCHECK_RUN_ON(&packet_sequence_checker_); + if (config_.rtp.local_ssrc == local_ssrc) + return; + + // TODO(tommi): Make sure we don't rely on local_ssrc via the config struct. + const_cast(config_.rtp.local_ssrc) = local_ssrc; + rtp_video_stream_receiver_.OnLocalSsrcChange(local_ssrc); +} + void VideoReceiveStream2::Start() { RTC_DCHECK_RUN_ON(&worker_sequence_checker_); @@ -476,9 +486,8 @@ void VideoReceiveStream2::SetRtpExtensions( // and guarded by `packet_sequence_checker_`. However the scope of that state // is huge (the whole Config struct), and would require all methods that touch // the struct to abide the needs of the `extensions` member. - VideoReceiveStream::Config& c = - const_cast(config_); - c.rtp.extensions = std::move(extensions); + const_cast&>(config_.rtp.extensions) = + std::move(extensions); } RtpHeaderExtensionMap VideoReceiveStream2::GetRtpExtensionMap() const { diff --git a/video/video_receive_stream2.h b/video/video_receive_stream2.h index d5b2b18df2..184fd20dfd 100644 --- a/video/video_receive_stream2.h +++ b/video/video_receive_stream2.h @@ -131,6 +131,10 @@ class VideoReceiveStream2 void SetSync(Syncable* audio_syncable); + // Updates the `rtp_video_stream_receiver_`'s `local_ssrc` when the default + // sender has been created, changed or removed. + void SetLocalSsrc(uint32_t local_ssrc); + // Implements webrtc::VideoReceiveStream. void Start() override; void Stop() override;