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