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