1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <stdint.h> 6 7 #include "base/test/simple_test_tick_clock.h" 8 #include "media/cast/cast_defines.h" 9 #include "media/cast/cast_environment.h" 10 #include "media/cast/rtcp/mock_rtcp_receiver_feedback.h" 11 #include "media/cast/rtcp/mock_rtcp_sender_feedback.h" 12 #include "media/cast/rtcp/rtcp.h" 13 #include "media/cast/rtcp/test_rtcp_packet_builder.h" 14 #include "media/cast/test/fake_single_thread_task_runner.h" 15 #include "media/cast/transport/cast_transport_config.h" 16 #include "media/cast/transport/cast_transport_sender_impl.h" 17 #include "media/cast/transport/pacing/paced_sender.h" 18 #include "testing/gmock/include/gmock/gmock.h" 19 20 namespace media { 21 namespace cast { 22 23 using testing::_; 24 25 static const uint32 kSenderSsrc = 0x10203; 26 static const uint32 kReceiverSsrc = 0x40506; 27 static const std::string kCName("test (at) 10.1.1.1"); 28 static const uint32 kRtcpIntervalMs = 500; 29 static const int64 kAddedDelay = 123; 30 static const int64 kAddedShortDelay = 100; 31 32 class RtcpTestPacketSender : public transport::PacketSender { 33 public: 34 explicit RtcpTestPacketSender(base::SimpleTestTickClock* testing_clock) 35 : drop_packets_(false), 36 short_delay_(false), 37 rtcp_receiver_(NULL), 38 testing_clock_(testing_clock) {} 39 virtual ~RtcpTestPacketSender() {} 40 // Packet lists imply a RTP packet. 41 void set_rtcp_receiver(Rtcp* rtcp) { rtcp_receiver_ = rtcp; } 42 43 void set_short_delay() { short_delay_ = true; } 44 45 void set_drop_packets(bool drop_packets) { drop_packets_ = drop_packets; } 46 47 // A singular packet implies a RTCP packet. 48 virtual bool SendPacket(transport::PacketRef packet, 49 const base::Closure& cb) OVERRIDE { 50 if (short_delay_) { 51 testing_clock_->Advance( 52 base::TimeDelta::FromMilliseconds(kAddedShortDelay)); 53 } else { 54 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(kAddedDelay)); 55 } 56 if (drop_packets_) 57 return true; 58 59 rtcp_receiver_->IncomingRtcpPacket(&packet->data[0], packet->data.size()); 60 return true; 61 } 62 63 private: 64 bool drop_packets_; 65 bool short_delay_; 66 Rtcp* rtcp_receiver_; 67 base::SimpleTestTickClock* testing_clock_; 68 69 DISALLOW_COPY_AND_ASSIGN(RtcpTestPacketSender); 70 }; 71 72 class LocalRtcpTransport : public transport::PacedPacketSender { 73 public: 74 LocalRtcpTransport(scoped_refptr<CastEnvironment> cast_environment, 75 base::SimpleTestTickClock* testing_clock) 76 : drop_packets_(false), 77 short_delay_(false), 78 testing_clock_(testing_clock) {} 79 80 void set_rtcp_receiver(Rtcp* rtcp) { rtcp_ = rtcp; } 81 82 void set_short_delay() { short_delay_ = true; } 83 84 void set_drop_packets(bool drop_packets) { drop_packets_ = drop_packets; } 85 86 virtual bool SendRtcpPacket(uint32 ssrc, 87 transport::PacketRef packet) OVERRIDE { 88 if (short_delay_) { 89 testing_clock_->Advance( 90 base::TimeDelta::FromMilliseconds(kAddedShortDelay)); 91 } else { 92 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(kAddedDelay)); 93 } 94 if (drop_packets_) 95 return true; 96 97 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size()); 98 return true; 99 } 100 101 virtual bool SendPackets( 102 const transport::SendPacketVector& packets) OVERRIDE { 103 return false; 104 } 105 106 virtual bool ResendPackets( 107 const transport::SendPacketVector& packets, 108 base::TimeDelta dedupe_window) OVERRIDE { 109 return false; 110 } 111 112 virtual void CancelSendingPacket( 113 const transport::PacketKey& packet_key) OVERRIDE { 114 } 115 116 private: 117 bool drop_packets_; 118 bool short_delay_; 119 Rtcp* rtcp_; 120 base::SimpleTestTickClock* testing_clock_; 121 scoped_refptr<CastEnvironment> cast_environment_; 122 123 DISALLOW_COPY_AND_ASSIGN(LocalRtcpTransport); 124 }; 125 126 class RtcpPeer : public Rtcp { 127 public: 128 RtcpPeer(scoped_refptr<CastEnvironment> cast_environment, 129 RtcpSenderFeedback* sender_feedback, 130 transport::CastTransportSender* const transport_sender, 131 transport::PacedPacketSender* paced_packet_sender, 132 RtpReceiverStatistics* rtp_receiver_statistics, 133 RtcpMode rtcp_mode, 134 const base::TimeDelta& rtcp_interval, 135 uint32 local_ssrc, 136 uint32 remote_ssrc, 137 const std::string& c_name) 138 : Rtcp(cast_environment, 139 sender_feedback, 140 transport_sender, 141 paced_packet_sender, 142 rtp_receiver_statistics, 143 rtcp_mode, 144 rtcp_interval, 145 local_ssrc, 146 remote_ssrc, 147 c_name, 148 AUDIO_EVENT) {} 149 150 using Rtcp::OnReceivedNtp; 151 using Rtcp::OnReceivedLipSyncInfo; 152 }; 153 154 class RtcpTest : public ::testing::Test { 155 protected: 156 RtcpTest() 157 : testing_clock_(new base::SimpleTestTickClock()), 158 task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), 159 cast_environment_(new CastEnvironment( 160 scoped_ptr<base::TickClock>(testing_clock_).Pass(), 161 task_runner_, 162 task_runner_, 163 task_runner_)), 164 sender_to_receiver_(testing_clock_), 165 receiver_to_sender_(cast_environment_, testing_clock_) { 166 testing_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); 167 net::IPEndPoint dummy_endpoint; 168 transport_sender_.reset(new transport::CastTransportSenderImpl( 169 NULL, 170 testing_clock_, 171 dummy_endpoint, 172 base::Bind(&UpdateCastTransportStatus), 173 transport::BulkRawEventsCallback(), 174 base::TimeDelta(), 175 task_runner_, 176 &sender_to_receiver_)); 177 transport::CastTransportAudioConfig config; 178 config.rtp.config.ssrc = kSenderSsrc; 179 config.rtp.max_outstanding_frames = 1; 180 transport_sender_->InitializeAudio(config); 181 EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(0); 182 } 183 184 virtual ~RtcpTest() {} 185 186 static void UpdateCastTransportStatus(transport::CastTransportStatus status) { 187 bool result = (status == transport::TRANSPORT_AUDIO_INITIALIZED || 188 status == transport::TRANSPORT_VIDEO_INITIALIZED); 189 EXPECT_TRUE(result); 190 } 191 192 void RunTasks(int during_ms) { 193 for (int i = 0; i < during_ms; ++i) { 194 // Call process the timers every 1 ms. 195 testing_clock_->Advance(base::TimeDelta::FromMilliseconds(1)); 196 task_runner_->RunTasks(); 197 } 198 } 199 200 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. 201 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; 202 scoped_refptr<CastEnvironment> cast_environment_; 203 RtcpTestPacketSender sender_to_receiver_; 204 scoped_ptr<transport::CastTransportSenderImpl> transport_sender_; 205 LocalRtcpTransport receiver_to_sender_; 206 MockRtcpSenderFeedback mock_sender_feedback_; 207 208 DISALLOW_COPY_AND_ASSIGN(RtcpTest); 209 }; 210 211 TEST_F(RtcpTest, TimeToSend) { 212 const base::TimeTicks start_time = testing_clock_->NowTicks(); 213 Rtcp rtcp(cast_environment_, 214 &mock_sender_feedback_, 215 transport_sender_.get(), 216 &receiver_to_sender_, 217 NULL, 218 kRtcpCompound, 219 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 220 kSenderSsrc, 221 kReceiverSsrc, 222 kCName, 223 AUDIO_EVENT); 224 receiver_to_sender_.set_rtcp_receiver(&rtcp); 225 EXPECT_LE(start_time, rtcp.TimeToSendNextRtcpReport()); 226 EXPECT_GE( 227 start_time + base::TimeDelta::FromMilliseconds(kRtcpIntervalMs * 3 / 2), 228 rtcp.TimeToSendNextRtcpReport()); 229 base::TimeDelta delta = rtcp.TimeToSendNextRtcpReport() - start_time; 230 testing_clock_->Advance(delta); 231 EXPECT_EQ(testing_clock_->NowTicks(), rtcp.TimeToSendNextRtcpReport()); 232 } 233 234 TEST_F(RtcpTest, BasicSenderReport) { 235 Rtcp rtcp(cast_environment_, 236 &mock_sender_feedback_, 237 transport_sender_.get(), 238 NULL, 239 NULL, 240 kRtcpCompound, 241 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 242 kSenderSsrc, 243 kReceiverSsrc, 244 kCName, 245 AUDIO_EVENT); 246 sender_to_receiver_.set_rtcp_receiver(&rtcp); 247 rtcp.SendRtcpFromRtpSender(base::TimeTicks(), 0); 248 } 249 250 TEST_F(RtcpTest, BasicReceiverReport) { 251 Rtcp rtcp(cast_environment_, 252 &mock_sender_feedback_, 253 NULL, 254 &receiver_to_sender_, 255 NULL, 256 kRtcpCompound, 257 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 258 kSenderSsrc, 259 kReceiverSsrc, 260 kCName, 261 AUDIO_EVENT); 262 receiver_to_sender_.set_rtcp_receiver(&rtcp); 263 rtcp.SendRtcpFromRtpReceiver(NULL, NULL); 264 } 265 266 TEST_F(RtcpTest, BasicCast) { 267 EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(1); 268 269 // Media receiver. 270 Rtcp rtcp(cast_environment_, 271 &mock_sender_feedback_, 272 NULL, 273 &receiver_to_sender_, 274 NULL, 275 kRtcpReducedSize, 276 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 277 kSenderSsrc, 278 kSenderSsrc, 279 kCName, 280 AUDIO_EVENT); 281 receiver_to_sender_.set_rtcp_receiver(&rtcp); 282 RtcpCastMessage cast_message(kSenderSsrc); 283 cast_message.ack_frame_id_ = kAckFrameId; 284 PacketIdSet missing_packets; 285 cast_message.missing_frames_and_packets_[kLostFrameId] = missing_packets; 286 287 missing_packets.insert(kLostPacketId1); 288 missing_packets.insert(kLostPacketId2); 289 missing_packets.insert(kLostPacketId3); 290 cast_message.missing_frames_and_packets_[kFrameIdWithLostPackets] = 291 missing_packets; 292 rtcp.SendRtcpFromRtpReceiver(&cast_message, NULL); 293 } 294 295 TEST_F(RtcpTest, RttReducedSizeRtcp) { 296 // Media receiver. 297 Rtcp rtcp_receiver(cast_environment_, 298 &mock_sender_feedback_, 299 NULL, 300 &receiver_to_sender_, 301 NULL, 302 kRtcpReducedSize, 303 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 304 kReceiverSsrc, 305 kSenderSsrc, 306 kCName, 307 AUDIO_EVENT); 308 309 // Media sender. 310 Rtcp rtcp_sender(cast_environment_, 311 &mock_sender_feedback_, 312 transport_sender_.get(), 313 NULL, 314 NULL, 315 kRtcpReducedSize, 316 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 317 kSenderSsrc, 318 kReceiverSsrc, 319 kCName, 320 AUDIO_EVENT); 321 322 sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); 323 receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); 324 325 base::TimeDelta rtt; 326 base::TimeDelta avg_rtt; 327 base::TimeDelta min_rtt; 328 base::TimeDelta max_rtt; 329 EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 330 EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 331 332 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 1); 333 RunTasks(33); 334 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 335 EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 336 EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 337 EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); 338 EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); 339 EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); 340 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 341 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 2); 342 RunTasks(33); 343 EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 344 345 EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); 346 EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); 347 EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); 348 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 349 } 350 351 TEST_F(RtcpTest, Rtt) { 352 // Media receiver. 353 Rtcp rtcp_receiver(cast_environment_, 354 &mock_sender_feedback_, 355 NULL, 356 &receiver_to_sender_, 357 NULL, 358 kRtcpCompound, 359 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 360 kReceiverSsrc, 361 kSenderSsrc, 362 kCName, 363 AUDIO_EVENT); 364 365 // Media sender. 366 Rtcp rtcp_sender(cast_environment_, 367 &mock_sender_feedback_, 368 transport_sender_.get(), 369 NULL, 370 NULL, 371 kRtcpCompound, 372 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 373 kSenderSsrc, 374 kReceiverSsrc, 375 kCName, 376 AUDIO_EVENT); 377 378 receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); 379 sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); 380 381 base::TimeDelta rtt; 382 base::TimeDelta avg_rtt; 383 base::TimeDelta min_rtt; 384 base::TimeDelta max_rtt; 385 EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 386 EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 387 388 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 1); 389 RunTasks(33); 390 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 391 392 EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 393 RunTasks(33); 394 395 EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 396 RunTasks(33); 397 398 EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); 399 EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); 400 EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); 401 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 402 403 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 2); 404 RunTasks(33); 405 EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 406 EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); 407 EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); 408 EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); 409 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 410 411 receiver_to_sender_.set_short_delay(); 412 sender_to_receiver_.set_short_delay(); 413 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 414 EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 415 EXPECT_NEAR(kAddedDelay + kAddedShortDelay, rtt.InMilliseconds(), 2); 416 EXPECT_NEAR( 417 (kAddedShortDelay + 3 * kAddedDelay) / 2, avg_rtt.InMilliseconds(), 2); 418 EXPECT_NEAR(kAddedDelay + kAddedShortDelay, min_rtt.InMilliseconds(), 2); 419 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 420 421 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 3); 422 RunTasks(33); 423 EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 424 EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 1); 425 EXPECT_NEAR((2 * kAddedShortDelay + 2 * kAddedDelay) / 2, 426 avg_rtt.InMilliseconds(), 427 1); 428 EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); 429 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 430 431 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 432 EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 433 EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 2); 434 EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); 435 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 436 437 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 438 EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 439 EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 2); 440 EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); 441 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); 442 } 443 444 TEST_F(RtcpTest, RttWithPacketLoss) { 445 // Media receiver. 446 Rtcp rtcp_receiver(cast_environment_, 447 &mock_sender_feedback_, 448 NULL, 449 &receiver_to_sender_, 450 NULL, 451 kRtcpReducedSize, 452 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 453 kReceiverSsrc, 454 kSenderSsrc, 455 kCName, 456 AUDIO_EVENT); 457 458 // Media sender. 459 Rtcp rtcp_sender(cast_environment_, 460 &mock_sender_feedback_, 461 transport_sender_.get(), 462 NULL, 463 NULL, 464 kRtcpReducedSize, 465 base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), 466 kSenderSsrc, 467 kReceiverSsrc, 468 kCName, 469 AUDIO_EVENT); 470 471 receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); 472 sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); 473 474 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 475 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 0); 476 RunTasks(33); 477 478 base::TimeDelta rtt; 479 base::TimeDelta avg_rtt; 480 base::TimeDelta min_rtt; 481 base::TimeDelta max_rtt; 482 EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 483 EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 484 EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 1); 485 EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 1); 486 EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 1); 487 EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 1); 488 489 receiver_to_sender_.set_short_delay(); 490 sender_to_receiver_.set_short_delay(); 491 receiver_to_sender_.set_drop_packets(true); 492 493 rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); 494 rtcp_sender.SendRtcpFromRtpSender(testing_clock_->NowTicks(), 1); 495 RunTasks(33); 496 497 EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); 498 EXPECT_NEAR(kAddedDelay + kAddedShortDelay, rtt.InMilliseconds(), 2); 499 } 500 501 TEST_F(RtcpTest, NtpAndTime) { 502 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60); 503 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60); 504 505 uint32 ntp_seconds_1 = 0; 506 uint32 ntp_fraction_1 = 0; 507 base::TimeTicks input_time = base::TimeTicks::Now(); 508 ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1); 509 510 // Verify absolute value. 511 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010); 512 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030); 513 514 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1); 515 EXPECT_EQ(input_time, out_1); // Verify inverse. 516 517 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000); 518 input_time += time_delta; 519 520 uint32 ntp_seconds_2 = 0; 521 uint32 ntp_fraction_2 = 0; 522 523 ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2); 524 base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2); 525 EXPECT_EQ(input_time, out_2); // Verify inverse. 526 527 // Verify delta. 528 EXPECT_EQ((out_2 - out_1), time_delta); 529 EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1)); 530 EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1); 531 532 time_delta = base::TimeDelta::FromMilliseconds(500); 533 input_time += time_delta; 534 535 uint32 ntp_seconds_3 = 0; 536 uint32 ntp_fraction_3 = 0; 537 538 ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3); 539 base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3); 540 EXPECT_EQ(input_time, out_3); // Verify inverse. 541 542 // Verify delta. 543 EXPECT_EQ((out_3 - out_2), time_delta); 544 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1); 545 } 546 547 } // namespace cast 548 } // namespace media 549