OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <limits> | |
12 #include <memory> | |
13 #include <vector> | |
14 | |
15 #include "webrtc/base/checks.h" | |
16 #include "webrtc/base/mod_ops.h" | |
17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | |
18 #include "webrtc/test/gmock.h" | |
19 #include "webrtc/test/gtest.h" | |
20 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" | |
21 | |
22 using webrtc::rtcp::TransportFeedback; | |
23 using testing::Return; | |
24 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( | |
elad.alon_webrtc.org
2017/01/23 11:08:15
With the mocking gone, we can no use a status vect
| |
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 | |
OLD | NEW |