source_tracker_unittest.cc (22426B)
1 /* 2 * Copyright (c) 2019 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/rtp_rtcp/source/source_tracker.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <list> 16 #include <optional> 17 #include <random> 18 #include <set> 19 #include <tuple> 20 #include <utility> 21 #include <vector> 22 23 #include "api/rtp_headers.h" 24 #include "api/rtp_packet_info.h" 25 #include "api/rtp_packet_infos.h" 26 #include "api/transport/rtp/rtp_source.h" 27 #include "api/units/time_delta.h" 28 #include "api/units/timestamp.h" 29 #include "system_wrappers/include/clock.h" 30 #include "system_wrappers/include/ntp_time.h" 31 #include "test/gmock.h" 32 #include "test/gtest.h" 33 #include "test/time_controller/simulated_time_controller.h" 34 35 namespace webrtc { 36 namespace { 37 38 using ::testing::Combine; 39 using ::testing::ElementsAre; 40 using ::testing::ElementsAreArray; 41 using ::testing::IsEmpty; 42 using ::testing::TestWithParam; 43 using ::testing::Values; 44 45 constexpr size_t kPacketInfosCountMax = 5; 46 47 // Simple "guaranteed to be correct" re-implementation of `SourceTracker` for 48 // dual-implementation testing purposes. 49 class ExpectedSourceTracker { 50 public: 51 explicit ExpectedSourceTracker(Clock* clock) : clock_(clock) {} 52 53 void OnFrameDelivered(const RtpPacketInfos& packet_infos) { 54 const Timestamp now = clock_->CurrentTime(); 55 56 for (const auto& packet_info : packet_infos) { 57 RtpSource::Extensions extensions = { 58 .audio_level = packet_info.audio_level(), 59 .absolute_capture_time = packet_info.absolute_capture_time(), 60 .local_capture_clock_offset = 61 packet_info.local_capture_clock_offset()}; 62 63 for (const auto& csrc : packet_info.csrcs()) { 64 entries_.emplace_front(now, csrc, RtpSourceType::CSRC, 65 packet_info.rtp_timestamp(), extensions); 66 } 67 68 entries_.emplace_front(now, packet_info.ssrc(), RtpSourceType::SSRC, 69 packet_info.rtp_timestamp(), extensions); 70 } 71 72 PruneEntries(now); 73 } 74 75 std::vector<RtpSource> GetSources() const { 76 PruneEntries(clock_->CurrentTime()); 77 78 return std::vector<RtpSource>(entries_.begin(), entries_.end()); 79 } 80 81 private: 82 void PruneEntries(Timestamp now) const { 83 const Timestamp prune = now - TimeDelta::Seconds(10); 84 85 std::set<std::pair<RtpSourceType, uint32_t>> seen; 86 87 auto it = entries_.begin(); 88 auto end = entries_.end(); 89 while (it != end) { 90 auto next = it; 91 ++next; 92 93 auto key = std::make_pair(it->source_type(), it->source_id()); 94 if (!seen.insert(key).second || it->timestamp() < prune) { 95 entries_.erase(it); 96 } 97 98 it = next; 99 } 100 } 101 102 Clock* const clock_; 103 104 mutable std::list<RtpSource> entries_; 105 }; 106 107 class SourceTrackerRandomTest 108 : public TestWithParam<std::tuple<uint32_t, uint32_t>> { 109 protected: 110 SourceTrackerRandomTest() 111 : ssrcs_count_(std::get<0>(GetParam())), 112 csrcs_count_(std::get<1>(GetParam())), 113 generator_(42) {} 114 115 RtpPacketInfos GeneratePacketInfos() { 116 size_t count = std::uniform_int_distribution<size_t>( 117 1, kPacketInfosCountMax)(generator_); 118 119 RtpPacketInfos::vector_type packet_infos; 120 for (size_t i = 0; i < count; ++i) { 121 packet_infos 122 .emplace_back(GenerateSsrc(), GenerateCsrcs(), GenerateRtpTimestamp(), 123 GenerateReceiveTime()) 124 .set_audio_level(GenerateAudioLevel()) 125 .set_absolute_capture_time(GenerateAbsoluteCaptureTime()) 126 .set_local_capture_clock_offset(GenerateLocalCaptureClockOffset()); 127 } 128 129 return RtpPacketInfos(std::move(packet_infos)); 130 } 131 132 TimeDelta GenerateClockAdvanceTime() { 133 double roll = std::uniform_real_distribution<double>(0.0, 1.0)(generator_); 134 135 if (roll < 0.05) { 136 return TimeDelta::Zero(); 137 } 138 139 if (roll < 0.08) { 140 return SourceTracker::kTimeout - TimeDelta::Millis(1); 141 } 142 143 if (roll < 0.11) { 144 return SourceTracker::kTimeout; 145 } 146 147 if (roll < 0.19) { 148 return TimeDelta::Millis(std::uniform_int_distribution<int64_t>( 149 SourceTracker::kTimeout.ms(), 150 SourceTracker::kTimeout.ms() * 1000)(generator_)); 151 } 152 153 return TimeDelta::Millis(std::uniform_int_distribution<int64_t>( 154 1, SourceTracker::kTimeout.ms() - 1)(generator_)); 155 } 156 157 private: 158 uint32_t GenerateSsrc() { 159 return std::uniform_int_distribution<uint32_t>(1, ssrcs_count_)(generator_); 160 } 161 162 std::vector<uint32_t> GenerateCsrcs() { 163 std::vector<uint32_t> csrcs; 164 for (size_t i = 1; i <= csrcs_count_ && csrcs.size() < kRtpCsrcSize; ++i) { 165 if (std::bernoulli_distribution(0.5)(generator_)) { 166 csrcs.push_back(i); 167 } 168 } 169 170 return csrcs; 171 } 172 173 uint32_t GenerateRtpTimestamp() { 174 return std::uniform_int_distribution<uint32_t>()(generator_); 175 } 176 177 std::optional<uint8_t> GenerateAudioLevel() { 178 if (std::bernoulli_distribution(0.25)(generator_)) { 179 return std::nullopt; 180 } 181 182 // Workaround for std::uniform_int_distribution<uint8_t> not being allowed. 183 return static_cast<uint8_t>( 184 std::uniform_int_distribution<uint16_t>()(generator_)); 185 } 186 187 std::optional<AbsoluteCaptureTime> GenerateAbsoluteCaptureTime() { 188 if (std::bernoulli_distribution(0.25)(generator_)) { 189 return std::nullopt; 190 } 191 192 AbsoluteCaptureTime value; 193 194 value.absolute_capture_timestamp = 195 std::uniform_int_distribution<uint64_t>()(generator_); 196 197 if (std::bernoulli_distribution(0.5)(generator_)) { 198 value.estimated_capture_clock_offset = std::nullopt; 199 } else { 200 value.estimated_capture_clock_offset = 201 std::uniform_int_distribution<int64_t>()(generator_); 202 } 203 204 return value; 205 } 206 207 std::optional<TimeDelta> GenerateLocalCaptureClockOffset() { 208 if (std::bernoulli_distribution(0.5)(generator_)) { 209 return std::nullopt; 210 } 211 return TimeDelta::Millis( 212 UQ32x32ToInt64Ms(std::uniform_int_distribution<int64_t>()(generator_))); 213 } 214 215 Timestamp GenerateReceiveTime() { 216 return Timestamp::Micros( 217 std::uniform_int_distribution<int64_t>()(generator_)); 218 } 219 220 protected: 221 GlobalSimulatedTimeController time_controller_{Timestamp::Seconds(1000)}; 222 223 private: 224 const uint32_t ssrcs_count_; 225 const uint32_t csrcs_count_; 226 227 std::mt19937 generator_; 228 }; 229 230 } // namespace 231 232 TEST_P(SourceTrackerRandomTest, RandomOperations) { 233 constexpr size_t kIterationsCount = 200; 234 235 SourceTracker actual_tracker(time_controller_.GetClock()); 236 ExpectedSourceTracker expected_tracker(time_controller_.GetClock()); 237 238 ASSERT_THAT(actual_tracker.GetSources(), IsEmpty()); 239 ASSERT_THAT(expected_tracker.GetSources(), IsEmpty()); 240 241 for (size_t i = 0; i < kIterationsCount; ++i) { 242 RtpPacketInfos packet_infos = GeneratePacketInfos(); 243 244 actual_tracker.OnFrameDelivered(packet_infos); 245 expected_tracker.OnFrameDelivered(packet_infos); 246 247 time_controller_.AdvanceTime(GenerateClockAdvanceTime()); 248 ASSERT_THAT(actual_tracker.GetSources(), 249 ElementsAreArray(expected_tracker.GetSources())); 250 } 251 } 252 253 INSTANTIATE_TEST_SUITE_P(All, 254 SourceTrackerRandomTest, 255 Combine(/*ssrcs_count_=*/Values(1, 2, 4), 256 /*csrcs_count_=*/Values(0, 1, 3, 7))); 257 258 TEST(SourceTrackerTest, StartEmpty) { 259 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); 260 SourceTracker tracker(time_controller.GetClock()); 261 262 EXPECT_THAT(tracker.GetSources(), IsEmpty()); 263 } 264 265 TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesDistinctSsrcs) { 266 constexpr uint32_t kSsrc1 = 10; 267 constexpr uint32_t kSsrc2 = 11; 268 constexpr uint32_t kCsrcs0 = 20; 269 constexpr uint32_t kCsrcs1 = 21; 270 constexpr uint32_t kCsrcs2 = 22; 271 constexpr uint32_t kRtpTimestamp0 = 40; 272 constexpr uint32_t kRtpTimestamp1 = 50; 273 constexpr std::optional<uint8_t> kAudioLevel0 = 50; 274 constexpr std::optional<uint8_t> kAudioLevel1 = 20; 275 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime = 276 AbsoluteCaptureTime{.absolute_capture_timestamp = 12, 277 .estimated_capture_clock_offset = std::nullopt}; 278 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset = std::nullopt; 279 constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); 280 constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70); 281 282 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); 283 SourceTracker tracker(time_controller.GetClock()); 284 285 tracker.OnFrameDelivered(RtpPacketInfos( 286 {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) 287 .set_audio_level(kAudioLevel0) 288 .set_absolute_capture_time(kAbsoluteCaptureTime) 289 .set_local_capture_clock_offset(kLocalCaptureClockOffset), 290 RtpPacketInfo(kSsrc2, {kCsrcs2}, kRtpTimestamp1, kReceiveTime1) 291 .set_audio_level(kAudioLevel1) 292 .set_absolute_capture_time(kAbsoluteCaptureTime) 293 .set_local_capture_clock_offset(kLocalCaptureClockOffset)})); 294 295 Timestamp timestamp = time_controller.GetClock()->CurrentTime(); 296 constexpr RtpSource::Extensions extensions0 = { 297 .audio_level = kAudioLevel0, 298 .absolute_capture_time = kAbsoluteCaptureTime, 299 .local_capture_clock_offset = kLocalCaptureClockOffset}; 300 constexpr RtpSource::Extensions extensions1 = { 301 .audio_level = kAudioLevel1, 302 .absolute_capture_time = kAbsoluteCaptureTime, 303 .local_capture_clock_offset = kLocalCaptureClockOffset}; 304 305 time_controller.AdvanceTime(TimeDelta::Zero()); 306 307 EXPECT_THAT(tracker.GetSources(), 308 ElementsAre(RtpSource(timestamp, kSsrc2, RtpSourceType::SSRC, 309 kRtpTimestamp1, extensions1), 310 RtpSource(timestamp, kCsrcs2, RtpSourceType::CSRC, 311 kRtpTimestamp1, extensions1), 312 RtpSource(timestamp, kSsrc1, RtpSourceType::SSRC, 313 kRtpTimestamp0, extensions0), 314 RtpSource(timestamp, kCsrcs1, RtpSourceType::CSRC, 315 kRtpTimestamp0, extensions0), 316 RtpSource(timestamp, kCsrcs0, RtpSourceType::CSRC, 317 kRtpTimestamp0, extensions0))); 318 } 319 320 TEST(SourceTrackerTest, OnFrameDeliveredRecordsSourcesSameSsrc) { 321 constexpr uint32_t kSsrc = 10; 322 constexpr uint32_t kCsrcs0 = 20; 323 constexpr uint32_t kCsrcs1 = 21; 324 constexpr uint32_t kCsrcs2 = 22; 325 constexpr uint32_t kRtpTimestamp0 = 40; 326 constexpr uint32_t kRtpTimestamp1 = 45; 327 constexpr uint32_t kRtpTimestamp2 = 50; 328 constexpr std::optional<uint8_t> kAudioLevel0 = 50; 329 constexpr std::optional<uint8_t> kAudioLevel1 = 20; 330 constexpr std::optional<uint8_t> kAudioLevel2 = 10; 331 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime = 332 AbsoluteCaptureTime{.absolute_capture_timestamp = 12, 333 .estimated_capture_clock_offset = std::nullopt}; 334 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset = std::nullopt; 335 constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); 336 constexpr Timestamp kReceiveTime1 = Timestamp::Millis(70); 337 constexpr Timestamp kReceiveTime2 = Timestamp::Millis(80); 338 339 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); 340 SourceTracker tracker(time_controller.GetClock()); 341 342 tracker.OnFrameDelivered(RtpPacketInfos({ 343 RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) 344 .set_audio_level(kAudioLevel0) 345 .set_absolute_capture_time(kAbsoluteCaptureTime) 346 .set_local_capture_clock_offset(kLocalCaptureClockOffset), 347 RtpPacketInfo(kSsrc, {kCsrcs2}, kRtpTimestamp1, kReceiveTime1) 348 .set_audio_level(kAudioLevel1) 349 .set_absolute_capture_time(kAbsoluteCaptureTime) 350 .set_local_capture_clock_offset(kLocalCaptureClockOffset), 351 RtpPacketInfo(kSsrc, {kCsrcs0}, kRtpTimestamp2, kReceiveTime2) 352 .set_audio_level(kAudioLevel2) 353 .set_absolute_capture_time(kAbsoluteCaptureTime) 354 .set_local_capture_clock_offset(kLocalCaptureClockOffset), 355 })); 356 357 time_controller.AdvanceTime(TimeDelta::Zero()); 358 Timestamp timestamp = time_controller.GetClock()->CurrentTime(); 359 constexpr RtpSource::Extensions extensions0 = { 360 .audio_level = kAudioLevel0, 361 .absolute_capture_time = kAbsoluteCaptureTime, 362 .local_capture_clock_offset = kLocalCaptureClockOffset}; 363 constexpr RtpSource::Extensions extensions1 = { 364 .audio_level = kAudioLevel1, 365 .absolute_capture_time = kAbsoluteCaptureTime, 366 .local_capture_clock_offset = kLocalCaptureClockOffset}; 367 constexpr RtpSource::Extensions extensions2 = { 368 .audio_level = kAudioLevel2, 369 .absolute_capture_time = kAbsoluteCaptureTime, 370 .local_capture_clock_offset = kLocalCaptureClockOffset}; 371 372 EXPECT_THAT(tracker.GetSources(), 373 ElementsAre(RtpSource(timestamp, kSsrc, RtpSourceType::SSRC, 374 kRtpTimestamp2, extensions2), 375 RtpSource(timestamp, kCsrcs0, RtpSourceType::CSRC, 376 kRtpTimestamp2, extensions2), 377 RtpSource(timestamp, kCsrcs2, RtpSourceType::CSRC, 378 kRtpTimestamp1, extensions1), 379 RtpSource(timestamp, kCsrcs1, RtpSourceType::CSRC, 380 kRtpTimestamp0, extensions0))); 381 } 382 383 TEST(SourceTrackerTest, OnFrameDeliveredUpdatesSources) { 384 constexpr uint32_t kSsrc1 = 10; 385 constexpr uint32_t kSsrc2 = 11; 386 constexpr uint32_t kCsrcs0 = 20; 387 constexpr uint32_t kCsrcs1 = 21; 388 constexpr uint32_t kCsrcs2 = 22; 389 constexpr uint32_t kRtpTimestamp0 = 40; 390 constexpr uint32_t kRtpTimestamp1 = 41; 391 constexpr uint32_t kRtpTimestamp2 = 42; 392 constexpr std::optional<uint8_t> kAudioLevel0 = 50; 393 constexpr std::optional<uint8_t> kAudioLevel1 = std::nullopt; 394 constexpr std::optional<uint8_t> kAudioLevel2 = 10; 395 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 = 396 AbsoluteCaptureTime{.absolute_capture_timestamp = 12, 397 .estimated_capture_clock_offset = 34}; 398 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 = 399 AbsoluteCaptureTime{.absolute_capture_timestamp = 56, 400 .estimated_capture_clock_offset = 78}; 401 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime2 = 402 AbsoluteCaptureTime{.absolute_capture_timestamp = 89, 403 .estimated_capture_clock_offset = 90}; 404 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset0 = 405 TimeDelta::Millis(123); 406 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset1 = 407 TimeDelta::Millis(456); 408 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset2 = 409 TimeDelta::Millis(789); 410 constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); 411 constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61); 412 constexpr Timestamp kReceiveTime2 = Timestamp::Millis(62); 413 414 constexpr RtpSource::Extensions extensions0 = { 415 .audio_level = kAudioLevel0, 416 .absolute_capture_time = kAbsoluteCaptureTime0, 417 .local_capture_clock_offset = kLocalCaptureClockOffset0}; 418 constexpr RtpSource::Extensions extensions1 = { 419 .audio_level = kAudioLevel1, 420 .absolute_capture_time = kAbsoluteCaptureTime1, 421 .local_capture_clock_offset = kLocalCaptureClockOffset1}; 422 constexpr RtpSource::Extensions extensions2 = { 423 .audio_level = kAudioLevel2, 424 .absolute_capture_time = kAbsoluteCaptureTime2, 425 .local_capture_clock_offset = kLocalCaptureClockOffset2}; 426 427 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); 428 SourceTracker tracker(time_controller.GetClock()); 429 430 tracker.OnFrameDelivered(RtpPacketInfos( 431 {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) 432 .set_audio_level(kAudioLevel0) 433 .set_absolute_capture_time(kAbsoluteCaptureTime0) 434 .set_local_capture_clock_offset(kLocalCaptureClockOffset0)})); 435 436 time_controller.AdvanceTime(TimeDelta::Zero()); 437 Timestamp timestamp_0 = time_controller.GetClock()->CurrentTime(); 438 EXPECT_THAT(tracker.GetSources(), 439 ElementsAre(RtpSource(timestamp_0, kSsrc1, RtpSourceType::SSRC, 440 kRtpTimestamp0, extensions0), 441 RtpSource(timestamp_0, kCsrcs1, RtpSourceType::CSRC, 442 kRtpTimestamp0, extensions0), 443 RtpSource(timestamp_0, kCsrcs0, RtpSourceType::CSRC, 444 kRtpTimestamp0, extensions0))); 445 446 // Deliver packets with updated sources. 447 448 time_controller.AdvanceTime(TimeDelta::Millis(17)); 449 tracker.OnFrameDelivered(RtpPacketInfos( 450 {RtpPacketInfo(kSsrc1, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kReceiveTime1) 451 .set_audio_level(kAudioLevel1) 452 .set_absolute_capture_time(kAbsoluteCaptureTime1) 453 .set_local_capture_clock_offset(kLocalCaptureClockOffset1)})); 454 455 time_controller.AdvanceTime(TimeDelta::Zero()); 456 Timestamp timestamp_1 = time_controller.GetClock()->CurrentTime(); 457 458 EXPECT_THAT(tracker.GetSources(), 459 ElementsAre(RtpSource(timestamp_1, kSsrc1, RtpSourceType::SSRC, 460 kRtpTimestamp1, extensions1), 461 RtpSource(timestamp_1, kCsrcs2, RtpSourceType::CSRC, 462 kRtpTimestamp1, extensions1), 463 RtpSource(timestamp_1, kCsrcs0, RtpSourceType::CSRC, 464 kRtpTimestamp1, extensions1), 465 RtpSource(timestamp_0, kCsrcs1, RtpSourceType::CSRC, 466 kRtpTimestamp0, extensions0))); 467 468 // Deliver more packets with update csrcs and a new ssrc. 469 time_controller.AdvanceTime(TimeDelta::Millis(17)); 470 471 tracker.OnFrameDelivered(RtpPacketInfos( 472 {RtpPacketInfo(kSsrc2, {kCsrcs0}, kRtpTimestamp2, kReceiveTime2) 473 .set_audio_level(kAudioLevel2) 474 .set_absolute_capture_time(kAbsoluteCaptureTime2) 475 .set_local_capture_clock_offset(kLocalCaptureClockOffset2)})); 476 477 time_controller.AdvanceTime(TimeDelta::Zero()); 478 Timestamp timestamp_2 = time_controller.GetClock()->CurrentTime(); 479 480 EXPECT_THAT(tracker.GetSources(), 481 ElementsAre(RtpSource(timestamp_2, kSsrc2, RtpSourceType::SSRC, 482 kRtpTimestamp2, extensions2), 483 RtpSource(timestamp_2, kCsrcs0, RtpSourceType::CSRC, 484 kRtpTimestamp2, extensions2), 485 RtpSource(timestamp_1, kSsrc1, RtpSourceType::SSRC, 486 kRtpTimestamp1, extensions1), 487 RtpSource(timestamp_1, kCsrcs2, RtpSourceType::CSRC, 488 kRtpTimestamp1, extensions1), 489 RtpSource(timestamp_0, kCsrcs1, RtpSourceType::CSRC, 490 kRtpTimestamp0, extensions0))); 491 } 492 493 TEST(SourceTrackerTest, TimedOutSourcesAreRemoved) { 494 constexpr uint32_t kSsrc = 10; 495 constexpr uint32_t kCsrcs0 = 20; 496 constexpr uint32_t kCsrcs1 = 21; 497 constexpr uint32_t kCsrcs2 = 22; 498 constexpr uint32_t kRtpTimestamp0 = 40; 499 constexpr uint32_t kRtpTimestamp1 = 41; 500 constexpr std::optional<uint8_t> kAudioLevel0 = 50; 501 constexpr std::optional<uint8_t> kAudioLevel1 = std::nullopt; 502 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime0 = 503 AbsoluteCaptureTime{.absolute_capture_timestamp = 12, 504 .estimated_capture_clock_offset = 34}; 505 constexpr std::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime1 = 506 AbsoluteCaptureTime{.absolute_capture_timestamp = 56, 507 .estimated_capture_clock_offset = 78}; 508 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset0 = 509 TimeDelta::Millis(123); 510 constexpr std::optional<TimeDelta> kLocalCaptureClockOffset1 = 511 TimeDelta::Millis(456); 512 constexpr Timestamp kReceiveTime0 = Timestamp::Millis(60); 513 constexpr Timestamp kReceiveTime1 = Timestamp::Millis(61); 514 515 GlobalSimulatedTimeController time_controller(Timestamp::Seconds(1000)); 516 SourceTracker tracker(time_controller.GetClock()); 517 518 tracker.OnFrameDelivered(RtpPacketInfos( 519 {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kReceiveTime0) 520 .set_audio_level(kAudioLevel0) 521 .set_absolute_capture_time(kAbsoluteCaptureTime0) 522 .set_local_capture_clock_offset(kLocalCaptureClockOffset0)})); 523 524 time_controller.AdvanceTime(TimeDelta::Millis(17)); 525 526 tracker.OnFrameDelivered(RtpPacketInfos( 527 {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kReceiveTime1) 528 .set_audio_level(kAudioLevel1) 529 .set_absolute_capture_time(kAbsoluteCaptureTime1) 530 .set_local_capture_clock_offset(kLocalCaptureClockOffset1)})); 531 532 Timestamp timestamp_1 = time_controller.GetClock()->CurrentTime(); 533 534 time_controller.AdvanceTime(SourceTracker::kTimeout); 535 536 constexpr RtpSource::Extensions extensions1 = { 537 .audio_level = kAudioLevel1, 538 .absolute_capture_time = kAbsoluteCaptureTime1, 539 .local_capture_clock_offset = kLocalCaptureClockOffset1}; 540 541 EXPECT_THAT(tracker.GetSources(), 542 ElementsAre(RtpSource(timestamp_1, kSsrc, RtpSourceType::SSRC, 543 kRtpTimestamp1, extensions1), 544 RtpSource(timestamp_1, kCsrcs2, RtpSourceType::CSRC, 545 kRtpTimestamp1, extensions1), 546 RtpSource(timestamp_1, kCsrcs0, RtpSourceType::CSRC, 547 kRtpTimestamp1, extensions1))); 548 } 549 550 TEST(SourceTrackerTest, AvoidNegativeTimestamp) { 551 SimulatedClock clock(Timestamp::Zero()); 552 SourceTracker tracker(&clock); 553 tracker.OnFrameDelivered(RtpPacketInfos( 554 {RtpPacketInfo(/*ssrc=*/111, /*csrcs=*/{}, /*rtp_timestamp=*/0, 555 /*receive_time=*/Timestamp::Zero())})); 556 } 557 558 } // namespace webrtc