1 /*
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
11 #include "modules/remote_bitrate_estimator/remote_estimator_proxy.h"
12
13 #include <memory>
14 #include <utility>
15
16 #include "api/transport/network_types.h"
17 #include "api/transport/test/mock_network_control.h"
18 #include "api/units/data_size.h"
19 #include "api/units/time_delta.h"
20 #include "api/units/timestamp.h"
21 #include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
22 #include "modules/rtp_rtcp/source/rtp_header_extensions.h"
23 #include "system_wrappers/include/clock.h"
24 #include "test/gmock.h"
25 #include "test/gtest.h"
26
27 namespace webrtc {
28 namespace {
29
30 using ::testing::_;
31 using ::testing::ElementsAre;
32 using ::testing::Invoke;
33 using ::testing::MockFunction;
34 using ::testing::Return;
35 using ::testing::SizeIs;
36
37 constexpr DataSize kDefaultPacketSize = DataSize::Bytes(100);
38 constexpr uint32_t kMediaSsrc = 456;
39 constexpr uint16_t kBaseSeq = 10;
40 constexpr Timestamp kBaseTime = Timestamp::Millis(123);
41 constexpr TimeDelta kBaseTimeWrapAround =
42 rtcp::TransportFeedback::kDeltaTick * (int64_t{1} << 32);
43 constexpr TimeDelta kMaxSmallDelta = rtcp::TransportFeedback::kDeltaTick * 0xFF;
44
45 constexpr TimeDelta kBackWindow = TimeDelta::Millis(500);
46 constexpr TimeDelta kMinSendInterval = TimeDelta::Millis(50);
47 constexpr TimeDelta kMaxSendInterval = TimeDelta::Millis(250);
48 constexpr TimeDelta kDefaultSendInterval = TimeDelta::Millis(100);
49
SequenceNumbers(const rtcp::TransportFeedback & feedback_packet)50 std::vector<uint16_t> SequenceNumbers(
51 const rtcp::TransportFeedback& feedback_packet) {
52 std::vector<uint16_t> sequence_numbers;
53 for (const auto& rtp_packet_received : feedback_packet.GetReceivedPackets()) {
54 sequence_numbers.push_back(rtp_packet_received.sequence_number());
55 }
56 return sequence_numbers;
57 }
58
Timestamps(const rtcp::TransportFeedback & feedback_packet)59 std::vector<Timestamp> Timestamps(
60 const rtcp::TransportFeedback& feedback_packet) {
61 std::vector<Timestamp> timestamps;
62 Timestamp timestamp = feedback_packet.BaseTime();
63 // rtcp::TransportFeedback makes no promises about epoch of the base time,
64 // It may add several kBaseTimeWrapAround periods to make it large enough and
65 // thus to support negative deltas. Align it close to the kBaseTime to make
66 // tests expectations simpler.
67 if (timestamp > kBaseTime) {
68 timestamp -= (timestamp - kBaseTime).RoundTo(kBaseTimeWrapAround);
69 }
70 for (const auto& rtp_packet_received : feedback_packet.GetReceivedPackets()) {
71 timestamp += rtp_packet_received.delta();
72 timestamps.push_back(timestamp);
73 }
74 return timestamps;
75 }
76
77 class RemoteEstimatorProxyTest : public ::testing::Test {
78 public:
RemoteEstimatorProxyTest()79 RemoteEstimatorProxyTest()
80 : clock_(0),
81 proxy_(feedback_sender_.AsStdFunction(), &network_state_estimator_) {}
82
83 protected:
IncomingPacket(uint16_t seq,Timestamp arrival_time,absl::optional<FeedbackRequest> feedback_request=absl::nullopt)84 void IncomingPacket(
85 uint16_t seq,
86 Timestamp arrival_time,
87 absl::optional<FeedbackRequest> feedback_request = absl::nullopt) {
88 proxy_.IncomingPacket({.arrival_time = arrival_time,
89 .size = DataSize::Bytes(100),
90 .ssrc = kMediaSsrc,
91 .transport_sequence_number = seq,
92 .feedback_request = feedback_request});
93 }
94
Process()95 void Process() {
96 clock_.AdvanceTime(kDefaultSendInterval);
97 proxy_.Process(clock_.CurrentTime());
98 }
99
100 SimulatedClock clock_;
101 MockFunction<void(std::vector<std::unique_ptr<rtcp::RtcpPacket>>)>
102 feedback_sender_;
103 ::testing::NiceMock<MockNetworkStateEstimator> network_state_estimator_;
104 RemoteEstimatorProxy proxy_;
105 };
106
TEST_F(RemoteEstimatorProxyTest,SendsSinglePacketFeedback)107 TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
108 IncomingPacket(kBaseSeq, kBaseTime);
109
110 EXPECT_CALL(feedback_sender_, Call)
111 .WillOnce(Invoke(
112 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
113 rtcp::TransportFeedback* feedback_packet =
114 static_cast<rtcp::TransportFeedback*>(
115 feedback_packets[0].get());
116 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
117 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
118
119 EXPECT_THAT(SequenceNumbers(*feedback_packet),
120 ElementsAre(kBaseSeq));
121 EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
122 }));
123
124 Process();
125 }
126
TEST_F(RemoteEstimatorProxyTest,DuplicatedPackets)127 TEST_F(RemoteEstimatorProxyTest, DuplicatedPackets) {
128 IncomingPacket(kBaseSeq, kBaseTime);
129 IncomingPacket(kBaseSeq, kBaseTime + TimeDelta::Seconds(1));
130
131 EXPECT_CALL(feedback_sender_, Call)
132 .WillOnce(Invoke(
133 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
134 rtcp::TransportFeedback* feedback_packet =
135 static_cast<rtcp::TransportFeedback*>(
136 feedback_packets[0].get());
137 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
138 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
139
140 EXPECT_THAT(SequenceNumbers(*feedback_packet),
141 ElementsAre(kBaseSeq));
142 EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
143 return true;
144 }));
145
146 Process();
147 }
148
TEST_F(RemoteEstimatorProxyTest,FeedbackWithMissingStart)149 TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
150 // First feedback.
151 IncomingPacket(kBaseSeq, kBaseTime);
152 IncomingPacket(kBaseSeq + 1, kBaseTime + TimeDelta::Seconds(1));
153 EXPECT_CALL(feedback_sender_, Call);
154 Process();
155
156 // Second feedback starts with a missing packet (DROP kBaseSeq + 2).
157 IncomingPacket(kBaseSeq + 3, kBaseTime + TimeDelta::Seconds(3));
158
159 EXPECT_CALL(feedback_sender_, Call)
160 .WillOnce(Invoke(
161 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
162 rtcp::TransportFeedback* feedback_packet =
163 static_cast<rtcp::TransportFeedback*>(
164 feedback_packets[0].get());
165 EXPECT_EQ(kBaseSeq + 2, feedback_packet->GetBaseSequence());
166 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
167
168 EXPECT_THAT(SequenceNumbers(*feedback_packet),
169 ElementsAre(kBaseSeq + 3));
170 EXPECT_THAT(Timestamps(*feedback_packet),
171 ElementsAre(kBaseTime + TimeDelta::Seconds(3)));
172 }));
173
174 Process();
175 }
176
TEST_F(RemoteEstimatorProxyTest,SendsFeedbackWithVaryingDeltas)177 TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
178 IncomingPacket(kBaseSeq, kBaseTime);
179 IncomingPacket(kBaseSeq + 1, kBaseTime + kMaxSmallDelta);
180 IncomingPacket(kBaseSeq + 2,
181 kBaseTime + (2 * kMaxSmallDelta) + TimeDelta::Millis(1));
182
183 EXPECT_CALL(feedback_sender_, Call)
184 .WillOnce(Invoke(
185 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
186 rtcp::TransportFeedback* feedback_packet =
187 static_cast<rtcp::TransportFeedback*>(
188 feedback_packets[0].get());
189 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
190 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
191
192 EXPECT_THAT(SequenceNumbers(*feedback_packet),
193 ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 2));
194 EXPECT_THAT(Timestamps(*feedback_packet),
195 ElementsAre(kBaseTime, kBaseTime + kMaxSmallDelta,
196 kBaseTime + (2 * kMaxSmallDelta) +
197 TimeDelta::Millis(1)));
198 }));
199
200 Process();
201 }
202
TEST_F(RemoteEstimatorProxyTest,SendsFragmentedFeedback)203 TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
204 static constexpr TimeDelta kTooLargeDelta =
205 rtcp::TransportFeedback::kDeltaTick * (1 << 16);
206
207 IncomingPacket(kBaseSeq, kBaseTime);
208 IncomingPacket(kBaseSeq + 1, kBaseTime + kTooLargeDelta);
209
210 EXPECT_CALL(feedback_sender_, Call)
211 .WillOnce(Invoke(
212 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
213 rtcp::TransportFeedback* feedback_packet =
214 static_cast<rtcp::TransportFeedback*>(
215 feedback_packets[0].get());
216 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
217 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
218
219 EXPECT_THAT(SequenceNumbers(*feedback_packet),
220 ElementsAre(kBaseSeq));
221 EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
222 }))
223 .WillOnce(Invoke(
224 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
225 rtcp::TransportFeedback* feedback_packet =
226 static_cast<rtcp::TransportFeedback*>(
227 feedback_packets[0].get());
228 EXPECT_EQ(kBaseSeq + 1, feedback_packet->GetBaseSequence());
229 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
230
231 EXPECT_THAT(SequenceNumbers(*feedback_packet),
232 ElementsAre(kBaseSeq + 1));
233 EXPECT_THAT(Timestamps(*feedback_packet),
234 ElementsAre(kBaseTime + kTooLargeDelta));
235 }));
236
237 Process();
238 }
239
TEST_F(RemoteEstimatorProxyTest,HandlesReorderingAndWrap)240 TEST_F(RemoteEstimatorProxyTest, HandlesReorderingAndWrap) {
241 const TimeDelta kDelta = TimeDelta::Seconds(1);
242 const uint16_t kLargeSeq = 62762;
243 IncomingPacket(kBaseSeq, kBaseTime);
244 IncomingPacket(kLargeSeq, kBaseTime + kDelta);
245
246 EXPECT_CALL(feedback_sender_, Call)
247 .WillOnce(Invoke(
248 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
249 rtcp::TransportFeedback* feedback_packet =
250 static_cast<rtcp::TransportFeedback*>(
251 feedback_packets[0].get());
252 EXPECT_EQ(kLargeSeq, feedback_packet->GetBaseSequence());
253 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
254
255 EXPECT_THAT(Timestamps(*feedback_packet),
256 ElementsAre(kBaseTime + kDelta, kBaseTime));
257 }));
258
259 Process();
260 }
261
TEST_F(RemoteEstimatorProxyTest,HandlesMalformedSequenceNumbers)262 TEST_F(RemoteEstimatorProxyTest, HandlesMalformedSequenceNumbers) {
263 // This test generates incoming packets with large jumps in sequence numbers.
264 // When unwrapped, the sequeunce numbers of these 30 incoming packets, will
265 // span a range of roughly 650k packets. Test that we only send feedback for
266 // the last packets. Test for regression found in chromium:949020.
267 const TimeDelta kDelta = TimeDelta::Seconds(1);
268 for (int i = 0; i < 10; ++i) {
269 IncomingPacket(kBaseSeq + i, kBaseTime + 3 * i * kDelta);
270 IncomingPacket(kBaseSeq + 20000 + i, kBaseTime + (3 * i + 1) * kDelta);
271 IncomingPacket(kBaseSeq + 40000 + i, kBaseTime + (3 * i + 2) * kDelta);
272 }
273
274 // Only expect feedback for the last two packets.
275 EXPECT_CALL(feedback_sender_, Call)
276 .WillOnce(Invoke(
277 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
278 rtcp::TransportFeedback* feedback_packet =
279 static_cast<rtcp::TransportFeedback*>(
280 feedback_packets[0].get());
281 EXPECT_EQ(kBaseSeq + 20000 + 9, feedback_packet->GetBaseSequence());
282 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
283 EXPECT_THAT(SequenceNumbers(*feedback_packet),
284 ElementsAre(kBaseSeq + 20009, kBaseSeq + 40009));
285 EXPECT_THAT(
286 Timestamps(*feedback_packet),
287 ElementsAre(kBaseTime + 28 * kDelta, kBaseTime + 29 * kDelta));
288 }));
289
290 Process();
291 }
292
TEST_F(RemoteEstimatorProxyTest,HandlesBackwardsWrappingSequenceNumbers)293 TEST_F(RemoteEstimatorProxyTest, HandlesBackwardsWrappingSequenceNumbers) {
294 // This test is like HandlesMalformedSequenceNumbers but for negative wrap
295 // arounds. Test that we only send feedback for the packets with highest
296 // sequence numbers. Test for regression found in chromium:949020.
297 const TimeDelta kDelta = TimeDelta::Seconds(1);
298 for (int i = 0; i < 10; ++i) {
299 IncomingPacket(kBaseSeq + i, kBaseTime + 3 * i * kDelta);
300 IncomingPacket(kBaseSeq + 40000 + i, kBaseTime + (3 * i + 1) * kDelta);
301 IncomingPacket(kBaseSeq + 20000 + i, kBaseTime + (3 * i + 2) * kDelta);
302 }
303
304 // Only expect feedback for the first two packets.
305 EXPECT_CALL(feedback_sender_, Call)
306 .WillOnce(Invoke(
307 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
308 rtcp::TransportFeedback* feedback_packet =
309 static_cast<rtcp::TransportFeedback*>(
310 feedback_packets[0].get());
311 EXPECT_EQ(kBaseSeq + 40000, feedback_packet->GetBaseSequence());
312 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
313 EXPECT_THAT(SequenceNumbers(*feedback_packet),
314 ElementsAre(kBaseSeq + 40000, kBaseSeq));
315 EXPECT_THAT(Timestamps(*feedback_packet),
316 ElementsAre(kBaseTime + kDelta, kBaseTime));
317 }));
318
319 Process();
320 }
321
TEST_F(RemoteEstimatorProxyTest,ResendsTimestampsOnReordering)322 TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
323 IncomingPacket(kBaseSeq, kBaseTime);
324 IncomingPacket(kBaseSeq + 2, kBaseTime + TimeDelta::Millis(2));
325
326 EXPECT_CALL(feedback_sender_, Call)
327 .WillOnce(Invoke(
328 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
329 rtcp::TransportFeedback* feedback_packet =
330 static_cast<rtcp::TransportFeedback*>(
331 feedback_packets[0].get());
332 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
333 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
334
335 EXPECT_THAT(SequenceNumbers(*feedback_packet),
336 ElementsAre(kBaseSeq, kBaseSeq + 2));
337 EXPECT_THAT(
338 Timestamps(*feedback_packet),
339 ElementsAre(kBaseTime, kBaseTime + TimeDelta::Millis(2)));
340 }));
341
342 Process();
343
344 IncomingPacket(kBaseSeq + 1, kBaseTime + TimeDelta::Millis(1));
345
346 EXPECT_CALL(feedback_sender_, Call)
347 .WillOnce(Invoke(
348 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
349 rtcp::TransportFeedback* feedback_packet =
350 static_cast<rtcp::TransportFeedback*>(
351 feedback_packets[0].get());
352 EXPECT_EQ(kBaseSeq + 1, feedback_packet->GetBaseSequence());
353 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
354
355 EXPECT_THAT(SequenceNumbers(*feedback_packet),
356 ElementsAre(kBaseSeq + 1, kBaseSeq + 2));
357 EXPECT_THAT(Timestamps(*feedback_packet),
358 ElementsAre(kBaseTime + TimeDelta::Millis(1),
359 kBaseTime + TimeDelta::Millis(2)));
360 }));
361
362 Process();
363 }
364
TEST_F(RemoteEstimatorProxyTest,RemovesTimestampsOutOfScope)365 TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
366 const Timestamp kTimeoutTime = kBaseTime + kBackWindow;
367
368 IncomingPacket(kBaseSeq + 2, kBaseTime);
369
370 EXPECT_CALL(feedback_sender_, Call)
371 .WillOnce(Invoke(
372 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
373 rtcp::TransportFeedback* feedback_packet =
374 static_cast<rtcp::TransportFeedback*>(
375 feedback_packets[0].get());
376 EXPECT_EQ(kBaseSeq + 2, feedback_packet->GetBaseSequence());
377
378 EXPECT_THAT(Timestamps(*feedback_packet), ElementsAre(kBaseTime));
379 }));
380
381 Process();
382
383 IncomingPacket(kBaseSeq + 3, kTimeoutTime); // kBaseSeq + 2 times out here.
384
385 EXPECT_CALL(feedback_sender_, Call)
386 .WillOnce(Invoke(
387 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
388 rtcp::TransportFeedback* feedback_packet =
389 static_cast<rtcp::TransportFeedback*>(
390 feedback_packets[0].get());
391 EXPECT_EQ(kBaseSeq + 3, feedback_packet->GetBaseSequence());
392
393 EXPECT_THAT(Timestamps(*feedback_packet),
394 ElementsAre(kTimeoutTime));
395 }));
396
397 Process();
398
399 // New group, with sequence starting below the first so that they may be
400 // retransmitted.
401 IncomingPacket(kBaseSeq, kBaseTime - TimeDelta::Millis(1));
402 IncomingPacket(kBaseSeq + 1, kTimeoutTime - TimeDelta::Millis(1));
403
404 EXPECT_CALL(feedback_sender_, Call)
405 .WillOnce(Invoke(
406 [&](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
407 rtcp::TransportFeedback* feedback_packet =
408 static_cast<rtcp::TransportFeedback*>(
409 feedback_packets[0].get());
410 EXPECT_EQ(kBaseSeq, feedback_packet->GetBaseSequence());
411
412 EXPECT_THAT(SequenceNumbers(*feedback_packet),
413 ElementsAre(kBaseSeq, kBaseSeq + 1, kBaseSeq + 3));
414 EXPECT_THAT(
415 Timestamps(*feedback_packet),
416 ElementsAre(kBaseTime - TimeDelta::Millis(1),
417 kTimeoutTime - TimeDelta::Millis(1), kTimeoutTime));
418 }));
419
420 Process();
421 }
422
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsDefaultOnUnkownBitrate)423 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsDefaultOnUnkownBitrate) {
424 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), kDefaultSendInterval);
425 }
426
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMinIntervalOn300kbps)427 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMinIntervalOn300kbps) {
428 proxy_.OnBitrateChanged(300'000);
429 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), kMinSendInterval);
430 }
431
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMaxIntervalOn0kbps)432 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn0kbps) {
433 // TimeUntilNextProcess should be limited by `kMaxSendIntervalMs` when
434 // bitrate is small. We choose 0 bps as a special case, which also tests
435 // erroneous behaviors like division-by-zero.
436 proxy_.OnBitrateChanged(0);
437 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), kMaxSendInterval);
438 }
439
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMaxIntervalOn20kbps)440 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn20kbps) {
441 proxy_.OnBitrateChanged(20'000);
442 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), kMaxSendInterval);
443 }
444
TEST_F(RemoteEstimatorProxyTest,TwccReportsUse5PercentOfAvailableBandwidth)445 TEST_F(RemoteEstimatorProxyTest, TwccReportsUse5PercentOfAvailableBandwidth) {
446 proxy_.OnBitrateChanged(80'000);
447 // 80kbps * 0.05 = TwccReportSize(68B * 8b/B) * 1000ms / SendInterval(136ms)
448 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), TimeDelta::Millis(136));
449 }
450
451 //////////////////////////////////////////////////////////////////////////////
452 // Tests for the extended protocol where the feedback is explicitly requested
453 // by the sender.
454 //////////////////////////////////////////////////////////////////////////////
455 typedef RemoteEstimatorProxyTest RemoteEstimatorProxyOnRequestTest;
TEST_F(RemoteEstimatorProxyOnRequestTest,DisablesPeriodicProcess)456 TEST_F(RemoteEstimatorProxyOnRequestTest, DisablesPeriodicProcess) {
457 proxy_.SetSendPeriodicFeedback(false);
458 EXPECT_EQ(proxy_.Process(clock_.CurrentTime()), TimeDelta::PlusInfinity());
459 }
460
TEST_F(RemoteEstimatorProxyOnRequestTest,ProcessDoesNotSendFeedback)461 TEST_F(RemoteEstimatorProxyOnRequestTest, ProcessDoesNotSendFeedback) {
462 proxy_.SetSendPeriodicFeedback(false);
463 IncomingPacket(kBaseSeq, kBaseTime);
464 EXPECT_CALL(feedback_sender_, Call).Times(0);
465 Process();
466 }
467
TEST_F(RemoteEstimatorProxyOnRequestTest,RequestSinglePacketFeedback)468 TEST_F(RemoteEstimatorProxyOnRequestTest, RequestSinglePacketFeedback) {
469 proxy_.SetSendPeriodicFeedback(false);
470 IncomingPacket(kBaseSeq, kBaseTime);
471 IncomingPacket(kBaseSeq + 1, kBaseTime + kMaxSmallDelta);
472 IncomingPacket(kBaseSeq + 2, kBaseTime + 2 * kMaxSmallDelta);
473
474 EXPECT_CALL(feedback_sender_, Call)
475 .WillOnce(Invoke(
476 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
477 rtcp::TransportFeedback* feedback_packet =
478 static_cast<rtcp::TransportFeedback*>(
479 feedback_packets[0].get());
480 EXPECT_EQ(kBaseSeq + 3, feedback_packet->GetBaseSequence());
481 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
482
483 EXPECT_THAT(SequenceNumbers(*feedback_packet),
484 ElementsAre(kBaseSeq + 3));
485 EXPECT_THAT(Timestamps(*feedback_packet),
486 ElementsAre(kBaseTime + 3 * kMaxSmallDelta));
487 }));
488
489 constexpr FeedbackRequest kSinglePacketFeedbackRequest = {
490 /*include_timestamps=*/true, /*sequence_count=*/1};
491 IncomingPacket(kBaseSeq + 3, kBaseTime + 3 * kMaxSmallDelta,
492 kSinglePacketFeedbackRequest);
493 }
494
TEST_F(RemoteEstimatorProxyOnRequestTest,RequestLastFivePacketFeedback)495 TEST_F(RemoteEstimatorProxyOnRequestTest, RequestLastFivePacketFeedback) {
496 proxy_.SetSendPeriodicFeedback(false);
497 int i = 0;
498 for (; i < 10; ++i) {
499 IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta);
500 }
501
502 EXPECT_CALL(feedback_sender_, Call)
503 .WillOnce(Invoke(
504 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
505 rtcp::TransportFeedback* feedback_packet =
506 static_cast<rtcp::TransportFeedback*>(
507 feedback_packets[0].get());
508 EXPECT_EQ(kBaseSeq + 6, feedback_packet->GetBaseSequence());
509 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
510
511 EXPECT_THAT(SequenceNumbers(*feedback_packet),
512 ElementsAre(kBaseSeq + 6, kBaseSeq + 7, kBaseSeq + 8,
513 kBaseSeq + 9, kBaseSeq + 10));
514 EXPECT_THAT(Timestamps(*feedback_packet),
515 ElementsAre(kBaseTime + 6 * kMaxSmallDelta,
516 kBaseTime + 7 * kMaxSmallDelta,
517 kBaseTime + 8 * kMaxSmallDelta,
518 kBaseTime + 9 * kMaxSmallDelta,
519 kBaseTime + 10 * kMaxSmallDelta));
520 }));
521
522 constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
523 /*include_timestamps=*/true, /*sequence_count=*/5};
524 IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta,
525 kFivePacketsFeedbackRequest);
526 }
527
TEST_F(RemoteEstimatorProxyOnRequestTest,RequestLastFivePacketFeedbackMissingPackets)528 TEST_F(RemoteEstimatorProxyOnRequestTest,
529 RequestLastFivePacketFeedbackMissingPackets) {
530 proxy_.SetSendPeriodicFeedback(false);
531 int i = 0;
532 for (; i < 10; ++i) {
533 if (i != 7 && i != 9)
534 IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta);
535 }
536
537 EXPECT_CALL(feedback_sender_, Call)
538 .WillOnce(Invoke(
539 [](std::vector<std::unique_ptr<rtcp::RtcpPacket>> feedback_packets) {
540 rtcp::TransportFeedback* feedback_packet =
541 static_cast<rtcp::TransportFeedback*>(
542 feedback_packets[0].get());
543 EXPECT_EQ(kBaseSeq + 6, feedback_packet->GetBaseSequence());
544 EXPECT_EQ(kMediaSsrc, feedback_packet->media_ssrc());
545
546 EXPECT_THAT(SequenceNumbers(*feedback_packet),
547 ElementsAre(kBaseSeq + 6, kBaseSeq + 8, kBaseSeq + 10));
548 EXPECT_THAT(Timestamps(*feedback_packet),
549 ElementsAre(kBaseTime + 6 * kMaxSmallDelta,
550 kBaseTime + 8 * kMaxSmallDelta,
551 kBaseTime + 10 * kMaxSmallDelta));
552 }));
553
554 constexpr FeedbackRequest kFivePacketsFeedbackRequest = {
555 /*include_timestamps=*/true, /*sequence_count=*/5};
556 IncomingPacket(kBaseSeq + i, kBaseTime + i * kMaxSmallDelta,
557 kFivePacketsFeedbackRequest);
558 }
559
TEST_F(RemoteEstimatorProxyTest,ReportsIncomingPacketToNetworkStateEstimator)560 TEST_F(RemoteEstimatorProxyTest, ReportsIncomingPacketToNetworkStateEstimator) {
561 Timestamp first_send_timestamp = Timestamp::Zero();
562 const DataSize kPacketOverhead = DataSize::Bytes(38);
563 proxy_.SetTransportOverhead(kPacketOverhead);
564
565 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
566 .WillOnce(Invoke([&](const PacketResult& packet) {
567 EXPECT_EQ(packet.receive_time, kBaseTime);
568 EXPECT_EQ(packet.sent_packet.size,
569 kDefaultPacketSize + kPacketOverhead);
570 first_send_timestamp = packet.sent_packet.send_time;
571 }));
572 // Incoming packet with abs sendtime but without transport sequence number.
573 proxy_.IncomingPacket(
574 {.arrival_time = kBaseTime,
575 .size = kDefaultPacketSize,
576 .ssrc = kMediaSsrc,
577 .absolute_send_time_24bits = AbsoluteSendTime::To24Bits(kBaseTime)});
578
579 // Expect packet with older abs send time to be treated as sent at the same
580 // time as the previous packet due to reordering.
581 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
582 .WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
583 EXPECT_EQ(packet.receive_time, kBaseTime);
584 EXPECT_EQ(packet.sent_packet.send_time, first_send_timestamp);
585 }));
586
587 proxy_.IncomingPacket(
588 {.arrival_time = kBaseTime,
589 .size = kDefaultPacketSize,
590 .ssrc = kMediaSsrc,
591 .absolute_send_time_24bits =
592 AbsoluteSendTime::To24Bits(kBaseTime - TimeDelta::Millis(12))});
593 }
594
TEST_F(RemoteEstimatorProxyTest,IncomingPacketHandlesWrapInAbsSendTime)595 TEST_F(RemoteEstimatorProxyTest, IncomingPacketHandlesWrapInAbsSendTime) {
596 // abs send time use 24bit precision.
597 const uint32_t kFirstAbsSendTime =
598 AbsoluteSendTime::To24Bits(Timestamp::Millis((1 << 24) - 30));
599 // Second abs send time has wrapped.
600 const uint32_t kSecondAbsSendTime =
601 AbsoluteSendTime::To24Bits(Timestamp::Millis(1 << 24));
602 const TimeDelta kExpectedAbsSendTimeDelta = TimeDelta::Millis(30);
603
604 Timestamp first_send_timestamp = Timestamp::Zero();
605 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
606 .WillOnce(Invoke([&first_send_timestamp](const PacketResult& packet) {
607 EXPECT_EQ(packet.receive_time, kBaseTime);
608 first_send_timestamp = packet.sent_packet.send_time;
609 }));
610 proxy_.IncomingPacket({.arrival_time = kBaseTime,
611 .size = kDefaultPacketSize,
612 .ssrc = kMediaSsrc,
613 .absolute_send_time_24bits = kFirstAbsSendTime,
614 .transport_sequence_number = kBaseSeq});
615
616 EXPECT_CALL(network_state_estimator_, OnReceivedPacket(_))
617 .WillOnce(Invoke([first_send_timestamp,
618 kExpectedAbsSendTimeDelta](const PacketResult& packet) {
619 EXPECT_EQ(packet.receive_time, kBaseTime + TimeDelta::Millis(123));
620 EXPECT_EQ(packet.sent_packet.send_time.ms(),
621 (first_send_timestamp + kExpectedAbsSendTimeDelta).ms());
622 }));
623 proxy_.IncomingPacket({.arrival_time = kBaseTime + TimeDelta::Millis(123),
624 .size = kDefaultPacketSize,
625 .ssrc = kMediaSsrc,
626 .absolute_send_time_24bits = kSecondAbsSendTime,
627 .transport_sequence_number = kBaseSeq + 1});
628 }
629
TEST_F(RemoteEstimatorProxyTest,SendTransportFeedbackAndNetworkStateUpdate)630 TEST_F(RemoteEstimatorProxyTest, SendTransportFeedbackAndNetworkStateUpdate) {
631 proxy_.IncomingPacket(
632 {.arrival_time = kBaseTime,
633 .size = kDefaultPacketSize,
634 .ssrc = kMediaSsrc,
635 .absolute_send_time_24bits =
636 AbsoluteSendTime::To24Bits(kBaseTime - TimeDelta::Millis(1)),
637 .transport_sequence_number = kBaseSeq});
638 EXPECT_CALL(network_state_estimator_, GetCurrentEstimate())
639 .WillOnce(Return(NetworkStateEstimate()));
640 EXPECT_CALL(feedback_sender_, Call(SizeIs(2)));
641 Process();
642 }
643
644 } // namespace
645 } // namespace webrtc
646