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