Make it possible to enable/disable receive-side RTT with a setter.
This will allow us to enable receive-side RTT without having to recreate all AudioReceiveStream objects.
Bug: webrtc:12951
Change-Id: I1227297ec4ebeea9ba15fe2ed904349829b2e669
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/225262
Commit-Queue: Ivo Creusen <ivoc@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Jakob Ivarsson <jakobi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34464}
diff --git a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
index a7707ec..59b8cf1 100644
--- a/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
+++ b/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h
@@ -66,6 +66,7 @@
MOCK_METHOD(void, SetSequenceNumber, (uint16_t seq), (override));
MOCK_METHOD(void, SetRtpState, (const RtpState& rtp_state), (override));
MOCK_METHOD(void, SetRtxState, (const RtpState& rtp_state), (override));
+ MOCK_METHOD(void, SetNonSenderRttMeasurement, (bool enabled), (override));
MOCK_METHOD(RtpState, GetRtpState, (), (const, override));
MOCK_METHOD(RtpState, GetRtxState, (), (const, override));
MOCK_METHOD(uint32_t, SSRC, (), (const, override));
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.cc b/modules/rtp_rtcp/source/rtcp_receiver.cc
index 3ab78df..a8e1dc5 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver.cc
@@ -303,6 +303,11 @@
return 0;
}
+void RTCPReceiver::SetNonSenderRttMeasurement(bool enabled) {
+ MutexLock lock(&rtcp_receiver_lock_);
+ xr_rrtr_status_ = enabled;
+}
+
bool RTCPReceiver::GetAndResetXrRrRtt(int64_t* rtt_ms) {
RTC_DCHECK(rtt_ms);
MutexLock lock(&rtcp_receiver_lock_);
diff --git a/modules/rtp_rtcp/source/rtcp_receiver.h b/modules/rtp_rtcp/source/rtcp_receiver.h
index fa9f367..206b63a 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver.h
+++ b/modules/rtp_rtcp/source/rtcp_receiver.h
@@ -108,6 +108,7 @@
int64_t* min_rtt_ms,
int64_t* max_rtt_ms) const;
+ void SetNonSenderRttMeasurement(bool enabled);
bool GetAndResetXrRrRtt(int64_t* rtt_ms);
// Called once per second on the worker thread to do rtt calculations.
@@ -371,7 +372,7 @@
received_rrtrs_ssrc_it_ RTC_GUARDED_BY(rtcp_receiver_lock_);
// Estimated rtt, zero when there is no valid estimate.
- const bool xr_rrtr_status_;
+ bool xr_rrtr_status_ RTC_GUARDED_BY(rtcp_receiver_lock_);
int64_t xr_rr_rtt_ms_;
int64_t oldest_tmmbr_info_ms_ RTC_GUARDED_BY(rtcp_receiver_lock_);
diff --git a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
index 3065534..e61ae64 100644
--- a/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_receiver_unittest.cc
@@ -11,6 +11,7 @@
#include "modules/rtp_rtcp/source/rtcp_receiver.h"
#include <memory>
+#include <set>
#include <utility>
#include "api/array_view.h"
@@ -939,6 +940,64 @@
EXPECT_NEAR(kRttMs, rtt_ms, 1);
}
+// Same test as above but enables receive-side RTT using the setter instead of
+// the config struct.
+TEST(RtcpReceiverTest, SetterEnablesReceiverRtt) {
+ ReceiverMocks mocks;
+ auto config = DefaultConfiguration(&mocks);
+ config.non_sender_rtt_measurement = false;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+ receiver.SetNonSenderRttMeasurement(true);
+
+ Random rand(0x0123456789abcdef);
+ const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
+ const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
+ const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
+ NtpTime now = mocks.clock.CurrentNtpTime();
+ uint32_t sent_ntp = CompactNtp(now);
+ mocks.clock.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
+
+ rtcp::ExtendedReports xr;
+ xr.SetSenderSsrc(kSenderSsrc);
+ xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
+
+ receiver.IncomingPacket(xr.Build());
+
+ int64_t rtt_ms = 0;
+ EXPECT_TRUE(receiver.GetAndResetXrRrRtt(&rtt_ms));
+ EXPECT_NEAR(rtt_ms, kRttMs, 1);
+}
+
+// Same test as above but disables receive-side RTT using the setter instead of
+// the config struct.
+TEST(RtcpReceiverTest, DoesntCalculateRttOnReceivedDlrr) {
+ ReceiverMocks mocks;
+ auto config = DefaultConfiguration(&mocks);
+ config.non_sender_rtt_measurement = true;
+ RTCPReceiver receiver(config, &mocks.rtp_rtcp_impl);
+ receiver.SetRemoteSSRC(kSenderSsrc);
+ receiver.SetNonSenderRttMeasurement(false);
+
+ Random rand(0x0123456789abcdef);
+ const int64_t kRttMs = rand.Rand(1, 9 * 3600 * 1000);
+ const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
+ const int64_t kDelayMs = CompactNtpRttToMs(kDelayNtp);
+ NtpTime now = mocks.clock.CurrentNtpTime();
+ uint32_t sent_ntp = CompactNtp(now);
+ mocks.clock.AdvanceTimeMilliseconds(kRttMs + kDelayMs);
+
+ rtcp::ExtendedReports xr;
+ xr.SetSenderSsrc(kSenderSsrc);
+ xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));
+
+ receiver.IncomingPacket(xr.Build());
+
+ // We expect that no RTT is available (because receive-side RTT was disabled).
+ int64_t rtt_ms = 0;
+ EXPECT_FALSE(receiver.GetAndResetXrRrRtt(&rtt_ms));
+}
+
TEST(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOne) {
ReceiverMocks mocks;
auto config = DefaultConfiguration(&mocks);
diff --git a/modules/rtp_rtcp/source/rtcp_sender.cc b/modules/rtp_rtcp/source/rtcp_sender.cc
index 8f5e3b1..7f5e327 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender.cc
@@ -231,6 +231,11 @@
}
}
+void RTCPSender::SetNonSenderRttMeasurement(bool enabled) {
+ MutexLock lock(&mutex_rtcp_sender_);
+ xr_send_receiver_reference_time_enabled_ = enabled;
+}
+
int32_t RTCPSender::SendLossNotification(const FeedbackState& feedback_state,
uint16_t last_decoded_seq_num,
uint16_t last_received_seq_num,
diff --git a/modules/rtp_rtcp/source/rtcp_sender.h b/modules/rtp_rtcp/source/rtcp_sender.h
index 2d1c7da..133eb83 100644
--- a/modules/rtp_rtcp/source/rtcp_sender.h
+++ b/modules/rtp_rtcp/source/rtcp_sender.h
@@ -118,7 +118,8 @@
bool enabled)
RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_); // combine the functions
- int32_t SetNackStatus(bool enable) RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_);
+ void SetNonSenderRttMeasurement(bool enabled)
+ RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_);
void SetTimestampOffset(uint32_t timestamp_offset)
RTC_LOCKS_EXCLUDED(mutex_rtcp_sender_);
@@ -282,7 +283,8 @@
size_t max_packet_size_ RTC_GUARDED_BY(mutex_rtcp_sender_);
// True if sending of XR Receiver reference time report is enabled.
- const bool xr_send_receiver_reference_time_enabled_;
+ bool xr_send_receiver_reference_time_enabled_
+ RTC_GUARDED_BY(mutex_rtcp_sender_);
RtcpPacketTypeCounterObserver* const packet_type_counter_observer_;
RtcpPacketTypeCounter packet_type_counter_ RTC_GUARDED_BY(mutex_rtcp_sender_);
diff --git a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
index 347be79..d05d8d6 100644
--- a/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
+++ b/modules/rtp_rtcp/source/rtcp_sender_unittest.cc
@@ -531,6 +531,35 @@
EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
}
+// Same test as above, but enable Rrtr with the setter.
+TEST_F(RtcpSenderTest, SendXrWithRrtrUsingSetter) {
+ RTCPSender::Configuration config = GetDefaultConfig();
+ config.non_sender_rtt_measurement = false;
+ auto rtcp_sender = CreateRtcpSender(config);
+ rtcp_sender->SetNonSenderRttMeasurement(true);
+ rtcp_sender->SetRTCPStatus(RtcpMode::kCompound);
+ rtcp_sender->SetSendingStatus(feedback_state(), false);
+ NtpTime ntp = clock_.CurrentNtpTime();
+ EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport));
+ EXPECT_EQ(1, parser()->xr()->num_packets());
+ EXPECT_EQ(kSenderSsrc, parser()->xr()->sender_ssrc());
+ EXPECT_FALSE(parser()->xr()->dlrr());
+ ASSERT_TRUE(parser()->xr()->rrtr());
+ EXPECT_EQ(ntp, parser()->xr()->rrtr()->ntp());
+}
+
+// Same test as above, but disable Rrtr with the setter.
+TEST_F(RtcpSenderTest, SendsNoRrtrUsingSetter) {
+ RTCPSender::Configuration config = GetDefaultConfig();
+ config.non_sender_rtt_measurement = true;
+ auto rtcp_sender = CreateRtcpSender(config);
+ rtcp_sender->SetNonSenderRttMeasurement(false);
+ rtcp_sender->SetRTCPStatus(RtcpMode::kCompound);
+ rtcp_sender->SetSendingStatus(feedback_state(), false);
+ EXPECT_EQ(0, rtcp_sender->SendRTCP(feedback_state(), kRtcpReport));
+ EXPECT_EQ(0, parser()->xr()->num_packets());
+}
+
TEST_F(RtcpSenderTest, TestNoXrRrtrSentIfSending) {
RTCPSender::Configuration config = GetDefaultConfig();
config.non_sender_rtt_measurement = true;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl.h b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
index b0e0b41..932a02d 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl.h
@@ -97,6 +97,8 @@
RtpState GetRtpState() const override;
RtpState GetRtxState() const override;
+ void SetNonSenderRttMeasurement(bool enabled) override {}
+
uint32_t SSRC() const override { return rtcp_sender_.SSRC(); }
void SetRid(const std::string& rid) override;
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
index 7fae1e3..c6d1977 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.cc
@@ -103,14 +103,11 @@
// webrtc::VideoSendStream::Config::Rtp::kDefaultMaxPacketSize.
const size_t kTcpOverIpv4HeaderSize = 40;
SetMaxRtpPacketSize(IP_PACKET_SIZE - kTcpOverIpv4HeaderSize);
-
- if (rtt_stats_) {
- rtt_update_task_ = RepeatingTaskHandle::DelayedStart(
- worker_queue_, kRttUpdateInterval, [this]() {
- PeriodicUpdate();
- return kRttUpdateInterval;
- });
- }
+ rtt_update_task_ = RepeatingTaskHandle::DelayedStart(
+ worker_queue_, kRttUpdateInterval, [this]() {
+ PeriodicUpdate();
+ return kRttUpdateInterval;
+ });
}
ModuleRtpRtcpImpl2::~ModuleRtpRtcpImpl2() {
@@ -204,6 +201,11 @@
return rtp_sender_->packet_generator.GetRtxRtpState();
}
+void ModuleRtpRtcpImpl2::SetNonSenderRttMeasurement(bool enabled) {
+ rtcp_sender_.SetNonSenderRttMeasurement(enabled);
+ rtcp_receiver_.SetNonSenderRttMeasurement(enabled);
+}
+
uint32_t ModuleRtpRtcpImpl2::local_media_ssrc() const {
RTC_DCHECK_RUN_ON(&packet_sequence_checker_);
RTC_DCHECK_EQ(rtcp_receiver_.local_media_ssrc(), rtcp_sender_.SSRC());
@@ -739,7 +741,9 @@
absl::optional<TimeDelta> rtt =
rtcp_receiver_.OnPeriodicRttUpdate(check_since, rtcp_sender_.Sending());
if (rtt) {
- rtt_stats_->OnRttUpdate(rtt->ms());
+ if (rtt_stats_) {
+ rtt_stats_->OnRttUpdate(rtt->ms());
+ }
set_rtt_ms(rtt->ms());
}
}
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_impl2.h b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
index 0ad4955..0440879 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_impl2.h
@@ -104,6 +104,8 @@
RtpState GetRtpState() const override;
RtpState GetRtxState() const override;
+ void SetNonSenderRttMeasurement(bool enabled) override;
+
uint32_t SSRC() const override { return rtcp_sender_.SSRC(); }
// Semantically identical to `SSRC()` but must be called on the packet
diff --git a/modules/rtp_rtcp/source/rtp_rtcp_interface.h b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
index dd5744e..5961b3d 100644
--- a/modules/rtp_rtcp/source/rtp_rtcp_interface.h
+++ b/modules/rtp_rtcp/source/rtp_rtcp_interface.h
@@ -237,6 +237,9 @@
virtual RtpState GetRtpState() const = 0;
virtual RtpState GetRtxState() const = 0;
+ // This can be used to enable/disable receive-side RTT.
+ virtual void SetNonSenderRttMeasurement(bool enabled) = 0;
+
// Returns SSRC.
virtual uint32_t SSRC() const = 0;