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}
This commit is contained in:
Ivo Creusen 2021-07-13 12:53:22 +00:00 committed by WebRTC LUCI CQ
parent 51969310ef
commit 8c40d510c8
11 changed files with 125 additions and 12 deletions

View File

@ -66,6 +66,7 @@ class MockRtpRtcpInterface : public RtpRtcpInterface {
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));

View File

@ -303,6 +303,11 @@ int32_t RTCPReceiver::RTT(uint32_t remote_ssrc,
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_);

View File

@ -108,6 +108,7 @@ class RTCPReceiver final {
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 @@ class RTCPReceiver final {
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_);

View File

@ -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 @@ TEST(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
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);

View File

@ -231,6 +231,11 @@ void RTCPSender::SetSendingStatus(const FeedbackState& feedback_state,
}
}
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,

View File

@ -118,7 +118,8 @@ class RTCPSender final {
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 @@ class RTCPSender final {
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_);

View File

@ -531,6 +531,35 @@ TEST_F(RtcpSenderTest, SendXrWithRrtr) {
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;

View File

@ -97,6 +97,8 @@ class ModuleRtpRtcpImpl : public RtpRtcp, public RTCPReceiver::ModuleRtpRtcp {
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;

View File

@ -103,14 +103,11 @@ ModuleRtpRtcpImpl2::ModuleRtpRtcpImpl2(const Configuration& configuration)
// 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 @@ RtpState ModuleRtpRtcpImpl2::GetRtxState() const {
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 @@ void ModuleRtpRtcpImpl2::PeriodicUpdate() {
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());
}
}

View File

@ -104,6 +104,8 @@ class ModuleRtpRtcpImpl2 final : public RtpRtcpInterface,
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

View File

@ -237,6 +237,9 @@ class RtpRtcpInterface : public RtcpFeedbackSenderInterface {
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;