1// Copyright 2014 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/net/cast_transport_config.h" 10#include "media/cast/net/pacing/paced_sender.h" 11#include "media/cast/net/rtcp/rtcp.h" 12#include "media/cast/test/skewed_tick_clock.h" 13#include "testing/gmock/include/gmock/gmock.h" 14 15namespace media { 16namespace cast { 17 18using testing::_; 19 20static const uint32 kSenderSsrc = 0x10203; 21static const uint32 kReceiverSsrc = 0x40506; 22static const int kInitialReceiverClockOffsetSeconds = -5; 23 24class FakeRtcpTransport : public PacedPacketSender { 25 public: 26 explicit FakeRtcpTransport(base::SimpleTestTickClock* clock) 27 : clock_(clock), 28 packet_delay_(base::TimeDelta::FromMilliseconds(42)) {} 29 30 void set_rtcp_destination(Rtcp* rtcp) { rtcp_ = rtcp; } 31 32 base::TimeDelta packet_delay() const { return packet_delay_; } 33 void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; } 34 35 virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) OVERRIDE { 36 clock_->Advance(packet_delay_); 37 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size()); 38 return true; 39 } 40 41 virtual bool SendPackets(const SendPacketVector& packets) OVERRIDE { 42 return false; 43 } 44 45 virtual bool ResendPackets( 46 const SendPacketVector& packets, const DedupInfo& dedup_info) OVERRIDE { 47 return false; 48 } 49 50 virtual void CancelSendingPacket(const PacketKey& packet_key) OVERRIDE { 51 } 52 53 private: 54 base::SimpleTestTickClock* const clock_; 55 base::TimeDelta packet_delay_; 56 Rtcp* rtcp_; 57 58 DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport); 59}; 60 61class FakeReceiverStats : public RtpReceiverStatistics { 62 public: 63 FakeReceiverStats() {} 64 virtual ~FakeReceiverStats() {} 65 66 virtual void GetStatistics(uint8* fraction_lost, 67 uint32* cumulative_lost, 68 uint32* extended_high_sequence_number, 69 uint32* jitter) OVERRIDE { 70 *fraction_lost = 0; 71 *cumulative_lost = 0; 72 *extended_high_sequence_number = 0; 73 *jitter = 0; 74 } 75 76 private: 77 DISALLOW_COPY_AND_ASSIGN(FakeReceiverStats); 78}; 79 80class MockFrameSender { 81 public: 82 MockFrameSender() {} 83 virtual ~MockFrameSender() {} 84 85 MOCK_METHOD1(OnReceivedCastFeedback, 86 void(const RtcpCastMessage& cast_message)); 87 MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt)); 88 89 private: 90 DISALLOW_COPY_AND_ASSIGN(MockFrameSender); 91}; 92 93class RtcpTest : public ::testing::Test { 94 protected: 95 RtcpTest() 96 : sender_clock_(new base::SimpleTestTickClock()), 97 receiver_clock_(new test::SkewedTickClock(sender_clock_.get())), 98 sender_to_receiver_(sender_clock_.get()), 99 receiver_to_sender_(sender_clock_.get()), 100 rtcp_for_sender_(base::Bind(&MockFrameSender::OnReceivedCastFeedback, 101 base::Unretained(&mock_frame_sender_)), 102 base::Bind(&MockFrameSender::OnMeasuredRoundTripTime, 103 base::Unretained(&mock_frame_sender_)), 104 RtcpLogMessageCallback(), 105 sender_clock_.get(), 106 &sender_to_receiver_, 107 kSenderSsrc, 108 kReceiverSsrc), 109 rtcp_for_receiver_(RtcpCastMessageCallback(), 110 RtcpRttCallback(), 111 RtcpLogMessageCallback(), 112 receiver_clock_.get(), 113 &receiver_to_sender_, 114 kReceiverSsrc, 115 kSenderSsrc) { 116 sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks()); 117 receiver_clock_->SetSkew( 118 1.0, // No skew. 119 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds)); 120 121 sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_); 122 receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_); 123 } 124 125 virtual ~RtcpTest() {} 126 127 scoped_ptr<base::SimpleTestTickClock> sender_clock_; 128 scoped_ptr<test::SkewedTickClock> receiver_clock_; 129 FakeRtcpTransport sender_to_receiver_; 130 FakeRtcpTransport receiver_to_sender_; 131 MockFrameSender mock_frame_sender_; 132 Rtcp rtcp_for_sender_; 133 Rtcp rtcp_for_receiver_; 134 FakeReceiverStats stats_; 135 136 DISALLOW_COPY_AND_ASSIGN(RtcpTest); 137}; 138 139TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) { 140 // Initially, expect no lip-sync info receiver-side without having first 141 // received a RTCP packet. 142 base::TimeTicks reference_time; 143 uint32 rtp_timestamp; 144 ASSERT_FALSE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp, 145 &reference_time)); 146 147 // Send a Sender Report to the receiver. 148 const base::TimeTicks reference_time_sent = sender_clock_->NowTicks(); 149 const uint32 rtp_timestamp_sent = 0xbee5; 150 rtcp_for_sender_.SendRtcpFromRtpSender( 151 reference_time_sent, rtp_timestamp_sent, 1, 1); 152 153 // Now the receiver should have lip-sync info. Confirm that the lip-sync 154 // reference time is the same as that sent. 155 EXPECT_TRUE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp, 156 &reference_time)); 157 const base::TimeTicks rolled_back_time = 158 (reference_time - 159 // Roll-back relative clock offset: 160 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds) - 161 // Roll-back packet transmission time (because RTT is not yet known): 162 sender_to_receiver_.packet_delay()); 163 EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5); 164 EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp); 165} 166 167// TODO(miu): There were a few tests here that didn't actually test anything 168// except that the code wouldn't crash and a callback method was invoked. We 169// need to fill-in more testing of RTCP now that much of the refactoring work 170// has been completed. 171 172TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) { 173 const int iterations = 12; 174 EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_)) 175 .Times(iterations); 176 177 // Initially, neither side knows the round trip time. 178 ASSERT_EQ(base::TimeDelta(), rtcp_for_sender_.current_round_trip_time()); 179 ASSERT_EQ(base::TimeDelta(), rtcp_for_receiver_.current_round_trip_time()); 180 181 // Do a number of ping-pongs, checking how the round trip times are measured 182 // by the sender and receiver. 183 base::TimeDelta expected_rtt_according_to_sender; 184 base::TimeDelta expected_rtt_according_to_receiver; 185 for (int i = 0; i < iterations; ++i) { 186 const base::TimeDelta one_way_trip_time = 187 base::TimeDelta::FromMilliseconds(1 << i); 188 sender_to_receiver_.set_packet_delay(one_way_trip_time); 189 receiver_to_sender_.set_packet_delay(one_way_trip_time); 190 191 // Sender --> Receiver 192 base::TimeTicks reference_time_sent = sender_clock_->NowTicks(); 193 uint32 rtp_timestamp_sent = 0xbee5 + i; 194 rtcp_for_sender_.SendRtcpFromRtpSender( 195 reference_time_sent, rtp_timestamp_sent, 1, 1); 196 EXPECT_EQ(expected_rtt_according_to_sender, 197 rtcp_for_sender_.current_round_trip_time()); 198#ifdef SENDER_PROVIDES_REPORT_BLOCK 199 EXPECT_EQ(expected_rtt_according_to_receiver, 200 rtcp_for_receiver_.current_round_trip_time()); 201#endif 202 203 // Receiver --> Sender 204 rtcp_for_receiver_.SendRtcpFromRtpReceiver( 205 NULL, base::TimeDelta(), NULL, &stats_); 206 expected_rtt_according_to_sender = one_way_trip_time * 2; 207 EXPECT_EQ(expected_rtt_according_to_sender, 208 rtcp_for_sender_.current_round_trip_time()); 209#ifdef SENDER_PROVIDES_REPORT_BLOCK 210 EXPECT_EQ(expected_rtt_according_to_receiver, 211 rtcp_for_receiver_.current_round_trip_time(); 212#endif 213 214 // In the next iteration of this loop, after the receiver gets the sender 215 // report, it will be measuring a round trip time consisting of two 216 // different one-way trip times. 217 expected_rtt_according_to_receiver = 218 (one_way_trip_time + one_way_trip_time * 2) / 2; 219 } 220} 221 222// TODO(miu): Find a better home for this test. 223TEST(MisplacedCastTest, NtpAndTime) { 224 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60); 225 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60); 226 227 uint32 ntp_seconds_1 = 0; 228 uint32 ntp_fraction_1 = 0; 229 base::TimeTicks input_time = base::TimeTicks::Now(); 230 ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1); 231 232 // Verify absolute value. 233 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010); 234 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030); 235 236 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1); 237 EXPECT_EQ(input_time, out_1); // Verify inverse. 238 239 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000); 240 input_time += time_delta; 241 242 uint32 ntp_seconds_2 = 0; 243 uint32 ntp_fraction_2 = 0; 244 245 ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2); 246 base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2); 247 EXPECT_EQ(input_time, out_2); // Verify inverse. 248 249 // Verify delta. 250 EXPECT_EQ((out_2 - out_1), time_delta); 251 EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1)); 252 EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1); 253 254 time_delta = base::TimeDelta::FromMilliseconds(500); 255 input_time += time_delta; 256 257 uint32 ntp_seconds_3 = 0; 258 uint32 ntp_fraction_3 = 0; 259 260 ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3); 261 base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3); 262 EXPECT_EQ(input_time, out_3); // Verify inverse. 263 264 // Verify delta. 265 EXPECT_EQ((out_3 - out_2), time_delta); 266 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1); 267} 268 269} // namespace cast 270} // namespace media 271