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 "webrtc/modules/pacing/packet_router.h"
12 #include "webrtc/modules/remote_bitrate_estimator/remote_estimator_proxy.h"
13 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
14 #include "webrtc/system_wrappers/include/clock.h"
15 #include "webrtc/test/gmock.h"
16 #include "webrtc/test/gtest.h"
17 
18 using ::testing::_;
19 using ::testing::InSequence;
20 using ::testing::Invoke;
21 using ::testing::Return;
22 
23 namespace webrtc {
24 
25 class MockPacketRouter : public PacketRouter {
26  public:
27   MOCK_METHOD1(SendFeedback, bool(rtcp::TransportFeedback* packet));
28 };
29 
30 class RemoteEstimatorProxyTest : public ::testing::Test {
31  public:
RemoteEstimatorProxyTest()32   RemoteEstimatorProxyTest() : clock_(0), proxy_(&clock_, &router_) {}
33 
34  protected:
IncomingPacket(uint16_t seq,int64_t time_ms)35   void IncomingPacket(uint16_t seq, int64_t time_ms) {
36     RTPHeader header;
37     header.extension.hasTransportSequenceNumber = true;
38     header.extension.transportSequenceNumber = seq;
39     header.ssrc = kMediaSsrc;
40     proxy_.IncomingPacket(time_ms, kDefaultPacketSize, header);
41   }
42 
Process()43   void Process() {
44     clock_.AdvanceTimeMilliseconds(
45         RemoteEstimatorProxy::kDefaultSendIntervalMs);
46     proxy_.Process();
47   }
48 
49   SimulatedClock clock_;
50   ::testing::StrictMock<MockPacketRouter> router_;
51   RemoteEstimatorProxy proxy_;
52 
53   const size_t kDefaultPacketSize = 100;
54   const uint32_t kMediaSsrc = 456;
55   const uint16_t kBaseSeq = 10;
56   const int64_t kBaseTimeMs = 123;
57   const int64_t kMaxSmallDeltaMs =
58       (rtcp::TransportFeedback::kDeltaScaleFactor * 0xFF) / 1000;
59 };
60 
TEST_F(RemoteEstimatorProxyTest,SendsSinglePacketFeedback)61 TEST_F(RemoteEstimatorProxyTest, SendsSinglePacketFeedback) {
62   IncomingPacket(kBaseSeq, kBaseTimeMs);
63 
64   EXPECT_CALL(router_, SendFeedback(_))
65       .Times(1)
66       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
67         packet->Build();
68         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
69         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
70 
71         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
72             packet->GetStatusVector();
73         EXPECT_EQ(1u, status_vec.size());
74         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
75                   status_vec[0]);
76         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
77         EXPECT_EQ(1u, delta_vec.size());
78         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
79         return true;
80       }));
81 
82   Process();
83 }
84 
TEST_F(RemoteEstimatorProxyTest,DuplicatedPackets)85 TEST_F(RemoteEstimatorProxyTest, DuplicatedPackets) {
86   IncomingPacket(kBaseSeq, kBaseTimeMs);
87   IncomingPacket(kBaseSeq, kBaseTimeMs + 1000);
88 
89   EXPECT_CALL(router_, SendFeedback(_))
90       .Times(1)
91       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
92         packet->Build();
93         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
94         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
95 
96         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
97             packet->GetStatusVector();
98         EXPECT_EQ(1u, status_vec.size());
99         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
100                   status_vec[0]);
101         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
102         EXPECT_EQ(1u, delta_vec.size());
103         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
104         return true;
105       }));
106 
107   Process();
108 }
109 
TEST_F(RemoteEstimatorProxyTest,FeedbackWithMissingStart)110 TEST_F(RemoteEstimatorProxyTest, FeedbackWithMissingStart) {
111   // First feedback.
112   IncomingPacket(kBaseSeq, kBaseTimeMs);
113   IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1000);
114   EXPECT_CALL(router_, SendFeedback(_)).Times(1).WillOnce(Return(true));
115   Process();
116 
117   // Second feedback starts with a missing packet (DROP kBaseSeq + 2).
118   IncomingPacket(kBaseSeq + 3, kBaseTimeMs + 3000);
119 
120   EXPECT_CALL(router_, SendFeedback(_))
121       .Times(1)
122       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
123         packet->Build();
124         EXPECT_EQ(kBaseSeq + 2, packet->GetBaseSequence());
125         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
126 
127         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
128             packet->GetStatusVector();
129         EXPECT_EQ(2u, status_vec.size());
130         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kNotReceived,
131                   status_vec[0]);
132         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
133                   status_vec[1]);
134         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
135         EXPECT_EQ(1u, delta_vec.size());
136         EXPECT_EQ(kBaseTimeMs + 3000,
137                   (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
138         return true;
139       }));
140 
141   Process();
142 }
143 
TEST_F(RemoteEstimatorProxyTest,SendsFeedbackWithVaryingDeltas)144 TEST_F(RemoteEstimatorProxyTest, SendsFeedbackWithVaryingDeltas) {
145   IncomingPacket(kBaseSeq, kBaseTimeMs);
146   IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kMaxSmallDeltaMs);
147   IncomingPacket(kBaseSeq + 2, kBaseTimeMs + (2 * kMaxSmallDeltaMs) + 1);
148 
149   EXPECT_CALL(router_, SendFeedback(_))
150       .Times(1)
151       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
152         packet->Build();
153         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
154         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
155 
156         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
157             packet->GetStatusVector();
158         EXPECT_EQ(3u, status_vec.size());
159         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
160                   status_vec[0]);
161         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
162                   status_vec[1]);
163         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedLargeDelta,
164                   status_vec[2]);
165 
166         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
167         EXPECT_EQ(3u, delta_vec.size());
168         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
169         EXPECT_EQ(kMaxSmallDeltaMs, delta_vec[1] / 1000);
170         EXPECT_EQ(kMaxSmallDeltaMs + 1, delta_vec[2] / 1000);
171         return true;
172       }));
173 
174   Process();
175 }
176 
TEST_F(RemoteEstimatorProxyTest,SendsFragmentedFeedback)177 TEST_F(RemoteEstimatorProxyTest, SendsFragmentedFeedback) {
178   const int64_t kTooLargeDelta =
179       rtcp::TransportFeedback::kDeltaScaleFactor * (1 << 16);
180 
181   IncomingPacket(kBaseSeq, kBaseTimeMs);
182   IncomingPacket(kBaseSeq + 1, kBaseTimeMs + kTooLargeDelta);
183 
184   InSequence s;
185   EXPECT_CALL(router_, SendFeedback(_))
186       .Times(1)
187       .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) {
188         packet->Build();
189         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
190         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
191 
192         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
193             packet->GetStatusVector();
194         EXPECT_EQ(1u, status_vec.size());
195         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
196                   status_vec[0]);
197         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
198         EXPECT_EQ(1u, delta_vec.size());
199         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
200         return true;
201       }))
202       .RetiresOnSaturation();
203 
204   EXPECT_CALL(router_, SendFeedback(_))
205       .Times(1)
206       .WillOnce(Invoke([kTooLargeDelta, this](rtcp::TransportFeedback* packet) {
207         packet->Build();
208         EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence());
209         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
210 
211         std::vector<rtcp::TransportFeedback::StatusSymbol> status_vec =
212             packet->GetStatusVector();
213         EXPECT_EQ(1u, status_vec.size());
214         EXPECT_EQ(rtcp::TransportFeedback::StatusSymbol::kReceivedSmallDelta,
215                   status_vec[0]);
216         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
217         EXPECT_EQ(1u, delta_vec.size());
218         EXPECT_EQ(kBaseTimeMs + kTooLargeDelta,
219                   (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
220         return true;
221       }))
222       .RetiresOnSaturation();
223 
224   Process();
225 }
226 
TEST_F(RemoteEstimatorProxyTest,GracefullyHandlesReorderingAndWrap)227 TEST_F(RemoteEstimatorProxyTest, GracefullyHandlesReorderingAndWrap) {
228   const int64_t kDeltaMs = 1000;
229   const uint16_t kLargeSeq = 62762;
230   IncomingPacket(kBaseSeq, kBaseTimeMs);
231   IncomingPacket(kLargeSeq, kBaseTimeMs + kDeltaMs);
232 
233   EXPECT_CALL(router_, SendFeedback(_))
234       .Times(1)
235       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
236         packet->Build();
237         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
238         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
239 
240         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
241         EXPECT_EQ(1u, delta_vec.size());
242         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
243         return true;
244       }));
245 
246   Process();
247 }
248 
TEST_F(RemoteEstimatorProxyTest,ResendsTimestampsOnReordering)249 TEST_F(RemoteEstimatorProxyTest, ResendsTimestampsOnReordering) {
250   IncomingPacket(kBaseSeq, kBaseTimeMs);
251   IncomingPacket(kBaseSeq + 2, kBaseTimeMs + 2);
252 
253   EXPECT_CALL(router_, SendFeedback(_))
254       .Times(1)
255       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
256         packet->Build();
257         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
258         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
259 
260         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
261         EXPECT_EQ(2u, delta_vec.size());
262         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
263         EXPECT_EQ(2, delta_vec[1] / 1000);
264         return true;
265       }));
266 
267   Process();
268 
269   IncomingPacket(kBaseSeq + 1, kBaseTimeMs + 1);
270 
271   EXPECT_CALL(router_, SendFeedback(_))
272       .Times(1)
273       .WillOnce(Invoke([this](rtcp::TransportFeedback* packet) {
274         packet->Build();
275         EXPECT_EQ(kBaseSeq + 1, packet->GetBaseSequence());
276         EXPECT_EQ(kMediaSsrc, packet->media_ssrc());
277 
278         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
279         EXPECT_EQ(2u, delta_vec.size());
280         EXPECT_EQ(kBaseTimeMs + 1,
281                   (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
282         EXPECT_EQ(1, delta_vec[1] / 1000);
283         return true;
284       }));
285 
286   Process();
287 }
288 
TEST_F(RemoteEstimatorProxyTest,RemovesTimestampsOutOfScope)289 TEST_F(RemoteEstimatorProxyTest, RemovesTimestampsOutOfScope) {
290   const int64_t kTimeoutTimeMs =
291       kBaseTimeMs + RemoteEstimatorProxy::kBackWindowMs;
292 
293   IncomingPacket(kBaseSeq + 2, kBaseTimeMs);
294 
295   EXPECT_CALL(router_, SendFeedback(_))
296       .Times(1)
297       .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
298         packet->Build();
299         EXPECT_EQ(kBaseSeq + 2, packet->GetBaseSequence());
300 
301         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
302         EXPECT_EQ(1u, delta_vec.size());
303         EXPECT_EQ(kBaseTimeMs, (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
304         return true;
305       }));
306 
307   Process();
308 
309   IncomingPacket(kBaseSeq + 3, kTimeoutTimeMs);  // kBaseSeq + 2 times out here.
310 
311   EXPECT_CALL(router_, SendFeedback(_))
312       .Times(1)
313       .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
314         packet->Build();
315         EXPECT_EQ(kBaseSeq + 3, packet->GetBaseSequence());
316 
317         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
318         EXPECT_EQ(1u, delta_vec.size());
319         EXPECT_EQ(kTimeoutTimeMs,
320                   (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
321         return true;
322       }));
323 
324   Process();
325 
326   // New group, with sequence starting below the first so that they may be
327   // retransmitted.
328   IncomingPacket(kBaseSeq, kBaseTimeMs - 1);
329   IncomingPacket(kBaseSeq + 1, kTimeoutTimeMs - 1);
330 
331   EXPECT_CALL(router_, SendFeedback(_))
332       .Times(1)
333       .WillOnce(Invoke([kTimeoutTimeMs, this](rtcp::TransportFeedback* packet) {
334         packet->Build();
335         EXPECT_EQ(kBaseSeq, packet->GetBaseSequence());
336 
337         // Four status entries (kBaseSeq + 3 missing).
338         EXPECT_EQ(4u, packet->GetStatusVector().size());
339 
340         // Only three actual timestamps.
341         std::vector<int64_t> delta_vec = packet->GetReceiveDeltasUs();
342         EXPECT_EQ(3u, delta_vec.size());
343         EXPECT_EQ(kBaseTimeMs - 1,
344                   (packet->GetBaseTimeUs() + delta_vec[0]) / 1000);
345         EXPECT_EQ(kTimeoutTimeMs - kBaseTimeMs, delta_vec[1] / 1000);
346         EXPECT_EQ(1, delta_vec[2] / 1000);
347         return true;
348       }));
349 
350   Process();
351 }
352 
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsZeroBeforeFirstProcess)353 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsZeroBeforeFirstProcess) {
354   EXPECT_EQ(0, proxy_.TimeUntilNextProcess());
355 }
356 
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsDefaultOnUnkownBitrate)357 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsDefaultOnUnkownBitrate) {
358   Process();
359   EXPECT_EQ(RemoteEstimatorProxy::kDefaultSendIntervalMs,
360             proxy_.TimeUntilNextProcess());
361 }
362 
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMinIntervalOn300kbps)363 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMinIntervalOn300kbps) {
364   Process();
365   proxy_.OnBitrateChanged(300000);
366   EXPECT_EQ(RemoteEstimatorProxy::kMinSendIntervalMs,
367             proxy_.TimeUntilNextProcess());
368 }
369 
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMaxIntervalOn0kbps)370 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn0kbps) {
371   Process();
372   // TimeUntilNextProcess should be limited by |kMaxSendIntervalMs| when
373   // bitrate is small. We choose 0 bps as a special case, which also tests
374   // erroneous behaviors like division-by-zero.
375   proxy_.OnBitrateChanged(0);
376   EXPECT_EQ(RemoteEstimatorProxy::kMaxSendIntervalMs,
377             proxy_.TimeUntilNextProcess());
378 }
379 
TEST_F(RemoteEstimatorProxyTest,TimeUntilNextProcessIsMaxIntervalOn20kbps)380 TEST_F(RemoteEstimatorProxyTest, TimeUntilNextProcessIsMaxIntervalOn20kbps) {
381   Process();
382   proxy_.OnBitrateChanged(20000);
383   EXPECT_EQ(RemoteEstimatorProxy::kMaxSendIntervalMs,
384             proxy_.TimeUntilNextProcess());
385 }
386 
TEST_F(RemoteEstimatorProxyTest,TwccReportsUse5PercentOfAvailableBandwidth)387 TEST_F(RemoteEstimatorProxyTest, TwccReportsUse5PercentOfAvailableBandwidth) {
388   Process();
389   proxy_.OnBitrateChanged(80000);
390   // 80kbps * 0.05 = TwccReportSize(68B * 8b/B) * 1000ms / SendInterval(136ms)
391   EXPECT_EQ(136, proxy_.TimeUntilNextProcess());
392 }
393 
394 }  // namespace webrtc
395