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
17namespace media {
18namespace cast {
19
20namespace {
21static const uint32 kSendingSsrc = 0x12345678;
22static const uint32 kMediaSsrc = 0x87654321;
23static const base::TimeDelta kDefaultDelay =
24    base::TimeDelta::FromMilliseconds(100);
25
26RtcpReportBlock 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
43class RtcpBuilderTest : public ::testing::Test {
44 protected:
45  RtcpBuilderTest()
46      : rtcp_builder_(new RtcpBuilder(kSendingSsrc)) {}
47
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
65TEST_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
79TEST_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
102TEST_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
131TEST_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
165TEST_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
240TEST_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
304TEST_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
357TEST_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
404TEST_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
463TEST_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