Index: webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc |
diff --git a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc |
index f0b6411af2711ffc3d2d39c446774268e5ecebec..99cef009e733a38b9727ddeeb0305951005751dd 100644 |
--- a/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc |
+++ b/webrtc/modules/rtp_rtcp/source/rtp_sender_unittest.cc |
@@ -15,6 +15,7 @@ |
#include "testing/gmock/include/gmock/gmock.h" |
#include "testing/gtest/include/gtest/gtest.h" |
#include "webrtc/base/buffer.h" |
+#include "webrtc/base/rate_limiter.h" |
#include "webrtc/call/mock/mock_rtc_event_log.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_cvo.h" |
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h" |
@@ -133,11 +134,11 @@ |
: fake_clock_(kStartTime), |
mock_rtc_event_log_(), |
mock_paced_sender_(), |
+ retransmission_rate_limiter_(&fake_clock_, 1000), |
rtp_sender_(), |
payload_(kPayload), |
transport_(), |
- kMarkerBit(true) { |
- } |
+ kMarkerBit(true) {} |
void SetUp() override { SetUpRtpSender(true); } |
@@ -145,7 +146,8 @@ |
rtp_sender_.reset(new RTPSender( |
false, &fake_clock_, &transport_, pacer ? &mock_paced_sender_ : nullptr, |
&seq_num_allocator_, nullptr, nullptr, nullptr, nullptr, |
- &mock_rtc_event_log_, &send_packet_observer_)); |
+ &mock_rtc_event_log_, &send_packet_observer_, |
+ &retransmission_rate_limiter_)); |
rtp_sender_->SetSequenceNumber(kSeqNum); |
} |
@@ -154,6 +156,7 @@ |
MockRtpPacketSender mock_paced_sender_; |
MockTransportSequenceNumberAllocator seq_num_allocator_; |
MockSendPacketObserver send_packet_observer_; |
+ RateLimiter retransmission_rate_limiter_; |
std::unique_ptr<RTPSender> rtp_sender_; |
int payload_; |
LoopbackTransportTest transport_; |
@@ -743,7 +746,6 @@ |
EXPECT_EQ( |
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, |
kAbsoluteSendTimeExtensionId)); |
- rtp_sender_->SetTargetBitrate(300000); |
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); |
int rtp_length_int = rtp_sender_->BuildRTPheader( |
packet_, kPayload, kMarkerBit, kTimestamp, capture_time_ms); |
@@ -797,7 +799,6 @@ |
EXPECT_EQ( |
0, rtp_sender_->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, |
kAbsoluteSendTimeExtensionId)); |
- rtp_sender_->SetTargetBitrate(300000); |
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); |
int rtp_length_int = rtp_sender_->BuildRTPheader( |
packet_, kPayload, kMarkerBit, kTimestamp, capture_time_ms); |
@@ -879,7 +880,6 @@ |
kAbsoluteSendTimeExtensionId); |
webrtc::RTPHeader rtp_header; |
- rtp_sender_->SetTargetBitrate(300000); |
int64_t capture_time_ms = fake_clock_.TimeInMilliseconds(); |
int rtp_length_int = rtp_sender_->BuildRTPheader( |
packet_, kPayload, kMarkerBit, timestamp, capture_time_ms); |
@@ -1011,7 +1011,7 @@ |
rtp_sender_.reset(new RTPSender( |
false, &fake_clock_, &transport_, &mock_paced_sender_, |
nullptr /* TransportSequenceNumberAllocator */, nullptr, nullptr, nullptr, |
- nullptr, nullptr, &send_packet_observer_)); |
+ nullptr, nullptr, &send_packet_observer_, nullptr)); |
rtp_sender_->SetSequenceNumber(kSeqNum); |
rtp_sender_->SetStorePacketsStatus(true, 10); |
@@ -1029,7 +1029,7 @@ |
MockTransport transport; |
rtp_sender_.reset(new RTPSender( |
false, &fake_clock_, &transport, &mock_paced_sender_, nullptr, nullptr, |
- nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr)); |
+ nullptr, nullptr, nullptr, &mock_rtc_event_log_, nullptr, nullptr)); |
rtp_sender_->SetSequenceNumber(kSeqNum); |
rtp_sender_->SetRtxPayloadType(kRtxPayload, kPayload); |
@@ -1054,7 +1054,6 @@ |
kTransmissionTimeOffsetExtensionId); |
rtp_parser->RegisterRtpHeaderExtension(kRtpExtensionAbsoluteSendTime, |
kAbsoluteSendTimeExtensionId); |
- rtp_sender_->SetTargetBitrate(300000); |
const size_t kNumPayloadSizes = 10; |
const size_t kPayloadSizes[kNumPayloadSizes] = {500, 550, 600, 650, 700, |
750, 800, 850, 900, 950}; |
@@ -1176,7 +1175,7 @@ |
rtp_sender_.reset(new RTPSender( |
false, &fake_clock_, &transport_, &mock_paced_sender_, nullptr, nullptr, |
- nullptr, &callback, nullptr, nullptr, nullptr)); |
+ nullptr, &callback, nullptr, nullptr, nullptr, nullptr)); |
char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC"; |
const uint8_t payload_type = 127; |
@@ -1213,30 +1212,39 @@ |
TEST_F(RtpSenderTest, BitrateCallbacks) { |
class TestCallback : public BitrateStatisticsObserver { |
public: |
- TestCallback() : BitrateStatisticsObserver(), num_calls_(0), ssrc_(0) {} |
+ TestCallback() |
+ : BitrateStatisticsObserver(), |
+ num_calls_(0), |
+ ssrc_(0), |
+ total_bitrate_(0), |
+ retransmit_bitrate_(0) {} |
virtual ~TestCallback() {} |
- void Notify(const BitrateStatistics& total_stats, |
- const BitrateStatistics& retransmit_stats, |
+ void Notify(uint32_t total_bitrate, |
+ uint32_t retransmit_bitrate, |
uint32_t ssrc) override { |
++num_calls_; |
ssrc_ = ssrc; |
- total_stats_ = total_stats; |
- retransmit_stats_ = retransmit_stats; |
+ total_bitrate_ = total_bitrate; |
+ retransmit_bitrate_ = retransmit_bitrate; |
} |
uint32_t num_calls_; |
uint32_t ssrc_; |
- BitrateStatistics total_stats_; |
- BitrateStatistics retransmit_stats_; |
+ uint32_t total_bitrate_; |
+ uint32_t retransmit_bitrate_; |
} callback; |
rtp_sender_.reset(new RTPSender(false, &fake_clock_, &transport_, nullptr, |
nullptr, nullptr, &callback, nullptr, nullptr, |
- nullptr, nullptr)); |
- |
- // Simulate kNumPackets sent with kPacketInterval ms intervals. |
- const uint32_t kNumPackets = 15; |
+ nullptr, nullptr, nullptr)); |
+ |
+ // Simulate kNumPackets sent with kPacketInterval ms intervals, with the |
+ // number of packets selected so that we fill (but don't overflow) the one |
+ // second averaging window. |
+ const uint32_t kWindowSizeMs = 1000; |
const uint32_t kPacketInterval = 20; |
+ const uint32_t kNumPackets = |
+ (kWindowSizeMs - kPacketInterval) / kPacketInterval; |
// Overhead = 12 bytes RTP header + 1 byte generic header. |
const uint32_t kPacketOverhead = 13; |
@@ -1250,7 +1258,6 @@ |
// Initial process call so we get a new time window. |
rtp_sender_->ProcessBitrate(); |
- uint64_t start_time = fake_clock_.CurrentNtpInMilliseconds(); |
// Send a few frames. |
for (uint32_t i = 0; i < kNumPackets; ++i) { |
@@ -1262,17 +1269,18 @@ |
rtp_sender_->ProcessBitrate(); |
- const uint32_t expected_packet_rate = 1000 / kPacketInterval; |
- |
// We get one call for every stats updated, thus two calls since both the |
// stream stats and the retransmit stats are updated once. |
EXPECT_EQ(2u, callback.num_calls_); |
EXPECT_EQ(ssrc, callback.ssrc_); |
- EXPECT_EQ(start_time + (kNumPackets * kPacketInterval), |
- callback.total_stats_.timestamp_ms); |
- EXPECT_EQ(expected_packet_rate, callback.total_stats_.packet_rate); |
- EXPECT_EQ((kPacketOverhead + sizeof(payload)) * 8 * expected_packet_rate, |
- callback.total_stats_.bitrate_bps); |
+ const uint32_t kTotalPacketSize = kPacketOverhead + sizeof(payload); |
+ // Bitrate measured over delta between last and first timestamp, plus one. |
+ const uint32_t kExpectedWindowMs = kNumPackets * kPacketInterval + 1; |
+ const uint32_t kExpectedBitsAccumulated = kTotalPacketSize * kNumPackets * 8; |
+ const uint32_t kExpectedRateBps = |
+ (kExpectedBitsAccumulated * 1000 + (kExpectedWindowMs / 2)) / |
+ kExpectedWindowMs; |
+ EXPECT_EQ(kExpectedRateBps, callback.total_bitrate_); |
rtp_sender_.reset(); |
} |
@@ -1285,7 +1293,7 @@ |
payload_ = kAudioPayload; |
rtp_sender_.reset(new RTPSender(true, &fake_clock_, &transport_, nullptr, |
nullptr, nullptr, nullptr, nullptr, nullptr, |
- nullptr, nullptr)); |
+ nullptr, nullptr, nullptr)); |
rtp_sender_->SetSequenceNumber(kSeqNum); |
} |
}; |
@@ -1553,9 +1561,9 @@ |
const int32_t kPacketSize = 1400; |
const int32_t kNumPackets = 30; |
+ retransmission_rate_limiter_.SetMaxRate(kPacketSize * kNumPackets * 8); |
+ |
rtp_sender_->SetStorePacketsStatus(true, kNumPackets); |
- // Set bitrate (in kbps) to fit kNumPackets รก kPacketSize bytes in one second. |
- rtp_sender_->SetTargetBitrate(kNumPackets * kPacketSize * 8); |
const uint16_t kStartSequenceNumber = rtp_sender_->SequenceNumber(); |
std::list<uint16_t> sequence_numbers; |
for (int32_t i = 0; i < kNumPackets; ++i) { |
@@ -1573,6 +1581,9 @@ |
rtp_sender_->OnReceivedNACK(sequence_numbers, 0); |
EXPECT_EQ(kNumPackets * 2, transport_.packets_sent_); |
+ // Must be at least 5ms in between retransmission attempts. |
+ fake_clock_.AdvanceTimeMilliseconds(5); |
+ |
// Resending should not work, bandwidth exceeded. |
rtp_sender_->OnReceivedNACK(sequence_numbers, 0); |
EXPECT_EQ(kNumPackets * 2, transport_.packets_sent_); |