// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/test/simple_test_tick_clock.h" #include "media/cast/cast_defines.h" #include "media/cast/cast_environment.h" #include "media/cast/rtcp/mock_rtcp_receiver_feedback.h" #include "media/cast/rtcp/mock_rtcp_sender_feedback.h" #include "media/cast/rtcp/rtcp.h" #include "media/cast/rtcp/test_rtcp_packet_builder.h" #include "media/cast/test/fake_single_thread_task_runner.h" #include "media/cast/transport/cast_transport_config.h" #include "media/cast/transport/cast_transport_sender_impl.h" #include "media/cast/transport/pacing/paced_sender.h" #include "testing/gmock/include/gmock/gmock.h" namespace media { namespace cast { using testing::_; static const uint32 kSenderSsrc = 0x10203; static const uint32 kReceiverSsrc = 0x40506; static const std::string kCName("test@10.1.1.1"); static const uint32 kRtcpIntervalMs = 500; static const int64 kStartMillisecond = GG_INT64_C(12345678900000); static const int64 kAddedDelay = 123; static const int64 kAddedShortDelay = 100; class RtcpTestPacketSender : public transport::PacketSender { public: explicit RtcpTestPacketSender(base::SimpleTestTickClock* testing_clock) : drop_packets_(false), short_delay_(false), rtcp_receiver_(NULL), testing_clock_(testing_clock) {} virtual ~RtcpTestPacketSender() {} // Packet lists imply a RTP packet. void set_rtcp_receiver(Rtcp* rtcp) { rtcp_receiver_ = rtcp; } void set_short_delay() { short_delay_ = true; } void set_drop_packets(bool drop_packets) { drop_packets_ = drop_packets; } // A singular packet implies a RTCP packet. virtual bool SendPacket(const Packet& packet) OVERRIDE { if (short_delay_) { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kAddedShortDelay)); } else { testing_clock_->Advance(base::TimeDelta::FromMilliseconds(kAddedDelay)); } if (drop_packets_) return true; rtcp_receiver_->IncomingRtcpPacket(&(packet[0]), packet.size()); return true; } private: bool drop_packets_; bool short_delay_; Rtcp* rtcp_receiver_; base::SimpleTestTickClock* testing_clock_; DISALLOW_COPY_AND_ASSIGN(RtcpTestPacketSender); }; class LocalRtcpTransport : public transport::PacedPacketSender { public: LocalRtcpTransport(scoped_refptr cast_environment, base::SimpleTestTickClock* testing_clock) : drop_packets_(false), short_delay_(false), testing_clock_(testing_clock) {} void set_rtcp_receiver(Rtcp* rtcp) { rtcp_ = rtcp; } void set_short_delay() { short_delay_ = true; } void set_drop_packets(bool drop_packets) { drop_packets_ = drop_packets; } virtual bool SendRtcpPacket(const Packet& packet) OVERRIDE { if (short_delay_) { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kAddedShortDelay)); } else { testing_clock_->Advance(base::TimeDelta::FromMilliseconds(kAddedDelay)); } if (drop_packets_) return true; rtcp_->IncomingRtcpPacket(&(packet[0]), packet.size()); return true; } virtual bool SendPackets(const PacketList& packets) OVERRIDE { return false; } virtual bool ResendPackets(const PacketList& packets) OVERRIDE { return false; } private: bool drop_packets_; bool short_delay_; Rtcp* rtcp_; base::SimpleTestTickClock* testing_clock_; scoped_refptr cast_environment_; DISALLOW_COPY_AND_ASSIGN(LocalRtcpTransport); }; class RtcpPeer : public Rtcp { public: RtcpPeer(scoped_refptr cast_environment, RtcpSenderFeedback* sender_feedback, transport::CastTransportSender* const transport_sender, transport::PacedPacketSender* paced_packet_sender, RtpReceiverStatistics* rtp_receiver_statistics, RtcpMode rtcp_mode, const base::TimeDelta& rtcp_interval, uint32 local_ssrc, uint32 remote_ssrc, const std::string& c_name) : Rtcp(cast_environment, sender_feedback, transport_sender, paced_packet_sender, rtp_receiver_statistics, rtcp_mode, rtcp_interval, local_ssrc, remote_ssrc, c_name) {} using Rtcp::CheckForWrapAround; using Rtcp::OnReceivedLipSyncInfo; }; class RtcpTest : public ::testing::Test { protected: RtcpTest() : testing_clock_(new base::SimpleTestTickClock()), task_runner_(new test::FakeSingleThreadTaskRunner(testing_clock_)), logging_config_(GetDefaultCastSenderLoggingConfig()), cast_environment_(new CastEnvironment( scoped_ptr(testing_clock_).Pass(), task_runner_, task_runner_, task_runner_, task_runner_, task_runner_, task_runner_, logging_config_)), sender_to_receiver_(testing_clock_), receiver_to_sender_(cast_environment_, testing_clock_), rtp_sender_stats_(kVideoFrequency) { testing_clock_->Advance( base::TimeDelta::FromMilliseconds(kStartMillisecond)); net::IPEndPoint dummy_endpoint; transport_sender_.reset(new transport::CastTransportSenderImpl( NULL, testing_clock_, dummy_endpoint, logging_config_, base::Bind(&UpdateCastTransportStatus), transport::BulkRawEventsCallback(), base::TimeDelta(), task_runner_, &sender_to_receiver_)); EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(0); } virtual ~RtcpTest() {} static void UpdateCastTransportStatus(transport::CastTransportStatus status) { bool result = (status == transport::TRANSPORT_AUDIO_INITIALIZED || status == transport::TRANSPORT_VIDEO_INITIALIZED); EXPECT_TRUE(result); } void RunTasks(int during_ms) { for (int i = 0; i < during_ms; ++i) { // Call process the timers every 1 ms. testing_clock_->Advance(base::TimeDelta::FromMilliseconds(1)); task_runner_->RunTasks(); } } base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. scoped_refptr task_runner_; CastLoggingConfig logging_config_; scoped_refptr cast_environment_; RtcpTestPacketSender sender_to_receiver_; scoped_ptr transport_sender_; LocalRtcpTransport receiver_to_sender_; MockRtcpSenderFeedback mock_sender_feedback_; RtpSenderStatistics rtp_sender_stats_; DISALLOW_COPY_AND_ASSIGN(RtcpTest); }; TEST_F(RtcpTest, TimeToSend) { base::TimeTicks start_time; start_time += base::TimeDelta::FromMilliseconds(kStartMillisecond); Rtcp rtcp(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), &receiver_to_sender_, NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); receiver_to_sender_.set_rtcp_receiver(&rtcp); EXPECT_LE(start_time, rtcp.TimeToSendNextRtcpReport()); EXPECT_GE( start_time + base::TimeDelta::FromMilliseconds(kRtcpIntervalMs * 3 / 2), rtcp.TimeToSendNextRtcpReport()); base::TimeDelta delta = rtcp.TimeToSendNextRtcpReport() - start_time; testing_clock_->Advance(delta); EXPECT_EQ(testing_clock_->NowTicks(), rtcp.TimeToSendNextRtcpReport()); } TEST_F(RtcpTest, BasicSenderReport) { Rtcp rtcp(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), NULL, NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); sender_to_receiver_.set_rtcp_receiver(&rtcp); transport::RtcpSenderLogMessage empty_sender_log; rtcp.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); } TEST_F(RtcpTest, BasicReceiverReport) { Rtcp rtcp(cast_environment_, &mock_sender_feedback_, NULL, &receiver_to_sender_, NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); receiver_to_sender_.set_rtcp_receiver(&rtcp); rtcp.SendRtcpFromRtpReceiver(NULL, NULL); } TEST_F(RtcpTest, BasicCast) { EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(1); // Media receiver. Rtcp rtcp(cast_environment_, &mock_sender_feedback_, NULL, &receiver_to_sender_, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kSenderSsrc, kCName); receiver_to_sender_.set_rtcp_receiver(&rtcp); RtcpCastMessage cast_message(kSenderSsrc); cast_message.ack_frame_id_ = kAckFrameId; PacketIdSet missing_packets; cast_message.missing_frames_and_packets_[kLostFrameId] = missing_packets; missing_packets.insert(kLostPacketId1); missing_packets.insert(kLostPacketId2); missing_packets.insert(kLostPacketId3); cast_message.missing_frames_and_packets_[kFrameIdWithLostPackets] = missing_packets; rtcp.SendRtcpFromRtpReceiver(&cast_message, NULL); } TEST_F(RtcpTest, RttReducedSizeRtcp) { // Media receiver. Rtcp rtcp_receiver(cast_environment_, &mock_sender_feedback_, NULL, &receiver_to_sender_, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, kSenderSsrc, kCName); // Media sender. Rtcp rtcp_sender(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), NULL, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); base::TimeDelta rtt; base::TimeDelta avg_rtt; base::TimeDelta min_rtt; base::TimeDelta max_rtt; EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); transport::RtcpSenderLogMessage empty_sender_log; rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); } TEST_F(RtcpTest, Rtt) { // Media receiver. Rtcp rtcp_receiver(cast_environment_, &mock_sender_feedback_, NULL, &receiver_to_sender_, NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, kSenderSsrc, kCName); // Media sender. Rtcp rtcp_sender(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), NULL, NULL, kRtcpCompound, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); base::TimeDelta rtt; base::TimeDelta avg_rtt; base::TimeDelta min_rtt; base::TimeDelta max_rtt; EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); transport::RtcpSenderLogMessage empty_sender_log; rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); RunTasks(33); EXPECT_FALSE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); RunTasks(33); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); receiver_to_sender_.set_short_delay(); sender_to_receiver_.set_short_delay(); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(kAddedDelay + kAddedShortDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR( (kAddedShortDelay + 3 * kAddedDelay) / 2, avg_rtt.InMilliseconds(), 2); EXPECT_NEAR(kAddedDelay + kAddedShortDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 1); EXPECT_NEAR((2 * kAddedShortDelay + 2 * kAddedDelay) / 2, avg_rtt.InMilliseconds(), 1); EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); EXPECT_TRUE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedShortDelay, rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedShortDelay, min_rtt.InMilliseconds(), 2); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 2); } TEST_F(RtcpTest, RttWithPacketLoss) { // Media receiver. Rtcp rtcp_receiver(cast_environment_, &mock_sender_feedback_, NULL, &receiver_to_sender_, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kSenderSsrc, kReceiverSsrc, kCName); // Media sender. Rtcp rtcp_sender(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), NULL, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, kSenderSsrc, kCName); receiver_to_sender_.set_rtcp_receiver(&rtcp_sender); sender_to_receiver_.set_rtcp_receiver(&rtcp_receiver); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); transport::RtcpSenderLogMessage empty_sender_log; rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); base::TimeDelta rtt; base::TimeDelta avg_rtt; base::TimeDelta min_rtt; base::TimeDelta max_rtt; EXPECT_FALSE(rtcp_sender.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(2 * kAddedDelay, rtt.InMilliseconds(), 1); EXPECT_NEAR(2 * kAddedDelay, avg_rtt.InMilliseconds(), 1); EXPECT_NEAR(2 * kAddedDelay, min_rtt.InMilliseconds(), 1); EXPECT_NEAR(2 * kAddedDelay, max_rtt.InMilliseconds(), 1); receiver_to_sender_.set_short_delay(); sender_to_receiver_.set_short_delay(); receiver_to_sender_.set_drop_packets(true); rtcp_receiver.SendRtcpFromRtpReceiver(NULL, NULL); rtcp_sender.SendRtcpFromRtpSender(empty_sender_log, rtp_sender_stats_.sender_info()); RunTasks(33); EXPECT_TRUE(rtcp_receiver.Rtt(&rtt, &avg_rtt, &min_rtt, &max_rtt)); EXPECT_NEAR(kAddedDelay + kAddedShortDelay, rtt.InMilliseconds(), 2); } TEST_F(RtcpTest, NtpAndTime) { const int64 kSecondsbetweenYear1900and2010 = GG_INT64_C(40176 * 24 * 60 * 60); const int64 kSecondsbetweenYear1900and2030 = GG_INT64_C(47481 * 24 * 60 * 60); uint32 ntp_seconds_1 = 0; uint32 ntp_fractions_1 = 0; base::TimeTicks input_time = base::TimeTicks::Now(); ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fractions_1); // Verify absolute value. EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010); EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030); base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fractions_1); EXPECT_EQ(input_time, out_1); // Verify inverse. base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000); input_time += time_delta; uint32 ntp_seconds_2 = 0; uint32 ntp_fractions_2 = 0; ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fractions_2); base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fractions_2); EXPECT_EQ(input_time, out_2); // Verify inverse. // Verify delta. EXPECT_EQ((out_2 - out_1), time_delta); EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), GG_UINT32_C(1)); EXPECT_NEAR(ntp_fractions_2, ntp_fractions_1, 1); time_delta = base::TimeDelta::FromMilliseconds(500); input_time += time_delta; uint32 ntp_seconds_3 = 0; uint32 ntp_fractions_3 = 0; ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fractions_3); base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fractions_3); EXPECT_EQ(input_time, out_3); // Verify inverse. // Verify delta. EXPECT_EQ((out_3 - out_2), time_delta); EXPECT_NEAR((ntp_fractions_3 - ntp_fractions_2), 0xffffffff / 2, 1); } TEST_F(RtcpTest, WrapAround) { RtcpPeer rtcp_peer(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), NULL, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, kSenderSsrc, kCName); uint32 new_timestamp = 0; uint32 old_timestamp = 0; EXPECT_EQ(0, rtcp_peer.CheckForWrapAround(new_timestamp, old_timestamp)); new_timestamp = 1234567890; old_timestamp = 1234567000; EXPECT_EQ(0, rtcp_peer.CheckForWrapAround(new_timestamp, old_timestamp)); new_timestamp = 1234567000; old_timestamp = 1234567890; EXPECT_EQ(0, rtcp_peer.CheckForWrapAround(new_timestamp, old_timestamp)); new_timestamp = 123; old_timestamp = 4234567890u; EXPECT_EQ(1, rtcp_peer.CheckForWrapAround(new_timestamp, old_timestamp)); new_timestamp = 4234567890u; old_timestamp = 123; EXPECT_EQ(-1, rtcp_peer.CheckForWrapAround(new_timestamp, old_timestamp)); } TEST_F(RtcpTest, RtpTimestampInSenderTime) { RtcpPeer rtcp_peer(cast_environment_, &mock_sender_feedback_, transport_sender_.get(), &receiver_to_sender_, NULL, kRtcpReducedSize, base::TimeDelta::FromMilliseconds(kRtcpIntervalMs), kReceiverSsrc, kSenderSsrc, kCName); int frequency = 32000; uint32 rtp_timestamp = 64000; base::TimeTicks rtp_timestamp_in_ticks; // Test fail before we get a OnReceivedLipSyncInfo. EXPECT_FALSE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); uint32 ntp_seconds = 0; uint32 ntp_fractions = 0; uint64 input_time_us = 12345678901000LL; base::TimeTicks input_time; input_time += base::TimeDelta::FromMicroseconds(input_time_us); // Test exact match. ConvertTimeTicksToNtp(input_time, &ntp_seconds, &ntp_fractions); rtcp_peer.OnReceivedLipSyncInfo(rtp_timestamp, ntp_seconds, ntp_fractions); EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time, rtp_timestamp_in_ticks); // Test older rtp_timestamp. rtp_timestamp = 32000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time - base::TimeDelta::FromMilliseconds(1000), rtp_timestamp_in_ticks); // Test older rtp_timestamp with wrap. rtp_timestamp = 4294903296u; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time - base::TimeDelta::FromMilliseconds(4000), rtp_timestamp_in_ticks); // Test newer rtp_timestamp. rtp_timestamp = 128000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time + base::TimeDelta::FromMilliseconds(2000), rtp_timestamp_in_ticks); // Test newer rtp_timestamp with wrap. rtp_timestamp = 4294903296u; rtcp_peer.OnReceivedLipSyncInfo(rtp_timestamp, ntp_seconds, ntp_fractions); rtp_timestamp = 64000; EXPECT_TRUE(rtcp_peer.RtpTimestampInSenderTime( frequency, rtp_timestamp, &rtp_timestamp_in_ticks)); EXPECT_EQ(input_time + base::TimeDelta::FromMilliseconds(4000), rtp_timestamp_in_ticks); } } // namespace cast } // namespace media