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

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) 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;
danilchap 2017/01/19 11:26:54 e.g. here this implementation might be used instea
minyue-webrtc 2017/01/19 11:28:39 right. will do
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 // Test the behavior of TransportFeedbackPacketLossTracker when there is a gap
303 // of more than 0x4000 in sequence number, i.e., 1/4 of total sequence numbers.
304 // Since the sequence number is used in a circular manner, i.e., after 0xffff,
305 // the sequence number wraps back to 0x0000, we refer to 1/4 of total sequence
306 // numbers as a quadrant. In this test, e.g., three transport feedbacks are
307 // added, whereas the 2nd and 3rd lie in the second quadrant w.r.t. the 1st
308 // feedback.
309 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) {
310 for (uint16_t base : kBases) {
311 float plr = 0.0f; // Packet-loss-rate
312 float cplr = 0.0f; // Consecutive-packet-loss-rate
313 TransportFeedbackPacketLossTracker tracker(5, 20);
314
315 // Expected window contents: [] -> [10011].
316 AddTransportFeedbackAndValidate(&tracker, base,
317 {true, false, false, true, true});
318
319 // Window *does* get updated with inputs from quadrant #2.
320 // Expected window contents: [10011] -> [10011-1].
321 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true});
322 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
323 EXPECT_EQ(plr, 2.0f / 6.0f);
324 EXPECT_EQ(cplr, 1.0f / 6.0f);
325
326 // Correct recognition of quadrant #2: up to, but not including, base +
327 // 0x8000
328 // Expected window contents: [10011-1] -> [10011-11].
329 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true});
330 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
331 EXPECT_EQ(plr, 2.0f / 7.0f);
332 EXPECT_EQ(cplr, 1.0f / 7.0f);
333 }
334 }
335
336 // Insertion into the third quadrant moves the base of the window.
337 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) {
338 for (uint16_t base : kBases) {
339 float plr = 0.0f; // Packet-loss-rate
340 float cplr = 0.0f; // Consecutive-packet-loss-rate
341 TransportFeedbackPacketLossTracker tracker(5, 20);
342
343 // Seed the test.
344 // Expected window contents: [] -> [10011-01].
345 AddTransportFeedbackAndValidate(
346 &tracker, base, {true, false, false, true, true, false, true});
347
348 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so
349 // that
350 // at least one (oldest) report shifts out of window.
351 // Expected window contents: [10011-01] -> [10110-01].
352 AddTransportFeedbackAndValidate(&tracker, base + 0x8000,
353 {true, false, false, true});
354 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
355 EXPECT_EQ(plr, 3.0f / 7.0f);
356 EXPECT_EQ(cplr, 1.0f / 7.0f);
357
358 // The base can move more than once, because the minimum quadrant-1 packets
359 // were dropped out of the window, and some remain.
360 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true});
361 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
362 EXPECT_EQ(plr, 2.0f / 7.0f);
363 EXPECT_EQ(cplr, 1.0f / 7.0f);
364 }
365 }
366
367 // After the base has moved due to insertion into the third quadrant, it is
368 // still possible to insert into the middle of the window and obtain the correct
369 // PLR and CPLR. Insertion into the middle before the max window size has been
370 // achieved does not cause older packets to be dropped.
371 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) {
372 for (uint16_t base : kBases) {
373 float plr = 0.0f; // Packet-loss-rate
374 float cplr = 0.0f; // Consecutive-packet-loss-rate
375 TransportFeedbackPacketLossTracker tracker(5, 20);
376
377 // Seed the test.
378 // Expected window contents: [] -> [10011-01].
379 AddTransportFeedbackAndValidate(
380 &tracker, base, {true, false, false, true, true, false, true});
381
382 // Expected window contents: [10011-01] -> [10110-01].
383 AddTransportFeedbackAndValidate(&tracker, base + 0x8000,
384 {true, false, false, true});
385
386 // Inserting into the middle still works after the base has shifted.
387 // Expected window contents: [10110-01] -> [10110-01011-001].
388 AddTransportFeedbackAndValidate(&tracker, base + 0x5000,
389 {true, false, false, true, false, true});
390 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
391 EXPECT_EQ(plr, 6.0f / 13.0f);
392 EXPECT_EQ(cplr, 2.0f / 13.0f);
393
394 // The base can keep moving after inserting into the middle.
395 // Expected window contents: [10110-01011-001] -> [11001-01100-111].
396 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true});
397 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
398 EXPECT_EQ(plr, 5.0f / 13.0f);
399 EXPECT_EQ(cplr, 2.0f / 13.0f);
400 }
401 }
402
403 // After moving the base of the window, the max window size is still observed.
404 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantObservesMaxWindow) {
405 for (uint16_t base : kBases) {
406 float plr = 0.0f; // Packet-loss-rate
407 float cplr = 0.0f; // Consecutive-packet-loss-rate
408 TransportFeedbackPacketLossTracker tracker(10, 15);
409
410 // Expected window contents: [] -> [10011-10101].
411 AddTransportFeedbackAndValidate(
412 &tracker, base,
413 {true, false, false, true, true, true, false, true, false, true});
414
415 // Expected window contents: [10011-10101] -> [11101-01101].
416 AddTransportFeedbackAndValidate(&tracker, base + 0x8000,
417 {true, false, true});
418
419 // Push into middle until max window is reached.
420 // Expected window contents: [11101-01101] -> [11101-01100-01101].
421 AddTransportFeedbackAndValidate(&tracker, base + 0x4000,
422 {true, false, false, false, true});
423
424 // Setup sanity
425 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
426 EXPECT_EQ(plr, 6.0f / 15.0f);
427 EXPECT_EQ(cplr, 2.0f / 15.0f);
428
429 // Pushing new packets into the middle would discard older packets.
430 // Expected window contents: [11101-01100-01101] -> [01011-00011-01101].
431 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5,
432 {true, false, true});
433 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
434 EXPECT_EQ(plr, 7.0f / 15.0f);
435 EXPECT_EQ(cplr, 2.0f / 15.0f);
436 }
437 }
438
439 // A new feedback in quadrant #3 might shift enough old feedbacks out of window,
440 // that we'd go back to an unknown PLR and CPLR.
441 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) {
442 for (uint16_t base : kBases) {
443 float plr = 0.0f; // Packet-loss-rate
444 float cplr = 0.0f; // Consecutive-packet-loss-rate
445 TransportFeedbackPacketLossTracker tracker(5, 20);
446
447 // Expected window contents: [] -> [10011-10101].
448 AddTransportFeedbackAndValidate(
449 &tracker, base,
450 {true, false, false, true, true, true, false, true, false, true});
451 EXPECT_TRUE(
452 tracker.GetPacketLossRates(&plr, &cplr)); // Min window reached.
453
454 // A new feedback in quadrant #3 might shift enough old feedbacks out of
455 // window, that we'd go back to an unknown PLR and CPLR. This *doesn't*
456 // necessarily mean all of the old ones were discarded, though.
457 // Expected window contents: [10011-10101] -> [0111].
458 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true});
459 EXPECT_FALSE(tracker.GetPacketLossRates(&plr, &cplr));
460
461 // Inserting in the middle shows that though some of the elements were
462 // ejected, some were retained.
463 // Expected window contents: [] -> [01101-11].
464 AddTransportFeedbackAndValidate(&tracker, base + 0x4000,
465 {true, false, true});
466 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
467 EXPECT_EQ(plr, 2.0f / 7.0f);
468 EXPECT_EQ(cplr, 0.0f / 7.0f);
469 }
470 }
471
472 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times.
473 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) {
474 for (uint16_t base : kBases) {
475 float plr = 0.0f; // Packet-loss-rate
476 float cplr = 0.0f; // Consecutive-packet-loss-rate
477 TransportFeedbackPacketLossTracker tracker(5, 20);
478
479 // Expected window contents: [] -> [10011].
480 AddTransportFeedbackAndValidate(&tracker, base,
481 {true, false, false, true, true});
482
483 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports
484 // consecutive reports).
485 // Expected window contents: [10011] -> [10011].
486 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
487 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true});
488 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
489 EXPECT_EQ(plr, 2.0f / 5.0f);
490 EXPECT_EQ(cplr, 1.0f / 5.0f);
491 }
492 }
493 }
494
495 // Receiving a packet from quadrant #1 resets the counter for quadrant #4.
496 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) {
497 for (uint16_t base : kBases) {
498 float plr = 0.0f; // Packet-loss-rate
499 float cplr = 0.0f; // Consecutive-packet-loss-rate
500 TransportFeedbackPacketLossTracker tracker(5, 20);
501
502 // Expected window contents: [] -> [10011].
503 AddTransportFeedbackAndValidate(&tracker, base,
504 {true, false, false, true, true});
505
506 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports
507 // consecutive reports).
508 // Expected window contents: [10011] -> [10011].
509 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
510 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true});
511 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
512 EXPECT_EQ(plr, 2.0f / 5.0f);
513 EXPECT_EQ(cplr, 1.0f / 5.0f);
514 }
515
516 // If we receive a feedback in quadrant #1, the above counter is reset.
517 // Expected window contents: [10011] -> [10011-1].
518 AddTransportFeedbackAndValidate(&tracker, base + 0x000f, {true});
519 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
520 // Note: though the feedback message reports three packets, it only gets
521 // counted once.
522 AddTransportFeedbackAndValidate(&tracker, base + 0xc000,
523 {true, false, true});
524 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
525 EXPECT_EQ(plr, 2.0f / 6.0f);
526 EXPECT_EQ(cplr, 1.0f / 6.0f);
527 }
528 }
529 }
530
531 // Receiving a packet from quadrant #2 resets the counter for quadrant #4.
532 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) {
533 for (uint16_t base : kBases) {
534 float plr = 0.0f; // Packet-loss-rate
535 float cplr = 0.0f; // Consecutive-packet-loss-rate
536 TransportFeedbackPacketLossTracker tracker(5, 20);
537
538 // Expected window contents: [] -> [10011].
539 AddTransportFeedbackAndValidate(&tracker, base,
540 {true, false, false, true, true});
541
542 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports
543 // consecutive reports).
544 // Expected window contents: [10011] -> [10011].
545 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
546 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true});
547 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
548 EXPECT_EQ(plr, 2.0f / 5.0f);
549 EXPECT_EQ(cplr, 1.0f / 5.0f);
550 }
551
552 // If we receive a feedback in quadrant #1, the above counter is reset.
553 // Expected window contents: [10011] -> [10011-1].
554 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true});
555 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
556 // Note: though the feedback message reports three packets, it only gets
557 // counted once.
558 AddTransportFeedbackAndValidate(&tracker, base + 0xc000,
559 {true, false, true});
560 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
561 EXPECT_EQ(plr, 2.0f / 6.0f);
562 EXPECT_EQ(cplr, 1.0f / 6.0f);
563 }
564 }
565 }
566
567 // Receiving a packet from quadrant #3 resets the counter for quadrant #4.
568 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ3) {
569 for (uint16_t base : kBases) {
570 float plr = 0.0f; // Packet-loss-rate
571 float cplr = 0.0f; // Consecutive-packet-loss-rate
572 TransportFeedbackPacketLossTracker tracker(5, 20);
573
574 // Expected window contents: [] -> [10011-10001].
575 AddTransportFeedbackAndValidate(
576 &tracker, base,
577 {true, false, false, true, true, true, false, false, false, true});
578
579 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports
580 // consecutive reports).
581 // Expected window contents: [10011-10001] -> [10011-10001].
582 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
583 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true});
584 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
585 EXPECT_EQ(plr, 5.0f / 10.0f);
586 EXPECT_EQ(cplr, 3.0f / 10.0f);
587 }
588
589 // If we receive a feedback in quadrant #1, the above counter is reset.
590 // Expected window contents: [10011-10001] -> [11100-01111].
591 AddTransportFeedbackAndValidate(&tracker, base + 0x8000,
592 {true, true, true});
593 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
594 // Note: though the feedback message reports three packets, it only gets
595 // counted once.
596 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10,
597 {true, false, true});
598 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
599 EXPECT_EQ(plr, 3.0f / 10.0f);
600 EXPECT_EQ(cplr, 2.0f / 10.0f);
601 }
602 }
603 }
604
605 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times.
606 // After that, the window is reset.
607 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) {
608 for (uint16_t base : kBases) {
609 float plr = 0.0f; // Packet-loss-rate
610 float cplr = 0.0f; // Consecutive-packet-loss-rate
611 TransportFeedbackPacketLossTracker tracker(5, 20);
612
613 // Expected window contents: [] -> [10011-10001].
614 AddTransportFeedbackAndValidate(
615 &tracker, base,
616 {true, false, false, true, true, true, false, false, false, true});
617
618 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored.
619 // It doesn't matter that they consist of multiple packets - each report
620 // is only counted once.
621 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) {
622 // Expected window contents: [10011-10001] -> [10011-10001].
623 AddTransportFeedbackAndValidate(&tracker, base + 0xc000,
624 {true, true, false, true});
625 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
626 EXPECT_EQ(plr, 5.0f / 10.0f);
627 EXPECT_EQ(cplr, 3.0f / 10.0f);
628 }
629
630 // One additional feedback in quadrant #4 brings us over
631 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the
632 // window.
633 // Note: The report doesn't have to be the same as the previous ones.
634 // Expected window contents: [10011-10001] -> [10011].
635 AddTransportFeedbackAndValidate(&tracker, base + 0xc000,
636 {true, false, false, true, true});
637 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
638
639 // The new window is not completely empty - it's been seeded with the
640 // packets reported in the feedback that has triggered the reset.
641 EXPECT_EQ(plr, 2.0f / 5.0f);
642 EXPECT_EQ(cplr, 1.0f / 5.0f);
643 }
644 }
645
646 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2).
647 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) {
648 for (uint16_t base : kBases) {
649 float plr = 0.0f; // Packet-loss-rate
650 float cplr = 0.0f; // Consecutive-packet-loss-rate
651 TransportFeedbackPacketLossTracker tracker(5, 20);
652
653 // Expected window contents: [] -> [10011].
654 AddTransportFeedbackAndValidate(&tracker, base,
655 {true, false, false, true, true});
656 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
657
658 // A feedback with entries in both quadrant #1 and #2 gets both counted:
659 // Expected window contents: [10011] -> [10011-11].
660 AddTransportFeedbackAndValidate(&tracker, base + 0x3fff, {true, true});
661 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
662 EXPECT_EQ(plr, 2.0f / 7.0f);
663 EXPECT_EQ(cplr, 1.0f / 7.0f);
664 }
665 }
666
667 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3).
668 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) {
669 for (uint16_t base : kBases) {
670 float plr = 0.0f; // Packet-loss-rate
671 float cplr = 0.0f; // Consecutive-packet-loss-rate
672 TransportFeedbackPacketLossTracker tracker(5, 20);
673
674 // Expected window contents: [] -> [10011-00001].
675 AddTransportFeedbackAndValidate(
676 &tracker, base,
677 {true, false, false, true, true, false, false, false, false, true});
678 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
679 EXPECT_EQ(plr, 6.0f / 10.0f);
680 EXPECT_EQ(cplr, 4.0f / 10.0f);
681
682 // A feedback with entries in both quadrant #2 and #3 gets both counted,
683 // but only those from #3 trigger throwing out old entries from quadrant #1:
684 // Expected window contents: [10011-00001] -> [01100-00110-01].
685 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe,
686 {true, false, false, true});
687 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
688 EXPECT_EQ(plr, 7.0f / 12.0f);
689 EXPECT_EQ(cplr, 4.0f / 12.0f);
690 }
691 }
692
693 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3).
694 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) {
695 for (uint16_t base : kBases) {
696 float plr = 0.0f; // Packet-loss-rate
697 float cplr = 0.0f; // Consecutive-packet-loss-rate
698
699 TransportFeedbackPacketLossTracker tracker(5, 20);
700
701 // Expected window contents: [] -> [10011-00001].
702 AddTransportFeedbackAndValidate(
703 &tracker, base,
704 {true, false, false, true, true, false, false, false, false, true});
705 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
706 EXPECT_EQ(plr, 6.0f / 10.0f);
707 EXPECT_EQ(cplr, 4.0f / 10.0f);
708
709 // A feedback with entries in both quadrant #3 and #4 would have the entries
710 // from quadrant #3 shift enough quadrant #1 entries out of window, that
711 // by the time the #4 packets are examined, the moving baseline has made
712 // them into quadrant #3 packets.
713 // Expected window contents: [10011-00001] -> [10011].
714 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff,
715 {true, false, false, true, true});
716 EXPECT_TRUE(tracker.GetPacketLossRates(&plr, &cplr));
717 EXPECT_EQ(plr, 2.0f / 5.0f);
718 EXPECT_EQ(cplr, 1.0f / 5.0f);
719 }
720 }
721
722 } // 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