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

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

Issue 2579613003: Add TransportFeedbackPacketLossTracker. (Closed)
Patch Set: moving to voice engine Created 3 years, 12 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/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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698