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 bool SendRtcpPacket(uint32 ssrc, PacketRef packet) override {
36 clock_->Advance(packet_delay_);
37 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
41 bool SendPackets(const SendPacketVector& packets) override { return false; }
43 bool ResendPackets(const SendPacketVector& packets,
44 const DedupInfo& dedup_info) override {
48 void CancelSendingPacket(const PacketKey& packet_key) override {}
51 base::SimpleTestTickClock* const clock_;
52 base::TimeDelta packet_delay_;
55 DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
58 class FakeReceiverStats : public RtpReceiverStatistics {
60 FakeReceiverStats() {}
61 ~FakeReceiverStats() override {}
63 void GetStatistics(uint8* fraction_lost,
64 uint32* cumulative_lost,
65 uint32* extended_high_sequence_number,
66 uint32* jitter) override {
69 *extended_high_sequence_number = 0;
74 DISALLOW_COPY_AND_ASSIGN(FakeReceiverStats);
77 class MockFrameSender {
80 virtual ~MockFrameSender() {}
82 MOCK_METHOD1(OnReceivedCastFeedback,
83 void(const RtcpCastMessage& cast_message));
84 MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt));
87 DISALLOW_COPY_AND_ASSIGN(MockFrameSender);
90 class RtcpTest : public ::testing::Test {
93 : sender_clock_(new base::SimpleTestTickClock()),
94 receiver_clock_(new test::SkewedTickClock(sender_clock_.get())),
95 sender_to_receiver_(sender_clock_.get()),
96 receiver_to_sender_(sender_clock_.get()),
97 rtcp_for_sender_(base::Bind(&MockFrameSender::OnReceivedCastFeedback,
98 base::Unretained(&mock_frame_sender_)),
99 base::Bind(&MockFrameSender::OnMeasuredRoundTripTime,
100 base::Unretained(&mock_frame_sender_)),
101 RtcpLogMessageCallback(),
103 &sender_to_receiver_,
106 rtcp_for_receiver_(RtcpCastMessageCallback(),
108 RtcpLogMessageCallback(),
109 receiver_clock_.get(),
110 &receiver_to_sender_,
113 sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
114 receiver_clock_->SetSkew(
116 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds));
118 sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_);
119 receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_);
122 ~RtcpTest() override {}
124 scoped_ptr<base::SimpleTestTickClock> sender_clock_;
125 scoped_ptr<test::SkewedTickClock> receiver_clock_;
126 FakeRtcpTransport sender_to_receiver_;
127 FakeRtcpTransport receiver_to_sender_;
128 MockFrameSender mock_frame_sender_;
129 Rtcp rtcp_for_sender_;
130 Rtcp rtcp_for_receiver_;
131 FakeReceiverStats stats_;
133 DISALLOW_COPY_AND_ASSIGN(RtcpTest);
136 TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) {
137 // Initially, expect no lip-sync info receiver-side without having first
138 // received a RTCP packet.
139 base::TimeTicks reference_time;
140 uint32 rtp_timestamp;
141 ASSERT_FALSE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
144 // Send a Sender Report to the receiver.
145 const base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
146 const uint32 rtp_timestamp_sent = 0xbee5;
147 rtcp_for_sender_.SendRtcpFromRtpSender(
148 reference_time_sent, rtp_timestamp_sent, 1, 1);
150 // Now the receiver should have lip-sync info. Confirm that the lip-sync
151 // reference time is the same as that sent.
152 EXPECT_TRUE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
154 const base::TimeTicks rolled_back_time =
156 // Roll-back relative clock offset:
157 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds) -
158 // Roll-back packet transmission time (because RTT is not yet known):
159 sender_to_receiver_.packet_delay());
160 EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5);
161 EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp);
164 // TODO(miu): There were a few tests here that didn't actually test anything
165 // except that the code wouldn't crash and a callback method was invoked. We
166 // need to fill-in more testing of RTCP now that much of the refactoring work
167 // has been completed.
169 TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
170 const int iterations = 12;
171 EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_))
174 // Initially, neither side knows the round trip time.
175 ASSERT_EQ(base::TimeDelta(), rtcp_for_sender_.current_round_trip_time());
176 ASSERT_EQ(base::TimeDelta(), rtcp_for_receiver_.current_round_trip_time());
178 // Do a number of ping-pongs, checking how the round trip times are measured
179 // by the sender and receiver.
180 base::TimeDelta expected_rtt_according_to_sender;
181 base::TimeDelta expected_rtt_according_to_receiver;
182 for (int i = 0; i < iterations; ++i) {
183 const base::TimeDelta one_way_trip_time =
184 base::TimeDelta::FromMilliseconds(1 << i);
185 sender_to_receiver_.set_packet_delay(one_way_trip_time);
186 receiver_to_sender_.set_packet_delay(one_way_trip_time);
188 // Sender --> Receiver
189 base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
190 uint32 rtp_timestamp_sent = 0xbee5 + i;
191 rtcp_for_sender_.SendRtcpFromRtpSender(
192 reference_time_sent, rtp_timestamp_sent, 1, 1);
193 EXPECT_EQ(expected_rtt_according_to_sender,
194 rtcp_for_sender_.current_round_trip_time());
195 #ifdef SENDER_PROVIDES_REPORT_BLOCK
196 EXPECT_EQ(expected_rtt_according_to_receiver,
197 rtcp_for_receiver_.current_round_trip_time());
200 // Receiver --> Sender
201 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
202 NULL, base::TimeDelta(), NULL, &stats_);
203 expected_rtt_according_to_sender = one_way_trip_time * 2;
204 EXPECT_EQ(expected_rtt_according_to_sender,
205 rtcp_for_sender_.current_round_trip_time());
206 #ifdef SENDER_PROVIDES_REPORT_BLOCK
207 EXPECT_EQ(expected_rtt_according_to_receiver,
208 rtcp_for_receiver_.current_round_trip_time();
211 // In the next iteration of this loop, after the receiver gets the sender
212 // report, it will be measuring a round trip time consisting of two
213 // different one-way trip times.
214 expected_rtt_according_to_receiver =
215 (one_way_trip_time + one_way_trip_time * 2) / 2;
219 // TODO(miu): Find a better home for this test.
220 TEST(MisplacedCastTest, NtpAndTime) {
221 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60);
222 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60);
224 uint32 ntp_seconds_1 = 0;
225 uint32 ntp_fraction_1 = 0;
226 base::TimeTicks input_time = base::TimeTicks::Now();
227 ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1);
229 // Verify absolute value.
230 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010);
231 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030);
233 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1);
234 EXPECT_EQ(input_time, out_1); // Verify inverse.
236 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000);
237 input_time += time_delta;
239 uint32 ntp_seconds_2 = 0;
240 uint32 ntp_fraction_2 = 0;
242 ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2);
243 base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2);
244 EXPECT_EQ(input_time, out_2); // Verify inverse.
247 EXPECT_EQ((out_2 - out_1), time_delta);
248 EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1));
249 EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1);
251 time_delta = base::TimeDelta::FromMilliseconds(500);
252 input_time += time_delta;
254 uint32 ntp_seconds_3 = 0;
255 uint32 ntp_fraction_3 = 0;
257 ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3);
258 base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3);
259 EXPECT_EQ(input_time, out_3); // Verify inverse.
262 EXPECT_EQ((out_3 - out_2), time_delta);
263 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1);