/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


/*
 * This file includes unit tests for the RTCPReceiver.
 */
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

// Note: This file has no directory. Lint warning must be ignored.
#include "webrtc/common_types.h"
#include "webrtc/modules/remote_bitrate_estimator/include/mock/mock_remote_bitrate_observer.h"
#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_receiver.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_rtcp_impl.h"
#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"

namespace webrtc {

namespace {  // Anonymous namespace; hide utility functions and classes.

// A very simple packet builder class for building RTCP packets.
class PacketBuilder {
 public:
  static const int kMaxPacketSize = 1024;

  struct ReportBlock {
    ReportBlock(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss,
                uint32_t cumulative_loss, uint32_t jitter)
        : ssrc(ssrc),
          extended_max(extended_max),
          fraction_loss(fraction_loss),
          cumulative_loss(cumulative_loss),
          jitter(jitter) {}

    uint32_t ssrc;
    uint32_t extended_max;
    uint8_t fraction_loss;
    uint32_t cumulative_loss;
    uint32_t jitter;
  };

  PacketBuilder()
      : pos_(0),
        pos_of_len_(0) {
  }


  void Add8(uint8_t byte) {
    EXPECT_LT(pos_, kMaxPacketSize - 1);
    buffer_[pos_] = byte;
    ++pos_;
  }

  void Add16(uint16_t word) {
    Add8(word >> 8);
    Add8(word & 0xFF);
  }

  void Add32(uint32_t word) {
    Add8(word >> 24);
    Add8((word >> 16) & 0xFF);
    Add8((word >> 8) & 0xFF);
    Add8(word & 0xFF);
  }

  void Add64(uint32_t upper_half, uint32_t lower_half) {
    Add32(upper_half);
    Add32(lower_half);
  }

  // Set the 5-bit value in the 1st byte of the header
  // and the payload type. Set aside room for the length field,
  // and make provision for backpatching it.
  // Note: No way to set the padding bit.
  void AddRtcpHeader(int payload, int format_or_count) {
    PatchLengthField();
    Add8(0x80 | (format_or_count & 0x1F));
    Add8(payload);
    pos_of_len_ = pos_;
    Add16(0xDEAD);  // Initialize length to "clearly illegal".
  }

  void AddTmmbrBandwidth(int mantissa, int exponent, int overhead) {
    // 6 bits exponent, 17 bits mantissa, 9 bits overhead.
    uint32_t word = 0;
    word |= (exponent << 26);
    word |= ((mantissa & 0x1FFFF) << 9);
    word |= (overhead & 0x1FF);
    Add32(word);
  }

  void AddSrPacket(uint32_t sender_ssrc) {
    AddRtcpHeader(200, 0);
    Add32(sender_ssrc);
    Add64(0x10203, 0x4050607);  // NTP timestamp
    Add32(0x10203);  // RTP timestamp
    Add32(0);  // Sender's packet count
    Add32(0);  // Sender's octet count
  }

  void AddRrPacket(uint32_t sender_ssrc, uint32_t rtp_ssrc,
                   uint32_t extended_max, uint8_t fraction_loss,
                   uint32_t cumulative_loss, uint32_t jitter) {
    ReportBlock report_block(rtp_ssrc, extended_max, fraction_loss,
                             cumulative_loss, jitter);
    std::list<ReportBlock> report_block_vector(&report_block,
                                               &report_block + 1);
    AddRrPacketMultipleReportBlocks(sender_ssrc, report_block_vector);
  }

  void AddRrPacketMultipleReportBlocks(
      uint32_t sender_ssrc, const std::list<ReportBlock>& report_blocks) {
    AddRtcpHeader(201, report_blocks.size());
    Add32(sender_ssrc);
    for (std::list<ReportBlock>::const_iterator it = report_blocks.begin();
         it != report_blocks.end(); ++it) {
      AddReportBlock(it->ssrc, it->extended_max, it->fraction_loss,
                     it->cumulative_loss, it->jitter);
    }
  }

  void AddReportBlock(uint32_t rtp_ssrc, uint32_t extended_max,
                      uint8_t fraction_loss, uint32_t cumulative_loss,
                      uint32_t jitter) {
    Add32(rtp_ssrc);
    Add32((fraction_loss << 24) + cumulative_loss);
    Add32(extended_max);
    Add32(jitter);
    Add32(0);  // Last SR.
    Add32(0);  // Delay since last SR.
  }

  void AddXrHeader(uint32_t sender_ssrc) {
    AddRtcpHeader(207, 0);
    Add32(sender_ssrc);
  }

  void AddXrReceiverReferenceTimeBlock(uint32_t ntp_sec, uint32_t ntp_frac) {
    Add8(4);                   // Block type.
    Add8(0);                   // Reserved.
    Add16(2);                  // Length.
    Add64(ntp_sec, ntp_frac);  // NTP timestamp.
  }

  void AddXrDlrrBlock(std::vector<uint32_t>& remote_ssrc) {
    ASSERT_LT(pos_ + 4 + static_cast<int>(remote_ssrc.size())*4,
        kMaxPacketSize-1) << "Max buffer size reached.";
    Add8(5);                      // Block type.
    Add8(0);                      // Reserved.
    Add16(remote_ssrc.size() * 3);  // Length.
    for (size_t i = 0; i < remote_ssrc.size(); ++i) {
      Add32(remote_ssrc.at(i));   // Receiver SSRC.
      Add32(0x10203);             // Last RR.
      Add32(0x40506);             // Delay since last RR.
    }
  }

  void AddXrUnknownBlock() {
    Add8(6);             // Block type.
    Add8(0);             // Reserved.
    Add16(9);            // Length.
    Add32(0);            // Receiver SSRC.
    Add64(0, 0);         // Remaining fields (RFC 3611) are set to zero.
    Add64(0, 0);
    Add64(0, 0);
    Add64(0, 0);
  }

  void AddXrVoipBlock(uint32_t remote_ssrc, uint8_t loss) {
    Add8(7);             // Block type.
    Add8(0);             // Reserved.
    Add16(8);            // Length.
    Add32(remote_ssrc);  // Receiver SSRC.
    Add8(loss);          // Loss rate.
    Add8(0);             // Remaining statistics (RFC 3611) are set to zero.
    Add16(0);
    Add64(0, 0);
    Add64(0, 0);
    Add64(0, 0);
  }

  const uint8_t* packet() {
    PatchLengthField();
    return buffer_;
  }

  unsigned int length() {
    return pos_;
  }
 private:
  void PatchLengthField() {
    if (pos_of_len_ > 0) {
      // Backpatch the packet length. The client must have taken
      // care of proper padding to 32-bit words.
      int this_packet_length = (pos_ - pos_of_len_ - 2);
      ASSERT_EQ(0, this_packet_length % 4)
          << "Packets must be a multiple of 32 bits long"
          << " pos " << pos_ << " pos_of_len " << pos_of_len_;
      buffer_[pos_of_len_] = this_packet_length >> 10;
      buffer_[pos_of_len_+1] = (this_packet_length >> 2) & 0xFF;
      pos_of_len_ = 0;
    }
  }

  int pos_;
  // Where the length field of the current packet is.
  // Note that 0 is not a legal value, so is used for "uninitialized".
  int pos_of_len_;
  uint8_t buffer_[kMaxPacketSize];
};

// This test transport verifies that no functions get called.
class TestTransport : public Transport,
                      public NullRtpData {
 public:
  explicit TestTransport()
      : rtcp_receiver_(NULL) {
  }
  void SetRTCPReceiver(RTCPReceiver* rtcp_receiver) {
    rtcp_receiver_ = rtcp_receiver;
  }
  virtual int SendPacket(int /*ch*/, const void* /*data*/, int /*len*/) {
    ADD_FAILURE();  // FAIL() gives a compile error.
    return -1;
  }

  // Injects an RTCP packet into the receiver.
  virtual int SendRTCPPacket(int /* ch */, const void *packet, int packet_len) {
    ADD_FAILURE();
    return 0;
  }

  virtual int OnReceivedPayloadData(const uint8_t* payloadData,
                                    const uint16_t payloadSize,
                                    const WebRtcRTPHeader* rtpHeader) {
    ADD_FAILURE();
    return 0;
  }
  RTCPReceiver* rtcp_receiver_;
};

class RtcpReceiverTest : public ::testing::Test {
 protected:
  RtcpReceiverTest()
      : over_use_detector_options_(),
        system_clock_(1335900000),
        remote_bitrate_observer_(),
        remote_bitrate_estimator_(
            RemoteBitrateEstimatorFactory().Create(
                &remote_bitrate_observer_,
                &system_clock_)) {
    test_transport_ = new TestTransport();

    RtpRtcp::Configuration configuration;
    configuration.id = 0;
    configuration.audio = false;
    configuration.clock = &system_clock_;
    configuration.outgoing_transport = test_transport_;
    configuration.remote_bitrate_estimator = remote_bitrate_estimator_.get();
    rtp_rtcp_impl_ = new ModuleRtpRtcpImpl(configuration);
    rtcp_receiver_ = new RTCPReceiver(0, &system_clock_, rtp_rtcp_impl_);
    test_transport_->SetRTCPReceiver(rtcp_receiver_);
  }
  ~RtcpReceiverTest() {
    delete rtcp_receiver_;
    delete rtp_rtcp_impl_;
    delete test_transport_;
  }

  // Injects an RTCP packet into the receiver.
  // Returns 0 for OK, non-0 for failure.
  int InjectRtcpPacket(const uint8_t* packet,
                       uint16_t packet_len) {
    RTCPUtility::RTCPParserV2 rtcpParser(packet,
                                         packet_len,
                                         true);  // Allow non-compound RTCP

    RTCPHelp::RTCPPacketInformation rtcpPacketInformation;
    EXPECT_EQ(0, rtcp_receiver_->IncomingRTCPPacket(rtcpPacketInformation,
                                                    &rtcpParser));
    rtcp_receiver_->TriggerCallbacksFromRTCPPacket(rtcpPacketInformation);
    // The NACK list is on purpose not copied below as it isn't needed by the
    // test.
    rtcp_packet_info_.rtcpPacketTypeFlags =
        rtcpPacketInformation.rtcpPacketTypeFlags;
    rtcp_packet_info_.remoteSSRC = rtcpPacketInformation.remoteSSRC;
    rtcp_packet_info_.applicationSubType =
        rtcpPacketInformation.applicationSubType;
    rtcp_packet_info_.applicationName = rtcpPacketInformation.applicationName;
    rtcp_packet_info_.report_blocks = rtcpPacketInformation.report_blocks;
    rtcp_packet_info_.rtt = rtcpPacketInformation.rtt;
    rtcp_packet_info_.interArrivalJitter =
        rtcpPacketInformation.interArrivalJitter;
    rtcp_packet_info_.sliPictureId = rtcpPacketInformation.sliPictureId;
    rtcp_packet_info_.rpsiPictureId = rtcpPacketInformation.rpsiPictureId;
    rtcp_packet_info_.receiverEstimatedMaxBitrate =
        rtcpPacketInformation.receiverEstimatedMaxBitrate;
    rtcp_packet_info_.ntp_secs = rtcpPacketInformation.ntp_secs;
    rtcp_packet_info_.ntp_frac = rtcpPacketInformation.ntp_frac;
    rtcp_packet_info_.rtp_timestamp = rtcpPacketInformation.rtp_timestamp;
    rtcp_packet_info_.xr_dlrr_item = rtcpPacketInformation.xr_dlrr_item;
    if (rtcpPacketInformation.VoIPMetric) {
      rtcp_packet_info_.AddVoIPMetric(rtcpPacketInformation.VoIPMetric);
    }
    return 0;
  }

  OverUseDetectorOptions over_use_detector_options_;
  SimulatedClock system_clock_;
  ModuleRtpRtcpImpl* rtp_rtcp_impl_;
  RTCPReceiver* rtcp_receiver_;
  TestTransport* test_transport_;
  RTCPHelp::RTCPPacketInformation rtcp_packet_info_;
  MockRemoteBitrateObserver remote_bitrate_observer_;
  scoped_ptr<RemoteBitrateEstimator> remote_bitrate_estimator_;
};


TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
  const uint8_t bad_packet[] = {0, 0, 0, 0};
  EXPECT_EQ(0, InjectRtcpPacket(bad_packet, sizeof(bad_packet)));
  EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST_F(RtcpReceiverTest, InjectSrPacket) {
  const uint32_t kSenderSsrc = 0x10203;
  PacketBuilder p;
  p.AddSrPacket(kSenderSsrc);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  // The parser will note the remote SSRC on a SR from other than his
  // expected peer, but will not flag that he's gotten a packet.
  EXPECT_EQ(kSenderSsrc, rtcp_packet_info_.remoteSSRC);
  EXPECT_EQ(0U,
            kRtcpSr & rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST_F(RtcpReceiverTest, XrPacketWithZeroReportBlocksIgnored) {
  PacketBuilder p;
  p.AddXrHeader(0x2345);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST_F(RtcpReceiverTest, InjectXrVoipPacket) {
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);

  const uint8_t kLossRate = 123;
  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrVoipBlock(kSourceSsrc, kLossRate);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  ASSERT_TRUE(rtcp_packet_info_.VoIPMetric != NULL);
  EXPECT_EQ(kLossRate, rtcp_packet_info_.VoIPMetric->lossRate);
  EXPECT_EQ(kRtcpXrVoipMetric, rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST_F(RtcpReceiverTest, InjectXrReceiverReferenceTimePacket) {
  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrReceiverReferenceTimeBlock(0x10203, 0x40506);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(kRtcpXrReceiverReferenceTime,
            rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST_F(RtcpReceiverTest, InjectXrDlrrPacketWithNoSubBlock) {
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrDlrrBlock(remote_ssrcs);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
  EXPECT_FALSE(rtcp_packet_info_.xr_dlrr_item);
}

TEST_F(RtcpReceiverTest, XrDlrrPacketNotToUsIgnored) {
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;
  remote_ssrcs.push_back(kSourceSsrc+1);

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrDlrrBlock(remote_ssrcs);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(0U, rtcp_packet_info_.rtcpPacketTypeFlags);
  EXPECT_FALSE(rtcp_packet_info_.xr_dlrr_item);
}

TEST_F(RtcpReceiverTest, InjectXrDlrrPacketWithSubBlock) {
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;
  remote_ssrcs.push_back(kSourceSsrc);

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrDlrrBlock(remote_ssrcs);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  // The parser should note the DLRR report block item, but not flag the packet
  // since the RTT is not estimated.
  EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
}

TEST_F(RtcpReceiverTest, InjectXrDlrrPacketWithMultipleSubBlocks) {
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;
  remote_ssrcs.push_back(kSourceSsrc+2);
  remote_ssrcs.push_back(kSourceSsrc+1);
  remote_ssrcs.push_back(kSourceSsrc);

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrDlrrBlock(remote_ssrcs);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  // The parser should note the DLRR report block item, but not flag the packet
  // since the RTT is not estimated.
  EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
}

TEST_F(RtcpReceiverTest, InjectXrPacketWithMultipleReportBlocks) {
  const uint8_t kLossRate = 123;
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;
  remote_ssrcs.push_back(kSourceSsrc);

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrDlrrBlock(remote_ssrcs);
  p.AddXrVoipBlock(kSourceSsrc, kLossRate);
  p.AddXrReceiverReferenceTimeBlock(0x10203, 0x40506);

  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(static_cast<unsigned int>(kRtcpXrReceiverReferenceTime +
                                      kRtcpXrVoipMetric),
            rtcp_packet_info_.rtcpPacketTypeFlags);
  // The parser should note the DLRR report block item, but not flag the packet
  // since the RTT is not estimated.
  EXPECT_TRUE(rtcp_packet_info_.xr_dlrr_item);
}

TEST_F(RtcpReceiverTest, InjectXrPacketWithUnknownReportBlock) {
  const uint8_t kLossRate = 123;
  const uint32_t kSourceSsrc = 0x123456;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);
  std::vector<uint32_t> remote_ssrcs;
  remote_ssrcs.push_back(kSourceSsrc);

  PacketBuilder p;
  p.AddXrHeader(0x2345);
  p.AddXrVoipBlock(kSourceSsrc, kLossRate);
  p.AddXrUnknownBlock();
  p.AddXrReceiverReferenceTimeBlock(0x10203, 0x40506);

  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(static_cast<unsigned int>(kRtcpXrReceiverReferenceTime +
                                      kRtcpXrVoipMetric),
            rtcp_packet_info_.rtcpPacketTypeFlags);
}

TEST(RtcpUtilityTest, MidNtp) {
  const uint32_t kNtpSec = 0x12345678;
  const uint32_t kNtpFrac = 0x23456789;
  const uint32_t kNtpMid = 0x56782345;
  EXPECT_EQ(kNtpMid, RTCPUtility::MidNtp(kNtpSec, kNtpFrac));
}

TEST_F(RtcpReceiverTest, TestXrRrRttInitiallyFalse) {
  uint16_t rtt_ms;
  EXPECT_FALSE(rtcp_receiver_->GetAndResetXrRrRtt(&rtt_ms));
}

TEST_F(RtcpReceiverTest, LastReceivedXrReferenceTimeInfoInitiallyFalse) {
  RtcpReceiveTimeInfo info;
  EXPECT_FALSE(rtcp_receiver_->LastReceivedXrReferenceTimeInfo(&info));
}

TEST_F(RtcpReceiverTest, GetLastReceivedXrReferenceTimeInfo) {
  const uint32_t kSenderSsrc = 0x123456;
  const uint32_t kNtpSec = 0x10203;
  const uint32_t kNtpFrac = 0x40506;
  const uint32_t kNtpMid = RTCPUtility::MidNtp(kNtpSec, kNtpFrac);

  PacketBuilder p;
  p.AddXrHeader(kSenderSsrc);
  p.AddXrReceiverReferenceTimeBlock(kNtpSec, kNtpFrac);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(kRtcpXrReceiverReferenceTime,
      rtcp_packet_info_.rtcpPacketTypeFlags);

  RtcpReceiveTimeInfo info;
  EXPECT_TRUE(rtcp_receiver_->LastReceivedXrReferenceTimeInfo(&info));
  EXPECT_EQ(kSenderSsrc, info.sourceSSRC);
  EXPECT_EQ(kNtpMid, info.lastRR);
  EXPECT_EQ(0U, info.delaySinceLastRR);

  system_clock_.AdvanceTimeMilliseconds(1000);
  EXPECT_TRUE(rtcp_receiver_->LastReceivedXrReferenceTimeInfo(&info));
  EXPECT_EQ(65536U, info.delaySinceLastRR);
}

TEST_F(RtcpReceiverTest, ReceiveReportTimeout) {
  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kSourceSsrc = 0x40506;
  const int64_t kRtcpIntervalMs = 1000;

  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);

  uint32_t sequence_number = 1234;
  system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);

  // No RR received, shouldn't trigger a timeout.
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));

  // Add a RR and advance the clock just enough to not trigger a timeout.
  PacketBuilder p1;
  p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0, 0);
  EXPECT_EQ(0, InjectRtcpPacket(p1.packet(), p1.length()));
  system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));

  // Add a RR with the same extended max as the previous RR to trigger a
  // sequence number timeout, but not a RR timeout.
  PacketBuilder p2;
  p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0, 0);
  EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
  system_clock_.AdvanceTimeMilliseconds(2);
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));

  // Advance clock enough to trigger an RR timeout too.
  system_clock_.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
  EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));

  // We should only get one timeout even though we still haven't received a new
  // RR.
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));

  // Add a new RR with increase sequence number to reset timers.
  PacketBuilder p3;
  sequence_number++;
  p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0, 0);
  EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_FALSE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));

  // Verify we can get a timeout again once we've received new RR.
  system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
  PacketBuilder p4;
  p4.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number, 0, 0, 0);
  EXPECT_EQ(0, InjectRtcpPacket(p4.packet(), p4.length()));
  system_clock_.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
  EXPECT_FALSE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
  EXPECT_TRUE(rtcp_receiver_->RtcpRrSequenceNumberTimeout(kRtcpIntervalMs));
  system_clock_.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
  EXPECT_TRUE(rtcp_receiver_->RtcpRrTimeout(kRtcpIntervalMs));
}

TEST_F(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
  // This call is expected to fail because no data has arrived.
  EXPECT_EQ(-1, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
}

TEST_F(RtcpReceiverTest, TwoReportBlocks) {
  const uint32_t kSenderSsrc = 0x10203;
  const int kNumSsrcs = 2;
  const uint32_t kSourceSsrcs[kNumSsrcs] = {0x40506, 0x50607};
  uint32_t sequence_numbers[kNumSsrcs] = {10, 12423};

  std::set<uint32_t> ssrcs(kSourceSsrcs, kSourceSsrcs + kNumSsrcs);
  rtcp_receiver_->SetSsrcs(kSourceSsrcs[0], ssrcs);

  PacketBuilder packet;
  std::list<PacketBuilder::ReportBlock> report_blocks;
  report_blocks.push_back(PacketBuilder::ReportBlock(
      kSourceSsrcs[0], sequence_numbers[0], 10, 5, 0));
  report_blocks.push_back(PacketBuilder::ReportBlock(
      kSourceSsrcs[1], sequence_numbers[1], 0, 0, 0));
  packet.AddRrPacketMultipleReportBlocks(kSenderSsrc, report_blocks);
  EXPECT_EQ(0, InjectRtcpPacket(packet.packet(), packet.length()));
  ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size());
  EXPECT_EQ(10, rtcp_packet_info_.report_blocks.front().fractionLost);
  EXPECT_EQ(0, rtcp_packet_info_.report_blocks.back().fractionLost);

  PacketBuilder packet2;
  report_blocks.clear();
  report_blocks.push_back(PacketBuilder::ReportBlock(
      kSourceSsrcs[0], sequence_numbers[0], 0, 0, 0));
  report_blocks.push_back(PacketBuilder::ReportBlock(
      kSourceSsrcs[1], sequence_numbers[1], 20, 10, 0));
  packet2.AddRrPacketMultipleReportBlocks(kSenderSsrc, report_blocks);
  EXPECT_EQ(0, InjectRtcpPacket(packet2.packet(), packet2.length()));
  ASSERT_EQ(2u, rtcp_packet_info_.report_blocks.size());
  EXPECT_EQ(0, rtcp_packet_info_.report_blocks.front().fractionLost);
  EXPECT_EQ(20, rtcp_packet_info_.report_blocks.back().fractionLost);
}

TEST_F(RtcpReceiverTest, TmmbrPacketAccepted) {
  const uint32_t kMediaFlowSsrc = 0x2040608;
  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kMediaRecipientSsrc = 0x101;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kMediaFlowSsrc);  // Matches "media source" above.
  rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);

  PacketBuilder p;
  p.AddSrPacket(kSenderSsrc);
  // TMMBR packet.
  p.AddRtcpHeader(205, 3);
  p.Add32(kSenderSsrc);
  p.Add32(kMediaRecipientSsrc);
  p.Add32(kMediaFlowSsrc);
  p.AddTmmbrBandwidth(30000, 0, 0);  // 30 Kbits/sec bandwidth, no overhead.

  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
  TMMBRSet candidate_set;
  candidate_set.VerifyAndAllocateSet(1);
  EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(1, 0, &candidate_set));
  EXPECT_LT(0U, candidate_set.Tmmbr(0));
  EXPECT_EQ(kMediaRecipientSsrc, candidate_set.Ssrc(0));
}

TEST_F(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
  const uint32_t kMediaFlowSsrc = 0x2040608;
  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kMediaRecipientSsrc = 0x101;
  const uint32_t kOtherMediaFlowSsrc = 0x9999;

  PacketBuilder p;
  p.AddSrPacket(kSenderSsrc);
  // TMMBR packet.
  p.AddRtcpHeader(205, 3);
  p.Add32(kSenderSsrc);
  p.Add32(kMediaRecipientSsrc);
  p.Add32(kOtherMediaFlowSsrc);  // This SSRC is not what we're sending.
  p.AddTmmbrBandwidth(30000, 0, 0);

  std::set<uint32_t> ssrcs;
  ssrcs.insert(kMediaFlowSsrc);
  rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);
  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
}

TEST_F(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
  const uint32_t kMediaFlowSsrc = 0x2040608;
  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kMediaRecipientSsrc = 0x101;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kMediaFlowSsrc);  // Matches "media source" above.
  rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);

  PacketBuilder p;
  p.AddSrPacket(kSenderSsrc);
  // TMMBR packet.
  p.AddRtcpHeader(205, 3);
  p.Add32(kSenderSsrc);
  p.Add32(kMediaRecipientSsrc);
  p.Add32(kMediaFlowSsrc);
  p.AddTmmbrBandwidth(0, 0, 0);  // Rate zero.

  EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
  EXPECT_EQ(0, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
}

TEST_F(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
  const uint32_t kMediaFlowSsrc = 0x2040608;
  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kMediaRecipientSsrc = 0x101;
  std::set<uint32_t> ssrcs;
  ssrcs.insert(kMediaFlowSsrc);  // Matches "media source" above.
  rtcp_receiver_->SetSsrcs(kMediaFlowSsrc, ssrcs);

  // Inject 3 packets "from" kMediaRecipientSsrc, Ssrc+1, Ssrc+2.
  // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
  for (uint32_t ssrc = kMediaRecipientSsrc;
       ssrc < kMediaRecipientSsrc+3; ++ssrc) {
    PacketBuilder p;
    p.AddSrPacket(kSenderSsrc);
    // TMMBR packet.
    p.AddRtcpHeader(205, 3);
    p.Add32(kSenderSsrc);
    p.Add32(ssrc);
    p.Add32(kMediaFlowSsrc);
    p.AddTmmbrBandwidth(30000, 0, 0);  // 30 Kbits/sec bandwidth, no overhead.

    EXPECT_EQ(0, InjectRtcpPacket(p.packet(), p.length()));
    // 5 seconds between each packet.
    system_clock_.AdvanceTimeMilliseconds(5000);
  }
  // It is now starttime+15.
  EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
  TMMBRSet candidate_set;
  candidate_set.VerifyAndAllocateSet(3);
  EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
  EXPECT_LT(0U, candidate_set.Tmmbr(0));
  // We expect the timeout to be 25 seconds. Advance the clock by 12
  // seconds, timing out the first packet.
  system_clock_.AdvanceTimeMilliseconds(12000);
  // Odd behaviour: Just counting them does not trigger the timeout.
  EXPECT_EQ(3, rtcp_receiver_->TMMBRReceived(0, 0, NULL));
  // Odd behaviour: There's only one left after timeout, not 2.
  EXPECT_EQ(1, rtcp_receiver_->TMMBRReceived(3, 0, &candidate_set));
  EXPECT_EQ(kMediaRecipientSsrc + 2, candidate_set.Ssrc(0));
}

TEST_F(RtcpReceiverTest, Callbacks) {
  class RtcpCallbackImpl : public RtcpStatisticsCallback {
   public:
    RtcpCallbackImpl() : RtcpStatisticsCallback(), ssrc_(0) {}
    virtual ~RtcpCallbackImpl() {}

    virtual void StatisticsUpdated(const RtcpStatistics& statistics,
                                   uint32_t ssrc) {
      stats_ = statistics;
      ssrc_ = ssrc;
    }

    bool Matches(uint32_t ssrc, uint32_t extended_max, uint8_t fraction_loss,
                 uint32_t cumulative_loss, uint32_t jitter) {
      return ssrc_ == ssrc &&
          stats_.fraction_lost == fraction_loss &&
          stats_.cumulative_lost == cumulative_loss &&
          stats_.extended_max_sequence_number == extended_max &&
          stats_.jitter == jitter;
    }

    RtcpStatistics stats_;
    uint32_t ssrc_;
  } callback;

  rtcp_receiver_->RegisterRtcpStatisticsCallback(&callback);

  const uint32_t kSenderSsrc = 0x10203;
  const uint32_t kSourceSsrc = 0x123456;
  const uint8_t fraction_loss = 3;
  const uint32_t cumulative_loss = 7;
  const uint32_t jitter = 9;
  uint32_t sequence_number = 1234;

  std::set<uint32_t> ssrcs;
  ssrcs.insert(kSourceSsrc);
  rtcp_receiver_->SetSsrcs(kSourceSsrc, ssrcs);

  // First packet, all numbers should just propagate
  PacketBuilder p1;
  p1.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number,
                 fraction_loss, cumulative_loss, jitter);
  EXPECT_EQ(0, InjectRtcpPacket(p1.packet(), p1.length()));
  EXPECT_TRUE(callback.Matches(kSourceSsrc, sequence_number, fraction_loss,
                               cumulative_loss, jitter));

  rtcp_receiver_->RegisterRtcpStatisticsCallback(NULL);

  // Add arbitrary numbers, callback should not be called (retain old values)
  PacketBuilder p2;
  p2.AddRrPacket(kSenderSsrc, kSourceSsrc, sequence_number + 1, 42, 137, 4711);
  EXPECT_EQ(0, InjectRtcpPacket(p2.packet(), p2.length()));
  EXPECT_TRUE(callback.Matches(kSourceSsrc, sequence_number, fraction_loss,
                               cumulative_loss, jitter));
}

}  // Anonymous namespace

}  // namespace webrtc
