OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 #include <limits> | 11 #include <limits> |
12 #include <memory> | 12 #include <memory> |
13 #include <vector> | 13 #include <vector> |
14 | 14 |
15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/mod_ops.h" | 16 #include "webrtc/base/mod_ops.h" |
17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" | 17 #include "webrtc/modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h" |
18 #include "webrtc/test/gmock.h" | 18 #include "webrtc/test/gmock.h" |
19 #include "webrtc/test/gtest.h" | 19 #include "webrtc/test/gtest.h" |
20 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" | 20 #include "webrtc/voice_engine/transport_feedback_packet_loss_tracker.h" |
21 | 21 |
22 using webrtc::rtcp::TransportFeedback; | 22 using webrtc::rtcp::TransportFeedback; |
23 using testing::Return; | 23 using testing::Return; |
24 using testing::StrictMock; | 24 using testing::StrictMock; |
25 | 25 |
26 namespace webrtc { | 26 namespace webrtc { |
27 | 27 |
28 namespace { | 28 namespace { |
29 | 29 |
30 constexpr size_t kMaxConsecutiveOldReports = 4; | |
31 | |
32 // All tests are run multiple times with various baseline sequence number, | 30 // All tests are run multiple times with various baseline sequence number, |
33 // to weed out potential bugs with wrap-around handling. | 31 // to weed out potential bugs with wrap-around handling. |
34 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; | 32 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; |
35 | 33 |
34 void SimulatePacketTransmission(TransportFeedbackPacketLossTracker* tracker, | |
minyue-webrtc
2017/02/14 16:46:59
"Simulate" may not be needed since the test itself
elad.alon_webrtc.org
2017/02/15 16:47:36
Done.
| |
35 uint16_t seq_num, | |
36 bool with_validation = true) { | |
37 tracker->OnPacketAdded(seq_num); | |
38 if (with_validation) { | |
39 tracker->Validate(); | |
40 } | |
41 } | |
42 | |
43 void SimulatePacketTransmission(TransportFeedbackPacketLossTracker* tracker, | |
44 const std::vector<uint16_t>& seq_nums, | |
45 bool validate_all = true) { | |
46 for (uint16_t seq_num : seq_nums) { | |
47 tracker->OnPacketAdded(seq_num); | |
48 if (validate_all) { | |
49 tracker->Validate(); | |
50 } | |
51 } | |
52 // We've either validated after each packet, or, for making sure the UT | |
53 // doesn't run too long, we might validate only at the end of the range. | |
54 if (!validate_all) { | |
55 tracker->Validate(); | |
56 } | |
57 } | |
58 | |
59 void SimulatePacketTransmissionRange( | |
60 TransportFeedbackPacketLossTracker* tracker, | |
61 uint16_t first_seq_num, | |
62 size_t num_of_seq_nums, | |
63 bool validate_all = true) { | |
64 for (size_t i = 0; i < num_of_seq_nums; i++) { | |
65 SimulatePacketTransmission(tracker, first_seq_num + i, validate_all); | |
minyue-webrtc
2017/02/14 16:46:59
can we use SimulatePacketTransmission ver.2 to avo
elad.alon_webrtc.org
2017/02/15 16:47:36
Done.
| |
66 } | |
67 // We've either validated after each packet, or, for making sure the UT | |
68 // doesn't run too long, we might validate only at the end of the range. | |
69 if (!validate_all) { | |
70 tracker->Validate(); | |
71 } | |
72 } | |
73 | |
36 void AddTransportFeedbackAndValidate( | 74 void AddTransportFeedbackAndValidate( |
37 TransportFeedbackPacketLossTracker* tracker, | 75 TransportFeedbackPacketLossTracker* tracker, |
38 uint16_t base_sequence_num, | 76 uint16_t base_sequence_num, |
39 const std::vector<bool>& reception_status_vec) { | 77 const std::vector<bool>& reception_status_vec) { |
40 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. | 78 const int64_t kBaseTimeUs = 1234; // Irrelevant to this test. |
41 TransportFeedback test_feedback; | 79 TransportFeedback test_feedback; |
42 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); | 80 test_feedback.SetBase(base_sequence_num, kBaseTimeUs); |
43 uint16_t sequence_num = base_sequence_num; | 81 uint16_t sequence_num = base_sequence_num; |
44 for (bool status : reception_status_vec) { | 82 for (bool status : reception_status_vec) { |
45 if (status) | 83 if (status) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 } | 161 } |
124 | 162 |
125 // Sanity check on minimum filled window - PLR known, RPLR unknown. | 163 // Sanity check on minimum filled window - PLR known, RPLR unknown. |
126 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { | 164 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { |
127 for (uint16_t base : kBases) { | 165 for (uint16_t base : kBases) { |
128 TransportFeedbackPacketLossTracker tracker(10, 5, 5); | 166 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
129 | 167 |
130 // PLR correctly calculated after minimum window size reached. | 168 // PLR correctly calculated after minimum window size reached. |
131 // RPLR not necessarily known at that time (not if min-pairs not reached). | 169 // RPLR not necessarily known at that time (not if min-pairs not reached). |
132 // Expected window contents: [] -> [10011]. | 170 // Expected window contents: [] -> [10011]. |
171 SimulatePacketTransmissionRange(&tracker, base, 5); | |
133 AddTransportFeedbackAndValidate(&tracker, base, | 172 AddTransportFeedbackAndValidate(&tracker, base, |
134 {true, false, false, true, true}); | 173 {true, false, false, true, true}); |
135 ValidatePacketLossStatistics(tracker, | 174 ValidatePacketLossStatistics(tracker, |
136 rtc::Optional<float>(2.0f / 5.0f), | 175 rtc::Optional<float>(2.0f / 5.0f), |
137 rtc::Optional<float>()); | 176 rtc::Optional<float>()); |
138 } | 177 } |
139 } | 178 } |
140 | 179 |
141 // Sanity check on minimum filled window - PLR unknown, RPLR known. | 180 // Sanity check on minimum filled window - PLR unknown, RPLR known. |
142 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { | 181 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { |
143 for (uint16_t base : kBases) { | 182 for (uint16_t base : kBases) { |
144 TransportFeedbackPacketLossTracker tracker(10, 6, 4); | 183 TransportFeedbackPacketLossTracker tracker(10, 6, 4); |
145 | 184 |
146 // RPLR correctly calculated after minimum pairs reached. | 185 // RPLR correctly calculated after minimum pairs reached. |
147 // PLR not necessarily known at that time (not if min window not reached). | 186 // PLR not necessarily known at that time (not if min window not reached). |
148 // Expected window contents: [] -> [10011]. | 187 // Expected window contents: [] -> [10011]. |
188 SimulatePacketTransmissionRange(&tracker, base, 5); | |
149 AddTransportFeedbackAndValidate(&tracker, base, | 189 AddTransportFeedbackAndValidate(&tracker, base, |
150 {true, false, false, true, true}); | 190 {true, false, false, true, true}); |
151 ValidatePacketLossStatistics(tracker, | 191 ValidatePacketLossStatistics(tracker, |
152 rtc::Optional<float>(), | 192 rtc::Optional<float>(), |
153 rtc::Optional<float>(1.0f / 4.0f)); | 193 rtc::Optional<float>(1.0f / 4.0f)); |
154 } | 194 } |
155 } | 195 } |
156 | 196 |
157 // Additional reports update PLR and RPLR. | 197 // Additional reports update PLR and RPLR. |
158 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { | 198 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { |
159 for (uint16_t base : kBases) { | 199 for (uint16_t base : kBases) { |
160 TransportFeedbackPacketLossTracker tracker(20, 5, 5); | 200 TransportFeedbackPacketLossTracker tracker(20, 5, 5); |
161 | 201 |
202 SimulatePacketTransmissionRange(&tracker, base, 25); | |
203 | |
162 // Expected window contents: [] -> [10011]. | 204 // Expected window contents: [] -> [10011]. |
163 AddTransportFeedbackAndValidate(&tracker, base, | 205 AddTransportFeedbackAndValidate(&tracker, base, |
164 {true, false, false, true, true}); | 206 {true, false, false, true, true}); |
165 ValidatePacketLossStatistics(tracker, | 207 ValidatePacketLossStatistics(tracker, |
166 rtc::Optional<float>(2.0f / 5.0f), | 208 rtc::Optional<float>(2.0f / 5.0f), |
167 rtc::Optional<float>()); | 209 rtc::Optional<float>()); |
168 | 210 |
169 // Expected window contents: [10011] -> [1001110101]. | 211 // Expected window contents: [10011] -> [1001110101]. |
170 AddTransportFeedbackAndValidate(&tracker, base + 5, | 212 AddTransportFeedbackAndValidate(&tracker, base + 5, |
171 {true, false, true, false, true}); | 213 {true, false, true, false, true}); |
172 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 214 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
173 | 215 |
174 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. | 216 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. |
175 AddTransportFeedbackAndValidate(&tracker, base + 20, | 217 AddTransportFeedbackAndValidate(&tracker, base + 20, |
176 {true, false, false, false, true}); | 218 {true, false, false, false, true}); |
177 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); | 219 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); |
178 } | 220 } |
179 } | 221 } |
180 | 222 |
181 // All packets correctly received. | 223 // Sanity - all packets correctly received. |
182 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { | 224 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { |
183 for (uint16_t base : kBases) { | 225 for (uint16_t base : kBases) { |
184 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 226 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
185 | 227 |
186 // PLR and RPLR correctly calculated after minimum window size reached. | 228 // PLR and RPLR correctly calculated after minimum window size reached. |
187 // Expected window contents: [] -> [11111]. | 229 // Expected window contents: [] -> [11111]. |
230 SimulatePacketTransmissionRange(&tracker, base, 5); | |
188 AddTransportFeedbackAndValidate(&tracker, base, | 231 AddTransportFeedbackAndValidate(&tracker, base, |
189 {true, true, true, true, true}); | 232 {true, true, true, true, true}); |
190 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); | 233 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); |
191 } | 234 } |
192 } | 235 } |
193 | 236 |
194 // Repeated reports are ignored. | 237 // Repeated reports are ignored. |
195 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { | 238 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { |
196 for (uint16_t base : kBases) { | 239 for (uint16_t base : kBases) { |
197 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 240 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
198 | 241 |
242 SimulatePacketTransmissionRange(&tracker, base, 5); | |
243 | |
199 // Expected window contents: [] -> [10011]. | 244 // Expected window contents: [] -> [10011]. |
200 AddTransportFeedbackAndValidate(&tracker, base, | 245 AddTransportFeedbackAndValidate(&tracker, base, |
201 {true, false, false, true, true}); | 246 {true, false, false, true, true}); |
202 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 247 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
203 | 248 |
204 // Repeat entire previous feedback | 249 // Repeat entire previous feedback |
205 // Expected window contents: [10011] -> [10011]. | 250 // Expected window contents: [10011] -> [10011]. |
206 AddTransportFeedbackAndValidate(&tracker, base, | 251 AddTransportFeedbackAndValidate(&tracker, base, |
207 {true, false, false, true, true}); | 252 {true, false, false, true, true}); |
208 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 253 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
209 } | 254 } |
210 } | 255 } |
211 | 256 |
212 // Report overlap. | 257 // Report overlap. |
213 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { | 258 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { |
214 for (uint16_t base : kBases) { | 259 for (uint16_t base : kBases) { |
215 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 260 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
216 | 261 |
262 SimulatePacketTransmissionRange(&tracker, base, 15); | |
263 | |
217 // Expected window contents: [] -> [10011]. | 264 // Expected window contents: [] -> [10011]. |
218 AddTransportFeedbackAndValidate(&tracker, base, | 265 AddTransportFeedbackAndValidate(&tracker, base, |
219 {true, false, false, true, true}); | 266 {true, false, false, true, true}); |
220 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 267 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
221 | 268 |
222 // Expected window contents: [10011] -> [1001101]. | 269 // Expected window contents: [10011] -> [1001101]. |
223 AddTransportFeedbackAndValidate(&tracker, base + 3, | 270 AddTransportFeedbackAndValidate(&tracker, base + 3, |
224 {true, true, false, true}); | 271 {true, true, false, true}); |
225 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 272 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
226 } | 273 } |
227 } | 274 } |
228 | 275 |
229 // Report conflict. | 276 // Report conflict. |
230 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { | 277 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { |
231 for (uint16_t base : kBases) { | 278 for (uint16_t base : kBases) { |
232 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 279 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
233 | 280 |
281 SimulatePacketTransmissionRange(&tracker, base, 15); | |
282 | |
234 // Expected window contents: [] -> [01001]. | 283 // Expected window contents: [] -> [01001]. |
235 AddTransportFeedbackAndValidate(&tracker, base, | 284 AddTransportFeedbackAndValidate(&tracker, base, |
236 {false, true, false, false, true}); | 285 {false, true, false, false, true}); |
237 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); | 286 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); |
238 | 287 |
239 // Expected window contents: [01001] -> [11101]. | 288 // Expected window contents: [01001] -> [11101]. |
240 // While false->true will be applied, true -> false will be ignored. | 289 // While false->true will be applied, true -> false will be ignored. |
241 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | 290 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); |
242 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 291 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
243 } | 292 } |
244 } | 293 } |
245 | 294 |
246 // Skipped packets treated as unknown (not lost). | 295 // Skipped packets treated as unknown (not lost). |
247 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { | 296 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { |
248 for (uint16_t base : kBases) { | 297 for (uint16_t base : kBases) { |
249 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 298 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
250 | 299 |
300 SimulatePacketTransmissionRange(&tracker, base, 200); | |
301 | |
251 // Expected window contents: [] -> [10011]. | 302 // Expected window contents: [] -> [10011]. |
252 AddTransportFeedbackAndValidate(&tracker, base, | 303 AddTransportFeedbackAndValidate(&tracker, base, |
253 {true, false, false, true, true}); | 304 {true, false, false, true, true}); |
254 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 305 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
255 | 306 |
256 // Expected window contents: [10011] -> [10011-GAP-101]. | 307 // Expected window contents: [10011] -> [10011-GAP-101]. |
257 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); | 308 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); |
258 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); | 309 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); |
259 } | 310 } |
260 } | 311 } |
261 | 312 |
262 // The window retain information up to the configured max-window-size, but | 313 // The window retain information up to the configured max-window-size, but |
263 // starts discarding after that. | 314 // starts discarding after that. (Sent packets are not counted.) |
264 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { | 315 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { |
265 for (uint16_t base : kBases) { | 316 for (uint16_t base : kBases) { |
266 TransportFeedbackPacketLossTracker tracker(10, 10, 1); | 317 TransportFeedbackPacketLossTracker tracker(10, 10, 1); |
267 | 318 |
319 SimulatePacketTransmissionRange(&tracker, base, 200); | |
320 | |
268 // Up to max-window-size retained. | 321 // Up to max-window-size retained. |
269 // Expected window contents: [] -> [1010100001]. | 322 // Expected window contents: [] -> [1010100001]. |
270 AddTransportFeedbackAndValidate( | 323 AddTransportFeedbackAndValidate( |
271 &tracker, base, | 324 &tracker, base, |
272 {true, false, true, false, true, false, false, false, false, true}); | 325 {true, false, true, false, true, false, false, false, false, true}); |
273 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); | 326 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); |
274 | 327 |
275 // After max-window-size, older entries discarded to accommodate newer ones. | 328 // After max-window-size, older entries discarded to accommodate newer ones. |
276 // Expected window contents: [1010100001] -> [0000110111]. | 329 // Expected window contents: [1010100001] -> [0000110111]. |
277 AddTransportFeedbackAndValidate(&tracker, base + 10, | 330 AddTransportFeedbackAndValidate(&tracker, base + 10, |
278 {true, false, true, true, true}); | 331 {true, false, true, true, true}); |
279 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | 332 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
280 } | 333 } |
281 } | 334 } |
282 | 335 |
283 // Inserting into the middle of a full window works correctly. | 336 // Inserting feedback into the middle of a full window works correctly. |
284 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { | 337 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { |
285 for (uint16_t base : kBases) { | 338 for (uint16_t base : kBases) { |
286 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 339 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
287 | 340 |
341 SimulatePacketTransmissionRange(&tracker, base, 300); | |
342 | |
288 // Expected window contents: [] -> [10101]. | 343 // Expected window contents: [] -> [10101]. |
289 AddTransportFeedbackAndValidate(&tracker, base, | 344 AddTransportFeedbackAndValidate(&tracker, base, |
290 {true, false, true, false, true}); | 345 {true, false, true, false, true}); |
291 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); | 346 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); |
292 | 347 |
293 // Expected window contents: [10101] -> [10101-GAP-10001]. | 348 // Expected window contents: [10101] -> [10101-GAP-10001]. |
294 AddTransportFeedbackAndValidate(&tracker, base + 100, | 349 AddTransportFeedbackAndValidate(&tracker, base + 100, |
295 {true, false, false, false, true}); | 350 {true, false, false, false, true}); |
296 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); | 351 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); |
297 | 352 |
298 // Insert into the middle of this full window - it discards the older data. | 353 // Insert into the middle of this full window - it discards the older data. |
299 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. | 354 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. |
300 AddTransportFeedbackAndValidate(&tracker, base + 50, | 355 AddTransportFeedbackAndValidate(&tracker, base + 50, |
301 {true, true, true, true, true}); | 356 {true, true, true, true, true}); |
302 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); | 357 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); |
303 } | 358 } |
304 } | 359 } |
305 | 360 |
306 // Inserting into the middle of a full window works correctly. | 361 // Inserting feedback into the middle of a full window works correctly - can |
362 // complete two pairs. | |
307 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { | 363 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { |
308 for (uint16_t base : kBases) { | 364 for (uint16_t base : kBases) { |
309 TransportFeedbackPacketLossTracker tracker(15, 5, 1); | 365 TransportFeedbackPacketLossTracker tracker(15, 5, 1); |
310 | 366 |
367 SimulatePacketTransmissionRange(&tracker, base, 300); | |
368 | |
311 // Expected window contents: [] -> [10111]. | 369 // Expected window contents: [] -> [10111]. |
312 AddTransportFeedbackAndValidate(&tracker, base, | 370 AddTransportFeedbackAndValidate(&tracker, base, |
313 {true, false, true, true, true}); | 371 {true, false, true, true, true}); |
314 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 372 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
315 | 373 |
316 // Expected window contents: [10111] -> [10111-GAP-10101]. | 374 // Expected window contents: [10111] -> [10111-GAP-10101]. |
317 AddTransportFeedbackAndValidate(&tracker, base + 7, | 375 AddTransportFeedbackAndValidate(&tracker, base + 7, |
318 {true, false, true, false, true}); | 376 {true, false, true, false, true}); |
319 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 377 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
320 | 378 |
321 // Insert in between, closing the gap completely. | 379 // Insert in between, closing the gap completely. |
322 // Expected window contents: [10111-GAP-10101] -> [101111010101]. | 380 // Expected window contents: [10111-GAP-10101] -> [101111010101]. |
323 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); | 381 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); |
324 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); | 382 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); |
325 } | 383 } |
326 } | 384 } |
327 | 385 |
328 // Entries in the second quadrant treated like those in the first. | 386 // The window can meaningfully hold up to 0x8000 SENT packetts (of which only |
329 // The sequence number is used in a looped manner. 0xFFFF is followed by 0x0000. | 387 // up to max-window acked messages will be kept and regarded). |
330 // In many tests, we divide the circle of sequence number into 4 quadrants, and | |
331 // verify the behavior of TransportFeedbackPacketLossTracker over them. | |
332 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { | 388 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { |
333 for (uint16_t base : kBases) { | 389 for (uint16_t base : kBases) { |
334 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 390 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
335 | 391 |
392 SimulatePacketTransmissionRange(&tracker, base, 0x8000, false); | |
393 | |
336 // Expected window contents: [] -> [10011]. | 394 // Expected window contents: [] -> [10011]. |
337 AddTransportFeedbackAndValidate(&tracker, base, | 395 AddTransportFeedbackAndValidate(&tracker, base, |
338 {true, false, false, true, true}); | 396 {true, false, false, true, true}); |
339 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 397 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
340 | 398 |
341 // Window *does* get updated with inputs from quadrant #2. | 399 // Window *does* get updated with inputs from quadrant #2. |
342 // Expected window contents: [10011] -> [100111]. | 400 // Expected window contents: [10011] -> [100111]. |
343 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); | 401 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); |
344 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); | 402 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); |
345 | 403 |
346 // Correct recognition of quadrant #2: up to, but not including, base + | 404 // Correct recognition of quadrant #2: up to, but not including, base + |
347 // 0x8000 | 405 // 0x8000 |
348 // Expected window contents: [100111] -> [1001111]. | 406 // Expected window contents: [100111] -> [1001111]. |
349 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); | 407 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); |
350 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); | 408 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); |
351 } | 409 } |
352 } | 410 } |
353 | 411 |
354 // Insertion into the third quadrant moves the base of the window. | |
355 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantMovesBase) { | |
356 for (uint16_t base : kBases) { | |
357 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
358 | |
359 // Seed the test. | |
360 // Expected window contents: [] -> [1001101]. | |
361 AddTransportFeedbackAndValidate( | |
362 &tracker, base, {true, false, false, true, true, false, true}); | |
363 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | |
364 | |
365 // Quadrant #3 begins at base + 0x8000. It triggers moving the window so | |
366 // that | |
367 // at least one (oldest) report shifts out of window. | |
368 // Expected window contents: [1001101] -> [101-GAP-1001]. | |
369 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
370 {true, false, false, true}); | |
371 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); | |
372 | |
373 // The base can move more than once, because the minimum quadrant-1 packets | |
374 // were dropped out of the window, and some remain. | |
375 // Expected window contents: [101-GAP-1001] -> [1-GAP-100111]. | |
376 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | |
377 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.0f); | |
378 } | |
379 } | |
380 | |
381 // After the base has moved due to insertion into the third quadrant, it is | 412 // After the base has moved due to insertion into the third quadrant, it is |
382 // still possible to insert into the middle of the window and obtain the correct | 413 // still possible to get feedbacks in the middle of the window and obtain the |
383 // PLR and RPLR. Insertion into the middle before the max window size has been | 414 // correct PLR and RPLR. Insertion into the middle before the max window size |
384 // achieved does not cause older packets to be dropped. | 415 // has been achieved does not cause older packets to be dropped. |
385 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMove) { | 416 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMoved) { |
386 for (uint16_t base : kBases) { | 417 for (uint16_t base : kBases) { |
387 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 418 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
388 | 419 |
389 // Seed the test. | 420 SimulatePacketTransmissionRange(&tracker, base, 20); |
421 SimulatePacketTransmissionRange(&tracker, base + 0x5000, 20); | |
422 | |
390 // Expected window contents: [] -> [1001101]. | 423 // Expected window contents: [] -> [1001101]. |
391 AddTransportFeedbackAndValidate( | 424 AddTransportFeedbackAndValidate( |
392 &tracker, base, {true, false, false, true, true, false, true}); | 425 &tracker, base, {true, false, false, true, true, false, true}); |
393 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 426 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
394 | 427 |
395 // Expected window contents: [1001101] -> [101-GAP-1001]. | 428 // Expected window contents: [1001101] -> [101-GAP-1001]. |
429 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 4); | |
396 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 430 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
397 {true, false, false, true}); | 431 {true, false, false, true}); |
398 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); | 432 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); |
399 | 433 |
400 // Inserting into the middle still works after the base has shifted. | 434 // Inserting into the middle still works after the base has shifted. |
401 // Expected window contents: | 435 // Expected window contents: |
402 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] | 436 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] |
403 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, | 437 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, |
404 {true, false, false, true, false, true}); | 438 {true, false, false, true, false, true}); |
405 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); | 439 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); |
406 | 440 |
407 // The base can keep moving after inserting into the middle. | 441 // The base can keep moving after inserting into the middle. |
408 // Expected window contents: | 442 // Expected window contents: |
409 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. | 443 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. |
444 SimulatePacketTransmissionRange(&tracker, base + 0x8000 + 4, 2); | |
410 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | 445 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); |
411 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); | 446 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); |
412 } | 447 } |
413 } | 448 } |
414 | 449 |
415 // After moving the base of the window, the max window size is still observed. | 450 // After moving the base of the window, the max window size is still observed. |
416 TEST(TransportFeedbackPacketLossTrackerTest, ThirdQuadrantObservesMaxWindow) { | 451 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowObservedAfterBaseMoved) { |
417 for (uint16_t base : kBases) { | 452 for (uint16_t base : kBases) { |
418 TransportFeedbackPacketLossTracker tracker(15, 10, 1); | 453 TransportFeedbackPacketLossTracker tracker(15, 10, 1); |
419 | 454 |
420 // Expected window contents: [] -> [1001110101]. | 455 // Expected window contents: [] -> [1001110101]. |
456 SimulatePacketTransmissionRange(&tracker, base, 10); | |
421 AddTransportFeedbackAndValidate( | 457 AddTransportFeedbackAndValidate( |
422 &tracker, base, | 458 &tracker, base, |
423 {true, false, false, true, true, true, false, true, false, true}); | 459 {true, false, false, true, true, true, false, true, false, true}); |
424 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 460 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
425 | 461 |
462 // Create gap (on both sides). | |
463 SimulatePacketTransmissionRange(&tracker, base + 0x4000, 20); | |
464 | |
426 // Expected window contents: [1001110101] -> [1110101-GAP-101]. | 465 // Expected window contents: [1001110101] -> [1110101-GAP-101]. |
466 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 3); | |
427 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 467 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
428 {true, false, true}); | 468 {true, false, true}); |
429 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 469 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
430 | 470 |
431 // Push into middle until max window is reached. | 471 // Push into middle until max window is reached. The gap is NOT completed. |
432 // Expected window contents: | 472 // Expected window contents: |
433 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] | 473 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] |
434 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 474 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2, |
435 {true, false, false, false, true}); | 475 {true, false, false, false, true}); |
436 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); | 476 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); |
437 | 477 |
438 // Pushing new packets into the middle would discard older packets. | 478 // Pushing new packets into the middle would discard older packets. |
439 // Expected window contents: | 479 // Expected window contents: |
440 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] | 480 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] |
441 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 5, | 481 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2 + 5, |
442 {true, false, true}); | 482 {true, false, true}); |
443 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); | 483 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); |
444 } | 484 } |
445 } | 485 } |
446 | 486 |
447 // A new feedback in quadrant #3 might shift enough old feedbacks out of window, | 487 // A packet with a new enough sequence number might shift enough old feedbacks |
448 // that we'd go back to an unknown PLR and RPLR. | 488 // out window, that we'd go back to an unknown PLR and RPLR. |
449 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantThreeMovedBaseMinWindow) { | 489 TEST(TransportFeedbackPacketLossTrackerTest, NewPacketMovesWindowBase) { |
450 for (uint16_t base : kBases) { | 490 for (uint16_t base : kBases) { |
451 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 491 TransportFeedbackPacketLossTracker tracker(20, 5, 3); |
492 | |
493 SimulatePacketTransmissionRange(&tracker, base, 50); | |
494 SimulatePacketTransmissionRange(&tracker, base + 0x4000 - 1, 6); // Gap | |
452 | 495 |
453 // Expected window contents: [] -> [1001110101]. | 496 // Expected window contents: [] -> [1001110101]. |
454 AddTransportFeedbackAndValidate( | 497 AddTransportFeedbackAndValidate( |
455 &tracker, base, | 498 &tracker, base, |
456 {true, false, false, true, true, true, false, true, false, true}); | 499 {true, false, false, true, true, true, false, true, false, true}); |
457 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 500 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
458 | 501 |
459 // A new feedback in quadrant #3 might shift enough old feedbacks out of | 502 // A new sent packet with a new enough sequence number could shift enough |
460 // window, that we'd go back to an unknown PLR and RPLR. This *doesn't* | 503 // acked packets out of window, that we'd go back to an unknown PLR |
461 // necessarily mean all of the old ones were discarded, though. | 504 // and RPLR. This *doesn't* // necessarily mean all of the old ones |
462 // Expected window contents: [1001110101] -> [01-GAP-11]. | 505 // were discarded, though. |
506 // Expected window contents: [1001110101] -> [01]. | |
507 SimulatePacketTransmissionRange(&tracker, base + 0x8006, 2); | |
508 ValidatePacketLossStatistics(tracker, | |
509 rtc::Optional<float>(), // Still invalid. | |
510 rtc::Optional<float>()); | |
511 | |
512 // Even if those messages are acked, we'd still might be in unknown PLR | |
513 // and RPLR, because we might have shifted more packets out of the window | |
514 // than we have inserted. | |
515 // Expected window contents: [01] -> [01-GAP-11]. | |
463 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); | 516 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); |
464 ValidatePacketLossStatistics(tracker, | 517 ValidatePacketLossStatistics(tracker, |
465 rtc::Optional<float>(), // Still invalid. | 518 rtc::Optional<float>(), // Still invalid. |
466 rtc::Optional<float>(1.0f / 2.0f)); | 519 rtc::Optional<float>()); |
467 | 520 |
468 // Inserting in the middle shows that though some of the elements were | 521 // Inserting in the middle shows that though some of the elements were |
469 // ejected, some were retained. | 522 // ejected, some were retained. |
470 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. | 523 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. |
471 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 524 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, |
472 {true, false, false, true}); | 525 {true, false, false, true}); |
473 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); | 526 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); |
474 } | 527 } |
475 } | 528 } |
476 | 529 |
477 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | 530 // Sequence number gaps are not gaps in reception. However, gaps in reception |
478 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourInitiallyIgnored) { | 531 // are still possible, if a packet which WAS sent on the stream is not acked. |
532 TEST(TransportFeedbackPacketLossTrackerTest, SanityGapsInSequenceNumbers) { | |
479 for (uint16_t base : kBases) { | 533 for (uint16_t base : kBases) { |
480 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 534 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
481 | 535 |
482 // Expected window contents: [] -> [10011]. | 536 SimulatePacketTransmission( |
483 AddTransportFeedbackAndValidate(&tracker, base, | 537 &tracker, {base, base + 2, base + 4, base + 6, base + 8}); |
484 {true, false, false, true, true}); | |
485 | 538 |
486 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | 539 // Gaps in sequence numbers not considered as gaps in window, because only |
487 // consecutive reports). | 540 // those sequence numbers which were associated with the stream count. |
488 // Expected window contents: [10011] -> [10011]. | 541 // Expected window contents: [] -> [11011]. |
489 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | 542 AddTransportFeedbackAndValidate( |
490 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | 543 // Note: Left packets belong to this stream, odd ones ignored. |
491 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 544 &tracker, base, {true, false, |
492 } | 545 true, false, |
546 false, false, | |
547 true, false, | |
548 true, true}); | |
549 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | |
550 | |
551 | |
552 // Create gap by sending [base + 10] but not acking it. | |
553 // Note: Acks for [base + 11] and [base + 13] ignored (other stream). | |
554 // Expected window contents: [11011] -> [11011-GAP-01]. | |
555 SimulatePacketTransmission(&tracker, {base + 10, base + 12, base + 14}); | |
556 AddTransportFeedbackAndValidate(&tracker, base + 11, | |
557 {false, false, false, true, true}); | |
558 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 2.0f / 5.0f); | |
493 } | 559 } |
494 } | 560 } |
495 | 561 |
496 // Receiving a packet from quadrant #1 resets the counter for quadrant #4. | |
497 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ1) { | |
498 for (uint16_t base : kBases) { | |
499 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
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 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
511 } | |
512 | |
513 // If we receive a feedback in quadrant #1, the above counter is reset. | |
514 // Expected window contents: [10011] -> [100111]. | |
515 AddTransportFeedbackAndValidate(&tracker, base + 5, {true}); | |
516 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
517 // Note: though the feedback message reports three packets, it only gets | |
518 // counted once. | |
519 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
520 {true, false, true}); | |
521 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 5.0f); | |
522 } | |
523 | |
524 // The same is true for reports which create a gap - they still reset. | |
525 // Expected window contents: [10011] -> [100111-GAP-01]. | |
526 AddTransportFeedbackAndValidate(&tracker, base + 0x00ff, {false, true}); | |
527 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
528 // Note: though the feedback message reports three packets, it only gets | |
529 // counted once. | |
530 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
531 {true, false, true}); | |
532 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); | |
533 } | |
534 } | |
535 } | |
536 | |
537 // Receiving a packet from quadrant #2 resets the counter for quadrant #4. | |
538 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourCounterResetByQ2) { | |
539 for (uint16_t base : kBases) { | |
540 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
541 | |
542 // Expected window contents: [] -> [10011]. | |
543 AddTransportFeedbackAndValidate(&tracker, base, | |
544 {true, false, false, true, true}); | |
545 | |
546 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
547 // consecutive reports). | |
548 // Expected window contents: [10011] -> [10011]. | |
549 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
550 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
551 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
552 } | |
553 | |
554 // If we receive a feedback in quadrant #2, the above counter is reset. | |
555 // Expected window contents: [10011] -> [10011-GAP-11]. | |
556 AddTransportFeedbackAndValidate(&tracker, base + 0x400f, {true, true}); | |
557 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
558 // Note: though the feedback message reports three packets, it only gets | |
559 // counted once. | |
560 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
561 {true, false, true}); | |
562 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 5.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 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
571 | |
572 // Expected window contents: [] -> [1001110001]. | |
573 AddTransportFeedbackAndValidate( | |
574 &tracker, base, | |
575 {true, false, false, true, true, true, false, false, false, true}); | |
576 | |
577 // Feedbacks in quadrant #4 are discarded (up to kMaxConsecutiveOldReports | |
578 // consecutive reports). | |
579 // Expected window contents: [1001110001] -> [1001110001]. | |
580 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
581 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, {true, true}); | |
582 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | |
583 } | |
584 | |
585 // If we receive a feedback in quadrant #1, the above counter is reset. | |
586 // Expected window contents: [1001110001] -> [1110001-GAP-111]. | |
587 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | |
588 {true, true, true}); | |
589 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
590 // Note: though the feedback message reports three packets, it only gets | |
591 // counted once. | |
592 AddTransportFeedbackAndValidate(&tracker, base + 0xc000 + 10, | |
593 {true, false, true}); | |
594 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); | |
595 } | |
596 } | |
597 } | |
598 | |
599 // Quadrant four reports ignored for up to kMaxConsecutiveOldReports times. | |
600 // After that, the window is reset. | |
601 TEST(TransportFeedbackPacketLossTrackerTest, QuadrantFourReset) { | |
602 for (uint16_t base : kBases) { | |
603 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
604 | |
605 // Expected window contents: [] -> [1001110001]. | |
606 AddTransportFeedbackAndValidate( | |
607 &tracker, base, | |
608 {true, false, false, true, true, true, false, false, false, true}); | |
609 | |
610 // Sanity | |
611 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | |
612 | |
613 // The first kMaxConsecutiveOldReports quadrant #4 reports are ignored. | |
614 // It doesn't matter that they consist of multiple packets - each report | |
615 // is only counted once. | |
616 for (size_t i = 0; i < kMaxConsecutiveOldReports; i++) { | |
617 // Expected window contents: [1001110001] -> [1001110001]. | |
618 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
619 {true, true, false, true}); | |
620 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | |
621 } | |
622 | |
623 // One additional feedback in quadrant #4 brings us over | |
624 // kMaxConsecutiveOldReports consecutive "old" reports, resetting the | |
625 // window. | |
626 // The new window is not completely empty - it's been seeded with the | |
627 // packets reported in the feedback that has triggered the reset. | |
628 // Note: The report doesn't have to be the same as the previous ones. | |
629 // Expected window contents: [1001110001] -> [10011]. | |
630 AddTransportFeedbackAndValidate(&tracker, base + 0xc000, | |
631 {true, false, false, true, true}); | |
632 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
633 } | |
634 } | |
635 | |
636 // Feedbacks spanning multiple quadrant are treated correctly (Q1-Q2). | |
minyue-webrtc
2017/02/14 16:46:59
why the tests below here also become obsolete?
minyue-webrtc
2017/02/16 09:51:44
missed this comment?
elad.alon_webrtc.org
2017/02/16 15:51:40
Yes, I'd missed the comment; thanks for pointing i
minyue-webrtc
2017/02/17 11:09:14
Ok. then, as you said, the removing of old packets
elad.alon_webrtc.org
2017/02/17 12:24:42
Yes. The following UTs have been added (when revie
| |
637 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ1Q2) { | |
638 for (uint16_t base : kBases) { | |
639 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
640 | |
641 // Expected window contents: [] -> [10011]. | |
642 AddTransportFeedbackAndValidate(&tracker, base, | |
643 {true, false, false, true, true}); | |
644 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
645 | |
646 // A feedback with entries in both quadrant #1 and #2 gets both counted: | |
647 // Expected window contents: [10011] -> [10011-GAP-1001]. | |
648 AddTransportFeedbackAndValidate(&tracker, base + 0x3ffe, | |
649 {true, false, false, true}); | |
650 ValidatePacketLossStatistics(tracker, 4.0f / 9.0f, 2.0f / 7.0f); | |
651 } | |
652 } | |
653 | |
654 // Feedbacks spanning multiple quadrant are treated correctly (Q2-Q3). | |
655 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ2Q3) { | |
656 for (uint16_t base : kBases) { | |
657 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
658 | |
659 // Expected window contents: [] -> [1001100001]. | |
660 AddTransportFeedbackAndValidate( | |
661 &tracker, base, | |
662 {true, false, false, true, true, false, false, false, false, true}); | |
663 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); | |
664 | |
665 // A feedback with entries in both quadrant #2 and #3 gets both counted, | |
666 // but only those from #3 trigger throwing out old entries from quadrant #1: | |
667 // Expected window contents: [1001100001] -> [01100001-GAP-1001]. | |
668 AddTransportFeedbackAndValidate(&tracker, base + 0x7ffe, | |
669 {true, false, false, true}); | |
670 ValidatePacketLossStatistics(tracker, 7.0f / 12.0f, 3.0f / 10.0f); | |
671 } | |
672 } | |
673 | |
674 // Feedbacks spanning multiple quadrant are treated correctly (Q3-Q4). | |
675 TEST(TransportFeedbackPacketLossTrackerTest, MultiQuadrantQ3Q4) { | |
676 for (uint16_t base : kBases) { | |
677 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | |
678 | |
679 // Expected window contents: [] -> [1001100001]. | |
680 AddTransportFeedbackAndValidate( | |
681 &tracker, base, | |
682 {true, false, false, true, true, false, false, false, false, true}); | |
683 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 2.0f / 9.0f); | |
684 | |
685 // A feedback with entries in both quadrant #3 and #4 would have the entries | |
686 // from quadrant #3 shift enough quadrant #1 entries out of window, that | |
687 // by the time the #4 packets are examined, the moving baseline has made | |
688 // them into quadrant #3 packets. | |
689 // Expected window contents: [1001100001] -> [10011]. | |
690 AddTransportFeedbackAndValidate(&tracker, base + 0xbfff, | |
691 {true, false, false, true, true}); | |
692 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | |
693 } | |
694 } | |
695 | |
696 } // namespace webrtc | 562 } // namespace webrtc |
OLD | NEW |