OLD | NEW |
---|---|
(Empty) | |
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 <limits> | |
12 #include <memory> | |
13 #include <vector> | |
14 | |
15 #include "webrtc/base/checks.h" | |
16 #include "webrtc/base/mod_ops.h" | |
17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
18 #include "webrtc/test/gmock.h" | |
19 #include "webrtc/test/gtest.h" | |
20 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" | |
21 | |
22 using webrtc::rtcp::TransportFeedback; | |
23 using testing::Return; | |
24 | |
25 namespace webrtc { | |
26 | |
27 namespace { | |
28 | |
29 constexpr size_t kMaxConsecutiveOldReports = 4; | |
30 | |
31 // All tests are run multiple times with various baseline sequence number, | |
32 // to weed out potential bugs with wrap-around handling. | |
33 constexpr uint16_t kBases[4] = {0x0000, 0x3456, 0xc032, 0xfffe}; | |
kwiberg-webrtc
2016/12/22 02:31:41
Remove the explicit "4".
minyue-webrtc
2016/12/28 14:48:33
Done.
| |
34 | |
35 class MockTransportFeedback : public TransportFeedback { | |
36 public: | |
37 MOCK_CONST_METHOD0(GetBaseSequence, uint16_t()); | |
38 MOCK_CONST_METHOD0(GetStatusVector, | |
39 std::vector<TransportFeedback::StatusSymbol>()); | |
40 }; | |
41 | |
42 void AddTransportFeedbackAndValidate( | |
43 TransportFeedbackPacketLossTracker* tracker, | |
44 uint16_t base_sequence_num, | |
45 std::vector<bool> reception_status_vec) { | |
kwiberg-webrtc
2016/12/22 02:31:42
Pass the vector by const reference?
minyue-webrtc
2016/12/28 14:48:33
yes of course.
| |
46 std::vector<TransportFeedback::StatusSymbol> statuses; | |
47 for (bool status : reception_status_vec) { | |
48 if (!status) { | |
49 statuses.push_back(TransportFeedback::StatusSymbol::kNotReceived); | |
50 } else { | |
51 // |kReceivedSmallDelta| and |kReceivedLargeDelta| make no difference to | |
52 // TransportFeedbackPacketLossTracker. So we test only one case. | |
53 statuses.push_back(TransportFeedback::StatusSymbol::kReceivedSmallDelta); | |
54 } | |
55 } | |
56 MockTransportFeedback mock_feedback; | |
57 EXPECT_CALL(mock_feedback, GetBaseSequence()) | |
58 .WillOnce(Return(base_sequence_num)); | |
59 EXPECT_CALL(mock_feedback, GetStatusVector()).WillOnce(Return(statuses)); | |
60 tracker->OnReceivedTransportFeedback(mock_feedback); | |
61 tracker->Validate(); | |
62 } | |
63 | |
64 } // namespace | |
65 | |
66 // Sanity check on an empty window | |
kwiberg-webrtc
2016/12/22 02:31:42
Here and in several other comments: period at the
minyue-webrtc
2016/12/28 14:48:33
sure.
| |
67 TEST(TransportFeedbackPacketLossTrackerTest, EmptyWindow) { | |
68 std::unique_ptr<TransportFeedback> feedback; | |
69 float plr = 0.0f; // Packet-loss-rate | |
70 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
71 | |
72 TransportFeedbackPacketLossTracker tracker(5, 10); | |
73 | |
74 // PLR and PLED reported as unknown before reception of first feedback. | |
75 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | |
76 } | |
77 | |
78 // Sanity on partially filled window | |
kwiberg-webrtc
2016/12/22 02:31:41
Sanity check.
minyue-webrtc
2016/12/28 14:48:33
Done.
| |
79 TEST(TransportFeedbackPacketLossTrackerTest, PartiallyFilledWindow) { | |
80 for (uint16_t base : kBases) { | |
81 float plr = 0.0f; // Packet-loss-rate | |
82 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
83 TransportFeedbackPacketLossTracker tracker(5, 10); | |
84 | |
85 // PLR and PLED reported as unknown before minimum window size reached. | |
86 // Expected window contents: [] -> [1001] | |
87 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); | |
88 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | |
89 } | |
90 } | |
91 | |
92 // Sanity on minimum filled window | |
93 TEST(TransportFeedbackPacketLossTrackerTest, MinimumFilledWindow) { | |
94 for (uint16_t base : kBases) { | |
95 float plr = 0.0f; // Packet-loss-rate | |
96 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
97 TransportFeedbackPacketLossTracker tracker(5, 10); | |
98 | |
99 // PLR and PLED correctly calculated after minimum window size reached. | |
100 // Expected window contents: [] -> [10011] | |
101 AddTransportFeedbackAndValidate(&tracker, base, | |
102 {true, false, false, true, true}); | |
103 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
104 EXPECT_EQ(plr, 2.0f / 5.0f); | |
105 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
106 } | |
107 } | |
108 | |
109 // Additional reports update PLR and PLED | |
110 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { | |
111 for (uint16_t base : kBases) { | |
112 float plr = 0.0f; // Packet-loss-rate | |
113 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
114 TransportFeedbackPacketLossTracker tracker(5, 20); | |
115 | |
116 // Expected window contents: [] -> [10011] | |
117 AddTransportFeedbackAndValidate(&tracker, base, | |
118 {true, false, false, true, true}); | |
119 | |
120 // Expected window contents: [10011] -> [10011-10101] | |
121 AddTransportFeedbackAndValidate(&tracker, base + 5, | |
122 {true, false, true, false, true}); | |
123 | |
124 // Expected window contents: [10011-10101] -> [10011-10101-10001] | |
125 AddTransportFeedbackAndValidate(&tracker, base + 10, | |
126 {true, false, false, false, true}); | |
127 | |
128 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
129 EXPECT_EQ(plr, 7.0f / 15.0f); | |
130 EXPECT_EQ(cplr, 3.0f / 15.0f); | |
131 } | |
132 } | |
133 | |
134 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { | |
135 for (uint16_t base : kBases) { | |
136 float plr = 0.0f; // Packet-loss-rate | |
137 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
138 TransportFeedbackPacketLossTracker tracker(5, 10); | |
139 | |
140 // PLR and PLED correctly calculated after minimum window size reached. | |
141 // Expected window contents: [] -> [11111] | |
142 AddTransportFeedbackAndValidate(&tracker, base, | |
143 {true, true, true, true, true}); | |
144 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
145 EXPECT_EQ(plr, 0.0f); | |
146 EXPECT_EQ(cplr, 0.0f); | |
147 } | |
148 } | |
149 | |
150 TEST(TransportFeedbackPacketLossTrackerTest, AllLost) { | |
151 for (uint16_t base : kBases) { | |
152 float plr = 0.0f; // Packet-loss-rate | |
153 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
154 TransportFeedbackPacketLossTracker tracker(5, 10); | |
155 | |
156 // PLR and PLED correctly calculated after minimum window size reached. | |
157 // Expected window contents: [] -> [00000] | |
158 AddTransportFeedbackAndValidate(&tracker, base, | |
159 {false, false, false, false, false}); | |
160 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
161 EXPECT_EQ(plr, 5.0f / 5.0f); | |
162 EXPECT_EQ(cplr, 4.0f / 5.0f); | |
163 } | |
164 } | |
165 | |
166 // Repeated reports are ignored | |
167 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { | |
168 for (uint16_t base : kBases) { | |
169 float plr = 0.0f; // Packet-loss-rate | |
170 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
171 TransportFeedbackPacketLossTracker tracker(5, 10); | |
172 | |
173 // Expected window contents: [] -> [10011] | |
174 AddTransportFeedbackAndValidate(&tracker, base, | |
175 {true, false, false, true, true}); | |
176 | |
177 // Repeat entire previous feedback | |
178 // Expected window contents: [10011] -> [10011] | |
179 AddTransportFeedbackAndValidate(&tracker, base, | |
180 {true, false, false, true, true}); | |
181 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
182 EXPECT_EQ(plr, 2.0f / 5.0f); | |
183 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
184 } | |
185 } | |
186 | |
187 // Report overlap | |
188 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { | |
189 for (uint16_t base : kBases) { | |
190 float plr = 0.0f; // Packet-loss-rate | |
191 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
192 TransportFeedbackPacketLossTracker tracker(5, 10); | |
193 | |
194 // Expected window contents: [] -> [10011] | |
195 AddTransportFeedbackAndValidate(&tracker, base, | |
196 {true, false, false, true, true}); | |
197 | |
198 // Expected window contents: [10011] -> [10011-01] | |
199 AddTransportFeedbackAndValidate(&tracker, base + 3, | |
200 {true, true, false, true}); | |
201 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
202 EXPECT_EQ(plr, 3.0f / 7.0f); | |
203 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
204 } | |
205 } | |
206 | |
207 // Report conflict | |
208 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { | |
209 for (uint16_t base : kBases) { | |
210 float plr = 0.0f; // Packet-loss-rate | |
211 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
212 TransportFeedbackPacketLossTracker tracker(5, 10); | |
213 | |
214 // Expected window contents: [] -> [01001] | |
215 AddTransportFeedbackAndValidate(&tracker, base, | |
216 {false, true, false, false, true}); | |
217 | |
218 // Expected window contents: [01001] -> [11101] | |
219 // While false->true will be applied, true -> false will be ignored. | |
220 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | |
221 | |
222 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
223 EXPECT_EQ(plr, 1.0f / 5.0f); | |
224 EXPECT_EQ(cplr, 0.0f / 5.0f); | |
225 } | |
226 } | |
227 | |
228 // Skipped packets treated as unknown (not lost). | |
229 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { | |
230 for (uint16_t base : kBases) { | |
231 float plr = 0.0f; // Packet-loss-rate | |
232 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
233 TransportFeedbackPacketLossTracker tracker(5, 10); | |
234 | |
235 // Expected window contents: [] -> [10011] | |
236 AddTransportFeedbackAndValidate(&tracker, base, | |
237 {true, false, false, true, true}); | |
238 | |
239 // Expected window contents: [10011] -> [10011-101] | |
240 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); | |
241 | |
242 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
243 EXPECT_EQ(plr, 3.0f / 8.0f); | |
244 EXPECT_EQ(cplr, 1.0f / 8.0f); | |
245 } | |
246 } | |
247 | |
248 // The window retain information up to the configured max-window-size, but | |
249 // starts discarding after that. | |
250 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { | |
251 for (uint16_t base : kBases) { | |
252 float plr = 0.0f; // Packet-loss-rate | |
253 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
254 TransportFeedbackPacketLossTracker tracker(10, 10); | |
255 | |
256 // Expected window contents: [] -> [10101-00001] | |
257 AddTransportFeedbackAndValidate( | |
258 &tracker, base, | |
259 {true, false, true, false, true, false, false, false, false, true}); | |
260 | |
261 // Up to max-window-size retained. | |
262 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
263 EXPECT_EQ(plr, 6.0f / 10.0f); | |
264 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
265 | |
266 // Expected window contents: [10101-00001] -> [00001-10111] | |
267 AddTransportFeedbackAndValidate(&tracker, base + 10, | |
268 {true, false, true, true, true}); | |
269 | |
270 // After max-window-size, older entries discarded to accommodate newer ones. | |
271 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
272 EXPECT_EQ(plr, 5.0f / 10.0f); | |
273 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
274 } | |
275 } | |
276 | |
277 // Inserting into the middle of a full window works correctly. | |
278 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { | |
279 for (uint16_t base : kBases) { | |
280 float plr = 0.0f; // Packet-loss-rate | |
281 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
282 TransportFeedbackPacketLossTracker tracker(10, 10); | |
283 | |
284 // Expected window contents: [] -> [10101] | |
285 AddTransportFeedbackAndValidate(&tracker, base, | |
286 {true, false, true, false, true}); | |
287 | |
288 // Expected window contents: [10101] -> [10101-10001] | |
289 AddTransportFeedbackAndValidate(&tracker, base + 100, | |
290 {true, false, false, false, true}); | |
291 | |
292 // Setup sanity | |
293 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
294 EXPECT_EQ(plr, 5.0f / 10.0f); | |
295 EXPECT_EQ(cplr, 2.0f / 10.0f); | |
296 | |
297 // Insert into the middle of this full window - it discards the older data. | |
298 // Expected window contents: [10101-10001] -> [11111-10001] | |
299 AddTransportFeedbackAndValidate(&tracker, base + 50, | |
300 {true, true, true, true, true}); | |
301 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
302 EXPECT_EQ(plr, 3.0f / 10.0f); | |
303 EXPECT_EQ(cplr, 2.0f / 10.0f); | |
304 } | |
305 } | |
306 | |
307 // Entries in the second quadrant treated like those in the first. | |
kwiberg-webrtc
2016/12/22 02:31:41
What's a quadrant, in this context? They're mentio
minyue-webrtc
2016/12/28 14:48:33
Ok. will define at the first mentioning of it.
| |
308 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { | |
309 for (uint16_t base : kBases) { | |
310 float plr = 0.0f; // Packet-loss-rate | |
311 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
312 TransportFeedbackPacketLossTracker tracker(5, 20); | |
313 | |
314 // Expected window contents: [] -> [10011] | |
315 AddTransportFeedbackAndValidate(&tracker, base, | |
316 {true, false, false, true, true}); | |
317 | |
318 // Window *does* get updated with inputs from quadrant #2. | |
319 // Expected window contents: [10011] -> [10011-1] | |
320 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); | |
321 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
322 EXPECT_EQ(plr, 2.0f / 6.0f); | |
323 EXPECT_EQ(cplr, 1.0f / 6.0f); | |
324 | |
325 // Correct recognition of quadrant #2: up to, but not including, base + | |
326 // 0x8000 | |
327 // Expected window contents: [10011-1] -> [10011-11] | |
328 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); | |
329 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
330 EXPECT_EQ(plr, 2.0f / 7.0f); | |
331 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
332 } | |
333 } | |
334 | |
335 // Insertion into the third quardrant moves the base of the window. | |
kwiberg-webrtc
2016/12/22 02:31:42
spelling
minyue-webrtc
2016/12/28 14:48:33
eagle eye :)
kwiberg-webrtc
2017/01/05 02:51:12
No, I was just searching for uses of "quadrant", a
| |
336 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) { | |
337 for (uint16_t base : kBases) { | |
338 float plr = 0.0f; // Packet-loss-rate | |
339 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
340 TransportFeedbackPacketLossTracker tracker(5, 20); | |
341 | |
342 // Seed the test. | |
343 // Expected window contents: [] -> [10011-01] | |
344 AddTransportFeedbackAndValidate( | |
345 &tracker, base, {true, false, false, true, true, false, true}); | |
346 | |
347 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so | |
348 // that | |
349 // at least one (oldest) report shifts out of window. | |
350 // Expected window contents: [10011-01] -> [10110-01] | |
351 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
352 {true, false, false, true}); | |
353 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
354 EXPECT_EQ(plr, 3.0f / 7.0f); | |
355 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
356 | |
357 // The base can move more than once, because the minimum quadrant-1 packets | |
358 // were dropped out of the window, and some remain. | |
359 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | |
360 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
361 EXPECT_EQ(plr, 2.0f / 7.0f); | |
362 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
363 } | |
364 } | |
365 | |
366 // After the base has moved due to insertion into the third quardrant, it is | |
367 // still possible to insert into the middle of the window and obtain the correct | |
368 // PLR and PLED. Insertion into the middle before the max window size has been | |
369 // achieved does not cause older packets to be dropped. | |
370 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) { | |
371 for (uint16_t base : kBases) { | |
372 float plr = 0.0f; // Packet-loss-rate | |
373 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
374 TransportFeedbackPacketLossTracker tracker(5, 20); | |
375 | |
376 // Seed the test. | |
377 // Expected window contents: [] -> [10011-01] | |
378 AddTransportFeedbackAndValidate( | |
379 &tracker, base, {true, false, false, true, true, false, true}); | |
380 | |
381 // Expected window contents: [10011-01] -> [10110-01] | |
382 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
383 {true, false, false, true}); | |
384 | |
385 // Inserting into the middle still works after the base has shifted. | |
386 // Expected window contents: [10110-01] -> [10110-01011-001] | |
387 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, | |
388 {true, false, false, true, false, true}); | |
389 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
390 EXPECT_EQ(plr, 6.0f / 13.0f); | |
391 EXPECT_EQ(cplr, 2.0f / 13.0f); | |
392 | |
393 // The base can keep moving after inserting into the middle. | |
394 // Expected window contents: [10110-01011-001] -> [11001-01100-111] | |
395 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | |
396 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
397 EXPECT_EQ(plr, 5.0f / 13.0f); | |
398 EXPECT_EQ(cplr, 2.0f / 13.0f); | |
399 } | |
400 } | |
401 | |
402 // After moving the base of the window, the max window size is still observed. | |
403 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuardrantObservesMaxWindow) { | |
404 for (uint16_t base : kBases) { | |
405 float plr = 0.0f; // Packet-loss-rate | |
406 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
407 TransportFeedbackPacketLossTracker tracker(10, 15); | |
408 | |
409 // Expected window contents: [] -> [10011-10101] | |
410 AddTransportFeedbackAndValidate( | |
411 &tracker, base, | |
412 {true, false, false, true, true, true, false, true, false, true}); | |
413 | |
414 // Expected window contents: [10011-10101] -> [11101-01101] | |
415 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
416 {true, false, true}); | |
417 | |
418 // Push into middle until max window is reached. | |
419 // Expected window contents: [11101-01101] -> [11101-01100-01101] | |
420 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | |
421 {true, false, false, false, true}); | |
422 | |
423 // Setup sanity | |
424 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
425 EXPECT_EQ(plr, 6.0f / 15.0f); | |
426 EXPECT_EQ(cplr, 2.0f / 15.0f); | |
427 | |
428 // Pushing new packets into the middle would discard older packets. | |
429 // Expected window contents: [11101-01100-01101] -> [01011-00011-01101] | |
430 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5, | |
431 {true, false, true}); | |
432 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
433 EXPECT_EQ(plr, 7.0f / 15.0f); | |
434 EXPECT_EQ(cplr, 2.0f / 15.0f); | |
435 } | |
436 } | |
437 | |
438 // A new feedback in quadrant #3 might shift enough old feedbacks out of window, | |
439 // that we'd go back to an unknown PLR and PLED. | |
440 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) { | |
441 for (uint16_t base : kBases) { | |
442 float plr = 0.0f; // Packet-loss-rate | |
443 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
444 TransportFeedbackPacketLossTracker tracker(5, 20); | |
445 | |
446 // Expected window contents: [] -> [10011-10101] | |
447 AddTransportFeedbackAndValidate( | |
448 &tracker, base, | |
449 {true, false, false, true, true, true, false, true, false, true}); | |
450 EXPECT_TRUE( | |
451 tracker.GetPacketLossRates(&plr, &cplr)); // Min window reached. | |
452 | |
453 // A new feedback in quadrant #3 might shift enough old feedbacks out of | |
454 // window, that we'd go back to an unknown PLR and PLED. This *doesn't* | |
455 // necessarily mean all of the old ones were discarded, though. | |
456 // Expected window contents: [10011-10101] -> [0111] | |
457 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); | |
458 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr)); | |
459 | |
460 // Inserting in the middle shows that though some of the elements were | |
461 // ejected, some were retained. | |
462 // Expected window contents: [] -> [01101-11] | |
463 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | |
464 {true, false, true}); | |
465 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
466 EXPECT_EQ(plr, 2.0f / 7.0f); | |
467 EXPECT_EQ(cplr, 0.0f / 7.0f); | |
468 } | |
469 } | |
470 | |
471 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | |
472 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) { | |
473 for (uint16_t base : kBases) { | |
474 float plr = 0.0f; // Packet-loss-rate | |
475 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
476 TransportFeedbackPacketLossTracker tracker(5, 20); | |
477 | |
478 // Expected window contents: [] -> [10011] | |
479 AddTransportFeedbackAndValidate(&tracker, base, | |
480 {true, false, false, true, true}); | |
481 | |
482 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
483 // consecutive reports). | |
484 // Expected window contents: [10011] -> [10011] | |
485 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
486 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
487 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
488 EXPECT_EQ(plr, 2.0f / 5.0f); | |
489 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
490 } | |
491 } | |
492 } | |
493 | |
494 // Receiving a packet from quadrant #1 resets the counter for quadrant #4. | |
495 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) { | |
496 for (uint16_t base : kBases) { | |
497 float plr = 0.0f; // Packet-loss-rate | |
498 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
499 TransportFeedbackPacketLossTracker tracker(5, 20); | |
500 | |
501 // Expected window contents: [] -> [10011] | |
502 AddTransportFeedbackAndValidate(&tracker, base, | |
503 {true, false, false, true, true}); | |
504 | |
505 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
506 // consecutive reports). | |
507 // Expected window contents: [10011] -> [10011] | |
508 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
509 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
510 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
511 EXPECT_EQ(plr, 2.0f / 5.0f); | |
512 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
513 } | |
514 | |
515 // If we receive a feedback in quadrant #1, the above counter is reset. | |
516 // Expected window contents: [10011] -> [10011-1] | |
517 AddTransportFeedbackAndValidate(&tracker, base + 0x000f, {true}); | |
518 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
519 // Note: though the feedback message reports three packets, it only gets | |
520 // counted once. | |
521 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
522 {true, false, true}); | |
523 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
524 EXPECT_EQ(plr, 2.0f / 6.0f); | |
525 EXPECT_EQ(cplr, 1.0f / 6.0f); | |
526 } | |
527 } | |
528 } | |
529 | |
530 // Receiving a packet from quadrant #2 resets the counter for quadrant #4. | |
531 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) { | |
532 for (uint16_t base : kBases) { | |
533 float plr = 0.0f; // Packet-loss-rate | |
534 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
535 TransportFeedbackPacketLossTracker tracker(5, 20); | |
536 | |
537 // Expected window contents: [] -> [10011] | |
538 AddTransportFeedbackAndValidate(&tracker, base, | |
539 {true, false, false, true, true}); | |
540 | |
541 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
542 // consecutive reports). | |
543 // Expected window contents: [10011] -> [10011] | |
544 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
545 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
546 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
547 EXPECT_EQ(plr, 2.0f / 5.0f); | |
548 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
549 } | |
550 | |
551 // If we receive a feedback in quadrant #1, the above counter is reset. | |
552 // Expected window contents: [10011] -> [10011-1] | |
553 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true}); | |
554 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
555 // Note: though the feedback message reports three packets, it only gets | |
556 // counted once. | |
557 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
558 {true, false, true}); | |
559 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
560 EXPECT_EQ(plr, 2.0f / 6.0f); | |
561 EXPECT_EQ(cplr, 1.0f / 6.0f); | |
562 } | |
563 } | |
564 } | |
565 | |
566 // Receiving a packet from quadrant #3 resets the counter for quadrant #4. | |
567 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ3) { | |
568 for (uint16_t base : kBases) { | |
569 float plr = 0.0f; // Packet-loss-rate | |
570 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
571 TransportFeedbackPacketLossTracker tracker(5, 20); | |
572 | |
573 // Expected window contents: [] -> [10011-10001] | |
574 AddTransportFeedbackAndValidate( | |
575 &tracker, base, | |
576 {true, false, false, true, true, true, false, false, false, true}); | |
577 | |
578 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
579 // consecutive reports). | |
580 // Expected window contents: [10011-10001] -> [10011-10001] | |
581 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
582 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
583 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
584 EXPECT_EQ(plr, 5.0f / 10.0f); | |
585 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
586 } | |
587 | |
588 // If we receive a feedback in quadrant #1, the above counter is reset. | |
589 // Expected window contents: [10011-10001] -> [11100-01111] | |
590 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
591 {true, true, true}); | |
592 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
593 // Note: though the feedback message reports three packets, it only gets | |
594 // counted once. | |
595 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10, | |
596 {true, false, true}); | |
597 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
598 EXPECT_EQ(plr, 3.0f / 10.0f); | |
599 EXPECT_EQ(cplr, 2.0f / 10.0f); | |
600 } | |
601 } | |
602 } | |
603 | |
604 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | |
605 // After that, the window is reset. | |
606 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) { | |
607 for (uint16_t base : kBases) { | |
608 float plr = 0.0f; // Packet-loss-rate | |
609 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
610 TransportFeedbackPacketLossTracker tracker(5, 20); | |
611 | |
612 // Expected window contents: [] -> [10011-10001] | |
613 AddTransportFeedbackAndValidate( | |
614 &tracker, base, | |
615 {true, false, false, true, true, true, false, false, false, true}); | |
616 | |
617 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored. | |
618 // It doesn't matter that they consist of multiple packets - each report | |
619 // is only counted once. | |
620 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
621 // Expected window contents: [10011-10001] -> [10011-10001] | |
622 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
623 {true, true, false, true}); | |
624 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
625 EXPECT_EQ(plr, 5.0f / 10.0f); | |
626 EXPECT_EQ(cplr, 3.0f / 10.0f); | |
627 } | |
628 | |
629 // One additional feedback in quardrant #4 brings us over | |
630 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the | |
631 // window. | |
632 // Note: The report doesn't have to be the same as the previous ones. | |
633 // Expected window contents: [10011-10001] -> [10011] | |
634 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
635 {true, false, false, true, true}); | |
636 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
637 | |
638 // The new window is not completely empty - it's been seeded with the | |
639 // packets reported in the feedback that has triggered the reset. | |
640 EXPECT_EQ(plr, 2.0f / 5.0f); | |
641 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
642 } | |
643 } | |
644 | |
645 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2). | |
646 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) { | |
647 for (uint16_t base : kBases) { | |
648 float plr = 0.0f; // Packet-loss-rate | |
649 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
650 TransportFeedbackPacketLossTracker tracker(5, 20); | |
651 | |
652 // Expected window contents: [] -> [10011] | |
653 AddTransportFeedbackAndValidate(&tracker, base, | |
654 {true, false, false, true, true}); | |
655 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
656 | |
657 // A feedback with entries in both quadrant #1 and #2 gets both counted: | |
658 // Expected window contents: [10011] -> [10011-11] | |
659 AddTransportFeedbackAndValidate(&tracker, base + 0x3fff, {true, true}); | |
660 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
661 EXPECT_EQ(plr, 2.0f / 7.0f); | |
662 EXPECT_EQ(cplr, 1.0f / 7.0f); | |
663 } | |
664 } | |
665 | |
666 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | |
667 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) { | |
668 for (uint16_t base : kBases) { | |
669 float plr = 0.0f; // Packet-loss-rate | |
670 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
671 TransportFeedbackPacketLossTracker tracker(5, 20); | |
672 | |
673 // Expected window contents: [] -> [10011-00001] | |
674 AddTransportFeedbackAndValidate( | |
675 &tracker, base, | |
676 {true, false, false, true, true, false, false, false, false, true}); | |
677 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
678 EXPECT_EQ(plr, 6.0f / 10.0f); | |
679 EXPECT_EQ(cplr, 4.0f / 10.0f); | |
680 | |
681 // A feedback with entries in both quadrant #2 and #3 gets both counted, | |
682 // but only those from #3 trigger throwing out old entries from quadrant #1: | |
683 // Expected window contents: [10011-00001] -> [01100-00110-01] | |
684 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe, | |
685 {true, false, false, true}); | |
686 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
687 EXPECT_EQ(plr, 7.0f / 12.0f); | |
688 EXPECT_EQ(cplr, 4.0f / 12.0f); | |
689 } | |
690 } | |
691 | |
692 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | |
693 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) { | |
694 for (uint16_t base : kBases) { | |
695 float plr = 0.0f; // Packet-loss-rate | |
696 float cplr = 0.0f; // Consecutive-packet-loss-rate | |
697 | |
698 TransportFeedbackPacketLossTracker tracker(5, 20); | |
699 | |
700 // Expected window contents: [] -> [10011-00001] | |
701 AddTransportFeedbackAndValidate( | |
702 &tracker, base, | |
703 {true, false, false, true, true, false, false, false, false, true}); | |
704 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
705 EXPECT_EQ(plr, 6.0f / 10.0f); | |
706 EXPECT_EQ(cplr, 4.0f / 10.0f); | |
707 | |
708 // A feedback with entries in both quadrant #3 and #4 would have the entries | |
709 // from quardrant #3 shift enough quadrant #1 entries out of window, that | |
710 // by the time the #4 packets are examined, the moving baseline has made | |
711 // them into quadrant #3 packets. | |
712 // Expected window contents: [10011-00001] -> [10011] | |
713 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff, | |
714 {true, false, false, true, true}); | |
715 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr)); | |
716 EXPECT_EQ(plr, 2.0f / 5.0f); | |
717 EXPECT_EQ(cplr, 1.0f / 5.0f); | |
718 } | |
719 } | |
720 | |
721 } // namespace webrtc | |
OLD | NEW |