Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / media / cast / net / rtcp / rtcp_unittest.cc
blobce6c3b24622e7242daeebccd242fe258548c2f01
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.
5 #include <stdint.h>
6 #include <vector>
8 #include "base/bind.h"
9 #include "base/test/simple_test_tick_clock.h"
10 #include "media/cast/cast_defines.h"
11 #include "media/cast/net/cast_transport_config.h"
12 #include "media/cast/net/pacing/paced_sender.h"
13 #include "media/cast/net/rtcp/rtcp.h"
14 #include "media/cast/test/skewed_tick_clock.h"
15 #include "testing/gmock/include/gmock/gmock.h"
17 namespace media {
18 namespace cast {
20 using testing::_;
22 static const uint32 kSenderSsrc = 0x10203;
23 static const uint32 kReceiverSsrc = 0x40506;
24 static const int kInitialReceiverClockOffsetSeconds = -5;
26 class FakeRtcpTransport : public PacedPacketSender {
27 public:
28 explicit FakeRtcpTransport(base::SimpleTestTickClock* clock)
29 : clock_(clock),
30 packet_delay_(base::TimeDelta::FromMilliseconds(42)),
31 paused_(false) {}
33 void set_rtcp_destination(Rtcp* rtcp) { rtcp_ = rtcp; }
35 base::TimeDelta packet_delay() const { return packet_delay_; }
36 void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; }
38 bool SendRtcpPacket(uint32 ssrc, PacketRef packet) final {
39 clock_->Advance(packet_delay_);
40 if (paused_) {
41 packet_queue_.push_back(packet);
42 } else {
43 rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
45 return true;
48 bool SendPackets(const SendPacketVector& packets) final { return false; }
50 bool ResendPackets(const SendPacketVector& packets,
51 const DedupInfo& dedup_info) final {
52 return false;
55 void CancelSendingPacket(const PacketKey& packet_key) final {}
57 void Pause() {
58 paused_ = true;
61 void Unpause() {
62 paused_ = false;
63 for (size_t i = 0; i < packet_queue_.size(); ++i) {
64 rtcp_->IncomingRtcpPacket(&packet_queue_[i]->data[0],
65 packet_queue_[i]->data.size());
67 packet_queue_.clear();
70 void ReversePacketQueue() {
71 std::reverse(packet_queue_.begin(), packet_queue_.end());
74 private:
75 base::SimpleTestTickClock* const clock_;
76 base::TimeDelta packet_delay_;
77 Rtcp* rtcp_;
78 bool paused_;
79 std::vector<PacketRef> packet_queue_;
81 DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
84 class MockFrameSender {
85 public:
86 MockFrameSender() {}
87 virtual ~MockFrameSender() {}
89 MOCK_METHOD1(OnReceivedCastFeedback,
90 void(const RtcpCastMessage& cast_message));
91 MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt));
93 private:
94 DISALLOW_COPY_AND_ASSIGN(MockFrameSender);
97 class RtcpTest : public ::testing::Test {
98 protected:
99 RtcpTest()
100 : sender_clock_(new base::SimpleTestTickClock()),
101 receiver_clock_(new test::SkewedTickClock(sender_clock_.get())),
102 sender_to_receiver_(sender_clock_.get()),
103 receiver_to_sender_(sender_clock_.get()),
104 rtcp_for_sender_(base::Bind(&MockFrameSender::OnReceivedCastFeedback,
105 base::Unretained(&mock_frame_sender_)),
106 base::Bind(&MockFrameSender::OnMeasuredRoundTripTime,
107 base::Unretained(&mock_frame_sender_)),
108 RtcpLogMessageCallback(),
109 sender_clock_.get(),
110 &sender_to_receiver_,
111 kSenderSsrc,
112 kReceiverSsrc),
113 rtcp_for_receiver_(RtcpCastMessageCallback(),
114 RtcpRttCallback(),
115 RtcpLogMessageCallback(),
116 receiver_clock_.get(),
117 &receiver_to_sender_,
118 kReceiverSsrc,
119 kSenderSsrc) {
120 sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
121 receiver_clock_->SetSkew(
122 1.0, // No skew.
123 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds));
125 sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_);
126 receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_);
129 ~RtcpTest() override {}
131 scoped_ptr<base::SimpleTestTickClock> sender_clock_;
132 scoped_ptr<test::SkewedTickClock> receiver_clock_;
133 FakeRtcpTransport sender_to_receiver_;
134 FakeRtcpTransport receiver_to_sender_;
135 MockFrameSender mock_frame_sender_;
136 Rtcp rtcp_for_sender_;
137 Rtcp rtcp_for_receiver_;
139 DISALLOW_COPY_AND_ASSIGN(RtcpTest);
142 TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) {
143 // Initially, expect no lip-sync info receiver-side without having first
144 // received a RTCP packet.
145 base::TimeTicks reference_time;
146 uint32 rtp_timestamp;
147 ASSERT_FALSE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
148 &reference_time));
150 // Send a Sender Report to the receiver.
151 const base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
152 const uint32 rtp_timestamp_sent = 0xbee5;
153 rtcp_for_sender_.SendRtcpFromRtpSender(
154 reference_time_sent, rtp_timestamp_sent, 1, 1);
156 // Now the receiver should have lip-sync info. Confirm that the lip-sync
157 // reference time is the same as that sent.
158 EXPECT_TRUE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
159 &reference_time));
160 const base::TimeTicks rolled_back_time =
161 (reference_time -
162 // Roll-back relative clock offset:
163 base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds) -
164 // Roll-back packet transmission time (because RTT is not yet known):
165 sender_to_receiver_.packet_delay());
166 EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5);
167 EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp);
170 // TODO(miu): There were a few tests here that didn't actually test anything
171 // except that the code wouldn't crash and a callback method was invoked. We
172 // need to fill-in more testing of RTCP now that much of the refactoring work
173 // has been completed.
175 TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
176 const int iterations = 12;
177 EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_))
178 .Times(iterations);
180 // Initially, neither side knows the round trip time.
181 ASSERT_EQ(base::TimeDelta(), rtcp_for_sender_.current_round_trip_time());
182 ASSERT_EQ(base::TimeDelta(), rtcp_for_receiver_.current_round_trip_time());
184 // Do a number of ping-pongs, checking how the round trip times are measured
185 // by the sender and receiver.
186 base::TimeDelta expected_rtt_according_to_sender;
187 base::TimeDelta expected_rtt_according_to_receiver;
188 for (int i = 0; i < iterations; ++i) {
189 const base::TimeDelta one_way_trip_time =
190 base::TimeDelta::FromMilliseconds(1 << i);
191 sender_to_receiver_.set_packet_delay(one_way_trip_time);
192 receiver_to_sender_.set_packet_delay(one_way_trip_time);
194 // Sender --> Receiver
195 base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
196 uint32 rtp_timestamp_sent = 0xbee5 + i;
197 rtcp_for_sender_.SendRtcpFromRtpSender(
198 reference_time_sent, rtp_timestamp_sent, 1, 1);
199 EXPECT_EQ(expected_rtt_according_to_sender,
200 rtcp_for_sender_.current_round_trip_time());
201 #ifdef SENDER_PROVIDES_REPORT_BLOCK
202 EXPECT_EQ(expected_rtt_according_to_receiver,
203 rtcp_for_receiver_.current_round_trip_time());
204 #endif
206 // Receiver --> Sender
207 RtpReceiverStatistics stats;
208 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
209 rtcp_for_receiver_.ConvertToNTPAndSave(receiver_clock_->NowTicks()),
210 NULL, base::TimeDelta(), NULL, &stats);
211 expected_rtt_according_to_sender = one_way_trip_time * 2;
212 EXPECT_EQ(expected_rtt_according_to_sender,
213 rtcp_for_sender_.current_round_trip_time());
214 #ifdef SENDER_PROVIDES_REPORT_BLOCK
215 EXPECT_EQ(expected_rtt_according_to_receiver,
216 rtcp_for_receiver_.current_round_trip_time());
217 #endif
219 // In the next iteration of this loop, after the receiver gets the sender
220 // report, it will be measuring a round trip time consisting of two
221 // different one-way trip times.
222 expected_rtt_according_to_receiver =
223 (one_way_trip_time + one_way_trip_time * 2) / 2;
227 TEST_F(RtcpTest, RejectOldRtcpPacket) {
228 EXPECT_CALL(mock_frame_sender_, OnReceivedCastFeedback(_))
229 .Times(1);
231 // This is rejected.
232 RtcpCastMessage cast_message(kSenderSsrc);
233 cast_message.ack_frame_id = 1;
234 receiver_to_sender_.Pause();
235 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
236 rtcp_for_receiver_.ConvertToNTPAndSave(
237 receiver_clock_->NowTicks() - base::TimeDelta::FromSeconds(10)),
238 &cast_message, base::TimeDelta(), NULL, NULL);
240 cast_message.ack_frame_id = 2;
241 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
242 rtcp_for_receiver_.ConvertToNTPAndSave(receiver_clock_->NowTicks()),
243 &cast_message, base::TimeDelta(), NULL, NULL);
245 receiver_to_sender_.ReversePacketQueue();
246 receiver_to_sender_.Unpause();
249 TEST_F(RtcpTest, NegativeTimeTicks) {
250 EXPECT_CALL(mock_frame_sender_, OnReceivedCastFeedback(_))
251 .Times(2);
253 // Send a RRTR with NTP timestamp that translates to a very negative
254 // value for TimeTicks.
255 RtcpCastMessage cast_message(kSenderSsrc);
256 cast_message.ack_frame_id = 2;
257 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
258 rtcp_for_receiver_.ConvertToNTPAndSave(
259 base::TimeTicks() - base::TimeDelta::FromSeconds(5)),
260 &cast_message, base::TimeDelta(), NULL, NULL);
262 cast_message.ack_frame_id = 1;
263 rtcp_for_receiver_.SendRtcpFromRtpReceiver(
264 rtcp_for_receiver_.ConvertToNTPAndSave(base::TimeTicks()),
265 &cast_message, base::TimeDelta(), NULL, NULL);
268 // TODO(miu): Find a better home for this test.
269 TEST(MisplacedCastTest, NtpAndTime) {
270 const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60);
271 const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60);
273 uint32 ntp_seconds_1 = 0;
274 uint32 ntp_fraction_1 = 0;
275 base::TimeTicks input_time = base::TimeTicks::Now();
276 ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1);
278 // Verify absolute value.
279 EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010);
280 EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030);
282 base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1);
283 EXPECT_EQ(input_time, out_1); // Verify inverse.
285 base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000);
286 input_time += time_delta;
288 uint32 ntp_seconds_2 = 0;
289 uint32 ntp_fraction_2 = 0;
291 ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2);
292 base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2);
293 EXPECT_EQ(input_time, out_2); // Verify inverse.
295 // Verify delta.
296 EXPECT_EQ((out_2 - out_1), time_delta);
297 EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1));
298 EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1);
300 time_delta = base::TimeDelta::FromMilliseconds(500);
301 input_time += time_delta;
303 uint32 ntp_seconds_3 = 0;
304 uint32 ntp_fraction_3 = 0;
306 ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3);
307 base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3);
308 EXPECT_EQ(input_time, out_3); // Verify inverse.
310 // Verify delta.
311 EXPECT_EQ((out_3 - out_2), time_delta);
312 EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1);
315 } // namespace cast
316 } // namespace media