OLD | NEW |
| (Empty) |
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 "base/memory/scoped_ptr.h" | |
6 #include "base/test/simple_test_tick_clock.h" | |
7 #include "media/cast/cast_defines.h" | |
8 #include "media/cast/cast_environment.h" | |
9 #include "media/cast/net/cast_transport_defines.h" | |
10 #include "media/cast/net/pacing/paced_sender.h" | |
11 #include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h" | |
12 #include "media/cast/net/rtcp/rtcp_builder.h" | |
13 #include "media/cast/net/rtcp/rtcp_utility.h" | |
14 #include "media/cast/net/rtcp/test_rtcp_packet_builder.h" | |
15 #include "testing/gmock/include/gmock/gmock.h" | |
16 | |
17 namespace media { | |
18 namespace cast { | |
19 | |
20 namespace { | |
21 static const uint32 kSendingSsrc = 0x12345678; | |
22 static const uint32 kMediaSsrc = 0x87654321; | |
23 static const base::TimeDelta kDefaultDelay = | |
24 base::TimeDelta::FromMilliseconds(100); | |
25 | |
26 RtcpReportBlock GetReportBlock() { | |
27 RtcpReportBlock report_block; | |
28 // Initialize remote_ssrc to a "clearly illegal" value. | |
29 report_block.remote_ssrc = 0xDEAD; | |
30 report_block.media_ssrc = kMediaSsrc; // SSRC of the RTP packet sender. | |
31 report_block.fraction_lost = kLoss >> 24; | |
32 report_block.cumulative_lost = kLoss; // 24 bits valid. | |
33 report_block.extended_high_sequence_number = kExtendedMax; | |
34 report_block.jitter = kTestJitter; | |
35 report_block.last_sr = kLastSr; | |
36 report_block.delay_since_last_sr = kDelayLastSr; | |
37 return report_block; | |
38 } | |
39 | |
40 } // namespace | |
41 | |
42 | |
43 class RtcpBuilderTest : public ::testing::Test { | |
44 protected: | |
45 RtcpBuilderTest() | |
46 : testing_clock_(new base::SimpleTestTickClock()), | |
47 rtcp_builder_(new RtcpBuilder(kSendingSsrc)) {} | |
48 | |
49 void ExpectPacketEQ(scoped_ptr<Packet> golden_packet, | |
50 PacketRef packet) { | |
51 EXPECT_EQ(golden_packet->size(), packet->data.size()); | |
52 if (golden_packet->size() == packet->data.size()) { | |
53 for (size_t x = 0; x < golden_packet->size(); x++) { | |
54 EXPECT_EQ((*golden_packet)[x], packet->data[x]); | |
55 if ((*golden_packet)[x] != packet->data[x]) | |
56 break; | |
57 } | |
58 } | |
59 } | |
60 | |
61 base::SimpleTestTickClock* testing_clock_; // Owned by CastEnvironment. | |
62 scoped_ptr<RtcpBuilder> rtcp_builder_; | |
63 | |
64 DISALLOW_COPY_AND_ASSIGN(RtcpBuilderTest); | |
65 }; | |
66 | |
67 TEST_F(RtcpBuilderTest, RtcpReceiverReport) { | |
68 // Receiver report with report block. | |
69 TestRtcpPacketBuilder p2; | |
70 p2.AddRr(kSendingSsrc, 1); | |
71 p2.AddRb(kMediaSsrc); | |
72 | |
73 RtcpReportBlock report_block = GetReportBlock(); | |
74 | |
75 ExpectPacketEQ( | |
76 p2.GetPacket().Pass(), | |
77 rtcp_builder_->BuildRtcpFromReceiver( | |
78 &report_block, NULL, NULL, NULL, kDefaultDelay)); | |
79 } | |
80 | |
81 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtr) { | |
82 // Receiver report with report block. | |
83 TestRtcpPacketBuilder p; | |
84 p.AddRr(kSendingSsrc, 1); | |
85 p.AddRb(kMediaSsrc); | |
86 p.AddXrHeader(kSendingSsrc); | |
87 p.AddXrRrtrBlock(); | |
88 | |
89 RtcpReportBlock report_block = GetReportBlock(); | |
90 | |
91 RtcpReceiverReferenceTimeReport rrtr; | |
92 rrtr.ntp_seconds = kNtpHigh; | |
93 rrtr.ntp_fraction = kNtpLow; | |
94 | |
95 ExpectPacketEQ(p.GetPacket().Pass(), | |
96 rtcp_builder_->BuildRtcpFromReceiver( | |
97 &report_block, | |
98 &rrtr, | |
99 NULL, | |
100 NULL, | |
101 kDefaultDelay)); | |
102 } | |
103 | |
104 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithCast) { | |
105 // Receiver report with report block. | |
106 TestRtcpPacketBuilder p; | |
107 p.AddRr(kSendingSsrc, 1); | |
108 p.AddRb(kMediaSsrc); | |
109 p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); | |
110 | |
111 RtcpReportBlock report_block = GetReportBlock(); | |
112 | |
113 RtcpCastMessage cast_message(kMediaSsrc); | |
114 cast_message.ack_frame_id = kAckFrameId; | |
115 PacketIdSet missing_packets; | |
116 cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets; | |
117 | |
118 missing_packets.insert(kLostPacketId1); | |
119 missing_packets.insert(kLostPacketId2); | |
120 missing_packets.insert(kLostPacketId3); | |
121 cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] = | |
122 missing_packets; | |
123 | |
124 ExpectPacketEQ(p.GetPacket().Pass(), | |
125 rtcp_builder_->BuildRtcpFromReceiver( | |
126 &report_block, | |
127 NULL, | |
128 &cast_message, | |
129 NULL, | |
130 kDefaultDelay)); | |
131 } | |
132 | |
133 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtraAndCastMessage) { | |
134 TestRtcpPacketBuilder p; | |
135 p.AddRr(kSendingSsrc, 1); | |
136 p.AddRb(kMediaSsrc); | |
137 p.AddXrHeader(kSendingSsrc); | |
138 p.AddXrRrtrBlock(); | |
139 p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); | |
140 | |
141 RtcpReportBlock report_block = GetReportBlock(); | |
142 | |
143 RtcpReceiverReferenceTimeReport rrtr; | |
144 rrtr.ntp_seconds = kNtpHigh; | |
145 rrtr.ntp_fraction = kNtpLow; | |
146 | |
147 RtcpCastMessage cast_message(kMediaSsrc); | |
148 cast_message.ack_frame_id = kAckFrameId; | |
149 PacketIdSet missing_packets; | |
150 cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets; | |
151 | |
152 missing_packets.insert(kLostPacketId1); | |
153 missing_packets.insert(kLostPacketId2); | |
154 missing_packets.insert(kLostPacketId3); | |
155 cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] = | |
156 missing_packets; | |
157 | |
158 ExpectPacketEQ(p.GetPacket().Pass(), | |
159 rtcp_builder_->BuildRtcpFromReceiver( | |
160 &report_block, | |
161 &rrtr, | |
162 &cast_message, | |
163 NULL, | |
164 kDefaultDelay)); | |
165 } | |
166 | |
167 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) { | |
168 static const uint32 kTimeBaseMs = 12345678; | |
169 static const uint32 kTimeDelayMs = 10; | |
170 | |
171 TestRtcpPacketBuilder p; | |
172 p.AddRr(kSendingSsrc, 1); | |
173 p.AddRb(kMediaSsrc); | |
174 p.AddXrHeader(kSendingSsrc); | |
175 p.AddXrRrtrBlock(); | |
176 p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay); | |
177 | |
178 RtcpReportBlock report_block = GetReportBlock(); | |
179 | |
180 RtcpReceiverReferenceTimeReport rrtr; | |
181 rrtr.ntp_seconds = kNtpHigh; | |
182 rrtr.ntp_fraction = kNtpLow; | |
183 | |
184 RtcpCastMessage cast_message(kMediaSsrc); | |
185 cast_message.ack_frame_id = kAckFrameId; | |
186 PacketIdSet missing_packets; | |
187 cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets; | |
188 | |
189 missing_packets.insert(kLostPacketId1); | |
190 missing_packets.insert(kLostPacketId2); | |
191 missing_packets.insert(kLostPacketId3); | |
192 cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] = | |
193 missing_packets; | |
194 | |
195 ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); | |
196 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | |
197 | |
198 ExpectPacketEQ(p.GetPacket().Pass(), | |
199 rtcp_builder_->BuildRtcpFromReceiver( | |
200 &report_block, | |
201 &rrtr, | |
202 &cast_message, | |
203 &rtcp_events, | |
204 kDefaultDelay)); | |
205 | |
206 base::SimpleTestTickClock testing_clock; | |
207 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs)); | |
208 | |
209 p.AddReceiverLog(kSendingSsrc); | |
210 p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs); | |
211 p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); | |
212 p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED, kTimeDelayMs); | |
213 | |
214 FrameEvent frame_event; | |
215 frame_event.rtp_timestamp = kRtpTimestamp; | |
216 frame_event.type = FRAME_ACK_SENT; | |
217 frame_event.media_type = VIDEO_EVENT; | |
218 frame_event.timestamp = testing_clock.NowTicks(); | |
219 event_subscriber.OnReceiveFrameEvent(frame_event); | |
220 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs)); | |
221 | |
222 PacketEvent packet_event; | |
223 packet_event.rtp_timestamp = kRtpTimestamp; | |
224 packet_event.type = PACKET_RECEIVED; | |
225 packet_event.media_type = VIDEO_EVENT; | |
226 packet_event.timestamp = testing_clock.NowTicks(); | |
227 packet_event.packet_id = kLostPacketId1; | |
228 event_subscriber.OnReceivePacketEvent(packet_event); | |
229 event_subscriber.GetRtcpEventsAndReset(&rtcp_events); | |
230 EXPECT_EQ(2u, rtcp_events.size()); | |
231 | |
232 ExpectPacketEQ( | |
233 p.GetPacket().Pass(), | |
234 rtcp_builder_->BuildRtcpFromReceiver( | |
235 &report_block, | |
236 &rrtr, | |
237 &cast_message, | |
238 &rtcp_events, | |
239 kDefaultDelay)); | |
240 } | |
241 | |
242 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOversizedFrameLog) { | |
243 static const uint32 kTimeBaseMs = 12345678; | |
244 static const uint32 kTimeDelayMs = 10; | |
245 | |
246 TestRtcpPacketBuilder p; | |
247 p.AddRr(kSendingSsrc, 1); | |
248 p.AddRb(kMediaSsrc); | |
249 | |
250 RtcpReportBlock report_block = GetReportBlock(); | |
251 | |
252 base::SimpleTestTickClock testing_clock; | |
253 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs)); | |
254 | |
255 p.AddReceiverLog(kSendingSsrc); | |
256 | |
257 int remaining_bytes = kMaxReceiverLogBytes; | |
258 remaining_bytes -= kRtcpCastLogHeaderSize; | |
259 | |
260 remaining_bytes -= kRtcpReceiverFrameLogSize; | |
261 int num_events = remaining_bytes / kRtcpReceiverEventLogSize; | |
262 EXPECT_LE(num_events, static_cast<int>(kRtcpMaxReceiverLogMessages)); | |
263 // Only the last |num_events| events are sent due to receiver log size cap. | |
264 p.AddReceiverFrameLog( | |
265 kRtpTimestamp + 2345, | |
266 num_events, | |
267 kTimeBaseMs + (kRtcpMaxReceiverLogMessages - num_events) * kTimeDelayMs); | |
268 for (int i = 0; i < num_events; i++) { | |
269 p.AddReceiverEventLog( | |
270 kLostPacketId1, PACKET_RECEIVED, | |
271 static_cast<uint16>(kTimeDelayMs * i)); | |
272 } | |
273 | |
274 | |
275 ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); | |
276 FrameEvent frame_event; | |
277 frame_event.rtp_timestamp = kRtpTimestamp; | |
278 frame_event.type = FRAME_ACK_SENT; | |
279 frame_event.media_type = VIDEO_EVENT; | |
280 frame_event.timestamp = testing_clock.NowTicks(); | |
281 event_subscriber.OnReceiveFrameEvent(frame_event); | |
282 | |
283 for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) { | |
284 PacketEvent packet_event; | |
285 packet_event.rtp_timestamp = kRtpTimestamp + 2345; | |
286 packet_event.type = PACKET_RECEIVED; | |
287 packet_event.media_type = VIDEO_EVENT; | |
288 packet_event.timestamp = testing_clock.NowTicks(); | |
289 packet_event.packet_id = kLostPacketId1; | |
290 event_subscriber.OnReceivePacketEvent(packet_event); | |
291 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs)); | |
292 } | |
293 | |
294 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | |
295 event_subscriber.GetRtcpEventsAndReset(&rtcp_events); | |
296 | |
297 ExpectPacketEQ(p.GetPacket().Pass(), | |
298 rtcp_builder_->BuildRtcpFromReceiver( | |
299 &report_block, | |
300 NULL, | |
301 NULL, | |
302 &rtcp_events, | |
303 kDefaultDelay)); | |
304 } | |
305 | |
306 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithTooManyLogFrames) { | |
307 static const uint32 kTimeBaseMs = 12345678; | |
308 static const uint32 kTimeDelayMs = 10; | |
309 | |
310 TestRtcpPacketBuilder p; | |
311 p.AddRr(kSendingSsrc, 1); | |
312 p.AddRb(kMediaSsrc); | |
313 | |
314 RtcpReportBlock report_block = GetReportBlock(); | |
315 | |
316 base::SimpleTestTickClock testing_clock; | |
317 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs)); | |
318 | |
319 p.AddReceiverLog(kSendingSsrc); | |
320 | |
321 int remaining_bytes = kMaxReceiverLogBytes; | |
322 remaining_bytes -= kRtcpCastLogHeaderSize; | |
323 | |
324 int num_events = | |
325 remaining_bytes / (kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize); | |
326 | |
327 // The last |num_events| events are sent due to receiver log size cap. | |
328 for (size_t i = kRtcpMaxReceiverLogMessages - num_events; | |
329 i < kRtcpMaxReceiverLogMessages; | |
330 ++i) { | |
331 p.AddReceiverFrameLog(kRtpTimestamp + i, 1, kTimeBaseMs + i * kTimeDelayMs); | |
332 p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); | |
333 } | |
334 | |
335 ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); | |
336 | |
337 for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) { | |
338 FrameEvent frame_event; | |
339 frame_event.rtp_timestamp = kRtpTimestamp + static_cast<int>(i); | |
340 frame_event.type = FRAME_ACK_SENT; | |
341 frame_event.media_type = VIDEO_EVENT; | |
342 frame_event.timestamp = testing_clock.NowTicks(); | |
343 event_subscriber.OnReceiveFrameEvent(frame_event); | |
344 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs)); | |
345 } | |
346 | |
347 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | |
348 event_subscriber.GetRtcpEventsAndReset(&rtcp_events); | |
349 | |
350 ExpectPacketEQ(p.GetPacket().Pass(), | |
351 rtcp_builder_->BuildRtcpFromReceiver( | |
352 &report_block, | |
353 NULL, | |
354 NULL, | |
355 &rtcp_events, | |
356 kDefaultDelay)); | |
357 } | |
358 | |
359 TEST_F(RtcpBuilderTest, RtcpReceiverReportWithOldLogFrames) { | |
360 static const uint32 kTimeBaseMs = 12345678; | |
361 | |
362 TestRtcpPacketBuilder p; | |
363 p.AddRr(kSendingSsrc, 1); | |
364 p.AddRb(kMediaSsrc); | |
365 | |
366 RtcpReportBlock report_block = GetReportBlock(); | |
367 | |
368 base::SimpleTestTickClock testing_clock; | |
369 testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs)); | |
370 | |
371 p.AddReceiverLog(kSendingSsrc); | |
372 | |
373 // Log 11 events for a single frame, each |kTimeBetweenEventsMs| apart. | |
374 // Only last 10 events will be sent because the first event is more than | |
375 // 4095 milliseconds away from latest event. | |
376 const int kTimeBetweenEventsMs = 410; | |
377 p.AddReceiverFrameLog(kRtpTimestamp, 10, kTimeBaseMs + kTimeBetweenEventsMs); | |
378 for (int i = 0; i < 10; ++i) { | |
379 p.AddReceiverEventLog(0, FRAME_ACK_SENT, i * kTimeBetweenEventsMs); | |
380 } | |
381 | |
382 ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); | |
383 for (int i = 0; i < 11; ++i) { | |
384 FrameEvent frame_event; | |
385 frame_event.rtp_timestamp = kRtpTimestamp; | |
386 frame_event.type = FRAME_ACK_SENT; | |
387 frame_event.media_type = VIDEO_EVENT; | |
388 frame_event.timestamp = testing_clock.NowTicks(); | |
389 event_subscriber.OnReceiveFrameEvent(frame_event); | |
390 testing_clock.Advance( | |
391 base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs)); | |
392 } | |
393 | |
394 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | |
395 event_subscriber.GetRtcpEventsAndReset(&rtcp_events); | |
396 | |
397 ExpectPacketEQ(p.GetPacket().Pass(), | |
398 rtcp_builder_->BuildRtcpFromReceiver( | |
399 &report_block, | |
400 NULL, | |
401 NULL, | |
402 &rtcp_events, | |
403 kDefaultDelay)); | |
404 } | |
405 | |
406 TEST_F(RtcpBuilderTest, RtcpReceiverReportRedundancy) { | |
407 uint32 time_base_ms = 12345678; | |
408 int kTimeBetweenEventsMs = 10; | |
409 | |
410 RtcpReportBlock report_block = GetReportBlock(); | |
411 | |
412 base::SimpleTestTickClock testing_clock; | |
413 testing_clock.Advance(base::TimeDelta::FromMilliseconds(time_base_ms)); | |
414 | |
415 ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT); | |
416 size_t packet_count = kReceiveLogMessageHistorySize + 10; | |
417 for (size_t i = 0; i < packet_count; i++) { | |
418 TestRtcpPacketBuilder p; | |
419 p.AddRr(kSendingSsrc, 1); | |
420 p.AddRb(kMediaSsrc); | |
421 | |
422 p.AddReceiverLog(kSendingSsrc); | |
423 | |
424 if (i >= kSecondRedundancyOffset) { | |
425 p.AddReceiverFrameLog( | |
426 kRtpTimestamp, | |
427 1, | |
428 time_base_ms - kSecondRedundancyOffset * kTimeBetweenEventsMs); | |
429 p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); | |
430 } | |
431 if (i >= kFirstRedundancyOffset) { | |
432 p.AddReceiverFrameLog( | |
433 kRtpTimestamp, | |
434 1, | |
435 time_base_ms - kFirstRedundancyOffset * kTimeBetweenEventsMs); | |
436 p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); | |
437 } | |
438 p.AddReceiverFrameLog(kRtpTimestamp, 1, time_base_ms); | |
439 p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0); | |
440 | |
441 FrameEvent frame_event; | |
442 frame_event.rtp_timestamp = kRtpTimestamp; | |
443 frame_event.type = FRAME_ACK_SENT; | |
444 frame_event.media_type = VIDEO_EVENT; | |
445 frame_event.timestamp = testing_clock.NowTicks(); | |
446 event_subscriber.OnReceiveFrameEvent(frame_event); | |
447 | |
448 ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events; | |
449 event_subscriber.GetRtcpEventsAndReset(&rtcp_events); | |
450 | |
451 ExpectPacketEQ(p.GetPacket().Pass(), | |
452 rtcp_builder_->BuildRtcpFromReceiver( | |
453 &report_block, | |
454 NULL, | |
455 NULL, | |
456 &rtcp_events, | |
457 kDefaultDelay)); | |
458 | |
459 testing_clock.Advance( | |
460 base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs)); | |
461 time_base_ms += kTimeBetweenEventsMs; | |
462 } | |
463 } | |
464 | |
465 TEST_F(RtcpBuilderTest, RtcpSenderReport) { | |
466 RtcpSenderInfo sender_info; | |
467 sender_info.ntp_seconds = kNtpHigh; | |
468 sender_info.ntp_fraction = kNtpLow; | |
469 sender_info.rtp_timestamp = kRtpTimestamp; | |
470 sender_info.send_packet_count = kSendPacketCount; | |
471 sender_info.send_octet_count = kSendOctetCount; | |
472 | |
473 // Sender report. | |
474 TestRtcpPacketBuilder p; | |
475 p.AddSr(kSendingSsrc, 0); | |
476 | |
477 ExpectPacketEQ(p.GetPacket().Pass(), | |
478 rtcp_builder_->BuildRtcpFromSender(sender_info)); | |
479 } | |
480 | |
481 } // namespace cast | |
482 } // namespace media | |
OLD | NEW |