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; | |
24 using testing::StrictMock; | |
minyue-webrtc
2017/02/14 21:23:00
nice you found these
| |
25 | 23 |
26 namespace webrtc { | 24 namespace webrtc { |
27 | 25 |
28 namespace { | 26 namespace { |
29 | 27 |
30 // All tests are run multiple times with various baseline sequence number, | 28 class TransportFeedbackPacketLossTrackerTest |
31 // to weed out potential bugs with wrap-around handling. | 29 : public ::testing::TestWithParam<uint16_t> { |
32 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; | 30 public: |
31 TransportFeedbackPacketLossTrackerTest() = default; | |
minyue-webrtc
2017/02/14 21:23:00
I think parameter parsing can be placed here. Othe
sprang_webrtc
2017/02/15 10:47:44
+1
elad.alon_webrtc.org
2017/02/15 17:15:15
Done.
| |
32 virtual ~TransportFeedbackPacketLossTrackerTest() = default; | |
33 | |
34 private: | |
35 RTC_DISALLOW_COPY_AND_ASSIGN(TransportFeedbackPacketLossTrackerTest); | |
36 }; | |
33 | 37 |
34 void SimulatePacketTransmission(TransportFeedbackPacketLossTracker* tracker, | 38 void SimulatePacketTransmission(TransportFeedbackPacketLossTracker* tracker, |
35 uint16_t seq_num, | 39 uint16_t seq_num, |
36 bool with_validation = true) { | 40 bool with_validation = true) { |
37 tracker->OnPacketAdded(seq_num); | 41 tracker->OnPacketAdded(seq_num); |
38 if (with_validation) { | 42 if (with_validation) { |
39 tracker->Validate(); | 43 tracker->Validate(); |
40 } | 44 } |
41 } | 45 } |
42 | 46 |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 std::unique_ptr<TransportFeedback> feedback; | 143 std::unique_ptr<TransportFeedback> feedback; |
140 TransportFeedbackPacketLossTracker tracker(10, 5, 5); | 144 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
141 | 145 |
142 // PLR and RPLR reported as unknown before reception of first feedback. | 146 // PLR and RPLR reported as unknown before reception of first feedback. |
143 ValidatePacketLossStatistics(tracker, | 147 ValidatePacketLossStatistics(tracker, |
144 rtc::Optional<float>(), | 148 rtc::Optional<float>(), |
145 rtc::Optional<float>()); | 149 rtc::Optional<float>()); |
146 } | 150 } |
147 | 151 |
148 // Sanity check on partially filled window. | 152 // Sanity check on partially filled window. |
149 TEST(TransportFeedbackPacketLossTrackerTest, PlrPartiallyFilledWindow) { | 153 TEST_P(TransportFeedbackPacketLossTrackerTest, PlrPartiallyFilledWindow) { |
150 for (uint16_t base : kBases) { | 154 const uint16_t base = GetParam(); |
151 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 155 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
152 | 156 |
153 // PLR unknown before minimum window size reached. | 157 // PLR unknown before minimum window size reached. |
154 // RPLR unknown before minimum pairs reached. | 158 // RPLR unknown before minimum pairs reached. |
155 // Expected window contents: [] -> [1001]. | 159 // Expected window contents: [] -> [1001]. |
156 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); | 160 AddTransportFeedbackAndValidate(&tracker, base, {true, false, false, true}); |
157 ValidatePacketLossStatistics(tracker, | 161 ValidatePacketLossStatistics(tracker, |
158 rtc::Optional<float>(), | 162 rtc::Optional<float>(), |
159 rtc::Optional<float>()); | 163 rtc::Optional<float>()); |
160 } | |
161 } | 164 } |
162 | 165 |
163 // Sanity check on minimum filled window - PLR known, RPLR unknown. | 166 // Sanity check on minimum filled window - PLR known, RPLR unknown. |
164 TEST(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { | 167 TEST_P(TransportFeedbackPacketLossTrackerTest, PlrMinimumFilledWindow) { |
165 for (uint16_t base : kBases) { | 168 const uint16_t base = GetParam(); |
166 TransportFeedbackPacketLossTracker tracker(10, 5, 5); | 169 TransportFeedbackPacketLossTracker tracker(10, 5, 5); |
167 | 170 |
168 // PLR correctly calculated after minimum window size reached. | 171 // PLR correctly calculated after minimum window size reached. |
169 // RPLR not necessarily known at that time (not if min-pairs not reached). | 172 // RPLR not necessarily known at that time (not if min-pairs not reached). |
170 // Expected window contents: [] -> [10011]. | 173 // Expected window contents: [] -> [10011]. |
171 SimulatePacketTransmissionRange(&tracker, base, 5); | 174 SimulatePacketTransmissionRange(&tracker, base, 5); |
172 AddTransportFeedbackAndValidate(&tracker, base, | 175 AddTransportFeedbackAndValidate(&tracker, base, |
173 {true, false, false, true, true}); | 176 {true, false, false, true, true}); |
174 ValidatePacketLossStatistics(tracker, | 177 ValidatePacketLossStatistics(tracker, |
175 rtc::Optional<float>(2.0f / 5.0f), | 178 rtc::Optional<float>(2.0f / 5.0f), |
176 rtc::Optional<float>()); | 179 rtc::Optional<float>()); |
177 } | |
178 } | 180 } |
179 | 181 |
180 // Sanity check on minimum filled window - PLR unknown, RPLR known. | 182 // Sanity check on minimum filled window - PLR unknown, RPLR known. |
181 TEST(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { | 183 TEST_P(TransportFeedbackPacketLossTrackerTest, RplrMinimumFilledWindow) { |
182 for (uint16_t base : kBases) { | 184 const uint16_t base = GetParam(); |
183 TransportFeedbackPacketLossTracker tracker(10, 6, 4); | 185 TransportFeedbackPacketLossTracker tracker(10, 6, 4); |
184 | 186 |
185 // RPLR correctly calculated after minimum pairs reached. | 187 // RPLR correctly calculated after minimum pairs reached. |
186 // PLR not necessarily known at that time (not if min window not reached). | 188 // PLR not necessarily known at that time (not if min window not reached). |
187 // Expected window contents: [] -> [10011]. | 189 // Expected window contents: [] -> [10011]. |
188 SimulatePacketTransmissionRange(&tracker, base, 5); | 190 SimulatePacketTransmissionRange(&tracker, base, 5); |
189 AddTransportFeedbackAndValidate(&tracker, base, | 191 AddTransportFeedbackAndValidate(&tracker, base, |
190 {true, false, false, true, true}); | 192 {true, false, false, true, true}); |
191 ValidatePacketLossStatistics(tracker, | 193 ValidatePacketLossStatistics(tracker, |
192 rtc::Optional<float>(), | 194 rtc::Optional<float>(), |
193 rtc::Optional<float>(1.0f / 4.0f)); | 195 rtc::Optional<float>(1.0f / 4.0f)); |
194 } | |
195 } | 196 } |
196 | 197 |
197 // Additional reports update PLR and RPLR. | 198 // Additional reports update PLR and RPLR. |
198 TEST(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { | 199 TEST_P(TransportFeedbackPacketLossTrackerTest, ExtendWindow) { |
199 for (uint16_t base : kBases) { | 200 const uint16_t base = GetParam(); |
200 TransportFeedbackPacketLossTracker tracker(20, 5, 5); | 201 TransportFeedbackPacketLossTracker tracker(20, 5, 5); |
201 | 202 |
202 SimulatePacketTransmissionRange(&tracker, base, 25); | 203 SimulatePacketTransmissionRange(&tracker, base, 25); |
203 | 204 |
204 // Expected window contents: [] -> [10011]. | 205 // Expected window contents: [] -> [10011]. |
205 AddTransportFeedbackAndValidate(&tracker, base, | 206 AddTransportFeedbackAndValidate(&tracker, base, |
206 {true, false, false, true, true}); | 207 {true, false, false, true, true}); |
207 ValidatePacketLossStatistics(tracker, | 208 ValidatePacketLossStatistics(tracker, |
208 rtc::Optional<float>(2.0f / 5.0f), | 209 rtc::Optional<float>(2.0f / 5.0f), |
209 rtc::Optional<float>()); | 210 rtc::Optional<float>()); |
210 | 211 |
211 // Expected window contents: [10011] -> [1001110101]. | 212 // Expected window contents: [10011] -> [1001110101]. |
212 AddTransportFeedbackAndValidate(&tracker, base + 5, | 213 AddTransportFeedbackAndValidate(&tracker, base + 5, |
213 {true, false, true, false, true}); | 214 {true, false, true, false, true}); |
214 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 215 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
215 | 216 |
216 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. | 217 // Expected window contents: [1001110101] -> [1001110101-GAP-10001]. |
217 AddTransportFeedbackAndValidate(&tracker, base + 20, | 218 AddTransportFeedbackAndValidate(&tracker, base + 20, |
218 {true, false, false, false, true}); | 219 {true, false, false, false, true}); |
219 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); | 220 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 4.0f / 13.0f); |
220 } | |
221 } | 221 } |
222 | 222 |
223 // Sanity - all packets correctly received. | 223 // Sanity - all packets correctly received. |
224 TEST(TransportFeedbackPacketLossTrackerTest, AllReceived) { | 224 TEST_P(TransportFeedbackPacketLossTrackerTest, AllReceived) { |
225 for (uint16_t base : kBases) { | 225 const uint16_t base = GetParam(); |
226 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 226 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
227 | 227 |
228 // PLR and RPLR correctly calculated after minimum window size reached. | 228 // PLR and RPLR correctly calculated after minimum window size reached. |
229 // Expected window contents: [] -> [11111]. | 229 // Expected window contents: [] -> [11111]. |
230 SimulatePacketTransmissionRange(&tracker, base, 5); | 230 SimulatePacketTransmissionRange(&tracker, base, 5); |
231 AddTransportFeedbackAndValidate(&tracker, base, | 231 AddTransportFeedbackAndValidate(&tracker, base, |
232 {true, true, true, true, true}); | 232 {true, true, true, true, true}); |
233 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); | 233 ValidatePacketLossStatistics(tracker, 0.0f, 0.0f); |
234 } | |
235 } | 234 } |
236 | 235 |
237 // Repeated reports are ignored. | 236 // Repeated reports are ignored. |
238 TEST(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { | 237 TEST_P(TransportFeedbackPacketLossTrackerTest, ReportRepetition) { |
239 for (uint16_t base : kBases) { | 238 const uint16_t base = GetParam(); |
240 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 239 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
241 | 240 |
242 SimulatePacketTransmissionRange(&tracker, base, 5); | 241 SimulatePacketTransmissionRange(&tracker, base, 5); |
243 | 242 |
244 // Expected window contents: [] -> [10011]. | 243 // Expected window contents: [] -> [10011]. |
245 AddTransportFeedbackAndValidate(&tracker, base, | 244 AddTransportFeedbackAndValidate(&tracker, base, |
246 {true, false, false, true, true}); | 245 {true, false, false, true, true}); |
247 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 246 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
248 | 247 |
249 // Repeat entire previous feedback | 248 // Repeat entire previous feedback |
250 // Expected window contents: [10011] -> [10011]. | 249 // Expected window contents: [10011] -> [10011]. |
251 AddTransportFeedbackAndValidate(&tracker, base, | 250 AddTransportFeedbackAndValidate(&tracker, base, |
252 {true, false, false, true, true}); | 251 {true, false, false, true, true}); |
253 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 252 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
254 } | |
255 } | 253 } |
256 | 254 |
257 // Report overlap. | 255 // Report overlap. |
258 TEST(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { | 256 TEST_P(TransportFeedbackPacketLossTrackerTest, ReportOverlap) { |
259 for (uint16_t base : kBases) { | 257 const uint16_t base = GetParam(); |
260 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 258 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
261 | 259 |
262 SimulatePacketTransmissionRange(&tracker, base, 15); | 260 SimulatePacketTransmissionRange(&tracker, base, 15); |
263 | 261 |
264 // Expected window contents: [] -> [10011]. | 262 // Expected window contents: [] -> [10011]. |
265 AddTransportFeedbackAndValidate(&tracker, base, | 263 AddTransportFeedbackAndValidate(&tracker, base, |
266 {true, false, false, true, true}); | 264 {true, false, false, true, true}); |
267 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 265 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
268 | 266 |
269 // Expected window contents: [10011] -> [1001101]. | 267 // Expected window contents: [10011] -> [1001101]. |
270 AddTransportFeedbackAndValidate(&tracker, base + 3, | 268 AddTransportFeedbackAndValidate(&tracker, base + 3, |
271 {true, true, false, true}); | 269 {true, true, false, true}); |
272 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 270 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
273 } | |
274 } | 271 } |
275 | 272 |
276 // Report conflict. | 273 // Report conflict. |
277 TEST(TransportFeedbackPacketLossTrackerTest, ReportConflict) { | 274 TEST_P(TransportFeedbackPacketLossTrackerTest, ReportConflict) { |
278 for (uint16_t base : kBases) { | 275 const uint16_t base = GetParam(); |
279 TransportFeedbackPacketLossTracker tracker(10, 5, 4); | 276 TransportFeedbackPacketLossTracker tracker(10, 5, 4); |
280 | 277 |
281 SimulatePacketTransmissionRange(&tracker, base, 15); | 278 SimulatePacketTransmissionRange(&tracker, base, 15); |
282 | 279 |
283 // Expected window contents: [] -> [01001]. | 280 // Expected window contents: [] -> [01001]. |
284 AddTransportFeedbackAndValidate(&tracker, base, | 281 AddTransportFeedbackAndValidate(&tracker, base, |
285 {false, true, false, false, true}); | 282 {false, true, false, false, true}); |
286 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); | 283 ValidatePacketLossStatistics(tracker, 3.0f / 5.0f, 2.0f / 4.0f); |
287 | 284 |
288 // Expected window contents: [01001] -> [11101]. | 285 // Expected window contents: [01001] -> [11101]. |
289 // While false->true will be applied, true -> false will be ignored. | 286 // While false->true will be applied, true -> false will be ignored. |
290 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); | 287 AddTransportFeedbackAndValidate(&tracker, base, {true, false, true}); |
291 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 288 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
292 } | |
293 } | 289 } |
294 | 290 |
295 // Skipped packets treated as unknown (not lost). | 291 // Skipped packets treated as unknown (not lost). |
296 TEST(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { | 292 TEST_P(TransportFeedbackPacketLossTrackerTest, SkippedPackets) { |
297 for (uint16_t base : kBases) { | 293 const uint16_t base = GetParam(); |
298 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 294 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
299 | 295 |
300 SimulatePacketTransmissionRange(&tracker, base, 200); | 296 SimulatePacketTransmissionRange(&tracker, base, 200); |
301 | 297 |
302 // Expected window contents: [] -> [10011]. | 298 // Expected window contents: [] -> [10011]. |
303 AddTransportFeedbackAndValidate(&tracker, base, | 299 AddTransportFeedbackAndValidate(&tracker, base, |
304 {true, false, false, true, true}); | 300 {true, false, false, true, true}); |
305 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 301 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
306 | 302 |
307 // Expected window contents: [10011] -> [10011-GAP-101]. | 303 // Expected window contents: [10011] -> [10011-GAP-101]. |
308 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); | 304 AddTransportFeedbackAndValidate(&tracker, base + 100, {true, false, true}); |
309 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); | 305 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 6.0f); |
310 } | |
311 } | 306 } |
312 | 307 |
313 // The window retain information up to the configured max-window-size, but | 308 // The window retain information up to the configured max-window-size, but |
314 // starts discarding after that. (Sent packets are not counted.) | 309 // starts discarding after that. (Sent packets are not counted.) |
315 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { | 310 TEST_P(TransportFeedbackPacketLossTrackerTest, MaxWindowSize) { |
316 for (uint16_t base : kBases) { | 311 const uint16_t base = GetParam(); |
317 TransportFeedbackPacketLossTracker tracker(10, 10, 1); | 312 TransportFeedbackPacketLossTracker tracker(10, 10, 1); |
318 | 313 |
319 SimulatePacketTransmissionRange(&tracker, base, 200); | 314 SimulatePacketTransmissionRange(&tracker, base, 200); |
320 | 315 |
321 // Up to max-window-size retained. | 316 // Up to max-window-size retained. |
322 // Expected window contents: [] -> [1010100001]. | 317 // Expected window contents: [] -> [1010100001]. |
323 AddTransportFeedbackAndValidate( | 318 AddTransportFeedbackAndValidate( |
324 &tracker, base, | 319 &tracker, base, |
325 {true, false, true, false, true, false, false, false, false, true}); | 320 {true, false, true, false, true, false, false, false, false, true}); |
326 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); | 321 ValidatePacketLossStatistics(tracker, 6.0f / 10.0f, 3.0f / 9.0f); |
327 | 322 |
328 // After max-window-size, older entries discarded to accommodate newer ones. | 323 // After max-window-size, older entries discarded to accommodate newer ones. |
329 // Expected window contents: [1010100001] -> [0000110111]. | 324 // Expected window contents: [1010100001] -> [0000110111]. |
330 AddTransportFeedbackAndValidate(&tracker, base + 10, | 325 AddTransportFeedbackAndValidate(&tracker, base + 10, |
331 {true, false, true, true, true}); | 326 {true, false, true, true, true}); |
332 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); | 327 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 2.0f / 9.0f); |
333 } | |
334 } | 328 } |
335 | 329 |
336 // Inserting feedback into the middle of a full window works correctly. | 330 // Inserting feedback into the middle of a full window works correctly. |
337 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { | 331 TEST_P(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddle) { |
338 for (uint16_t base : kBases) { | 332 const uint16_t base = GetParam(); |
339 TransportFeedbackPacketLossTracker tracker(10, 5, 1); | 333 TransportFeedbackPacketLossTracker tracker(10, 5, 1); |
340 | 334 |
341 SimulatePacketTransmissionRange(&tracker, base, 300); | 335 SimulatePacketTransmissionRange(&tracker, base, 300); |
342 | 336 |
343 // Expected window contents: [] -> [10101]. | 337 // Expected window contents: [] -> [10101]. |
344 AddTransportFeedbackAndValidate(&tracker, base, | 338 AddTransportFeedbackAndValidate(&tracker, base, |
345 {true, false, true, false, true}); | 339 {true, false, true, false, true}); |
346 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); | 340 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 2.0f / 4.0f); |
347 | 341 |
348 // Expected window contents: [10101] -> [10101-GAP-10001]. | 342 // Expected window contents: [10101] -> [10101-GAP-10001]. |
349 AddTransportFeedbackAndValidate(&tracker, base + 100, | 343 AddTransportFeedbackAndValidate(&tracker, base + 100, |
350 {true, false, false, false, true}); | 344 {true, false, false, false, true}); |
351 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); | 345 ValidatePacketLossStatistics(tracker, 5.0f / 10.0f, 3.0f / 8.0f); |
352 | 346 |
353 // Insert into the middle of this full window - it discards the older data. | 347 // Insert into the middle of this full window - it discards the older data. |
354 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. | 348 // Expected window contents: [10101-GAP-10001] -> [11111-GAP-10001]. |
355 AddTransportFeedbackAndValidate(&tracker, base + 50, | 349 AddTransportFeedbackAndValidate(&tracker, base + 50, |
356 {true, true, true, true, true}); | 350 {true, true, true, true, true}); |
357 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); | 351 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 1.0f / 8.0f); |
358 } | |
359 } | 352 } |
360 | 353 |
361 // Inserting feedback into the middle of a full window works correctly - can | 354 // Inserting feedback into the middle of a full window works correctly - can |
362 // complete two pairs. | 355 // complete two pairs. |
363 TEST(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { | 356 TEST_P(TransportFeedbackPacketLossTrackerTest, InsertionCompletesTwoPairs) { |
364 for (uint16_t base : kBases) { | 357 const uint16_t base = GetParam(); |
365 TransportFeedbackPacketLossTracker tracker(15, 5, 1); | 358 TransportFeedbackPacketLossTracker tracker(15, 5, 1); |
366 | 359 |
367 SimulatePacketTransmissionRange(&tracker, base, 300); | 360 SimulatePacketTransmissionRange(&tracker, base, 300); |
368 | 361 |
369 // Expected window contents: [] -> [10111]. | 362 // Expected window contents: [] -> [10111]. |
370 AddTransportFeedbackAndValidate(&tracker, base, | 363 AddTransportFeedbackAndValidate(&tracker, base, |
371 {true, false, true, true, true}); | 364 {true, false, true, true, true}); |
372 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 365 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
373 | 366 |
374 // Expected window contents: [10111] -> [10111-GAP-10101]. | 367 // Expected window contents: [10111] -> [10111-GAP-10101]. |
375 AddTransportFeedbackAndValidate(&tracker, base + 7, | 368 AddTransportFeedbackAndValidate(&tracker, base + 7, |
376 {true, false, true, false, true}); | 369 {true, false, true, false, true}); |
377 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 370 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
378 | 371 |
379 // Insert in between, closing the gap completely. | 372 // Insert in between, closing the gap completely. |
380 // Expected window contents: [10111-GAP-10101] -> [101111010101]. | 373 // Expected window contents: [10111-GAP-10101] -> [101111010101]. |
381 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); | 374 AddTransportFeedbackAndValidate(&tracker, base + 5, {false, true}); |
382 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); | 375 ValidatePacketLossStatistics(tracker, 4.0f / 12.0f, 4.0f / 11.0f); |
383 } | |
384 } | 376 } |
385 | 377 |
386 // The window can meaningfully hold up to 0x8000 SENT packetts (of which only | 378 // The window can meaningfully hold up to 0x8000 SENT packetts (of which only |
387 // up to max-window acked messages will be kept and regarded). | 379 // up to max-window acked messages will be kept and regarded). |
388 TEST(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { | 380 TEST_P(TransportFeedbackPacketLossTrackerTest, SecondQuadrant) { |
389 for (uint16_t base : kBases) { | 381 const uint16_t base = GetParam(); |
390 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 382 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
391 | 383 |
392 SimulatePacketTransmissionRange(&tracker, base, 0x8000, false); | 384 SimulatePacketTransmissionRange(&tracker, base, 0x8000, false); |
393 | 385 |
394 // Expected window contents: [] -> [10011]. | 386 // Expected window contents: [] -> [10011]. |
395 AddTransportFeedbackAndValidate(&tracker, base, | 387 AddTransportFeedbackAndValidate(&tracker, base, |
396 {true, false, false, true, true}); | 388 {true, false, false, true, true}); |
397 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); | 389 ValidatePacketLossStatistics(tracker, 2.0f / 5.0f, 1.0f / 4.0f); |
398 | 390 |
399 // Window *does* get updated with inputs from quadrant #2. | 391 // Window *does* get updated with inputs from quadrant #2. |
400 // Expected window contents: [10011] -> [100111]. | 392 // Expected window contents: [10011] -> [100111]. |
401 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); | 393 AddTransportFeedbackAndValidate(&tracker, base + 0x4321, {true}); |
402 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); | 394 ValidatePacketLossStatistics(tracker, 2.0f / 6.0f, 1.0f / 4.0f); |
403 | 395 |
404 // Correct recognition of quadrant #2: up to, but not including, base + | 396 // Correct recognition of quadrant #2: up to, but not including, base + |
405 // 0x8000 | 397 // 0x8000 |
406 // Expected window contents: [100111] -> [1001111]. | 398 // Expected window contents: [100111] -> [1001111]. |
407 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); | 399 AddTransportFeedbackAndValidate(&tracker, base + 0x7fff, {true}); |
408 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); | 400 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 1.0f / 4.0f); |
409 } | |
410 } | 401 } |
411 | 402 |
412 // After the base has moved due to insertion into the third quadrant, it is | 403 // After the base has moved due to insertion into the third quadrant, it is |
413 // still possible to get feedbacks in the middle of the window and obtain the | 404 // still possible to get feedbacks in the middle of the window and obtain the |
414 // correct PLR and RPLR. Insertion into the middle before the max window size | 405 // correct PLR and RPLR. Insertion into the middle before the max window size |
415 // has been achieved does not cause older packets to be dropped. | 406 // has been achieved does not cause older packets to be dropped. |
416 TEST(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMoved) { | 407 TEST_P(TransportFeedbackPacketLossTrackerTest, InsertIntoMiddleAfterBaseMoved) { |
417 for (uint16_t base : kBases) { | 408 const uint16_t base = GetParam(); |
418 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 409 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
419 | 410 |
420 SimulatePacketTransmissionRange(&tracker, base, 20); | 411 SimulatePacketTransmissionRange(&tracker, base, 20); |
421 SimulatePacketTransmissionRange(&tracker, base + 0x5000, 20); | 412 SimulatePacketTransmissionRange(&tracker, base + 0x5000, 20); |
422 | 413 |
423 // Expected window contents: [] -> [1001101]. | 414 // Expected window contents: [] -> [1001101]. |
424 AddTransportFeedbackAndValidate( | 415 AddTransportFeedbackAndValidate( |
425 &tracker, base, {true, false, false, true, true, false, true}); | 416 &tracker, base, {true, false, false, true, true, false, true}); |
426 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); | 417 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 6.0f); |
427 | 418 |
428 // Expected window contents: [1001101] -> [101-GAP-1001]. | 419 // Expected window contents: [1001101] -> [101-GAP-1001]. |
429 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 4); | 420 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 4); |
430 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 421 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
431 {true, false, false, true}); | 422 {true, false, false, true}); |
432 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); | 423 ValidatePacketLossStatistics(tracker, 3.0f / 7.0f, 2.0f / 5.0f); |
433 | 424 |
434 // Inserting into the middle still works after the base has shifted. | 425 // Inserting into the middle still works after the base has shifted. |
435 // Expected window contents: | 426 // Expected window contents: |
436 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] | 427 // [101-GAP-1001] -> [101-GAP-100101-GAP-1001] |
437 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, | 428 AddTransportFeedbackAndValidate(&tracker, base + 0x5000, |
438 {true, false, false, true, false, true}); | 429 {true, false, false, true, false, true}); |
439 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); | 430 ValidatePacketLossStatistics(tracker, 6.0f / 13.0f, 4.0f / 10.0f); |
440 | 431 |
441 // The base can keep moving after inserting into the middle. | 432 // The base can keep moving after inserting into the middle. |
442 // Expected window contents: | 433 // Expected window contents: |
443 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. | 434 // [101-GAP-100101-GAP-1001] -> [1-GAP-100101-GAP-100111]. |
444 SimulatePacketTransmissionRange(&tracker, base + 0x8000 + 4, 2); | 435 SimulatePacketTransmissionRange(&tracker, base + 0x8000 + 4, 2); |
445 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); | 436 AddTransportFeedbackAndValidate(&tracker, base + 0x8000 + 4, {true, true}); |
446 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); | 437 ValidatePacketLossStatistics(tracker, 5.0f / 13.0f, 3.0f / 10.0f); |
447 } | |
448 } | 438 } |
449 | 439 |
450 // After moving the base of the window, the max window size is still observed. | 440 // After moving the base of the window, the max window size is still observed. |
451 TEST(TransportFeedbackPacketLossTrackerTest, MaxWindowObservedAfterBaseMoved) { | 441 TEST_P(TransportFeedbackPacketLossTrackerTest, |
452 for (uint16_t base : kBases) { | 442 MaxWindowObservedAfterBaseMoved) { |
453 TransportFeedbackPacketLossTracker tracker(15, 10, 1); | 443 const uint16_t base = GetParam(); |
454 | 444 TransportFeedbackPacketLossTracker tracker(15, 10, 1); |
455 // Expected window contents: [] -> [1001110101]. | 445 |
456 SimulatePacketTransmissionRange(&tracker, base, 10); | 446 // Expected window contents: [] -> [1001110101]. |
457 AddTransportFeedbackAndValidate( | 447 SimulatePacketTransmissionRange(&tracker, base, 10); |
458 &tracker, base, | 448 AddTransportFeedbackAndValidate( |
459 {true, false, false, true, true, true, false, true, false, true}); | 449 &tracker, base, |
460 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 450 {true, false, false, true, true, true, false, true, false, true}); |
461 | 451 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
462 // Create gap (on both sides). | 452 |
463 SimulatePacketTransmissionRange(&tracker, base + 0x4000, 20); | 453 // Create gap (on both sides). |
464 | 454 SimulatePacketTransmissionRange(&tracker, base + 0x4000, 20); |
465 // Expected window contents: [1001110101] -> [1110101-GAP-101]. | 455 |
466 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 3); | 456 // Expected window contents: [1001110101] -> [1110101-GAP-101]. |
467 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, | 457 SimulatePacketTransmissionRange(&tracker, base + 0x8000, 3); |
468 {true, false, true}); | 458 AddTransportFeedbackAndValidate(&tracker, base + 0x8000, |
469 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); | 459 {true, false, true}); |
470 | 460 ValidatePacketLossStatistics(tracker, 3.0f / 10.0f, 3.0f / 8.0f); |
471 // Push into middle until max window is reached. The gap is NOT completed. | 461 |
472 // Expected window contents: | 462 // Push into middle until max window is reached. The gap is NOT completed. |
473 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] | 463 // Expected window contents: |
474 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2, | 464 // [1110101-GAP-101] -> [1110101-GAP-10001-GAP-101] |
475 {true, false, false, false, true}); | 465 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2, |
476 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); | 466 {true, false, false, false, true}); |
477 | 467 ValidatePacketLossStatistics(tracker, 6.0f / 15.0f, 4.0f / 12.0f); |
478 // Pushing new packets into the middle would discard older packets. | 468 |
479 // Expected window contents: | 469 // Pushing new packets into the middle would discard older packets. |
480 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] | 470 // Expected window contents: |
481 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2 + 5, | 471 // [1110101-GAP-10001-GAP-101] -> [0101-GAP-10001101-GAP-101] |
482 {true, false, true}); | 472 AddTransportFeedbackAndValidate(&tracker, base + 0x4000 + 2 + 5, |
483 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); | 473 {true, false, true}); |
484 } | 474 ValidatePacketLossStatistics(tracker, 7.0f / 15.0f, 5.0f / 12.0f); |
485 } | 475 } |
486 | 476 |
487 // A packet with a new enough sequence number might shift enough old feedbacks | 477 // A packet with a new enough sequence number might shift enough old feedbacks |
488 // out window, that we'd go back to an unknown PLR and RPLR. | 478 // out window, that we'd go back to an unknown PLR and RPLR. |
489 TEST(TransportFeedbackPacketLossTrackerTest, NewPacketMovesWindowBase) { | 479 TEST_P(TransportFeedbackPacketLossTrackerTest, NewPacketMovesWindowBase) { |
490 for (uint16_t base : kBases) { | 480 const uint16_t base = GetParam(); |
491 TransportFeedbackPacketLossTracker tracker(20, 5, 3); | 481 TransportFeedbackPacketLossTracker tracker(20, 5, 3); |
492 | 482 |
493 SimulatePacketTransmissionRange(&tracker, base, 50); | 483 SimulatePacketTransmissionRange(&tracker, base, 50); |
494 SimulatePacketTransmissionRange(&tracker, base + 0x4000 - 1, 6); // Gap | 484 SimulatePacketTransmissionRange(&tracker, base + 0x4000 - 1, 6); // Gap |
495 | 485 |
496 // Expected window contents: [] -> [1001110101]. | 486 // Expected window contents: [] -> [1001110101]. |
497 AddTransportFeedbackAndValidate( | 487 AddTransportFeedbackAndValidate( |
498 &tracker, base, | 488 &tracker, base, |
499 {true, false, false, true, true, true, false, true, false, true}); | 489 {true, false, false, true, true, true, false, true, false, true}); |
500 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); | 490 ValidatePacketLossStatistics(tracker, 4.0f / 10.0f, 3.0f / 9.0f); |
501 | 491 |
502 // A new sent packet with a new enough sequence number could shift enough | 492 // A new sent packet with a new enough sequence number could shift enough |
503 // acked packets out of window, that we'd go back to an unknown PLR | 493 // acked packets out of window, that we'd go back to an unknown PLR |
504 // and RPLR. This *doesn't* // necessarily mean all of the old ones | 494 // and RPLR. This *doesn't* // necessarily mean all of the old ones |
505 // were discarded, though. | 495 // were discarded, though. |
506 // Expected window contents: [1001110101] -> [01]. | 496 // Expected window contents: [1001110101] -> [01]. |
507 SimulatePacketTransmissionRange(&tracker, base + 0x8006, 2); | 497 SimulatePacketTransmissionRange(&tracker, base + 0x8006, 2); |
508 ValidatePacketLossStatistics(tracker, | 498 ValidatePacketLossStatistics(tracker, |
509 rtc::Optional<float>(), // Still invalid. | 499 rtc::Optional<float>(), // Still invalid. |
510 rtc::Optional<float>()); | 500 rtc::Optional<float>()); |
511 | 501 |
512 // Even if those messages are acked, we'd still might be in unknown PLR | 502 // 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 | 503 // and RPLR, because we might have shifted more packets out of the window |
514 // than we have inserted. | 504 // than we have inserted. |
515 // Expected window contents: [01] -> [01-GAP-11]. | 505 // Expected window contents: [01] -> [01-GAP-11]. |
516 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); | 506 AddTransportFeedbackAndValidate(&tracker, base + 0x8006, {true, true}); |
517 ValidatePacketLossStatistics(tracker, | 507 ValidatePacketLossStatistics(tracker, |
518 rtc::Optional<float>(), // Still invalid. | 508 rtc::Optional<float>(), // Still invalid. |
519 rtc::Optional<float>()); | 509 rtc::Optional<float>()); |
520 | 510 |
521 // Inserting in the middle shows that though some of the elements were | 511 // Inserting in the middle shows that though some of the elements were |
522 // ejected, some were retained. | 512 // ejected, some were retained. |
523 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. | 513 // Expected window contents: [01-GAP-11] -> [01-GAP-1001-GAP-11]. |
524 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, | 514 AddTransportFeedbackAndValidate(&tracker, base + 0x4000, |
525 {true, false, false, true}); | 515 {true, false, false, true}); |
526 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); | 516 ValidatePacketLossStatistics(tracker, 3.0f / 8.0f, 2.0f / 5.0f); |
527 } | |
528 } | 517 } |
529 | 518 |
530 // Sequence number gaps are not gaps in reception. However, gaps in reception | 519 // Sequence number gaps are not gaps in reception. However, gaps in reception |
531 // are still possible, if a packet which WAS sent on the stream is not acked. | 520 // are still possible, if a packet which WAS sent on the stream is not acked. |
532 TEST(TransportFeedbackPacketLossTrackerTest, SanityGapsInSequenceNumbers) { | 521 TEST_P(TransportFeedbackPacketLossTrackerTest, SanityGapsInSequenceNumbers) { |
533 for (uint16_t base : kBases) { | 522 const uint16_t base = GetParam(); |
534 TransportFeedbackPacketLossTracker tracker(20, 5, 1); | 523 TransportFeedbackPacketLossTracker tracker(20, 5, 1); |
535 | 524 |
536 SimulatePacketTransmission( | 525 SimulatePacketTransmission( |
537 &tracker, {base, base + 2, base + 4, base + 6, base + 8}); | 526 &tracker, {base, base + 2, base + 4, base + 6, base + 8}); |
538 | 527 |
539 // Gaps in sequence numbers not considered as gaps in window, because only | 528 // Gaps in sequence numbers not considered as gaps in window, because only |
540 // those sequence numbers which were associated with the stream count. | 529 // those sequence numbers which were associated with the stream count. |
541 // Expected window contents: [] -> [11011]. | 530 // Expected window contents: [] -> [11011]. |
542 AddTransportFeedbackAndValidate( | 531 AddTransportFeedbackAndValidate( |
543 // Note: Left packets belong to this stream, odd ones ignored. | 532 // Note: Left packets belong to this stream, odd ones ignored. |
544 &tracker, base, {true, false, | 533 &tracker, base, {true, false, |
545 true, false, | 534 true, false, |
546 false, false, | 535 false, false, |
547 true, false, | 536 true, false, |
548 true, true}); | 537 true, true}); |
549 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); | 538 ValidatePacketLossStatistics(tracker, 1.0f / 5.0f, 1.0f / 4.0f); |
550 | 539 |
551 | 540 // Create gap by sending [base + 10] but not acking it. |
552 // Create gap by sending [base + 10] but not acking it. | 541 // Note: Acks for [base + 11] and [base + 13] ignored (other stream). |
553 // Note: Acks for [base + 11] and [base + 13] ignored (other stream). | 542 // Expected window contents: [11011] -> [11011-GAP-01]. |
554 // Expected window contents: [11011] -> [11011-GAP-01]. | 543 SimulatePacketTransmission(&tracker, {base + 10, base + 12, base + 14}); |
555 SimulatePacketTransmission(&tracker, {base + 10, base + 12, base + 14}); | 544 AddTransportFeedbackAndValidate(&tracker, base + 11, |
556 AddTransportFeedbackAndValidate(&tracker, base + 11, | 545 {false, false, false, true, true}); |
557 {false, false, false, true, true}); | 546 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 2.0f / 5.0f); |
558 ValidatePacketLossStatistics(tracker, 2.0f / 7.0f, 2.0f / 5.0f); | 547 } |
559 } | 548 |
560 } | 549 // All tests are run multiple times with various baseline sequence number, |
550 // to weed out potential bugs with wrap-around handling. | |
551 constexpr uint16_t kBases[] = {0x0000, 0x3456, 0xc032, 0xfffe}; | |
552 | |
553 INSTANTIATE_TEST_CASE_P(_, | |
554 TransportFeedbackPacketLossTrackerTest, | |
555 testing::ValuesIn(kBases)); | |
561 | 556 |
562 } // namespace webrtc | 557 } // namespace webrtc |
OLD | NEW |