inter_arrival_unittest.cc (18882B)
1 /* 2 * Copyright (c) 2013 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 "modules/remote_bitrate_estimator/inter_arrival.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <memory> 16 17 #include "test/gtest.h" 18 19 namespace webrtc { 20 namespace testing { 21 22 enum { 23 kTimestampGroupLengthUs = 5000, 24 kMinStep = 20, 25 kTriggerNewGroupUs = kTimestampGroupLengthUs + kMinStep, 26 kBurstThresholdMs = 5, 27 kAbsSendTimeFraction = 18, 28 kAbsSendTimeInterArrivalUpshift = 8, 29 kInterArrivalShift = kAbsSendTimeFraction + kAbsSendTimeInterArrivalUpshift, 30 }; 31 32 constexpr double kRtpTimestampToMs = 1.0 / 90.0; 33 constexpr double kAstToMs = 34 1000.0 / static_cast<double>(1 << kInterArrivalShift); 35 36 class InterArrivalTest : public ::testing::Test { 37 protected: 38 void SetUp() override { 39 inter_arrival_.reset(new InterArrival(kTimestampGroupLengthUs / 1000, 1.0)); 40 inter_arrival_rtp_.reset(new InterArrival( 41 MakeRtpTimestamp(kTimestampGroupLengthUs), kRtpTimestampToMs)); 42 inter_arrival_ast_.reset( 43 new InterArrival(MakeAbsSendTime(kTimestampGroupLengthUs), kAstToMs)); 44 } 45 46 // Test that neither inter_arrival instance complete the timestamp group from 47 // the given data. 48 void ExpectFalse(int64_t timestamp_us, 49 int64_t arrival_time_ms, 50 size_t packet_size) { 51 InternalExpectFalse(inter_arrival_rtp_.get(), 52 MakeRtpTimestamp(timestamp_us), arrival_time_ms, 53 packet_size); 54 InternalExpectFalse(inter_arrival_ast_.get(), MakeAbsSendTime(timestamp_us), 55 arrival_time_ms, packet_size); 56 } 57 58 // Test that both inter_arrival instances complete the timestamp group from 59 // the given data and that all returned deltas are as expected (except 60 // timestamp delta, which is rounded from us to different ranges and must 61 // match within an interval, given in |timestamp_near]. 62 void ExpectTrue(int64_t timestamp_us, 63 int64_t arrival_time_ms, 64 size_t packet_size, 65 int64_t expected_timestamp_delta_us, 66 int64_t expected_arrival_time_delta_ms, 67 int expected_packet_size_delta, 68 uint32_t timestamp_near) { 69 InternalExpectTrue(inter_arrival_rtp_.get(), MakeRtpTimestamp(timestamp_us), 70 arrival_time_ms, packet_size, 71 MakeRtpTimestamp(expected_timestamp_delta_us), 72 expected_arrival_time_delta_ms, 73 expected_packet_size_delta, timestamp_near); 74 InternalExpectTrue(inter_arrival_ast_.get(), MakeAbsSendTime(timestamp_us), 75 arrival_time_ms, packet_size, 76 MakeAbsSendTime(expected_timestamp_delta_us), 77 expected_arrival_time_delta_ms, 78 expected_packet_size_delta, timestamp_near << 8); 79 } 80 81 void WrapTestHelper(int64_t wrap_start_us, 82 uint32_t timestamp_near, 83 bool unorderly_within_group) { 84 // Step through the range of a 32 bit int, 1/4 at a time to not cause 85 // packets close to wraparound to be judged as out of order. 86 87 // G1 88 int64_t arrival_time = 17; 89 ExpectFalse(0, arrival_time, 1); 90 91 // G2 92 arrival_time += kBurstThresholdMs + 1; 93 ExpectFalse(wrap_start_us / 4, arrival_time, 1); 94 95 // G3 96 arrival_time += kBurstThresholdMs + 1; 97 ExpectTrue(wrap_start_us / 2, arrival_time, 1, wrap_start_us / 4, 6, 98 0, // Delta G2-G1 99 0); 100 101 // G4 102 arrival_time += kBurstThresholdMs + 1; 103 int64_t g4_arrival_time = arrival_time; 104 ExpectTrue(wrap_start_us / 2 + wrap_start_us / 4, arrival_time, 1, 105 wrap_start_us / 4, 6, 0, // Delta G3-G2 106 timestamp_near); 107 108 // G5 109 arrival_time += kBurstThresholdMs + 1; 110 ExpectTrue(wrap_start_us, arrival_time, 2, wrap_start_us / 4, 6, 111 0, // Delta G4-G3 112 timestamp_near); 113 for (int i = 0; i < 10; ++i) { 114 // Slowly step across the wrap point. 115 arrival_time += kBurstThresholdMs + 1; 116 if (unorderly_within_group) { 117 // These packets arrive with timestamps in decreasing order but are 118 // nevertheless accumulated to group because their timestamps are higher 119 // than the initial timestamp of the group. 120 ExpectFalse(wrap_start_us + kMinStep * (9 - i), arrival_time, 1); 121 } else { 122 ExpectFalse(wrap_start_us + kMinStep * i, arrival_time, 1); 123 } 124 } 125 int64_t g5_arrival_time = arrival_time; 126 127 // This packet is out of order and should be dropped. 128 arrival_time += kBurstThresholdMs + 1; 129 ExpectFalse(wrap_start_us - 100, arrival_time, 100); 130 131 // G6 132 arrival_time += kBurstThresholdMs + 1; 133 int64_t g6_arrival_time = arrival_time; 134 ExpectTrue(wrap_start_us + kTriggerNewGroupUs, arrival_time, 10, 135 wrap_start_us / 4 + 9 * kMinStep, 136 g5_arrival_time - g4_arrival_time, 137 (2 + 10) - 1, // Delta G5-G4 138 timestamp_near); 139 140 // This packet is out of order and should be dropped. 141 arrival_time += kBurstThresholdMs + 1; 142 ExpectFalse(wrap_start_us + kTimestampGroupLengthUs, arrival_time, 100); 143 144 // G7 145 arrival_time += kBurstThresholdMs + 1; 146 ExpectTrue(wrap_start_us + 2 * kTriggerNewGroupUs, arrival_time, 100, 147 // Delta G6-G5 148 kTriggerNewGroupUs - 9 * kMinStep, 149 g6_arrival_time - g5_arrival_time, 10 - (2 + 10), 150 timestamp_near); 151 } 152 153 std::unique_ptr<InterArrival> inter_arrival_; 154 155 private: 156 static uint32_t MakeRtpTimestamp(int64_t us) { 157 return static_cast<uint32_t>(static_cast<uint64_t>(us * 90 + 500) / 1000); 158 } 159 160 static uint32_t MakeAbsSendTime(int64_t us) { 161 uint32_t absolute_send_time = 162 static_cast<uint32_t>(((static_cast<uint64_t>(us) << 18) + 500000) / 163 1000000) & 164 0x00FFFFFFul; 165 return absolute_send_time << 8; 166 } 167 168 static void InternalExpectFalse(InterArrival* inter_arrival, 169 uint32_t timestamp, 170 int64_t arrival_time_ms, 171 size_t packet_size) { 172 uint32_t dummy_timestamp = 101; 173 int64_t dummy_arrival_time_ms = 303; 174 int dummy_packet_size = 909; 175 bool computed = inter_arrival->ComputeDeltas( 176 timestamp, arrival_time_ms, arrival_time_ms, packet_size, 177 &dummy_timestamp, &dummy_arrival_time_ms, &dummy_packet_size); 178 EXPECT_EQ(computed, false); 179 EXPECT_EQ(101ul, dummy_timestamp); 180 EXPECT_EQ(303, dummy_arrival_time_ms); 181 EXPECT_EQ(909, dummy_packet_size); 182 } 183 184 static void InternalExpectTrue(InterArrival* inter_arrival, 185 uint32_t timestamp, 186 int64_t arrival_time_ms, 187 size_t packet_size, 188 uint32_t expected_timestamp_delta, 189 int64_t expected_arrival_time_delta_ms, 190 int expected_packet_size_delta, 191 uint32_t timestamp_near) { 192 uint32_t delta_timestamp = 101; 193 int64_t delta_arrival_time_ms = 303; 194 int delta_packet_size = 909; 195 bool computed = inter_arrival->ComputeDeltas( 196 timestamp, arrival_time_ms, arrival_time_ms, packet_size, 197 &delta_timestamp, &delta_arrival_time_ms, &delta_packet_size); 198 EXPECT_EQ(true, computed); 199 EXPECT_NEAR(expected_timestamp_delta, delta_timestamp, timestamp_near); 200 EXPECT_EQ(expected_arrival_time_delta_ms, delta_arrival_time_ms); 201 EXPECT_EQ(expected_packet_size_delta, delta_packet_size); 202 } 203 204 std::unique_ptr<InterArrival> inter_arrival_rtp_; 205 std::unique_ptr<InterArrival> inter_arrival_ast_; 206 }; 207 208 TEST_F(InterArrivalTest, FirstPacket) { 209 ExpectFalse(0, 17, 1); 210 } 211 212 TEST_F(InterArrivalTest, FirstGroup) { 213 // G1 214 int64_t arrival_time = 17; 215 int64_t g1_arrival_time = arrival_time; 216 ExpectFalse(0, arrival_time, 1); 217 218 // G2 219 arrival_time += kBurstThresholdMs + 1; 220 int64_t g2_arrival_time = arrival_time; 221 ExpectFalse(kTriggerNewGroupUs, arrival_time, 2); 222 223 // G3 224 // Only once the first packet of the third group arrives, do we see the deltas 225 // between the first two. 226 arrival_time += kBurstThresholdMs + 1; 227 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1, 228 // Delta G2-G1 229 kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1, 0); 230 } 231 232 TEST_F(InterArrivalTest, SecondGroup) { 233 // G1 234 int64_t arrival_time = 17; 235 int64_t g1_arrival_time = arrival_time; 236 ExpectFalse(0, arrival_time, 1); 237 238 // G2 239 arrival_time += kBurstThresholdMs + 1; 240 int64_t g2_arrival_time = arrival_time; 241 ExpectFalse(kTriggerNewGroupUs, arrival_time, 2); 242 243 // G3 244 arrival_time += kBurstThresholdMs + 1; 245 int64_t g3_arrival_time = arrival_time; 246 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 1, 247 // Delta G2-G1 248 kTriggerNewGroupUs, g2_arrival_time - g1_arrival_time, 1, 0); 249 250 // G4 251 // First packet of 4th group yields deltas between group 2 and 3. 252 arrival_time += kBurstThresholdMs + 1; 253 ExpectTrue(3 * kTriggerNewGroupUs, arrival_time, 2, 254 // Delta G3-G2 255 kTriggerNewGroupUs, g3_arrival_time - g2_arrival_time, -1, 0); 256 } 257 258 TEST_F(InterArrivalTest, AccumulatedGroup) { 259 // G1 260 int64_t arrival_time = 17; 261 int64_t g1_arrival_time = arrival_time; 262 ExpectFalse(0, arrival_time, 1); 263 264 // G2 265 arrival_time += kBurstThresholdMs + 1; 266 ExpectFalse(kTriggerNewGroupUs, 28, 2); 267 int64_t timestamp = kTriggerNewGroupUs; 268 for (int i = 0; i < 10; ++i) { 269 // A bunch of packets arriving within the same group. 270 arrival_time += kBurstThresholdMs + 1; 271 timestamp += kMinStep; 272 ExpectFalse(timestamp, arrival_time, 1); 273 } 274 int64_t g2_arrival_time = arrival_time; 275 int64_t g2_timestamp = timestamp; 276 277 // G3 278 arrival_time = 500; 279 ExpectTrue(2 * kTriggerNewGroupUs, arrival_time, 100, g2_timestamp, 280 g2_arrival_time - g1_arrival_time, 281 (2 + 10) - 1, // Delta G2-G1 282 0); 283 } 284 285 TEST_F(InterArrivalTest, OutOfOrderPacket) { 286 // G1 287 int64_t arrival_time = 17; 288 int64_t timestamp = 0; 289 ExpectFalse(timestamp, arrival_time, 1); 290 int64_t g1_timestamp = timestamp; 291 int64_t g1_arrival_time = arrival_time; 292 293 // G2 294 arrival_time += 11; 295 timestamp += kTriggerNewGroupUs; 296 ExpectFalse(timestamp, 28, 2); 297 for (int i = 0; i < 10; ++i) { 298 arrival_time += kBurstThresholdMs + 1; 299 timestamp += kMinStep; 300 ExpectFalse(timestamp, arrival_time, 1); 301 } 302 int64_t g2_timestamp = timestamp; 303 int64_t g2_arrival_time = arrival_time; 304 305 // This packet is out of order and should be dropped. 306 arrival_time = 281; 307 ExpectFalse(g1_timestamp, arrival_time, 100); 308 309 // G3 310 arrival_time = 500; 311 timestamp = 2 * kTriggerNewGroupUs; 312 ExpectTrue(timestamp, arrival_time, 100, 313 // Delta G2-G1 314 g2_timestamp - g1_timestamp, g2_arrival_time - g1_arrival_time, 315 (2 + 10) - 1, 0); 316 } 317 318 TEST_F(InterArrivalTest, OutOfOrderWithinGroup) { 319 // G1 320 int64_t arrival_time = 17; 321 int64_t timestamp = 0; 322 ExpectFalse(timestamp, arrival_time, 1); 323 int64_t g1_timestamp = timestamp; 324 int64_t g1_arrival_time = arrival_time; 325 326 // G2 327 timestamp += kTriggerNewGroupUs; 328 arrival_time += 11; 329 ExpectFalse(kTriggerNewGroupUs, 28, 2); 330 timestamp += 10 * kMinStep; 331 int64_t g2_timestamp = timestamp; 332 for (int i = 0; i < 10; ++i) { 333 // These packets arrive with timestamps in decreasing order but are 334 // nevertheless accumulated to group because their timestamps are higher 335 // than the initial timestamp of the group. 336 arrival_time += kBurstThresholdMs + 1; 337 ExpectFalse(timestamp, arrival_time, 1); 338 timestamp -= kMinStep; 339 } 340 int64_t g2_arrival_time = arrival_time; 341 342 // However, this packet is deemed out of order and should be dropped. 343 arrival_time = 281; 344 timestamp = g1_timestamp; 345 ExpectFalse(timestamp, arrival_time, 100); 346 347 // G3 348 timestamp = 2 * kTriggerNewGroupUs; 349 arrival_time = 500; 350 ExpectTrue(timestamp, arrival_time, 100, g2_timestamp - g1_timestamp, 351 g2_arrival_time - g1_arrival_time, (2 + 10) - 1, 0); 352 } 353 354 TEST_F(InterArrivalTest, TwoBursts) { 355 // G1 356 int64_t g1_arrival_time = 17; 357 ExpectFalse(0, g1_arrival_time, 1); 358 359 // G2 360 int64_t timestamp = kTriggerNewGroupUs; 361 int64_t arrival_time = 100; // Simulate no packets arriving for 100 ms. 362 for (int i = 0; i < 10; ++i) { 363 // A bunch of packets arriving in one burst (within 5 ms apart). 364 timestamp += 30000; 365 arrival_time += kBurstThresholdMs; 366 ExpectFalse(timestamp, arrival_time, 1); 367 } 368 int64_t g2_arrival_time = arrival_time; 369 int64_t g2_timestamp = timestamp; 370 371 // G3 372 timestamp += 30000; 373 arrival_time += kBurstThresholdMs + 1; 374 ExpectTrue(timestamp, arrival_time, 100, g2_timestamp, 375 g2_arrival_time - g1_arrival_time, 376 10 - 1, // Delta G2-G1 377 0); 378 } 379 380 TEST_F(InterArrivalTest, NoBursts) { 381 // G1 382 ExpectFalse(0, 17, 1); 383 384 // G2 385 int64_t timestamp = kTriggerNewGroupUs; 386 int64_t arrival_time = 28; 387 ExpectFalse(timestamp, arrival_time, 2); 388 389 // G3 390 ExpectTrue(kTriggerNewGroupUs + 30000, arrival_time + kBurstThresholdMs + 1, 391 100, timestamp - 0, arrival_time - 17, 392 2 - 1, // Delta G2-G1 393 0); 394 } 395 396 // Yields 0xfffffffe when converted to internal representation in 397 // inter_arrival_rtp_ and inter_arrival_ast_ respectively. 398 static const int64_t kStartRtpTimestampWrapUs = 47721858827; 399 static const int64_t kStartAbsSendTimeWrapUs = 63999995; 400 401 TEST_F(InterArrivalTest, RtpTimestampWrap) { 402 WrapTestHelper(kStartRtpTimestampWrapUs, 1, false); 403 } 404 405 TEST_F(InterArrivalTest, AbsSendTimeWrap) { 406 WrapTestHelper(kStartAbsSendTimeWrapUs, 1, false); 407 } 408 409 TEST_F(InterArrivalTest, RtpTimestampWrapOutOfOrderWithinGroup) { 410 WrapTestHelper(kStartRtpTimestampWrapUs, 1, true); 411 } 412 413 TEST_F(InterArrivalTest, AbsSendTimeWrapOutOfOrderWithinGroup) { 414 WrapTestHelper(kStartAbsSendTimeWrapUs, 1, true); 415 } 416 417 TEST_F(InterArrivalTest, PositiveArrivalTimeJump) { 418 const size_t kPacketSize = 1000; 419 uint32_t send_time_ms = 10000; 420 int64_t arrival_time_ms = 20000; 421 int64_t system_time_ms = 30000; 422 423 uint32_t send_delta; 424 int64_t arrival_delta; 425 int size_delta; 426 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 427 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 428 &arrival_delta, &size_delta)); 429 430 const int kTimeDeltaMs = 30; 431 send_time_ms += kTimeDeltaMs; 432 arrival_time_ms += kTimeDeltaMs; 433 system_time_ms += kTimeDeltaMs; 434 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 435 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 436 &arrival_delta, &size_delta)); 437 438 send_time_ms += kTimeDeltaMs; 439 arrival_time_ms += kTimeDeltaMs + InterArrival::kArrivalTimeOffsetThresholdMs; 440 system_time_ms += kTimeDeltaMs; 441 EXPECT_TRUE(inter_arrival_->ComputeDeltas( 442 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 443 &arrival_delta, &size_delta)); 444 EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta)); 445 EXPECT_EQ(kTimeDeltaMs, arrival_delta); 446 EXPECT_EQ(size_delta, 0); 447 448 send_time_ms += kTimeDeltaMs; 449 arrival_time_ms += kTimeDeltaMs; 450 system_time_ms += kTimeDeltaMs; 451 // The previous arrival time jump should now be detected and cause a reset. 452 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 453 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 454 &arrival_delta, &size_delta)); 455 456 // The two next packets will not give a valid delta since we're in the initial 457 // state. 458 for (int i = 0; i < 2; ++i) { 459 send_time_ms += kTimeDeltaMs; 460 arrival_time_ms += kTimeDeltaMs; 461 system_time_ms += kTimeDeltaMs; 462 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 463 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 464 &arrival_delta, &size_delta)); 465 } 466 467 send_time_ms += kTimeDeltaMs; 468 arrival_time_ms += kTimeDeltaMs; 469 system_time_ms += kTimeDeltaMs; 470 EXPECT_TRUE(inter_arrival_->ComputeDeltas( 471 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 472 &arrival_delta, &size_delta)); 473 EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta)); 474 EXPECT_EQ(kTimeDeltaMs, arrival_delta); 475 EXPECT_EQ(size_delta, 0); 476 } 477 478 TEST_F(InterArrivalTest, NegativeArrivalTimeJump) { 479 const size_t kPacketSize = 1000; 480 uint32_t send_time_ms = 10000; 481 int64_t arrival_time_ms = 20000; 482 int64_t system_time_ms = 30000; 483 484 uint32_t send_delta; 485 int64_t arrival_delta; 486 int size_delta; 487 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 488 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 489 &arrival_delta, &size_delta)); 490 491 const int kTimeDeltaMs = 30; 492 send_time_ms += kTimeDeltaMs; 493 arrival_time_ms += kTimeDeltaMs; 494 system_time_ms += kTimeDeltaMs; 495 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 496 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 497 &arrival_delta, &size_delta)); 498 499 send_time_ms += kTimeDeltaMs; 500 arrival_time_ms += kTimeDeltaMs; 501 system_time_ms += kTimeDeltaMs; 502 EXPECT_TRUE(inter_arrival_->ComputeDeltas( 503 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 504 &arrival_delta, &size_delta)); 505 EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta)); 506 EXPECT_EQ(kTimeDeltaMs, arrival_delta); 507 EXPECT_EQ(size_delta, 0); 508 509 // Three out of order will fail, after that we will be reset and two more will 510 // fail before we get our first valid delta after the reset. 511 arrival_time_ms -= 1000; 512 for (int i = 0; i < InterArrival::kReorderedResetThreshold + 3; ++i) { 513 send_time_ms += kTimeDeltaMs; 514 arrival_time_ms += kTimeDeltaMs; 515 system_time_ms += kTimeDeltaMs; 516 // The previous arrival time jump should now be detected and cause a reset. 517 EXPECT_FALSE(inter_arrival_->ComputeDeltas( 518 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 519 &arrival_delta, &size_delta)); 520 } 521 522 send_time_ms += kTimeDeltaMs; 523 arrival_time_ms += kTimeDeltaMs; 524 system_time_ms += kTimeDeltaMs; 525 EXPECT_TRUE(inter_arrival_->ComputeDeltas( 526 send_time_ms, arrival_time_ms, system_time_ms, kPacketSize, &send_delta, 527 &arrival_delta, &size_delta)); 528 EXPECT_EQ(kTimeDeltaMs, static_cast<int>(send_delta)); 529 EXPECT_EQ(kTimeDeltaMs, arrival_delta); 530 EXPECT_EQ(size_delta, 0); 531 } 532 } // namespace testing 533 } // namespace webrtc