Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(480)

Side by Side Diff: webrtc/voice_engine/transport_feedback_packet_loss_tracker_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698