blob: 58f58168d1e74bb2c0143f676a191ed1f1b3cb81 [file] [log] [blame]
sprang233bd872015-09-08 20:25:161/*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
Mirko Bonadei92ea95e2017-09-15 04:47:3111#include "modules/remote_bitrate_estimator/remote_estimator_proxy.h"
Jonas Olssona4d87372019-07-05 17:08:3312
Per Kjellanderee153c92019-10-10 14:43:4613#include <memory>
14#include <utility>
15
Niels Möllerdecc0762019-04-17 12:14:3216#include "api/transport/field_trial_based_config.h"
Per Kjellanderee153c92019-10-10 14:43:4617#include "api/transport/network_types.h"
Per Kjellander52f7ae72019-09-10 17:28:0618#include "api/transport/test/mock_network_control.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3119#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
Per Kjellander898f0912021-04-21 09:56:3220#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3121#include "system_wrappers/include/clock.h"
22#include "test/gmock.h"
23#include "test/gtest.h"
sprang233bd872015-09-08 20:25:1624
25using ::testing::_;
danilchap4a0c7642017-01-18 10:40:3026using ::testing::ElementsAre;
sprang233bd872015-09-08 20:25:1627using ::testing::Invoke;
Per Kjellander898f0912021-04-21 09:56:3228using ::testing::MockFunction;
Erik Språng956ed712016-07-05 10:00:5629using ::testing::Return;
Per Kjellanderee153c92019-10-10 14:43:4630using ::testing::SizeIs;
sprang233bd872015-09-08 20:25:1631
32namespace webrtc {
danilchap4a0c7642017-01-18 10:40:3033namespace {
34
35constexpr size_t kDefaultPacketSize = 100;
36constexpr uint32_t kMediaSsrc = 456;
37constexpr uint16_t kBaseSeq = 10;
38constexpr int64_t kBaseTimeMs = 123;
39constexpr int64_t kMaxSmallDeltaMs =
40 (rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) / 1000;
41
Niels Möllerdecc0762019-04-17 12:14:3242constexpr int kBackWindowMs = 500;
43constexpr int kMinSendIntervalMs = 50;
44constexpr int kMaxSendIntervalMs = 250;
45constexpr int kDefaultSendIntervalMs = 100;
46
danilchap4a0c7642017-01-18 10:40:3047std::vector<uint16_t> SequenceNumbers(
48 const rtcp::TransportFeedback& feedback_packet) {
49 std::vector<uint16_t> sequence_numbers;
50 for (const auto& rtp_packet_received : feedback_packet.GetReceivedPackets()) {
51 sequence_numbers.push_back(rtp_packet_received.sequence_number());
52 }
53 return sequence_numbers;
54}
55
56std::vector<int64_t> TimestampsMs(
57 const rtcp::TransportFeedback& feedback_packet) {
58 std::vector<int64_t> timestamps;
59 int64_t timestamp_us = feedback_packet.GetBaseTimeUs();
60 for (const auto& rtp_packet_received : feedback_packet.GetReceivedPackets()) {
61 timestamp_us += rtp_packet_received.delta_us();
62 timestamps.push_back(timestamp_us / 1000);
63 }
64 return timestamps;
65}
sprang233bd872015-09-08 20:25:1666
sprang233bd872015-09-08 20:25:1667class RemoteEstimatorProxyTest : public ::testing::Test {
68 public:
Niels Möllerdecc0762019-04-17 12:14:3269 RemoteEstimatorProxyTest()
Per Kjellander52f7ae72019-09-10 17:28:0670 : clock_(0),
71 proxy_(&clock_,
Per Kjellander898f0912021-04-21 09:56:3272 feedback_sender_.AsStdFunction(),
Per Kjellander52f7ae72019-09-10 17:28:0673 &field_trial_config_,
74 &network_state_estimator_) {}
sprang233bd872015-09-08 20:25:1675
76 protected:
Per Kjellander52f7ae72019-09-10 17:28:0677 void IncomingPacket(
78 uint16_t seq,
79 int64_t time_ms,
80 absl::optional<FeedbackRequest> feedback_request = absl::nullopt) {
81 proxy_.IncomingPacket(time_ms, kDefaultPacketSize,
82 CreateHeader(seq, feedback_request, absl::nullopt));
sprang233bd872015-09-08 20:25:1683 }
84
Per Kjellander52f7ae72019-09-10 17:28:0685 RTPHeader CreateHeader(absl::optional<uint16_t> transport_sequence,
86 absl::optional<FeedbackRequest> feedback_request,
87 absl::optional<uint32_t> absolute_send_time) {
88 RTPHeader header;
89 if (transport_sequence) {
90 header.extension.hasTransportSequenceNumber = true;
91 header.extension.transportSequenceNumber = transport_sequence.value();
92 }
93 header.extension.feedback_request = feedback_request;
94 if (absolute_send_time) {
95 header.extension.hasAbsoluteSendTime = true;
96 header.extension.absoluteSendTime = absolute_send_time.value();
97 }
98 header.ssrc = kMediaSsrc;
99 return header;
Johannes Kron599d5922019-02-19 13:27:57100 }
101
sprang233bd872015-09-08 20:25:16102 void Process() {
Niels Möllerdecc0762019-04-17 12:14:32103 clock_.AdvanceTimeMilliseconds(kDefaultSendIntervalMs);
sprang233bd872015-09-08 20:25:16104 proxy_.Process();
105 }
106
Niels Möllerdecc0762019-04-17 12:14:32107 FieldTrialBasedConfig field_trial_config_;
sprang233bd872015-09-08 20:25:16108 SimulatedClock clock_;
Per Kjellander898f0912021-04-21 09:56:32109 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
110 feedback_sender_;
Per Kjellander52f7ae72019-09-10 17:28:06111 ::testing::NiceMock<MockNetworkStateEstimator> network_state_estimator_;
sprang233bd872015-09-08 20:25:16112 RemoteEstimatorProxy proxy_;
sprang233bd872015-09-08 20:25:16113};
114
115TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
116 IncomingPacket(kBaseSeq, kBaseTimeMs);
117
Per Kjellander898f0912021-04-21 09:56:32118 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46119 .WillOnce(Invoke(
120 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
121 rtcp::TransportFeedback* feedback_packet =
122 static_cast<rtcp::TransportFeedback*>(
123 feedback_packets[0].get());
124 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
125 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16126
Per Kjellanderee153c92019-10-10 14:43:46127 EXPECT_THAT(SequenceNumbers(*feedback_packet),
128 ElementsAre(kBaseSeq));
129 EXPECT_THAT(TimestampsMs(*feedback_packet),
130 ElementsAre(kBaseTimeMs));
Per Kjellanderee153c92019-10-10 14:43:46131 }));
sprang233bd872015-09-08 20:25:16132
133 Process();
134}
135
Stefan Holmer91c5b562016-02-25 11:35:15136TEST_F(RemoteEstimatorProxyTest, DuplicatedPackets) {
137 IncomingPacket(kBaseSeq, kBaseTimeMs);
138 IncomingPacket(kBaseSeq, kBaseTimeMs + 1000);
139
Per Kjellander898f0912021-04-21 09:56:32140 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46141 .WillOnce(Invoke(
142 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
143 rtcp::TransportFeedback* feedback_packet =
144 static_cast<rtcp::TransportFeedback*>(
145 feedback_packets[0].get());
146 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
147 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
Stefan Holmer91c5b562016-02-25 11:35:15148
Per Kjellanderee153c92019-10-10 14:43:46149 EXPECT_THAT(SequenceNumbers(*feedback_packet),
150 ElementsAre(kBaseSeq));
151 EXPECT_THAT(TimestampsMs(*feedback_packet),
152 ElementsAre(kBaseTimeMs));
153 return true;
154 }));
Stefan Holmer91c5b562016-02-25 11:35:15155
156 Process();
157}
158
Erik Språng956ed712016-07-05 10:00:56159TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
160 // First feedback.
161 IncomingPacket(kBaseSeq, kBaseTimeMs);
162 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1000);
Per Kjellander898f0912021-04-21 09:56:32163 EXPECT_CALL(feedback_sender_, Call);
Erik Språng956ed712016-07-05 10:00:56164 Process();
165
166 // Second feedback starts with a missing packet (DROP kBaseSeq + 2).
167 IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3000);
168
Per Kjellander898f0912021-04-21 09:56:32169 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46170 .WillOnce(Invoke(
171 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
172 rtcp::TransportFeedback* feedback_packet =
173 static_cast<rtcp::TransportFeedback*>(
174 feedback_packets[0].get());
175 EXPECT_EQ(kBaseSeq + 2, feedback_packet->GetBaseSequence());
176 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
Erik Språng956ed712016-07-05 10:00:56177
Per Kjellanderee153c92019-10-10 14:43:46178 EXPECT_THAT(SequenceNumbers(*feedback_packet),
179 ElementsAre(kBaseSeq + 3));
180 EXPECT_THAT(TimestampsMs(*feedback_packet),
181 ElementsAre(kBaseTimeMs + 3000));
Per Kjellanderee153c92019-10-10 14:43:46182 }));
Erik Språng956ed712016-07-05 10:00:56183
184 Process();
185}
186
sprang233bd872015-09-08 20:25:16187TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
188 IncomingPacket(kBaseSeq, kBaseTimeMs);
189 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
190 IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1);
191
Per Kjellander898f0912021-04-21 09:56:32192 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46193 .WillOnce(Invoke(
194 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
195 rtcp::TransportFeedback* feedback_packet =
196 static_cast<rtcp::TransportFeedback*>(
197 feedback_packets[0].get());
198 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
199 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16200
Per Kjellanderee153c92019-10-10 14:43:46201 EXPECT_THAT(SequenceNumbers(*feedback_packet),
202 ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 2));
203 EXPECT_THAT(TimestampsMs(*feedback_packet),
204 ElementsAre(kBaseTimeMs, kBaseTimeMs + kMaxSmallDeltaMs,
205 kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1));
Per Kjellanderee153c92019-10-10 14:43:46206 }));
sprang233bd872015-09-08 20:25:16207
208 Process();
209}
210
211TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
danilchap4a0c7642017-01-18 10:40:30212 static constexpr int64_t kTooLargeDelta =
sprang233bd872015-09-08 20:25:16213 rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 16);
214
215 IncomingPacket(kBaseSeq, kBaseTimeMs);
216 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta);
217
Per Kjellander898f0912021-04-21 09:56:32218 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46219 .WillOnce(Invoke(
220 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
221 rtcp::TransportFeedback* feedback_packet =
222 static_cast<rtcp::TransportFeedback*>(
223 feedback_packets[0].get());
224 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
225 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16226
Per Kjellanderee153c92019-10-10 14:43:46227 EXPECT_THAT(SequenceNumbers(*feedback_packet),
228 ElementsAre(kBaseSeq));
229 EXPECT_THAT(TimestampsMs(*feedback_packet),
230 ElementsAre(kBaseTimeMs));
Per Kjellanderee153c92019-10-10 14:43:46231 }))
232 .WillOnce(Invoke(
233 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
234 rtcp::TransportFeedback* feedback_packet =
235 static_cast<rtcp::TransportFeedback*>(
236 feedback_packets[0].get());
237 EXPECT_EQ(kBaseSeq + 1, feedback_packet->GetBaseSequence());
238 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16239
Per Kjellanderee153c92019-10-10 14:43:46240 EXPECT_THAT(SequenceNumbers(*feedback_packet),
241 ElementsAre(kBaseSeq + 1));
242 EXPECT_THAT(TimestampsMs(*feedback_packet),
243 ElementsAre(kBaseTimeMs + kTooLargeDelta));
Per Kjellanderee153c92019-10-10 14:43:46244 }));
sprang233bd872015-09-08 20:25:16245
246 Process();
247}
248
Johannes Kron3c15f462019-04-02 13:54:22249TEST_F(RemoteEstimatorProxyTest, HandlesReorderingAndWrap) {
stefan159a2fe2016-07-18 11:14:11250 const int64_t kDeltaMs = 1000;
251 const uint16_t kLargeSeq = 62762;
252 IncomingPacket(kBaseSeq, kBaseTimeMs);
253 IncomingPacket(kLargeSeq, kBaseTimeMs + kDeltaMs);
254
Per Kjellander898f0912021-04-21 09:56:32255 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46256 .WillOnce(Invoke(
257 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
258 rtcp::TransportFeedback* feedback_packet =
259 static_cast<rtcp::TransportFeedback*>(
260 feedback_packets[0].get());
261 EXPECT_EQ(kLargeSeq, feedback_packet->GetBaseSequence());
262 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
stefan159a2fe2016-07-18 11:14:11263
Per Kjellanderee153c92019-10-10 14:43:46264 EXPECT_THAT(TimestampsMs(*feedback_packet),
265 ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
Per Kjellanderee153c92019-10-10 14:43:46266 }));
stefan159a2fe2016-07-18 11:14:11267
268 Process();
269}
270
Johannes Kronf59666b2019-04-08 10:57:06271TEST_F(RemoteEstimatorProxyTest, HandlesMalformedSequenceNumbers) {
272 // This test generates incoming packets with large jumps in sequence numbers.
273 // When unwrapped, the sequeunce numbers of these 30 incoming packets, will
274 // span a range of roughly 650k packets. Test that we only send feedback for
275 // the last packets. Test for regression found in chromium:949020.
276 const int64_t kDeltaMs = 1000;
277 for (int i = 0; i < 10; ++i) {
278 IncomingPacket(kBaseSeq + i, kBaseTimeMs + 3 * i * kDeltaMs);
279 IncomingPacket(kBaseSeq + 20000 + i, kBaseTimeMs + (3 * i + 1) * kDeltaMs);
280 IncomingPacket(kBaseSeq + 40000 + i, kBaseTimeMs + (3 * i + 2) * kDeltaMs);
281 }
282
283 // Only expect feedback for the last two packets.
Per Kjellander898f0912021-04-21 09:56:32284 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46285 .WillOnce(Invoke(
286 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
287 rtcp::TransportFeedback* feedback_packet =
288 static_cast<rtcp::TransportFeedback*>(
289 feedback_packets[0].get());
290 EXPECT_EQ(kBaseSeq + 20000 + 9, feedback_packet->GetBaseSequence());
291 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
292 EXPECT_THAT(SequenceNumbers(*feedback_packet),
293 ElementsAre(kBaseSeq + 20009, kBaseSeq + 40009));
294 EXPECT_THAT(TimestampsMs(*feedback_packet),
295 ElementsAre(kBaseTimeMs + 28 * kDeltaMs,
296 kBaseTimeMs + 29 * kDeltaMs));
Per Kjellanderee153c92019-10-10 14:43:46297 }));
Johannes Kronf59666b2019-04-08 10:57:06298
299 Process();
300}
301
302TEST_F(RemoteEstimatorProxyTest, HandlesBackwardsWrappingSequenceNumbers) {
303 // This test is like HandlesMalformedSequenceNumbers but for negative wrap
304 // arounds. Test that we only send feedback for the packets with highest
305 // sequence numbers. Test for regression found in chromium:949020.
306 const int64_t kDeltaMs = 1000;
307 for (int i = 0; i < 10; ++i) {
308 IncomingPacket(kBaseSeq + i, kBaseTimeMs + 3 * i * kDeltaMs);
309 IncomingPacket(kBaseSeq + 40000 + i, kBaseTimeMs + (3 * i + 1) * kDeltaMs);
310 IncomingPacket(kBaseSeq + 20000 + i, kBaseTimeMs + (3 * i + 2) * kDeltaMs);
311 }
312
313 // Only expect feedback for the first two packets.
Per Kjellander898f0912021-04-21 09:56:32314 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46315 .WillOnce(Invoke(
316 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
317 rtcp::TransportFeedback* feedback_packet =
318 static_cast<rtcp::TransportFeedback*>(
319 feedback_packets[0].get());
320 EXPECT_EQ(kBaseSeq + 40000, feedback_packet->GetBaseSequence());
321 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
322 EXPECT_THAT(SequenceNumbers(*feedback_packet),
323 ElementsAre(kBaseSeq + 40000, kBaseSeq));
324 EXPECT_THAT(TimestampsMs(*feedback_packet),
325 ElementsAre(kBaseTimeMs + kDeltaMs, kBaseTimeMs));
Per Kjellanderee153c92019-10-10 14:43:46326 }));
Johannes Kronf59666b2019-04-08 10:57:06327
328 Process();
329}
330
sprang233bd872015-09-08 20:25:16331TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
332 IncomingPacket(kBaseSeq, kBaseTimeMs);
333 IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2);
334
Per Kjellander898f0912021-04-21 09:56:32335 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46336 .WillOnce(Invoke(
337 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
338 rtcp::TransportFeedback* feedback_packet =
339 static_cast<rtcp::TransportFeedback*>(
340 feedback_packets[0].get());
341 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
342 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16343
Per Kjellanderee153c92019-10-10 14:43:46344 EXPECT_THAT(SequenceNumbers(*feedback_packet),
345 ElementsAre(kBaseSeq, kBaseSeq + 2));
346 EXPECT_THAT(TimestampsMs(*feedback_packet),
347 ElementsAre(kBaseTimeMs, kBaseTimeMs + 2));
Per Kjellanderee153c92019-10-10 14:43:46348 }));
sprang233bd872015-09-08 20:25:16349
350 Process();
351
352 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1);
353
Per Kjellander898f0912021-04-21 09:56:32354 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46355 .WillOnce(Invoke(
356 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
357 rtcp::TransportFeedback* feedback_packet =
358 static_cast<rtcp::TransportFeedback*>(
359 feedback_packets[0].get());
360 EXPECT_EQ(kBaseSeq + 1, feedback_packet->GetBaseSequence());
361 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
sprang233bd872015-09-08 20:25:16362
Per Kjellanderee153c92019-10-10 14:43:46363 EXPECT_THAT(SequenceNumbers(*feedback_packet),
364 ElementsAre(kBaseSeq + 1, kBaseSeq + 2));
365 EXPECT_THAT(TimestampsMs(*feedback_packet),
366 ElementsAre(kBaseTimeMs + 1, kBaseTimeMs + 2));
Per Kjellanderee153c92019-10-10 14:43:46367 }));
sprang233bd872015-09-08 20:25:16368
369 Process();
370}
371
372TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
Niels Möllerdecc0762019-04-17 12:14:32373 const int64_t kTimeoutTimeMs = kBaseTimeMs + kBackWindowMs;
sprang233bd872015-09-08 20:25:16374
375 IncomingPacket(kBaseSeq + 2, kBaseTimeMs);
376
Per Kjellander898f0912021-04-21 09:56:32377 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46378 .WillOnce(Invoke(
379 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
380 rtcp::TransportFeedback* feedback_packet =
381 static_cast<rtcp::TransportFeedback*>(
382 feedback_packets[0].get());
383 EXPECT_EQ(kBaseSeq + 2, feedback_packet->GetBaseSequence());
sprang233bd872015-09-08 20:25:16384
Per Kjellanderee153c92019-10-10 14:43:46385 EXPECT_THAT(TimestampsMs(*feedback_packet),
386 ElementsAre(kBaseTimeMs));
Per Kjellanderee153c92019-10-10 14:43:46387 }));
sprang233bd872015-09-08 20:25:16388
389 Process();
390
391 IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs); // kBaseSeq + 2 times out here.
392
Per Kjellander898f0912021-04-21 09:56:32393 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46394 .WillOnce(Invoke(
395 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
396 rtcp::TransportFeedback* feedback_packet =
397 static_cast<rtcp::TransportFeedback*>(
398 feedback_packets[0].get());
danilchap4a0c7642017-01-18 10:40:30399 EXPECT_EQ(kBaseSeq + 3, feedback_packet->GetBaseSequence());
sprang233bd872015-09-08 20:25:16400
danilchap4a0c7642017-01-18 10:40:30401 EXPECT_THAT(TimestampsMs(*feedback_packet),
402 ElementsAre(kTimeoutTimeMs));
danilchap4a0c7642017-01-18 10:40:30403 }));
sprang233bd872015-09-08 20:25:16404
405 Process();
406
407 // New group, with sequence starting below the first so that they may be
408 // retransmitted.
409 IncomingPacket(kBaseSeq, kBaseTimeMs - 1);
410 IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1);
411
Per Kjellander898f0912021-04-21 09:56:32412 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46413 .WillOnce(Invoke(
414 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
415 rtcp::TransportFeedback* feedback_packet =
416 static_cast<rtcp::TransportFeedback*>(
417 feedback_packets[0].get());
danilchap4a0c7642017-01-18 10:40:30418 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
sprang233bd872015-09-08 20:25:16419
danilchap4a0c7642017-01-18 10:40:30420 EXPECT_THAT(SequenceNumbers(*feedback_packet),
421 ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 3));
422 EXPECT_THAT(TimestampsMs(*feedback_packet),
423 ElementsAre(kBaseTimeMs - 1, kTimeoutTimeMs - 1,
424 kTimeoutTimeMs));
danilchap4a0c7642017-01-18 10:40:30425 }));
sprang233bd872015-09-08 20:25:16426
427 Process();
428}
429
minyue8927b052016-11-07 15:51:20430TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsZeroBeforeFirstProcess) {
431 EXPECT_EQ(0, proxy_.TimeUntilNextProcess());
432}
433
434TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsDefaultOnUnkownBitrate) {
435 Process();
Niels Möllerdecc0762019-04-17 12:14:32436 EXPECT_EQ(kDefaultSendIntervalMs, proxy_.TimeUntilNextProcess());
minyue8927b052016-11-07 15:51:20437}
438
439TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMinIntervalOn300kbps) {
440 Process();
441 proxy_.OnBitrateChanged(300000);
Niels Möllerdecc0762019-04-17 12:14:32442 EXPECT_EQ(kMinSendIntervalMs, proxy_.TimeUntilNextProcess());
minyue8927b052016-11-07 15:51:20443}
444
445TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn0kbps) {
446 Process();
Artem Titov1fd7af52021-07-28 18:29:52447 // TimeUntilNextProcess should be limited by `kMaxSendIntervalMs` when
minyue8927b052016-11-07 15:51:20448 // bitrate is small. We choose 0 bps as a special case, which also tests
449 // erroneous behaviors like division-by-zero.
450 proxy_.OnBitrateChanged(0);
Niels Möllerdecc0762019-04-17 12:14:32451 EXPECT_EQ(kMaxSendIntervalMs, proxy_.TimeUntilNextProcess());
minyue8927b052016-11-07 15:51:20452}
453
454TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn20kbps) {
455 Process();
456 proxy_.OnBitrateChanged(20000);
Niels Möllerdecc0762019-04-17 12:14:32457 EXPECT_EQ(kMaxSendIntervalMs, proxy_.TimeUntilNextProcess());
minyue8927b052016-11-07 15:51:20458}
459
460TEST_F(RemoteEstimatorProxyTest, TwccReportsUse5PercentOfAvailableBandwidth) {
461 Process();
462 proxy_.OnBitrateChanged(80000);
463 // 80kbps * 0.05 = TwccReportSize(68B * 8b/B) * 1000ms / SendInterval(136ms)
464 EXPECT_EQ(136, proxy_.TimeUntilNextProcess());
465}
466
Johannes Kron599d5922019-02-19 13:27:57467//////////////////////////////////////////////////////////////////////////////
468// Tests for the extended protocol where the feedback is explicitly requested
469// by the sender.
470//////////////////////////////////////////////////////////////////////////////
471typedef RemoteEstimatorProxyTest RemoteEstimatorProxyOnRequestTest;
472TEST_F(RemoteEstimatorProxyOnRequestTest, TimeUntilNextProcessIsHigh) {
Johannes Kronf59666b2019-04-08 10:57:06473 proxy_.SetSendPeriodicFeedback(false);
Johannes Kron599d5922019-02-19 13:27:57474 EXPECT_GE(proxy_.TimeUntilNextProcess(), 60 * 60 * 1000);
475}
476
477TEST_F(RemoteEstimatorProxyOnRequestTest, ProcessDoesNotSendFeedback) {
Johannes Kronf59666b2019-04-08 10:57:06478 proxy_.SetSendPeriodicFeedback(false);
Johannes Kron599d5922019-02-19 13:27:57479 IncomingPacket(kBaseSeq, kBaseTimeMs);
Per Kjellander898f0912021-04-21 09:56:32480 EXPECT_CALL(feedback_sender_, Call).Times(0);
Johannes Kron599d5922019-02-19 13:27:57481 Process();
482}
483
484TEST_F(RemoteEstimatorProxyOnRequestTest, RequestSinglePacketFeedback) {
Johannes Kronf59666b2019-04-08 10:57:06485 proxy_.SetSendPeriodicFeedback(false);
Johannes Kron599d5922019-02-19 13:27:57486 IncomingPacket(kBaseSeq, kBaseTimeMs);
487 IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
488 IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2 * kMaxSmallDeltaMs);
489
Per Kjellander898f0912021-04-21 09:56:32490 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46491 .WillOnce(Invoke(
492 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
493 rtcp::TransportFeedback* feedback_packet =
494 static_cast<rtcp::TransportFeedback*>(
495 feedback_packets[0].get());
496 EXPECT_EQ(kBaseSeq + 3, feedback_packet->GetBaseSequence());
497 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
Johannes Kron599d5922019-02-19 13:27:57498
Per Kjellanderee153c92019-10-10 14:43:46499 EXPECT_THAT(SequenceNumbers(*feedback_packet),
500 ElementsAre(kBaseSeq + 3));
501 EXPECT_THAT(TimestampsMs(*feedback_packet),
502 ElementsAre(kBaseTimeMs + 3 * kMaxSmallDeltaMs));
Per Kjellanderee153c92019-10-10 14:43:46503 }));
Johannes Kron599d5922019-02-19 13:27:57504
505 constexpr FeedbackRequest kSinglePacketFeedbackRequest = {
Johannes Kron0da25a12019-03-06 08:34:13506 /*include_timestamps=*/true, /*sequence_count=*/1};
Johannes Kron599d5922019-02-19 13:27:57507 IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3 * kMaxSmallDeltaMs,
508 kSinglePacketFeedbackRequest);
509}
510
511TEST_F(RemoteEstimatorProxyOnRequestTest, RequestLastFivePacketFeedback) {
Johannes Kronf59666b2019-04-08 10:57:06512 proxy_.SetSendPeriodicFeedback(false);
Johannes Kron599d5922019-02-19 13:27:57513 int i = 0;
514 for (; i < 10; ++i) {
515 IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
516 }
517
Per Kjellander898f0912021-04-21 09:56:32518 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46519 .WillOnce(Invoke(
520 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
521 rtcp::TransportFeedback* feedback_packet =
522 static_cast<rtcp::TransportFeedback*>(
523 feedback_packets[0].get());
524 EXPECT_EQ(kBaseSeq + 6, feedback_packet->GetBaseSequence());
525 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
Johannes Kron599d5922019-02-19 13:27:57526
Per Kjellanderee153c92019-10-10 14:43:46527 EXPECT_THAT(SequenceNumbers(*feedback_packet),
528 ElementsAre(kBaseSeq + 6, kBaseSeq + 7, kBaseSeq + 8,
529 kBaseSeq + 9, kBaseSeq + 10));
530 EXPECT_THAT(TimestampsMs(*feedback_packet),
531 ElementsAre(kBaseTimeMs + 6 * kMaxSmallDeltaMs,
532 kBaseTimeMs + 7 * kMaxSmallDeltaMs,
533 kBaseTimeMs + 8 * kMaxSmallDeltaMs,
534 kBaseTimeMs + 9 * kMaxSmallDeltaMs,
535 kBaseTimeMs + 10 * kMaxSmallDeltaMs));
Per Kjellanderee153c92019-10-10 14:43:46536 }));
Johannes Kron599d5922019-02-19 13:27:57537
538 constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
Johannes Kron0da25a12019-03-06 08:34:13539 /*include_timestamps=*/true, /*sequence_count=*/5};
Johannes Kron599d5922019-02-19 13:27:57540 IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs,
541 kFivePacketsFeedbackRequest);
542}
543
544TEST_F(RemoteEstimatorProxyOnRequestTest,
545 RequestLastFivePacketFeedbackMissingPackets) {
Johannes Kronf59666b2019-04-08 10:57:06546 proxy_.SetSendPeriodicFeedback(false);
Johannes Kron599d5922019-02-19 13:27:57547 int i = 0;
548 for (; i < 10; ++i) {
549 if (i != 7 && i != 9)
550 IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs);
551 }
552
Per Kjellander898f0912021-04-21 09:56:32553 EXPECT_CALL(feedback_sender_, Call)
Per Kjellanderee153c92019-10-10 14:43:46554 .WillOnce(Invoke(
555 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
556 rtcp::TransportFeedback* feedback_packet =
557 static_cast<rtcp::TransportFeedback*>(
558 feedback_packets[0].get());
559 EXPECT_EQ(kBaseSeq + 6, feedback_packet->GetBaseSequence());
560 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
Johannes Kron599d5922019-02-19 13:27:57561
Per Kjellanderee153c92019-10-10 14:43:46562 EXPECT_THAT(SequenceNumbers(*feedback_packet),
563 ElementsAre(kBaseSeq + 6, kBaseSeq + 8, kBaseSeq + 10));
564 EXPECT_THAT(TimestampsMs(*feedback_packet),
565 ElementsAre(kBaseTimeMs + 6 * kMaxSmallDeltaMs,
566 kBaseTimeMs + 8 * kMaxSmallDeltaMs,
567 kBaseTimeMs + 10 * kMaxSmallDeltaMs));
Per Kjellanderee153c92019-10-10 14:43:46568 }));
Johannes Kron599d5922019-02-19 13:27:57569
570 constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
Johannes Kron0da25a12019-03-06 08:34:13571 /*include_timestamps=*/true, /*sequence_count=*/5};
Johannes Kron599d5922019-02-19 13:27:57572 IncomingPacket(kBaseSeq + i, kBaseTimeMs + i * kMaxSmallDeltaMs,
573 kFivePacketsFeedbackRequest);
574}
575
Per Kjellander52f7ae72019-09-10 17:28:06576TEST_F(RemoteEstimatorProxyTest, ReportsIncomingPacketToNetworkStateEstimator) {
Danil Chapovalov55284022020-02-07 13:53:52577 Timestamp first_send_timestamp = Timestamp::Millis(0);
Per Kjellander52f7ae72019-09-10 17:28:06578 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
579 .WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
Danil Chapovalov55284022020-02-07 13:53:52580 EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
Per Kjellander52f7ae72019-09-10 17:28:06581 first_send_timestamp = packet.sent_packet.send_time;
582 }));
583 // Incoming packet with abs sendtime but without transport sequence number.
584 proxy_.IncomingPacket(
585 kBaseTimeMs, kDefaultPacketSize,
586 CreateHeader(absl::nullopt, absl::nullopt,
587 AbsoluteSendTime::MsTo24Bits(kBaseTimeMs)));
588
589 // Expect packet with older abs send time to be treated as sent at the same
590 // time as the previous packet due to reordering.
591 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
592 .WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
Danil Chapovalov55284022020-02-07 13:53:52593 EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
Per Kjellander52f7ae72019-09-10 17:28:06594 EXPECT_EQ(packet.sent_packet.send_time, first_send_timestamp);
595 }));
596 proxy_.IncomingPacket(
597 kBaseTimeMs, kDefaultPacketSize,
598 CreateHeader(absl::nullopt, absl::nullopt,
599 AbsoluteSendTime::MsTo24Bits(kBaseTimeMs - 12)));
600}
601
602TEST_F(RemoteEstimatorProxyTest, IncomingPacketHandlesWrapInAbsSendTime) {
603 // abs send time use 24bit precision.
604 const uint32_t kFirstAbsSendTime =
605 AbsoluteSendTime::MsTo24Bits((1 << 24) - 30);
606 // Second abs send time has wrapped.
607 const uint32_t kSecondAbsSendTime = AbsoluteSendTime::MsTo24Bits((1 << 24));
Danil Chapovalov55284022020-02-07 13:53:52608 const TimeDelta kExpectedAbsSendTimeDelta = TimeDelta::Millis(30);
Per Kjellander52f7ae72019-09-10 17:28:06609
Danil Chapovalov55284022020-02-07 13:53:52610 Timestamp first_send_timestamp = Timestamp::Millis(0);
Per Kjellander52f7ae72019-09-10 17:28:06611 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
612 .WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
Danil Chapovalov55284022020-02-07 13:53:52613 EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs));
Per Kjellander52f7ae72019-09-10 17:28:06614 first_send_timestamp = packet.sent_packet.send_time;
615 }));
616 proxy_.IncomingPacket(
617 kBaseTimeMs, kDefaultPacketSize,
618 CreateHeader(kBaseSeq, absl::nullopt, kFirstAbsSendTime));
619
620 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
621 .WillOnce(Invoke([first_send_timestamp,
622 kExpectedAbsSendTimeDelta](const PacketResult& packet) {
Danil Chapovalov55284022020-02-07 13:53:52623 EXPECT_EQ(packet.receive_time, Timestamp::Millis(kBaseTimeMs + 123));
Per Kjellander52f7ae72019-09-10 17:28:06624 EXPECT_EQ(packet.sent_packet.send_time.ms(),
625 (first_send_timestamp + kExpectedAbsSendTimeDelta).ms());
626 }));
627 proxy_.IncomingPacket(
628 kBaseTimeMs + 123, kDefaultPacketSize,
629 CreateHeader(kBaseSeq + 1, absl::nullopt, kSecondAbsSendTime));
630}
631
632TEST_F(RemoteEstimatorProxyTest, SendTransportFeedbackAndNetworkStateUpdate) {
633 proxy_.IncomingPacket(
634 kBaseTimeMs, kDefaultPacketSize,
635 CreateHeader(kBaseSeq, absl::nullopt,
636 AbsoluteSendTime::MsTo24Bits(kBaseTimeMs - 1)));
Per Kjellander52f7ae72019-09-10 17:28:06637 EXPECT_CALL(network_state_estimator_, GetCurrentEstimate())
638 .WillOnce(Return(NetworkStateEstimate()));
Per Kjellander898f0912021-04-21 09:56:32639 EXPECT_CALL(feedback_sender_, Call(SizeIs(2)));
Per Kjellander52f7ae72019-09-10 17:28:06640 Process();
641}
642
danilchap4a0c7642017-01-18 10:40:30643} // namespace
sprang233bd872015-09-08 20:25:16644} // namespace webrtc