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 "base/memory/scoped_ptr.h"
6 #include "base/test/simple_test_tick_clock.h"
7 #include "media/cast/cast_environment.h"
8 #include "media/cast/net/cast_transport_defines.h"
9 #include "media/cast/net/rtcp/rtcp_utility.h"
10 #include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
11 #include "media/cast/test/fake_single_thread_task_runner.h"
12 #include "testing/gtest/include/gtest/gtest.h"
17 static const uint32 kSenderSsrc
= 0x10203;
18 static const uint32 kSourceSsrc
= 0x40506;
19 static const uint32 kUnknownSsrc
= 0xDEAD;
20 static const base::TimeDelta kTargetDelay
=
21 base::TimeDelta::FromMilliseconds(100);
23 class RtcpParserTest
: public ::testing::Test
{
26 : testing_clock_(new base::SimpleTestTickClock()),
27 task_runner_(new test::FakeSingleThreadTaskRunner(
28 testing_clock_
.get())) {
31 bool HasAnything(const RtcpParser
& parser
) {
32 return parser
.has_sender_report() ||
33 parser
.has_last_report() ||
34 parser
.has_receiver_log() ||
35 parser
.has_cast_message() ||
36 parser
.has_receiver_reference_time_report();
39 void ExpectSenderInfo(const RtcpParser
& parser
) {
40 EXPECT_TRUE(parser
.has_sender_report());
41 EXPECT_EQ(kNtpHigh
, parser
.sender_report().ntp_seconds
);
42 EXPECT_EQ(kNtpLow
, parser
.sender_report().ntp_fraction
);
43 EXPECT_EQ(kRtpTimestamp
, parser
.sender_report().rtp_timestamp
);
44 EXPECT_EQ(kSendPacketCount
, parser
.sender_report().send_packet_count
);
45 EXPECT_EQ(kSendOctetCount
, parser
.sender_report().send_octet_count
);
48 void ExpectLastReport(const RtcpParser
& parser
) {
49 EXPECT_TRUE(parser
.has_last_report());
50 EXPECT_EQ(kLastSr
, parser
.last_report());
51 EXPECT_EQ(kDelayLastSr
, parser
.delay_since_last_report());
54 void ExpectReceiverReference(const RtcpParser
& parser
) {
55 EXPECT_TRUE(parser
.has_receiver_reference_time_report());
56 EXPECT_EQ(kSenderSsrc
, parser
.receiver_reference_time_report().remote_ssrc
);
57 EXPECT_EQ(kNtpHigh
, parser
.receiver_reference_time_report().ntp_seconds
);
58 EXPECT_EQ(kNtpLow
, parser
.receiver_reference_time_report().ntp_fraction
);
61 void ExpectCastFeedback(const RtcpParser
& parser
) {
62 EXPECT_TRUE(parser
.has_cast_message());
63 EXPECT_EQ(kSenderSsrc
, parser
.cast_message().media_ssrc
);
64 EXPECT_EQ(kAckFrameId
, parser
.cast_message().ack_frame_id
);
66 MissingFramesAndPacketsMap::const_iterator frame_it
=
67 parser
.cast_message().missing_frames_and_packets
.begin();
70 frame_it
!= parser
.cast_message().missing_frames_and_packets
.end());
71 EXPECT_EQ(kLostFrameId
, frame_it
->first
);
72 EXPECT_EQ(frame_it
->second
.size(), 1UL);
73 EXPECT_EQ(*frame_it
->second
.begin(), kRtcpCastAllPacketsLost
);
76 frame_it
!= parser
.cast_message().missing_frames_and_packets
.end());
77 EXPECT_EQ(kFrameIdWithLostPackets
, frame_it
->first
);
78 EXPECT_EQ(3UL, frame_it
->second
.size());
79 PacketIdSet::const_iterator packet_it
= frame_it
->second
.begin();
80 EXPECT_EQ(kLostPacketId1
, *packet_it
);
82 EXPECT_EQ(kLostPacketId2
, *packet_it
);
84 EXPECT_EQ(kLostPacketId3
, *packet_it
);
87 frame_it
== parser
.cast_message().missing_frames_and_packets
.end());
90 void ExpectReceiverLog(const RtcpParser
& parser
,
91 const RtcpReceiverLogMessage
& expected_receiver_log
) {
92 EXPECT_TRUE(parser
.has_receiver_log());
93 EXPECT_EQ(expected_receiver_log
.size(), parser
.receiver_log().size());
94 RtcpReceiverLogMessage::const_iterator expected_it
=
95 expected_receiver_log
.begin();
96 RtcpReceiverLogMessage::const_iterator incoming_it
=
97 parser
.receiver_log().begin();
98 for (; incoming_it
!= parser
.receiver_log().end();
99 ++incoming_it
, ++expected_it
) {
100 EXPECT_EQ(expected_it
->rtp_timestamp_
, incoming_it
->rtp_timestamp_
);
101 EXPECT_EQ(expected_it
->event_log_messages_
.size(),
102 incoming_it
->event_log_messages_
.size());
104 RtcpReceiverEventLogMessages::const_iterator event_incoming_it
=
105 incoming_it
->event_log_messages_
.begin();
106 RtcpReceiverEventLogMessages::const_iterator event_expected_it
=
107 expected_it
->event_log_messages_
.begin();
108 for (; event_incoming_it
!= incoming_it
->event_log_messages_
.end();
109 ++event_incoming_it
, ++event_expected_it
) {
110 EXPECT_EQ(event_expected_it
->type
, event_incoming_it
->type
);
111 EXPECT_EQ(event_expected_it
->event_timestamp
,
112 event_incoming_it
->event_timestamp
);
113 if (event_expected_it
->type
== PACKET_RECEIVED
) {
114 EXPECT_EQ(event_expected_it
->packet_id
, event_incoming_it
->packet_id
);
116 EXPECT_EQ(event_expected_it
->delay_delta
,
117 event_incoming_it
->delay_delta
);
123 scoped_ptr
<base::SimpleTestTickClock
> testing_clock_
;
124 scoped_refptr
<test::FakeSingleThreadTaskRunner
> task_runner_
;
126 DISALLOW_COPY_AND_ASSIGN(RtcpParserTest
);
129 TEST_F(RtcpParserTest
, BrokenPacketIsIgnored
) {
130 const char bad_packet
[] = {0, 0, 0, 0};
131 RtcpParser
parser(kSourceSsrc
, kSenderSsrc
);
132 base::BigEndianReader
reader(bad_packet
, sizeof(bad_packet
));
133 EXPECT_FALSE(parser
.Parse(&reader
));
136 TEST_F(RtcpParserTest
, UnknownBlockIgnored
) {
137 // Only unknown data, nothing happens.
138 TestRtcpPacketBuilder p
;
140 RtcpParser
parser1(kSourceSsrc
, 0);
141 EXPECT_TRUE(parser1
.Parse(p
.Reader()));
142 EXPECT_FALSE(HasAnything(parser1
));
144 // Add valid sender report *after* unknown data - should work fine.
145 p
.AddSr(kSenderSsrc
, 0);
146 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
147 EXPECT_TRUE(parser2
.Parse(p
.Reader()));
148 ExpectSenderInfo(parser2
);
151 TEST_F(RtcpParserTest
, InjectSenderReportPacket
) {
152 TestRtcpPacketBuilder p
;
153 p
.AddSr(kSenderSsrc
, 0);
155 // Expected to be ignored since the sender ssrc does not match our
157 RtcpParser
parser1(kSourceSsrc
, 0);
158 EXPECT_TRUE(parser1
.Parse(p
.Reader()));
159 EXPECT_FALSE(HasAnything(parser1
));
161 // Expected to be pass through since the sender ssrc match our remote ssrc.
162 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
163 EXPECT_TRUE(parser2
.Parse(p
.Reader()));
164 ExpectSenderInfo(parser2
);
167 TEST_F(RtcpParserTest
, InjectReceiveReportPacket
) {
168 TestRtcpPacketBuilder p1
;
169 p1
.AddRr(kSenderSsrc
, 1);
170 p1
.AddRb(kUnknownSsrc
);
172 // Expected to be ignored since the source ssrc does not match our
174 RtcpParser
parser1(kSourceSsrc
, kSenderSsrc
);
175 EXPECT_TRUE(parser1
.Parse(p1
.Reader()));
176 EXPECT_FALSE(HasAnything(parser1
));
178 TestRtcpPacketBuilder p2
;
179 p2
.AddRr(kSenderSsrc
, 1);
180 p2
.AddRb(kSourceSsrc
);
182 // Expected to be pass through since the sender ssrc match our local ssrc.
183 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
184 EXPECT_TRUE(parser2
.Parse(p2
.Reader()));
185 ExpectLastReport(parser2
);
188 TEST_F(RtcpParserTest
, InjectSenderReportWithReportBlockPacket
) {
189 TestRtcpPacketBuilder p1
;
190 p1
.AddSr(kSenderSsrc
, 1);
191 p1
.AddRb(kUnknownSsrc
);
193 // Sender report expected to be ignored since the sender ssrc does not match
195 // Report block expected to be ignored since the source ssrc does not match
197 RtcpParser
parser1(kSourceSsrc
, 0);
198 EXPECT_TRUE(parser1
.Parse(p1
.Reader()));
199 EXPECT_FALSE(HasAnything(parser1
));
201 // Sender report expected to be pass through since the sender ssrc match our
203 // Report block expected to be ignored since the source ssrc does not match
205 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
206 EXPECT_TRUE(parser2
.Parse(p1
.Reader()));
207 ExpectSenderInfo(parser2
);
208 EXPECT_FALSE(parser2
.has_last_report());
210 // Sender report expected to be ignored since the sender ssrc does not match
212 // Report block expected to be ignored too since it's a part of the
214 TestRtcpPacketBuilder p2
;
215 p2
.AddSr(kSenderSsrc
, 1);
216 p2
.AddRb(kSourceSsrc
);
218 RtcpParser
parser3(kSourceSsrc
, 0);
219 EXPECT_TRUE(parser3
.Parse(p2
.Reader()));
220 EXPECT_FALSE(parser3
.has_last_report());
222 // Sender report expected to be pass through since the sender ssrc match our
224 // Report block expected to be pass through since the sender ssrc match
226 RtcpParser
parser4(kSourceSsrc
, kSenderSsrc
);
227 EXPECT_TRUE(parser4
.Parse(p2
.Reader()));
228 ExpectSenderInfo(parser4
);
229 ExpectLastReport(parser4
);
232 TEST_F(RtcpParserTest
, InjectSenderReportPacketWithDlrr
) {
233 TestRtcpPacketBuilder p
;
234 p
.AddSr(kSenderSsrc
, 0);
235 p
.AddXrHeader(kSenderSsrc
);
236 p
.AddXrUnknownBlock();
237 p
.AddXrExtendedDlrrBlock(kSenderSsrc
);
238 p
.AddXrUnknownBlock();
240 // Expected to be ignored since the source ssrc does not match our
242 RtcpParser
parser1(kSourceSsrc
, 0);
243 EXPECT_TRUE(parser1
.Parse(p
.Reader()));
244 EXPECT_FALSE(HasAnything(parser1
));
246 // Expected to be pass through since the sender ssrc match our local ssrc.
247 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
248 EXPECT_TRUE(parser2
.Parse(p
.Reader()));
249 ExpectSenderInfo(parser2
);
250 // DLRRs are ignored.
251 EXPECT_FALSE(parser2
.has_last_report());
254 TEST_F(RtcpParserTest
, InjectReceiverReportPacketWithRrtr
) {
255 TestRtcpPacketBuilder p1
;
256 p1
.AddRr(kSenderSsrc
, 1);
257 p1
.AddRb(kUnknownSsrc
);
258 p1
.AddXrHeader(kSenderSsrc
);
261 // Expected to be ignored since the source ssrc does not match our
263 RtcpParser
parser1(kSourceSsrc
, 0);
264 EXPECT_TRUE(parser1
.Parse(p1
.Reader()));
265 EXPECT_FALSE(HasAnything(parser1
));
267 TestRtcpPacketBuilder p2
;
268 p2
.AddRr(kSenderSsrc
, 1);
269 p2
.AddRb(kSourceSsrc
);
270 p2
.AddXrHeader(kSenderSsrc
);
273 // Expected to be pass through since the sender ssrc match our local ssrc.
274 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
275 EXPECT_TRUE(parser2
.Parse(p2
.Reader()));
276 ExpectLastReport(parser2
);
277 ExpectReceiverReference(parser2
);
280 TEST_F(RtcpParserTest
, InjectReceiverReportPacketWithIntraFrameRequest
) {
281 TestRtcpPacketBuilder p1
;
282 p1
.AddRr(kSenderSsrc
, 1);
283 p1
.AddRb(kUnknownSsrc
);
285 // Expected to be ignored since the source ssrc does not match our
287 RtcpParser
parser1(kSourceSsrc
, 0);
288 EXPECT_TRUE(parser1
.Parse(p1
.Reader()));
289 EXPECT_FALSE(HasAnything(parser1
));
291 TestRtcpPacketBuilder p2
;
292 p2
.AddRr(kSenderSsrc
, 1);
293 p2
.AddRb(kSourceSsrc
);
295 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
296 EXPECT_TRUE(parser2
.Parse(p2
.Reader()));
297 ExpectLastReport(parser2
);
300 TEST_F(RtcpParserTest
, InjectReceiverReportPacketWithCastFeedback
) {
301 TestRtcpPacketBuilder p1
;
302 p1
.AddRr(kSenderSsrc
, 1);
303 p1
.AddRb(kUnknownSsrc
);
304 p1
.AddCast(kSenderSsrc
, kUnknownSsrc
, kTargetDelay
);
306 // Expected to be ignored since the source ssrc does not match our
308 RtcpParser
parser1(kSourceSsrc
, 0);
309 EXPECT_TRUE(parser1
.Parse(p1
.Reader()));
310 EXPECT_FALSE(HasAnything(parser1
));
312 TestRtcpPacketBuilder p2
;
313 p2
.AddRr(kSenderSsrc
, 1);
314 p2
.AddRb(kSourceSsrc
);
315 p2
.AddCast(kSenderSsrc
, kSourceSsrc
, kTargetDelay
);
317 // Expected to be pass through since the sender ssrc match our local ssrc.
318 RtcpParser
parser2(kSourceSsrc
, kSenderSsrc
);
319 EXPECT_TRUE(parser2
.Parse(p2
.Reader()));
320 ExpectLastReport(parser2
);
321 ExpectCastFeedback(parser2
);
324 TEST_F(RtcpParserTest
, InjectReceiverReportWithReceiverLogVerificationBase
) {
325 static const uint32 kTimeBaseMs
= 12345678;
326 static const uint32 kTimeDelayMs
= 10;
327 static const uint32 kDelayDeltaMs
= 123;
328 base::SimpleTestTickClock testing_clock
;
329 testing_clock
.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs
));
331 RtcpReceiverLogMessage receiver_log
;
332 RtcpReceiverFrameLogMessage
frame_log(kRtpTimestamp
);
333 RtcpReceiverEventLogMessage event_log
;
335 event_log
.type
= FRAME_ACK_SENT
;
336 event_log
.event_timestamp
= testing_clock
.NowTicks();
337 event_log
.delay_delta
= base::TimeDelta::FromMilliseconds(kDelayDeltaMs
);
338 frame_log
.event_log_messages_
.push_back(event_log
);
340 testing_clock
.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs
));
341 event_log
.type
= PACKET_RECEIVED
;
342 event_log
.event_timestamp
= testing_clock
.NowTicks();
343 event_log
.packet_id
= kLostPacketId1
;
344 frame_log
.event_log_messages_
.push_back(event_log
);
346 event_log
.type
= PACKET_RECEIVED
;
347 event_log
.event_timestamp
= testing_clock
.NowTicks();
348 event_log
.packet_id
= kLostPacketId2
;
349 frame_log
.event_log_messages_
.push_back(event_log
);
351 receiver_log
.push_back(frame_log
);
353 TestRtcpPacketBuilder p
;
354 p
.AddRr(kSenderSsrc
, 1);
355 p
.AddRb(kSourceSsrc
);
356 p
.AddReceiverLog(kSenderSsrc
);
357 p
.AddReceiverFrameLog(kRtpTimestamp
, 3, kTimeBaseMs
);
358 p
.AddReceiverEventLog(kDelayDeltaMs
, FRAME_ACK_SENT
, 0);
359 p
.AddReceiverEventLog(kLostPacketId1
, PACKET_RECEIVED
, kTimeDelayMs
);
360 p
.AddReceiverEventLog(kLostPacketId2
, PACKET_RECEIVED
, kTimeDelayMs
);
362 RtcpParser
parser(kSourceSsrc
, kSenderSsrc
);
363 EXPECT_TRUE(parser
.Parse(p
.Reader()));
364 ExpectReceiverLog(parser
, receiver_log
);
367 TEST_F(RtcpParserTest
, InjectReceiverReportWithReceiverLogVerificationMulti
) {
368 static const uint32 kTimeBaseMs
= 12345678;
369 static const uint32 kTimeDelayMs
= 10;
370 static const int kDelayDeltaMs
= 123; // To be varied for every frame.
371 base::SimpleTestTickClock testing_clock
;
372 testing_clock
.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs
));
374 RtcpReceiverLogMessage receiver_log
;
376 for (int j
= 0; j
< 100; ++j
) {
377 RtcpReceiverFrameLogMessage
frame_log(kRtpTimestamp
);
378 RtcpReceiverEventLogMessage event_log
;
379 event_log
.type
= FRAME_ACK_SENT
;
380 event_log
.event_timestamp
= testing_clock
.NowTicks();
381 event_log
.delay_delta
=
382 base::TimeDelta::FromMilliseconds((j
- 50) * kDelayDeltaMs
);
383 frame_log
.event_log_messages_
.push_back(event_log
);
384 receiver_log
.push_back(frame_log
);
385 testing_clock
.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs
));
388 TestRtcpPacketBuilder p
;
389 p
.AddRr(kSenderSsrc
, 1);
390 p
.AddRb(kSourceSsrc
);
391 p
.AddReceiverLog(kSenderSsrc
);
392 for (int i
= 0; i
< 100; ++i
) {
393 p
.AddReceiverFrameLog(kRtpTimestamp
, 1, kTimeBaseMs
+ i
* kTimeDelayMs
);
394 const int delay
= (i
- 50) * kDelayDeltaMs
;
395 p
.AddReceiverEventLog(static_cast<uint16
>(delay
), FRAME_ACK_SENT
, 0);
398 RtcpParser
parser(kSourceSsrc
, kSenderSsrc
);
399 EXPECT_TRUE(parser
.Parse(p
.Reader()));
400 ExpectReceiverLog(parser
, receiver_log
);