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

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

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

Powered by Google App Engine
This is Rietveld 408576698