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