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