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.
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"
20 static const uint32 kSenderSsrc = 0x10203;
21 static const uint32 kReceiverSsrc = 0x40506;
22 static const int kInitialReceiverClockOffsetSeconds = -5;
24 class FakeRtcpTransport : public PacedPacketSender {
26 explicit FakeRtcpTransport(base::SimpleTestTickClock* clock)
28 packet_delay_(base::TimeDelta::FromMilliseconds(42)) {}
30 void set_rtcp_destination(Rtcp* rtcp) { rtcp_ = rtcp; }
32 base::TimeDelta packet_delay() const { return packet_delay_; }
33 void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; }
35 virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) OVERRIDE {
36 clock_->Advance(packet_delay_);
37 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
41 virtual bool SendPackets(const SendPacketVector& packets) OVERRIDE {
45 virtual bool ResendPackets(
46 const SendPacketVector& packets, const DedupInfo& dedup_info) OVERRIDE {
50 virtual void CancelSendingPacket(const PacketKey& packet_key) OVERRIDE {
54 base::SimpleTestTickClock* const clock_;
55 base::TimeDelta packet_delay_;
58 DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
61 class FakeReceiverStats : public RtpReceiverStatistics {
63 FakeReceiverStats() {}
64 virtual ~FakeReceiverStats() {}
66 virtual void GetStatistics(uint8* fraction_lost,
67 uint32* cumulative_lost,
68 uint32* extended_high_sequence_number,
69 uint32* jitter) OVERRIDE {
72 *extended_high_sequence_number = 0;
77 DISALLOW_COPY_AND_ASSIGN(FakeReceiverStats);
80 class MockFrameSender {
83 virtual ~MockFrameSender() {}
85 MOCK_METHOD1(OnReceivedCastFeedback,
86 void(const RtcpCastMessage& cast_message));
87 MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt));
90 DISALLOW_COPY_AND_ASSIGN(MockFrameSender);
93 class RtcpTest : public ::testing::Test {
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(),
106 &sender_to_receiver_,
109 rtcp_for_receiver_(RtcpCastMessageCallback(),
111 RtcpLogMessageCallback(),
112 receiver_clock_.get(),
113 &receiver_to_sender_,
116 sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
117 receiver_clock_->SetSkew(
119 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds));
121 sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_);
122 receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_);
125 virtual ~RtcpTest() {}
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_;
136 DISALLOW_COPY_AND_ASSIGN(RtcpTest);
139 TEST_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,
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);
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,
157 const base::TimeTicks rolled_back_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);
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.
172 TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
173 const int iterations = 12;
174 EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_))
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());
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);
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());
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();
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;
222 // TODO(miu): Find a better home for this test.
223 TEST(MisplacedCastTest, NtpAndTime) {
224 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60);
225 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60);
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);
232 // Verify absolute value.
233 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010);
234 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030);
236 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1);
237 EXPECT_EQ(input_time, out_1); // Verify inverse.
239 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000);
240 input_time += time_delta;
242 uint32 ntp_seconds_2 = 0;
243 uint32 ntp_fraction_2 = 0;
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.
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);
254 time_delta = base::TimeDelta::FromMilliseconds(500);
255 input_time += time_delta;
257 uint32 ntp_seconds_3 = 0;
258 uint32 ntp_fraction_3 = 0;
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.
265 EXPECT_EQ((out_3 - out_2), time_delta);
266 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1);