1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file.
4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/test/simple_test_tick_clock.h"
7424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "media/cast/cast_defines.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "media/cast/cast_environment.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/cast_transport_defines.h"
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/pacing/paced_sender.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/rtcp/receiver_rtcp_event_subscriber.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/cast/net/rtcp/rtcp_builder.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/rtcp/rtcp_utility.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "media/cast/net/rtcp/test_rtcp_packet_builder.h"
15424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
16424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace media {
18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)namespace cast {
19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
21424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const uint32 kSendingSsrc = 0x12345678;
22424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static const uint32 kMediaSsrc = 0x87654321;
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const base::TimeDelta kDefaultDelay =
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    base::TimeDelta::FromMilliseconds(100);
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
26116680a4aac90f2aa7413d9095a592090648e557Ben MurdochRtcpReportBlock GetReportBlock() {
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Initialize remote_ssrc to a "clearly illegal" value.
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.remote_ssrc = 0xDEAD;
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.media_ssrc = kMediaSsrc;  // SSRC of the RTP packet sender.
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.fraction_lost = kLoss >> 24;
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.cumulative_lost = kLoss;  // 24 bits valid.
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.extended_high_sequence_number = kExtendedMax;
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.jitter = kTestJitter;
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.last_sr = kLastSr;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  report_block.delay_since_last_sr = kDelayLastSr;
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return report_block;
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass RtcpBuilderTest : public ::testing::Test {
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protected:
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  RtcpBuilderTest()
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : rtcp_builder_(new RtcpBuilder(kSendingSsrc)) {}
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void ExpectPacketEQ(scoped_ptr<Packet> golden_packet,
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      PacketRef packet) {
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(golden_packet->size(), packet->data.size());
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (golden_packet->size() == packet->data.size()) {
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      for (size_t x = 0; x < golden_packet->size(); x++) {
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        EXPECT_EQ((*golden_packet)[x], packet->data[x]);
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        if ((*golden_packet)[x] != packet->data[x])
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          break;
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      }
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<RtcpBuilder> rtcp_builder_;
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(RtcpBuilderTest);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReport) {
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Receiver report with report block.
67424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TestRtcpPacketBuilder p2;
68424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p2.AddRr(kSendingSsrc, 1);
69424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p2.AddRb(kMediaSsrc);
70424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      p2.GetPacket().Pass(),
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rtcp_builder_->BuildRtcpFromReceiver(
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &report_block, NULL, NULL, NULL, kDefaultDelay));
77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtr) {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Receiver report with report block.
81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TestRtcpPacketBuilder p;
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddRb(kMediaSsrc);
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddXrHeader(kSendingSsrc);
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddXrRrtrBlock();
86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
89424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpReceiverReferenceTimeReport rrtr;
90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rrtr.ntp_seconds = kNtpHigh;
91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  rrtr.ntp_fraction = kNtpLow;
92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rrtr,
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
100424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
101424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithCast) {
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Receiver report with report block.
104424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  TestRtcpPacketBuilder p;
105424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
106424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  p.AddRb(kMediaSsrc);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
108424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
110424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
111424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  RtcpCastMessage cast_message(kMediaSsrc);
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.ack_frame_id = kAckFrameId;
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  PacketIdSet missing_packets;
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets;
115424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  missing_packets.insert(kLostPacketId1);
117424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  missing_packets.insert(kLostPacketId2);
118424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  missing_packets.insert(kLostPacketId3);
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] =
120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      missing_packets;
121424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &cast_message,
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtraAndCastMessage) {
132a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestRtcpPacketBuilder p;
133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRb(kMediaSsrc);
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddXrHeader(kSendingSsrc);
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddXrRrtrBlock();
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RtcpReceiverReferenceTimeReport rrtr;
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  rrtr.ntp_seconds = kNtpHigh;
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  rrtr.ntp_fraction = kNtpLow;
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RtcpCastMessage cast_message(kMediaSsrc);
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.ack_frame_id = kAckFrameId;
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PacketIdSet missing_packets;
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets;
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId1);
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId2);
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId3);
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] =
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      missing_packets;
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rrtr,
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &cast_message,
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithRrtrCastMessageAndLog) {
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeBaseMs = 12345678;
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeDelayMs = 10;
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestRtcpPacketBuilder p;
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRb(kMediaSsrc);
172a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddXrHeader(kSendingSsrc);
173a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddXrRrtrBlock();
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddCast(kSendingSsrc, kMediaSsrc, kDefaultDelay);
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RtcpReceiverReferenceTimeReport rrtr;
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  rrtr.ntp_seconds = kNtpHigh;
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  rrtr.ntp_fraction = kNtpLow;
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  RtcpCastMessage cast_message(kMediaSsrc);
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.ack_frame_id = kAckFrameId;
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  PacketIdSet missing_packets;
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kLostFrameId] = missing_packets;
186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
187a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId1);
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId2);
189a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  missing_packets.insert(kLostPacketId3);
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  cast_message.missing_frames_and_packets[kFrameIdWithLostPackets] =
191a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      missing_packets;
192a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
193cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rrtr,
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &cast_message,
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rtcp_events,
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
204a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::SimpleTestTickClock testing_clock;
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddReceiverLog(kSendingSsrc);
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs);
209cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
210cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  p.AddReceiverEventLog(kLostPacketId1, PACKET_RECEIVED, kTimeDelayMs);
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameEvent frame_event;
2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_event.rtp_timestamp = kRtpTimestamp;
214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame_event.type = FRAME_ACK_SENT;
215cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame_event.media_type = VIDEO_EVENT;
2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_event.timestamp = testing_clock.NowTicks();
2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  event_subscriber.OnReceiveFrameEvent(frame_event);
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs));
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PacketEvent packet_event;
2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  packet_event.rtp_timestamp = kRtpTimestamp;
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  packet_event.type = PACKET_RECEIVED;
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  packet_event.media_type = VIDEO_EVENT;
2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  packet_event.timestamp = testing_clock.NowTicks();
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  packet_event.packet_id = kLostPacketId1;
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  event_subscriber.OnReceivePacketEvent(packet_event);
227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  EXPECT_EQ(2u, rtcp_events.size());
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      p.GetPacket().Pass(),
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      rtcp_builder_->BuildRtcpFromReceiver(
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &report_block,
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &rrtr,
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &cast_message,
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &rtcp_events,
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          kDefaultDelay));
238a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithOversizedFrameLog) {
241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeBaseMs = 12345678;
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeDelayMs = 10;
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestRtcpPacketBuilder p;
245a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRb(kMediaSsrc);
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
249a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::SimpleTestTickClock testing_clock;
251a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));
252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddReceiverLog(kSendingSsrc);
254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
255a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int remaining_bytes = kMaxReceiverLogBytes;
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  remaining_bytes -= kRtcpCastLogHeaderSize;
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  remaining_bytes -= kRtcpReceiverFrameLogSize;
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_events = remaining_bytes / kRtcpReceiverEventLogSize;
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EXPECT_LE(num_events, static_cast<int>(kRtcpMaxReceiverLogMessages));
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Only the last |num_events| events are sent due to receiver log size cap.
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddReceiverFrameLog(
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kRtpTimestamp + 2345,
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      num_events,
265a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      kTimeBaseMs + (kRtcpMaxReceiverLogMessages - num_events) * kTimeDelayMs);
266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < num_events; i++) {
267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    p.AddReceiverEventLog(
268cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        kLostPacketId1, PACKET_RECEIVED,
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        static_cast<uint16>(kTimeDelayMs * i));
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FrameEvent frame_event;
2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_event.rtp_timestamp = kRtpTimestamp;
276cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame_event.type = FRAME_ACK_SENT;
277cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  frame_event.media_type = VIDEO_EVENT;
2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  frame_event.timestamp = testing_clock.NowTicks();
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  event_subscriber.OnReceiveFrameEvent(frame_event);
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) {
2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PacketEvent packet_event;
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_event.rtp_timestamp = kRtpTimestamp + 2345;
284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    packet_event.type = PACKET_RECEIVED;
285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    packet_event.media_type = VIDEO_EVENT;
2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_event.timestamp = testing_clock.NowTicks();
2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    packet_event.packet_id = kLostPacketId1;
2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    event_subscriber.OnReceivePacketEvent(packet_event);
289a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs));
290a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
291a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
292c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
293c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
294c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rtcp_events,
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
302a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
303a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithTooManyLogFrames) {
305a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeBaseMs = 12345678;
306a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const uint32 kTimeDelayMs = 10;
307a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
308a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  TestRtcpPacketBuilder p;
309a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
310a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddRb(kMediaSsrc);
311a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
312116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
314a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::SimpleTestTickClock testing_clock;
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  p.AddReceiverLog(kSendingSsrc);
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
319a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int remaining_bytes = kMaxReceiverLogBytes;
320a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  remaining_bytes -= kRtcpCastLogHeaderSize;
321a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
322a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  int num_events =
323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      remaining_bytes / (kRtcpReceiverFrameLogSize + kRtcpReceiverEventLogSize);
324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // The last |num_events| events are sent due to receiver log size cap.
326a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = kRtcpMaxReceiverLogMessages - num_events;
327a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       i < kRtcpMaxReceiverLogMessages;
328a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       ++i) {
3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    p.AddReceiverFrameLog(kRtpTimestamp + i, 1, kTimeBaseMs + i * kTimeDelayMs);
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
331a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (size_t i = 0; i < kRtcpMaxReceiverLogMessages; ++i) {
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    FrameEvent frame_event;
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    frame_event.rtp_timestamp = kRtpTimestamp + static_cast<int>(i);
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.type = FRAME_ACK_SENT;
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.media_type = VIDEO_EVENT;
3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    frame_event.timestamp = testing_clock.NowTicks();
3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    event_subscriber.OnReceiveFrameEvent(frame_event);
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs));
343a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
345c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
346c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
347c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rtcp_events,
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
355a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
356a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportWithOldLogFrames) {
358a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  static const uint32 kTimeBaseMs = 12345678;
359a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
360a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TestRtcpPacketBuilder p;
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddRr(kSendingSsrc, 1);
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddRb(kMediaSsrc);
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
364116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::SimpleTestTickClock testing_clock;
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddReceiverLog(kSendingSsrc);
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Log 11 events for a single frame, each |kTimeBetweenEventsMs| apart.
372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Only last 10 events will be sent because the first event is more than
373a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // 4095 milliseconds away from latest event.
374a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const int kTimeBetweenEventsMs = 410;
375a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  p.AddReceiverFrameLog(kRtpTimestamp, 10, kTimeBaseMs + kTimeBetweenEventsMs);
376a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 10; ++i) {
377cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    p.AddReceiverEventLog(0, FRAME_ACK_SENT, i * kTimeBetweenEventsMs);
378a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (int i = 0; i < 11; ++i) {
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FrameEvent frame_event;
383a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    frame_event.rtp_timestamp = kRtpTimestamp;
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.type = FRAME_ACK_SENT;
385cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.media_type = VIDEO_EVENT;
386a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    frame_event.timestamp = testing_clock.NowTicks();
387a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    event_subscriber.OnReceiveFrameEvent(frame_event);
388a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    testing_clock.Advance(
389a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs));
390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
391a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
392c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
393c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromReceiver(
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &report_block,
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     NULL,
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     &rtcp_events,
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                     kDefaultDelay));
402a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
403a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpReceiverReportRedundancy) {
405c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  uint32 time_base_ms = 12345678;
406c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int kTimeBetweenEventsMs = 10;
407c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RtcpReportBlock report_block = GetReportBlock();
409c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
410c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  base::SimpleTestTickClock testing_clock;
411c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  testing_clock.Advance(base::TimeDelta::FromMilliseconds(time_base_ms));
412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
413cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ReceiverRtcpEventSubscriber event_subscriber(500, VIDEO_EVENT);
414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  size_t packet_count = kReceiveLogMessageHistorySize + 10;
415c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  for (size_t i = 0; i < packet_count; i++) {
416c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    TestRtcpPacketBuilder p;
417c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    p.AddRr(kSendingSsrc, 1);
418c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    p.AddRb(kMediaSsrc);
419c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
420c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    p.AddReceiverLog(kSendingSsrc);
421c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
422c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (i >= kSecondRedundancyOffset) {
423c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      p.AddReceiverFrameLog(
424c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          kRtpTimestamp,
425c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          1,
426c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          time_base_ms - kSecondRedundancyOffset * kTimeBetweenEventsMs);
427cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
428c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
429c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if (i >= kFirstRedundancyOffset) {
430c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      p.AddReceiverFrameLog(
431c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          kRtpTimestamp,
432c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          1,
433c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch          time_base_ms - kFirstRedundancyOffset * kTimeBetweenEventsMs);
434cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
435c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    }
436c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    p.AddReceiverFrameLog(kRtpTimestamp, 1, time_base_ms);
437cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    p.AddReceiverEventLog(0, FRAME_ACK_SENT, 0);
438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    FrameEvent frame_event;
440c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    frame_event.rtp_timestamp = kRtpTimestamp;
441cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.type = FRAME_ACK_SENT;
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    frame_event.media_type = VIDEO_EVENT;
443c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    frame_event.timestamp = testing_clock.NowTicks();
444c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    event_subscriber.OnReceiveFrameEvent(frame_event);
445c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
446c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    ReceiverRtcpEventSubscriber::RtcpEventMultiMap rtcp_events;
447c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    event_subscriber.GetRtcpEventsAndReset(&rtcp_events);
448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ExpectPacketEQ(p.GetPacket().Pass(),
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   rtcp_builder_->BuildRtcpFromReceiver(
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       &report_block,
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       NULL,
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       NULL,
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       &rtcp_events,
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                       kDefaultDelay));
456c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
457c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    testing_clock.Advance(
458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch        base::TimeDelta::FromMilliseconds(kTimeBetweenEventsMs));
459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    time_base_ms += kTimeBetweenEventsMs;
460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(RtcpBuilderTest, RtcpSenderReport) {
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RtcpSenderInfo sender_info;
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sender_info.ntp_seconds = kNtpHigh;
4665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sender_info.ntp_fraction = kNtpLow;
4675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sender_info.rtp_timestamp = kRtpTimestamp;
4685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sender_info.send_packet_count = kSendPacketCount;
4695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  sender_info.send_octet_count = kSendOctetCount;
4705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Sender report.
4725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestRtcpPacketBuilder p;
4735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  p.AddSr(kSendingSsrc, 0);
4745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExpectPacketEQ(p.GetPacket().Pass(),
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 rtcp_builder_->BuildRtcpFromSender(sender_info));
4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace cast
480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}  // namespace media
481