/*
 *  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.
 */

#include "modules/rtp_rtcp/source/rtcp_receiver.h"

#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/environment/environment_factory.h"
#include "api/units/data_rate.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/video_bitrate_allocation.h"
#include "api/video/video_bitrate_allocator.h"
#include "api/video/video_codec_constants.h"
#include "modules/rtp_rtcp/include/report_block_data.h"
#include "modules/rtp_rtcp/include/rtcp_statistics.h"
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
#include "modules/rtp_rtcp/mocks/mock_network_link_rtcp_observer.h"
#include "modules/rtp_rtcp/source/byte_io.h"
#include "modules/rtp_rtcp/source/ntp_time_util.h"
#include "modules/rtp_rtcp/source/rtcp_packet/app.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"
#include "modules/rtp_rtcp/source/rtcp_packet/compound_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/congestion_control_feedback.h"
#include "modules/rtp_rtcp/source/rtcp_packet/dlrr.h"
#include "modules/rtp_rtcp/source/rtcp_packet/extended_reports.h"
#include "modules/rtp_rtcp/source/rtcp_packet/fir.h"
#include "modules/rtp_rtcp/source/rtcp_packet/nack.h"
#include "modules/rtp_rtcp/source/rtcp_packet/pli.h"
#include "modules/rtp_rtcp/source/rtcp_packet/rapid_resync_request.h"
#include "modules/rtp_rtcp/source/rtcp_packet/receiver_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/remb.h"
#include "modules/rtp_rtcp/source/rtcp_packet/rtpfb.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sdes.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtcp_packet/tmmbr.h"
#include "modules/rtp_rtcp/source/rtcp_packet/transport_feedback.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/buffer.h"
#include "rtc_base/random.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/clock.h"
#include "system_wrappers/include/ntp_time.h"
#include "test/explicit_key_value_config.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using rtcp::ReceiveTimeInfo;
using ::testing::_;
using ::testing::AllOf;
using ::testing::ElementsAre;
using ::testing::ElementsAreArray;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Gt;
using ::testing::InSequence;
using ::testing::IsEmpty;
using ::testing::NiceMock;
using ::testing::Property;
using ::testing::SizeIs;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::UnorderedElementsAre;
using ::webrtc::test::ExplicitKeyValueConfig;

class MockRtcpPacketTypeCounterObserver : public RtcpPacketTypeCounterObserver {
 public:
  MOCK_METHOD(void,
              RtcpPacketTypesCounterUpdated,
              (uint32_t, const RtcpPacketTypeCounter&),
              (override));
};

class MockRtcpIntraFrameObserver : public RtcpIntraFrameObserver {
 public:
  MOCK_METHOD(void, OnReceivedIntraFrameRequest, (uint32_t), (override));
};

class MockRtcpLossNotificationObserver : public RtcpLossNotificationObserver {
 public:
  ~MockRtcpLossNotificationObserver() override = default;
  MOCK_METHOD(void,
              OnReceivedLossNotification,
              (uint32_t ssrc,
               uint16_t seq_num_of_last_decodable,
               uint16_t seq_num_of_last_received,
               bool decodability_flag),
              (override));
};

class MockCnameCallbackImpl : public RtcpCnameCallback {
 public:
  MOCK_METHOD(void, OnCname, (uint32_t, absl::string_view), (override));
};

class MockReportBlockDataObserverImpl : public ReportBlockDataObserver {
 public:
  MOCK_METHOD(void, OnReportBlockDataUpdated, (ReportBlockData), (override));
};

class MockModuleRtpRtcp : public RTCPReceiver::ModuleRtpRtcp {
 public:
  MOCK_METHOD(void, SetTmmbn, (std::vector<rtcp::TmmbItem>), (override));
  MOCK_METHOD(void, OnRequestSendReport, (), (override));
  MOCK_METHOD(void, OnReceivedNack, (const std::vector<uint16_t>&), (override));
  MOCK_METHOD(void,
              OnReceivedRtcpReportBlocks,
              (rtc::ArrayView<const ReportBlockData>),
              (override));
};

class MockVideoBitrateAllocationObserver
    : public VideoBitrateAllocationObserver {
 public:
  MOCK_METHOD(void,
              OnBitrateAllocationUpdated,
              (const VideoBitrateAllocation& allocation),
              (override));
};

MATCHER_P2(Near, value, margin, "") {
  return value - margin <= arg && arg <= value + margin;
}

// SSRC of remote peer, that sends rtcp packet to the rtcp receiver under test.
constexpr uint32_t kSenderSsrc = 0x10203;
// SSRCs of local peer, that rtcp packet addressed to.
constexpr uint32_t kReceiverMainSsrc = 0x123456;
// RtcpReceiver can accept several ssrc, e.g. regular and rtx streams.
constexpr uint32_t kReceiverExtraSsrc = 0x1234567;
// SSRCs to ignore (i.e. not configured in RtcpReceiver).
constexpr uint32_t kNotToUsSsrc = 0x654321;
constexpr uint32_t kUnknownSenderSsrc = 0x54321;

constexpr int64_t kRtcpIntervalMs = 1000;
constexpr TimeDelta kEpsilon = TimeDelta::Millis(1);

}  // namespace

struct ReceiverMocks {
  SimulatedClock clock{1335900000};
  std::string field_trials;
  // Callbacks to packet_type_counter_observer are frequent but most of the time
  // are not interesting.
  NiceMock<MockRtcpPacketTypeCounterObserver> packet_type_counter_observer;
  StrictMock<MockRtcpIntraFrameObserver> intra_frame_observer;
  StrictMock<MockRtcpLossNotificationObserver> rtcp_loss_notification_observer;
  StrictMock<MockVideoBitrateAllocationObserver> bitrate_allocation_observer;
  StrictMock<MockModuleRtpRtcp> rtp_rtcp_impl;
  NiceMock<MockNetworkLinkRtcpObserver> network_link_rtcp_observer;

  RtpRtcpInterface::Configuration config = {
      .receiver_only = false,
      .intra_frame_callback = &intra_frame_observer,
      .rtcp_loss_notification_observer = &rtcp_loss_notification_observer,
      .network_link_rtcp_observer = &network_link_rtcp_observer,
      .bitrate_allocation_observer = &bitrate_allocation_observer,
      .rtcp_packet_type_counter_observer = &packet_type_counter_observer,
      .rtcp_report_interval_ms = kRtcpIntervalMs,
      .local_media_ssrc = kReceiverMainSsrc,
      .rtx_send_ssrc = kReceiverExtraSsrc};
};

RTCPReceiver Create(ReceiverMocks& mocks) {
  return RTCPReceiver(
      CreateEnvironment(
          &mocks.clock,
          std::make_unique<test::ExplicitKeyValueConfig>(mocks.field_trials)),
      mocks.config, &mocks.rtp_rtcp_impl);
}

TEST(RtcpReceiverTest, BrokenPacketIsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);

  const uint8_t bad_packet[] = {0, 0, 0, 0};
  EXPECT_CALL(mocks.packet_type_counter_observer, RtcpPacketTypesCounterUpdated)
      .Times(0);
  receiver.IncomingPacket(bad_packet);
}

TEST(RtcpReceiverTest, InvalidFeedbackPacketIsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);

  // Too short feedback packet.
  const uint8_t bad_packet[] = {0x81, rtcp::Rtpfb::kPacketType, 0, 0};

  EXPECT_CALL(mocks.packet_type_counter_observer, RtcpPacketTypesCounterUpdated)
      .Times(0);
  receiver.IncomingPacket(bad_packet);
}

TEST(RtcpReceiverTest, InjectSrPacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  EXPECT_FALSE(receiver.GetSenderReportStats());

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(IsEmpty()));
  receiver.IncomingPacket(sr.Build());

  EXPECT_TRUE(receiver.GetSenderReportStats());
}

TEST(RtcpReceiverTest, InjectSrPacketFromUnknownSender) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kUnknownSenderSsrc);

  // The parser will handle report blocks in Sender Report from other than their
  // expected peer.
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(sr.Build());

  // But will not flag that he's gotten sender information.
  EXPECT_FALSE(receiver.GetSenderReportStats());
}

TEST(RtcpReceiverTest, InjectSrPacketCalculatesRTT) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const TimeDelta kRtt = TimeDelta::Millis(123);
  const uint32_t kDelayNtp = 0x4321;
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);

  EXPECT_EQ(receiver.LastRtt(), std::nullopt);

  uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  rtcp::ReportBlock block;
  block.SetMediaSsrc(kReceiverMainSsrc);
  block.SetLastSr(sent_ntp);
  block.SetDelayLastSr(kDelayNtp);
  sr.AddReportBlock(block);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnRttUpdate);
  receiver.IncomingPacket(sr.Build());

  EXPECT_THAT(receiver.LastRtt(), Near(kRtt, TimeDelta::Millis(1)));
}

TEST(RtcpReceiverTest, InjectSrPacketCalculatesNegativeRTTAsOneMs) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const TimeDelta kRtt = TimeDelta::Millis(-13);
  const uint32_t kDelayNtp = 0x4321;
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);

  EXPECT_EQ(receiver.LastRtt(), std::nullopt);

  uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  rtcp::ReportBlock block;
  block.SetMediaSsrc(kReceiverMainSsrc);
  block.SetLastSr(sent_ntp);
  block.SetDelayLastSr(kDelayNtp);
  sr.AddReportBlock(block);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(1)));
  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnRttUpdate(_, TimeDelta::Millis(1)));
  receiver.IncomingPacket(sr.Build());

  EXPECT_EQ(receiver.LastRtt(), TimeDelta::Millis(1));
}

TEST(RtcpReceiverTest, TwoReportBlocksWithLastOneWithoutLastSrCalculatesRtt) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const TimeDelta kRtt = TimeDelta::Millis(125);
  const uint32_t kDelayNtp = 123000;
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);

  uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  rtcp::ReportBlock block;
  block.SetMediaSsrc(kReceiverMainSsrc);
  block.SetLastSr(sent_ntp);
  block.SetDelayLastSr(kDelayNtp);
  sr.AddReportBlock(block);
  block.SetMediaSsrc(kReceiverExtraSsrc);
  block.SetLastSr(0);
  sr.AddReportBlock(block);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(2)));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnRttUpdate(_, kRtt));
  receiver.IncomingPacket(sr.Build());
}

TEST(RtcpReceiverTest, InjectRrPacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(IsEmpty()));
  receiver.IncomingPacket(rr.Build());

  EXPECT_THAT(receiver.GetLatestReportBlockData(), IsEmpty());
}

TEST(RtcpReceiverTest, InjectRrPacketWithReportBlockNotToUsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ReportBlock rb;
  rb.SetMediaSsrc(kNotToUsSsrc);
  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.AddReportBlock(rb);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(IsEmpty()));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReport).Times(0);
  receiver.IncomingPacket(rr.Build());

  EXPECT_EQ(0, receiver.LastReceivedReportBlockMs());
  EXPECT_THAT(receiver.GetLatestReportBlockData(), IsEmpty());
}

TEST(RtcpReceiverTest, InjectRrPacketWithOneReportBlock) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Timestamp now = mocks.clock.CurrentTime();

  rtcp::ReportBlock rb;
  rb.SetMediaSsrc(kReceiverMainSsrc);
  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.AddReportBlock(rb);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(1)));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReport(now, SizeIs(1)));
  receiver.IncomingPacket(rr.Build());

  EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
  EXPECT_THAT(receiver.GetLatestReportBlockData(), SizeIs(1));
}

TEST(RtcpReceiverTest, InjectSrPacketWithOneReportBlock) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Timestamp now = mocks.clock.CurrentTime();

  rtcp::ReportBlock rb;
  rb.SetMediaSsrc(kReceiverMainSsrc);
  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  sr.AddReportBlock(rb);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(1)));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReport(now, SizeIs(1)));
  receiver.IncomingPacket(sr.Build());

  EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
  EXPECT_THAT(receiver.GetLatestReportBlockData(), SizeIs(1));
}

TEST(RtcpReceiverTest, InjectRrPacketWithTwoReportBlocks) {
  const uint16_t kSequenceNumbers[] = {10, 12423};
  const uint32_t kCumLost[] = {13, 555};
  const uint8_t kFracLost[] = {20, 11};
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Timestamp now = mocks.clock.CurrentTime();

  rtcp::ReportBlock rb1;
  rb1.SetMediaSsrc(kReceiverMainSsrc);
  rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
  rb1.SetFractionLost(10);

  rtcp::ReportBlock rb2;
  rb2.SetMediaSsrc(kReceiverExtraSsrc);
  rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
  rb2.SetFractionLost(0);

  rtcp::ReceiverReport rr1;
  rr1.SetSenderSsrc(kSenderSsrc);
  rr1.AddReportBlock(rb1);
  rr1.AddReportBlock(rb2);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(2)));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReport(now, SizeIs(2)));
  receiver.IncomingPacket(rr1.Build());

  EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
  EXPECT_THAT(
      receiver.GetLatestReportBlockData(),
      UnorderedElementsAre(Property(&ReportBlockData::fraction_lost_raw, 0),
                           Property(&ReportBlockData::fraction_lost_raw, 10)));

  // Insert next receiver report with same ssrc but new values.
  rtcp::ReportBlock rb3;
  rb3.SetMediaSsrc(kReceiverMainSsrc);
  rb3.SetExtHighestSeqNum(kSequenceNumbers[0]);
  rb3.SetFractionLost(kFracLost[0]);
  rb3.SetCumulativeLost(kCumLost[0]);

  rtcp::ReportBlock rb4;
  rb4.SetMediaSsrc(kReceiverExtraSsrc);
  rb4.SetExtHighestSeqNum(kSequenceNumbers[1]);
  rb4.SetFractionLost(kFracLost[1]);
  rb4.SetCumulativeLost(kCumLost[1]);

  rtcp::ReceiverReport rr2;
  rr2.SetSenderSsrc(kSenderSsrc);
  rr2.AddReportBlock(rb3);
  rr2.AddReportBlock(rb4);

  // Advance time to make 1st sent time and 2nd sent time different.
  mocks.clock.AdvanceTimeMilliseconds(500);
  now = mocks.clock.CurrentTime();

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(2)));
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReport(now, SizeIs(2)));
  receiver.IncomingPacket(rr2.Build());

  EXPECT_THAT(
      receiver.GetLatestReportBlockData(),
      UnorderedElementsAre(
          AllOf(Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
                Property(&ReportBlockData::fraction_lost_raw, kFracLost[0]),
                Property(&ReportBlockData::cumulative_lost, kCumLost[0]),
                Property(&ReportBlockData::extended_highest_sequence_number,
                         kSequenceNumbers[0])),
          AllOf(Property(&ReportBlockData::source_ssrc, kReceiverExtraSsrc),
                Property(&ReportBlockData::fraction_lost_raw, kFracLost[1]),
                Property(&ReportBlockData::cumulative_lost, kCumLost[1]),
                Property(&ReportBlockData::extended_highest_sequence_number,
                         kSequenceNumbers[1]))));
}

TEST(RtcpReceiverTest,
     InjectRrPacketsFromTwoRemoteSsrcsReturnsLatestReportBlock) {
  const uint32_t kSenderSsrc2 = 0x20304;
  const uint16_t kSequenceNumbers[] = {10, 12423};
  const int32_t kCumLost[] = {13, 555};
  const uint8_t kFracLost[] = {20, 11};
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ReportBlock rb1;
  rb1.SetMediaSsrc(kReceiverMainSsrc);
  rb1.SetExtHighestSeqNum(kSequenceNumbers[0]);
  rb1.SetFractionLost(kFracLost[0]);
  rb1.SetCumulativeLost(kCumLost[0]);
  rtcp::ReceiverReport rr1;
  rr1.SetSenderSsrc(kSenderSsrc);
  rr1.AddReportBlock(rb1);

  Timestamp now = mocks.clock.CurrentTime();

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(1)));
  receiver.IncomingPacket(rr1.Build());

  EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());

  EXPECT_THAT(receiver.GetLatestReportBlockData(),
              ElementsAre(AllOf(
                  Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
                  Property(&ReportBlockData::sender_ssrc, kSenderSsrc),
                  Property(&ReportBlockData::fraction_lost_raw, kFracLost[0]),
                  Property(&ReportBlockData::cumulative_lost, kCumLost[0]),
                  Property(&ReportBlockData::extended_highest_sequence_number,
                           kSequenceNumbers[0]))));

  rtcp::ReportBlock rb2;
  rb2.SetMediaSsrc(kReceiverMainSsrc);
  rb2.SetExtHighestSeqNum(kSequenceNumbers[1]);
  rb2.SetFractionLost(kFracLost[1]);
  rb2.SetCumulativeLost(kCumLost[1]);
  rtcp::ReceiverReport rr2;
  rr2.SetSenderSsrc(kSenderSsrc2);
  rr2.AddReportBlock(rb2);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(1)));
  receiver.IncomingPacket(rr2.Build());

  EXPECT_THAT(receiver.GetLatestReportBlockData(),
              UnorderedElementsAre(AllOf(
                  Property(&ReportBlockData::source_ssrc, kReceiverMainSsrc),
                  Property(&ReportBlockData::sender_ssrc, kSenderSsrc2),
                  Property(&ReportBlockData::fraction_lost_raw, kFracLost[1]),
                  Property(&ReportBlockData::cumulative_lost, kCumLost[1]),
                  Property(&ReportBlockData::extended_highest_sequence_number,
                           kSequenceNumbers[1]))));
}

TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnReportBlocks) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ReportBlock rb1;
  rb1.SetMediaSsrc(kReceiverMainSsrc);
  rb1.SetFractionLost(10);

  rtcp::ReportBlock rb2;
  rb2.SetMediaSsrc(kNotToUsSsrc);
  rb2.SetFractionLost(20);

  rtcp::ReportBlock rb3;
  rb3.SetMediaSsrc(kReceiverExtraSsrc);
  rb3.SetFractionLost(0);

  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.AddReportBlock(rb1);
  rr.AddReportBlock(rb2);
  rr.AddReportBlock(rb3);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks(SizeIs(2)));
  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnReport(mocks.clock.CurrentTime(),
                       UnorderedElementsAre(
                           Property(&ReportBlockData::fraction_lost_raw, 0),
                           Property(&ReportBlockData::fraction_lost_raw, 10))));
  receiver.IncomingPacket(rr.Build());
}

TEST(RtcpReceiverTest, GetRtt) {
  const uint32_t kSentCompactNtp = 0x1234;
  const uint32_t kDelayCompactNtp = 0x222;
  ReceiverMocks mocks;
  mocks.config.network_link_rtcp_observer = &mocks.network_link_rtcp_observer;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  // No report block received.
  EXPECT_EQ(receiver.LastRtt(), std::nullopt);
  EXPECT_EQ(receiver.AverageRtt(), std::nullopt);

  rtcp::ReportBlock rb;
  rb.SetMediaSsrc(kReceiverMainSsrc);
  rb.SetLastSr(kSentCompactNtp);
  rb.SetDelayLastSr(kDelayCompactNtp);

  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.AddReportBlock(rb);

  Timestamp now = mocks.clock.CurrentTime();
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnRttUpdate(now, Gt(TimeDelta::Zero())));
  receiver.IncomingPacket(rr.Build());

  EXPECT_EQ(receiver.LastReceivedReportBlockMs(), now.ms());
  EXPECT_NE(receiver.LastRtt(), std::nullopt);
  EXPECT_NE(receiver.AverageRtt(), std::nullopt);
}

// App packets are ignored.
TEST(RtcpReceiverTest, InjectApp) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::App app;
  app.SetSubType(30);
  app.SetName(0x17a177e);
  const uint8_t kData[] = {'t', 'e', 's', 't', 'd', 'a', 't', 'a'};
  app.SetData(kData, sizeof(kData));

  receiver.IncomingPacket(app.Build());
}

TEST(RtcpReceiverTest, InjectSdesWithOneChunk) {
  ReceiverMocks mocks;
  MockCnameCallbackImpl callback;
  mocks.config.rtcp_cname_callback = &callback;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const char kCname[] = "alice@host";
  rtcp::Sdes sdes;
  sdes.AddCName(kSenderSsrc, kCname);

  EXPECT_CALL(callback, OnCname(kSenderSsrc, StrEq(kCname)));
  receiver.IncomingPacket(sdes.Build());
}

TEST(RtcpReceiverTest, InjectByePacketRemovesReportBlocks) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ReportBlock rb1;
  rb1.SetMediaSsrc(kReceiverMainSsrc);
  rtcp::ReportBlock rb2;
  rb2.SetMediaSsrc(kReceiverExtraSsrc);
  rtcp::ReceiverReport rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.AddReportBlock(rb1);
  rr.AddReportBlock(rb2);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr.Build());

  EXPECT_THAT(receiver.GetLatestReportBlockData(), SizeIs(2));

  // Verify that BYE removes the report blocks.
  rtcp::Bye bye;
  bye.SetSenderSsrc(kSenderSsrc);

  receiver.IncomingPacket(bye.Build());

  EXPECT_THAT(receiver.GetLatestReportBlockData(), IsEmpty());

  // Inject packet again.
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr.Build());

  EXPECT_THAT(receiver.GetLatestReportBlockData(), SizeIs(2));
}

TEST(RtcpReceiverTest, InjectByePacketRemovesReferenceTimeInfo) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  rtcp::Rrtr rrtr;
  rrtr.SetNtp(NtpTime(0x10203, 0x40506));
  xr.SetRrtr(rrtr);
  receiver.IncomingPacket(xr.Build());

  rtcp::Bye bye;
  bye.SetSenderSsrc(kSenderSsrc);
  receiver.IncomingPacket(bye.Build());

  EXPECT_THAT(receiver.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
}

TEST(RtcpReceiverTest, InjectPliPacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Pli pli;
  pli.SetMediaSsrc(kReceiverMainSsrc);

  EXPECT_CALL(
      mocks.packet_type_counter_observer,
      RtcpPacketTypesCounterUpdated(
          kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 1)));
  EXPECT_CALL(mocks.intra_frame_observer,
              OnReceivedIntraFrameRequest(kReceiverMainSsrc));
  receiver.IncomingPacket(pli.Build());
}

TEST(RtcpReceiverTest, PliPacketNotToUsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Pli pli;
  pli.SetMediaSsrc(kNotToUsSsrc);

  EXPECT_CALL(
      mocks.packet_type_counter_observer,
      RtcpPacketTypesCounterUpdated(
          kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::pli_packets, 0)));
  EXPECT_CALL(mocks.intra_frame_observer, OnReceivedIntraFrameRequest).Times(0);
  receiver.IncomingPacket(pli.Build());
}

TEST(RtcpReceiverTest, InjectFirPacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Fir fir;
  fir.AddRequestTo(kReceiverMainSsrc, 13);

  EXPECT_CALL(
      mocks.packet_type_counter_observer,
      RtcpPacketTypesCounterUpdated(
          kReceiverMainSsrc, Field(&RtcpPacketTypeCounter::fir_packets, 1)));
  EXPECT_CALL(mocks.intra_frame_observer,
              OnReceivedIntraFrameRequest(kReceiverMainSsrc));
  receiver.IncomingPacket(fir.Build());
}

TEST(RtcpReceiverTest, FirPacketNotToUsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Fir fir;
  fir.AddRequestTo(kNotToUsSsrc, 13);

  EXPECT_CALL(mocks.intra_frame_observer, OnReceivedIntraFrameRequest).Times(0);
  receiver.IncomingPacket(fir.Build());
}

TEST(RtcpReceiverTest, ExtendedReportsPacketWithZeroReportBlocksIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);

  receiver.IncomingPacket(xr.Build());
}

TEST(RtcpReceiverTest, InjectExtendedReportsReceiverReferenceTimePacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const NtpTime kNtp(0x10203, 0x40506);
  rtcp::Rrtr rrtr;
  rrtr.SetNtp(kNtp);
  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.SetRrtr(rrtr);

  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  EXPECT_THAT(last_xr_rtis, IsEmpty());

  receiver.IncomingPacket(xr.Build());

  last_xr_rtis = receiver.ConsumeReceivedXrReferenceTimeInfo();
  ASSERT_THAT(last_xr_rtis, SizeIs(1));
  EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
  EXPECT_EQ(CompactNtp(kNtp), last_xr_rtis[0].last_rr);
  EXPECT_EQ(0U, last_xr_rtis[0].delay_since_last_rr);
}

TEST(RtcpReceiverTest, ExtendedReportsDlrrPacketNotToUsIgnored) {
  ReceiverMocks mocks;
  // Allow calculate rtt using dlrr/rrtr, simulating media receiver side.
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kNotToUsSsrc, 0x12345, 0x67890));

  receiver.IncomingPacket(xr.Build());

  EXPECT_FALSE(receiver.GetAndResetXrRrRtt());
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_TRUE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithSubBlock) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint32_t kLastRR = 0x12345;
  const uint32_t kDelay = 0x23456;
  EXPECT_FALSE(receiver.GetAndResetXrRrRtt());

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));

  receiver.IncomingPacket(xr.Build());

  uint32_t compact_ntp_now = CompactNtp(mocks.clock.CurrentNtpTime());
  uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
  EXPECT_THAT(receiver.GetAndResetXrRrRtt(),
              Near(CompactNtpRttToTimeDelta(rtt_ntp), kEpsilon));
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_GT(non_sender_rtt_stats.round_trip_time(), TimeDelta::Zero());
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, InjectExtendedReportsDlrrPacketWithMultipleSubBlocks) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint32_t kLastRR = 0x12345;
  const uint32_t kDelay = 0x56789;

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, kLastRR, kDelay));
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 1, 0x12345, 0x67890));
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc + 2, 0x12345, 0x67890));

  receiver.IncomingPacket(xr.Build());

  uint32_t compact_ntp_now = CompactNtp(mocks.clock.CurrentNtpTime());
  uint32_t rtt_ntp = compact_ntp_now - kDelay - kLastRR;
  EXPECT_THAT(receiver.GetAndResetXrRrRtt(),
              Near(CompactNtpRttToTimeDelta(rtt_ntp), kEpsilon));
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_GT(non_sender_rtt_stats.round_trip_time(), TimeDelta::Zero());
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, InjectExtendedReportsPacketWithMultipleReportBlocks) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Rrtr rrtr;
  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.SetRrtr(rrtr);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));

  receiver.IncomingPacket(xr.Build());

  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  EXPECT_THAT(last_xr_rtis, SizeIs(1));
  EXPECT_TRUE(receiver.GetAndResetXrRrRtt());
}

TEST(RtcpReceiverTest, InjectExtendedReportsPacketWithUnknownReportBlock) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Rrtr rrtr;
  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.SetRrtr(rrtr);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0x12345, 0x67890));

  rtc::Buffer packet = xr.Build();
  // Modify the DLRR block to have an unsupported block type, from 5 to 6.
  ASSERT_EQ(5, packet.data()[20]);
  packet.data()[20] = 6;
  receiver.IncomingPacket(packet);

  // Validate Rrtr was received and processed.
  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  EXPECT_THAT(last_xr_rtis, SizeIs(1));
  // Validate Dlrr report wasn't processed.
  EXPECT_FALSE(receiver.GetAndResetXrRrRtt());
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_TRUE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, TestExtendedReportsRrRttInitiallyFalse) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  EXPECT_FALSE(receiver.GetAndResetXrRrRtt());
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_TRUE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, RttCalculatedAfterExtendedReportsDlrr) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  EXPECT_THAT(receiver.GetAndResetXrRrRtt(), Near(kRtt, kEpsilon));
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().value().IsZero());
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

// Same test as above but enables receive-side RTT using the setter instead of
// the config struct.
TEST(RtcpReceiverTest, SetterEnablesReceiverRtt) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = false;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);
  receiver.SetNonSenderRttMeasurement(true);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  EXPECT_THAT(receiver.GetAndResetXrRrRtt(), Near(kRtt, kEpsilon));
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().value().IsZero());
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

// Same test as above but disables receive-side RTT using the setter instead of
// the config struct.
TEST(RtcpReceiverTest, DoesntCalculateRttOnReceivedDlrr) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);
  receiver.SetNonSenderRttMeasurement(false);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  // We expect that no RTT is available (because receive-side RTT was disabled).
  EXPECT_FALSE(receiver.GetAndResetXrRrRtt());
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_TRUE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, XrDlrrCalculatesNegativeRttAsOneMillisecond) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(-3600 * 1000, -1));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  EXPECT_EQ(receiver.GetAndResetXrRrRtt(), TimeDelta::Millis(1));
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().value().IsZero());
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);
}

// Test receiver RTT stats with multiple measurements.
TEST(RtcpReceiverTest, ReceiverRttWithMultipleMeasurements) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  // Check that the non-sender RTT stats are valid and based on a single
  // measurement.
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats.round_trip_time()->ms(), kRtt.ms(), 1);
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 1);
  EXPECT_EQ(non_sender_rtt_stats.total_round_trip_time().ms(),
            non_sender_rtt_stats.round_trip_time()->ms());

  // Generate another XR report with the same RTT and delay.
  NtpTime now2 = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp2 = CompactNtp(now2);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr2;
  xr2.SetSenderSsrc(kSenderSsrc);
  xr2.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp2, kDelayNtp));

  receiver.IncomingPacket(xr2.Build());

  // Check that the non-sender RTT stats are based on 2 measurements, and that
  // the values are as expected.
  non_sender_rtt_stats = receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats.round_trip_time()->ms(), kRtt.ms(), 1);
  EXPECT_EQ(non_sender_rtt_stats.round_trip_time_measurements(), 2);
  EXPECT_NEAR(non_sender_rtt_stats.total_round_trip_time().ms(), 2 * kRtt.ms(),
              2);
}

// Test that the receiver RTT stat resets when receiving a SR without XR. This
// behavior is described in the standard, see
// https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime.
TEST(RtcpReceiverTest, ReceiverRttResetOnSrWithoutXr) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats.round_trip_time()->ms(), kRtt.ms(), 1);

  // Generate a SR without XR.
  rtcp::ReportBlock rb;
  rb.SetMediaSsrc(kReceiverMainSsrc);
  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  sr.AddReportBlock(rb);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);

  receiver.IncomingPacket(sr.Build());

  // Check that the non-sender RTT stat is not set.
  non_sender_rtt_stats = receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
}

// Test that the receiver RTT stat resets when receiving a DLRR with a timestamp
// of zero. This behavior is described in the standard, see
// https://www.w3.org/TR/webrtc-stats/#dom-rtcremoteoutboundrtpstreamstats-roundtriptime.
TEST(RtcpReceiverTest, ReceiverRttResetOnDlrrWithZeroTimestamp) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = true;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats.round_trip_time()->ms(), kRtt.ms(), 1);

  // Generate an XR+DLRR with zero timestamp.
  rtcp::ExtendedReports xr2;
  xr2.SetSenderSsrc(kSenderSsrc);
  xr2.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, 0, kDelayNtp));

  receiver.IncomingPacket(xr2.Build());

  // Check that the non-sender RTT stat is not set.
  non_sender_rtt_stats = receiver.GetNonSenderRTT();
  EXPECT_FALSE(non_sender_rtt_stats.round_trip_time().has_value());
}

// Check that the receiver RTT works correctly when the remote SSRC changes.
TEST(RtcpReceiverTest, ReceiverRttWithMultipleRemoteSsrcs) {
  ReceiverMocks mocks;
  mocks.config.non_sender_rtt_measurement = false;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);
  receiver.SetNonSenderRttMeasurement(true);

  Random rand(0x0123456789abcdef);
  const TimeDelta kRtt = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);
  NtpTime now = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp = CompactNtp(now);
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp, kDelayNtp));

  receiver.IncomingPacket(xr.Build());

  // Generate an XR report for another SSRC.
  const TimeDelta kRtt2 = TimeDelta::Millis(rand.Rand(1, 9 * 3600 * 1000));
  const uint32_t kDelayNtp2 = rand.Rand(0, 0x7fffffff);
  const TimeDelta kDelay2 = CompactNtpRttToTimeDelta(kDelayNtp2);
  NtpTime now2 = mocks.clock.CurrentNtpTime();
  uint32_t sent_ntp2 = CompactNtp(now2);
  mocks.clock.AdvanceTime(kRtt2 + kDelay2);

  rtcp::ExtendedReports xr2;
  xr2.SetSenderSsrc(kSenderSsrc + 1);
  xr2.AddDlrrItem(ReceiveTimeInfo(kReceiverMainSsrc, sent_ntp2, kDelayNtp2));

  receiver.IncomingPacket(xr2.Build());

  // Check that the non-sender RTT stats match the first XR.
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats.round_trip_time()->ms(), kRtt.ms(), 1);
  EXPECT_FALSE(non_sender_rtt_stats.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats.round_trip_time_measurements(), 0);

  // Change the remote SSRC and check that the stats match the second XR.
  receiver.SetRemoteSSRC(kSenderSsrc + 1);
  RTCPReceiver::NonSenderRttStats non_sender_rtt_stats2 =
      receiver.GetNonSenderRTT();
  EXPECT_TRUE(non_sender_rtt_stats2.round_trip_time().has_value());
  EXPECT_NEAR(non_sender_rtt_stats2.round_trip_time()->ms(), kRtt2.ms(), 1);
  EXPECT_FALSE(non_sender_rtt_stats2.total_round_trip_time().IsZero());
  EXPECT_GT(non_sender_rtt_stats2.round_trip_time_measurements(), 0);
}

TEST(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfoInitiallyEmpty) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  EXPECT_THAT(receiver.ConsumeReceivedXrReferenceTimeInfo(), IsEmpty());
}

TEST(RtcpReceiverTest, ConsumeReceivedXrReferenceTimeInfo) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const NtpTime kNtp(0x10203, 0x40506);
  const uint32_t kNtpMid = CompactNtp(kNtp);

  rtcp::Rrtr rrtr;
  rrtr.SetNtp(kNtp);
  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  xr.SetRrtr(rrtr);

  receiver.IncomingPacket(xr.Build());

  mocks.clock.AdvanceTimeMilliseconds(1000);

  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  ASSERT_THAT(last_xr_rtis, SizeIs(1));
  EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
  EXPECT_EQ(kNtpMid, last_xr_rtis[0].last_rr);
  EXPECT_EQ(65536U, last_xr_rtis[0].delay_since_last_rr);
}

TEST(RtcpReceiverTest,
     ReceivedRrtrFromSameSsrcUpdatesReceivedReferenceTimeInfo) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const NtpTime kNtp1(0x10203, 0x40506);
  const NtpTime kNtp2(0x11223, 0x44556);
  const int64_t kDelayMs = 2000;

  rtcp::ExtendedReports xr;
  xr.SetSenderSsrc(kSenderSsrc);
  rtcp::Rrtr rrtr1;
  rrtr1.SetNtp(kNtp1);
  xr.SetRrtr(rrtr1);
  receiver.IncomingPacket(xr.Build());
  mocks.clock.AdvanceTimeMilliseconds(kDelayMs);
  rtcp::Rrtr rrtr2;
  rrtr2.SetNtp(kNtp2);
  xr.SetRrtr(rrtr2);
  receiver.IncomingPacket(xr.Build());
  mocks.clock.AdvanceTimeMilliseconds(kDelayMs);

  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  ASSERT_THAT(last_xr_rtis, SizeIs(1));
  EXPECT_EQ(kSenderSsrc, last_xr_rtis[0].ssrc);
  EXPECT_EQ(CompactNtp(kNtp2), last_xr_rtis[0].last_rr);
  EXPECT_EQ(kDelayMs * 65536 / 1000, last_xr_rtis[0].delay_since_last_rr);
}

TEST(RtcpReceiverTest, StoresLastReceivedRrtrPerSsrc) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const size_t kNumBufferedReports = 1;
  const size_t kNumReports =
      rtcp::ExtendedReports::kMaxNumberOfDlrrItems + kNumBufferedReports;
  for (size_t i = 0; i < kNumReports; ++i) {
    rtcp::ExtendedReports xr;
    xr.SetSenderSsrc(i * 100);
    rtcp::Rrtr rrtr;
    rrtr.SetNtp(NtpTime(i * 200, i * 300));
    xr.SetRrtr(rrtr);
    receiver.IncomingPacket(xr.Build());
    mocks.clock.AdvanceTimeMilliseconds(1000);
  }

  std::vector<rtcp::ReceiveTimeInfo> last_xr_rtis =
      receiver.ConsumeReceivedXrReferenceTimeInfo();
  ASSERT_THAT(last_xr_rtis,
              SizeIs(rtcp::ExtendedReports::kMaxNumberOfDlrrItems));
  for (size_t i = 0; i < rtcp::ExtendedReports::kMaxNumberOfDlrrItems; ++i) {
    EXPECT_EQ(i * 100, last_xr_rtis[i].ssrc);
    EXPECT_EQ(CompactNtp(NtpTime(i * 200, i * 300)), last_xr_rtis[i].last_rr);
    EXPECT_EQ(65536U * (kNumReports - i), last_xr_rtis[i].delay_since_last_rr);
  }

  last_xr_rtis = receiver.ConsumeReceivedXrReferenceTimeInfo();
  ASSERT_THAT(last_xr_rtis, SizeIs(kNumBufferedReports));
}

TEST(RtcpReceiverTest, ReceiveReportTimeout) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kSequenceNumber = 1234;
  mocks.clock.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);

  // No RR received, shouldn't trigger a timeout.
  EXPECT_FALSE(receiver.RtcpRrTimeout());
  EXPECT_FALSE(receiver.RtcpRrSequenceNumberTimeout());

  // Add a RR and advance the clock just enough to not trigger a timeout.
  rtcp::ReportBlock rb1;
  rb1.SetMediaSsrc(kReceiverMainSsrc);
  rb1.SetExtHighestSeqNum(kSequenceNumber);
  rtcp::ReceiverReport rr1;
  rr1.SetSenderSsrc(kSenderSsrc);
  rr1.AddReportBlock(rb1);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr1.Build());

  mocks.clock.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs - 1);
  EXPECT_FALSE(receiver.RtcpRrTimeout());
  EXPECT_FALSE(receiver.RtcpRrSequenceNumberTimeout());

  // Add a RR with the same extended max as the previous RR to trigger a
  // sequence number timeout, but not a RR timeout.
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr1.Build());

  mocks.clock.AdvanceTimeMilliseconds(2);
  EXPECT_FALSE(receiver.RtcpRrTimeout());
  EXPECT_TRUE(receiver.RtcpRrSequenceNumberTimeout());

  // Advance clock enough to trigger an RR timeout too.
  mocks.clock.AdvanceTimeMilliseconds(3 * kRtcpIntervalMs);
  EXPECT_TRUE(receiver.RtcpRrTimeout());

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

  // Add a new RR with increase sequence number to reset timers.
  rtcp::ReportBlock rb2;
  rb2.SetMediaSsrc(kReceiverMainSsrc);
  rb2.SetExtHighestSeqNum(kSequenceNumber + 1);
  rtcp::ReceiverReport rr2;
  rr2.SetSenderSsrc(kSenderSsrc);
  rr2.AddReportBlock(rb2);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr2.Build());

  EXPECT_FALSE(receiver.RtcpRrTimeout());
  EXPECT_FALSE(receiver.RtcpRrSequenceNumberTimeout());

  // Verify we can get a timeout again once we've received new RR.
  mocks.clock.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rr2.Build());

  mocks.clock.AdvanceTimeMilliseconds(kRtcpIntervalMs + 1);
  EXPECT_FALSE(receiver.RtcpRrTimeout());
  EXPECT_TRUE(receiver.RtcpRrSequenceNumberTimeout());

  mocks.clock.AdvanceTimeMilliseconds(2 * kRtcpIntervalMs);
  EXPECT_TRUE(receiver.RtcpRrTimeout());
}

TEST(RtcpReceiverTest, TmmbrReceivedWithNoIncomingPacket) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  EXPECT_THAT(receiver.TmmbrReceived(), IsEmpty());
}

TEST(RtcpReceiverTest, TmmbrPacketAccepted) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const DataRate kBitrate = DataRate::BitsPerSec(30'000);
  auto tmmbr = std::make_unique<rtcp::Tmmbr>();
  tmmbr->SetSenderSsrc(kSenderSsrc);
  tmmbr->AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, kBitrate.bps(), 0));
  auto sr = std::make_unique<rtcp::SenderReport>();
  sr->SetSenderSsrc(kSenderSsrc);
  rtcp::CompoundPacket compound;
  compound.Append(std::move(sr));
  compound.Append(std::move(tmmbr));

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  EXPECT_CALL(mocks.rtp_rtcp_impl, SetTmmbn(SizeIs(1)));
  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnReceiverEstimatedMaxBitrate(_, kBitrate));
  receiver.IncomingPacket(compound.Build());

  EXPECT_THAT(
      receiver.TmmbrReceived(),
      ElementsAre(AllOf(
          Property(&rtcp::TmmbItem::bitrate_bps, Eq(kBitrate.bps<uint64_t>())),
          Property(&rtcp::TmmbItem::ssrc, Eq(kSenderSsrc)))));
}

TEST(RtcpReceiverTest, TmmbrPacketNotForUsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint32_t kBitrateBps = 30000;
  auto tmmbr = std::make_unique<rtcp::Tmmbr>();
  tmmbr->SetSenderSsrc(kSenderSsrc);
  tmmbr->AddTmmbr(rtcp::TmmbItem(kNotToUsSsrc, kBitrateBps, 0));

  auto sr = std::make_unique<rtcp::SenderReport>();
  sr->SetSenderSsrc(kSenderSsrc);
  rtcp::CompoundPacket compound;
  compound.Append(std::move(sr));
  compound.Append(std::move(tmmbr));

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReceiverEstimatedMaxBitrate)
      .Times(0);
  receiver.IncomingPacket(compound.Build());

  EXPECT_EQ(0u, receiver.TmmbrReceived().size());
}

TEST(RtcpReceiverTest, TmmbrPacketZeroRateIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  auto tmmbr = std::make_unique<rtcp::Tmmbr>();
  tmmbr->SetSenderSsrc(kSenderSsrc);
  tmmbr->AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 0, 0));
  auto sr = std::make_unique<rtcp::SenderReport>();
  sr->SetSenderSsrc(kSenderSsrc);
  rtcp::CompoundPacket compound;
  compound.Append(std::move(sr));
  compound.Append(std::move(tmmbr));

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnReceiverEstimatedMaxBitrate)
      .Times(0);
  receiver.IncomingPacket(compound.Build());

  EXPECT_EQ(0u, receiver.TmmbrReceived().size());
}

TEST(RtcpReceiverTest, TmmbrThreeConstraintsTimeOut) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  // Inject 3 packets "from" kSenderSsrc, kSenderSsrc+1, kSenderSsrc+2.
  // The times of arrival are starttime + 0, starttime + 5 and starttime + 10.
  for (uint32_t ssrc = kSenderSsrc; ssrc < kSenderSsrc + 3; ++ssrc) {
    auto tmmbr = std::make_unique<rtcp::Tmmbr>();
    tmmbr->SetSenderSsrc(ssrc);
    tmmbr->AddTmmbr(rtcp::TmmbItem(kReceiverMainSsrc, 30000, 0));
    auto sr = std::make_unique<rtcp::SenderReport>();
    sr->SetSenderSsrc(ssrc);
    rtcp::CompoundPacket compound;
    compound.Append(std::move(sr));
    compound.Append(std::move(tmmbr));

    EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
    EXPECT_CALL(mocks.rtp_rtcp_impl, SetTmmbn);
    EXPECT_CALL(mocks.network_link_rtcp_observer,
                OnReceiverEstimatedMaxBitrate);
    receiver.IncomingPacket(compound.Build());

    // 5 seconds between each packet.
    mocks.clock.AdvanceTimeMilliseconds(5000);
  }
  // It is now starttime + 15.
  EXPECT_THAT(receiver.TmmbrReceived(),
              AllOf(SizeIs(3),
                    Each(Property(&rtcp::TmmbItem::bitrate_bps, Eq(30'000U)))));

  // We expect the timeout to be 25 seconds. Advance the clock by 12
  // seconds, timing out the first packet.
  mocks.clock.AdvanceTimeMilliseconds(12000);
  EXPECT_THAT(receiver.TmmbrReceived(),
              UnorderedElementsAre(
                  Property(&rtcp::TmmbItem::ssrc, Eq(kSenderSsrc + 1)),
                  Property(&rtcp::TmmbItem::ssrc, Eq(kSenderSsrc + 2))));
}

TEST(RtcpReceiverTest,
     VerifyBlockAndTimestampObtainedFromReportBlockDataObserver) {
  ReceiverMocks mocks;
  MockReportBlockDataObserverImpl observer;
  mocks.config.report_block_data_observer = &observer;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint8_t kFractionLoss = 3;
  const uint32_t kCumulativeLoss = 7;
  const uint32_t kJitter = 9;
  const uint16_t kSequenceNumber = 1234;
  const int64_t kNtpNowMs =
      mocks.clock.CurrentNtpInMilliseconds() - rtc::kNtpJan1970Millisecs;

  rtcp::ReportBlock rtcp_block;
  rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
  rtcp_block.SetExtHighestSeqNum(kSequenceNumber);
  rtcp_block.SetFractionLost(kFractionLoss);
  rtcp_block.SetCumulativeLost(kCumulativeLoss);
  rtcp_block.SetJitter(kJitter);

  rtcp::ReceiverReport rtcp_report;
  rtcp_report.SetSenderSsrc(kSenderSsrc);
  rtcp_report.AddReportBlock(rtcp_block);
  EXPECT_CALL(observer, OnReportBlockDataUpdated)
      .WillOnce([&](ReportBlockData report_block) {
        EXPECT_EQ(rtcp_block.source_ssrc(), report_block.source_ssrc());
        EXPECT_EQ(kSenderSsrc, report_block.sender_ssrc());
        EXPECT_EQ(rtcp_block.fraction_lost(), report_block.fraction_lost_raw());
        EXPECT_EQ(rtcp_block.cumulative_lost(), report_block.cumulative_lost());
        EXPECT_EQ(rtcp_block.extended_high_seq_num(),
                  report_block.extended_highest_sequence_number());
        EXPECT_EQ(rtcp_block.jitter(), report_block.jitter());
        EXPECT_EQ(report_block.report_block_timestamp_utc(),
                  Timestamp::Millis(kNtpNowMs));
        // No RTT is calculated in this test.
        EXPECT_EQ(0u, report_block.num_rtts());
      });
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report.Build());
}

TEST(RtcpReceiverTest, VerifyRttObtainedFromReportBlockDataObserver) {
  ReceiverMocks mocks;
  MockReportBlockDataObserverImpl observer;
  mocks.config.report_block_data_observer = &observer;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  // To avoid issues with rounding due to different way to represent time units,
  // use RTT that can be precisly represented both with
  // TimeDelta units (i.e. integer number of microseconds), and
  // ntp units (i.e. integer number of 2^(-32) seconds)
  const TimeDelta kRtt = TimeDelta::Millis(125);
  const uint32_t kDelayNtp = 123'000;
  const TimeDelta kDelay = CompactNtpRttToTimeDelta(kDelayNtp);

  uint32_t sent_ntp = CompactNtp(mocks.clock.CurrentNtpTime());
  mocks.clock.AdvanceTime(kRtt + kDelay);

  rtcp::SenderReport sr;
  sr.SetSenderSsrc(kSenderSsrc);
  rtcp::ReportBlock block;
  block.SetMediaSsrc(kReceiverMainSsrc);
  block.SetLastSr(sent_ntp);
  block.SetDelayLastSr(kDelayNtp);
  sr.AddReportBlock(block);
  block.SetMediaSsrc(kReceiverExtraSsrc);
  block.SetLastSr(0);
  sr.AddReportBlock(block);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  InSequence sequence;
  EXPECT_CALL(observer, OnReportBlockDataUpdated)
      .WillOnce([&](ReportBlockData report_block_data) {
        EXPECT_EQ(kReceiverMainSsrc, report_block_data.source_ssrc());
        EXPECT_EQ(1u, report_block_data.num_rtts());
        EXPECT_EQ(kRtt, report_block_data.sum_rtts());
        EXPECT_EQ(kRtt, report_block_data.last_rtt());
      });
  EXPECT_CALL(observer, OnReportBlockDataUpdated)
      .WillOnce([](ReportBlockData report_block_data) {
        EXPECT_EQ(kReceiverExtraSsrc, report_block_data.source_ssrc());
        EXPECT_EQ(0u, report_block_data.num_rtts());
      });
  receiver.IncomingPacket(sr.Build());
}

TEST(RtcpReceiverTest, GetReportBlockDataAfterOneReportBlock) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kSequenceNumber = 1234;

  rtcp::ReportBlock rtcp_block;
  rtcp_block.SetMediaSsrc(kReceiverMainSsrc);
  rtcp_block.SetExtHighestSeqNum(kSequenceNumber);

  rtcp::ReceiverReport rtcp_report;
  rtcp_report.SetSenderSsrc(kSenderSsrc);
  rtcp_report.AddReportBlock(rtcp_block);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report.Build());

  auto report_block_datas = receiver.GetLatestReportBlockData();
  ASSERT_THAT(report_block_datas, SizeIs(1));
  EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
  EXPECT_EQ(kSequenceNumber,
            report_block_datas[0].extended_highest_sequence_number());
}

TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfSameSsrc) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kSequenceNumber1 = 1234;
  const uint16_t kSequenceNumber2 = 1235;

  rtcp::ReportBlock rtcp_block1;
  rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
  rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);

  rtcp::ReceiverReport rtcp_report1;
  rtcp_report1.SetSenderSsrc(kSenderSsrc);
  rtcp_report1.AddReportBlock(rtcp_block1);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report1.Build());

  // Inject a report block with an increased the sequence number for the same
  // source SSRC.
  rtcp::ReportBlock rtcp_block2;
  rtcp_block2.SetMediaSsrc(kReceiverMainSsrc);
  rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);

  rtcp::ReceiverReport rtcp_report2;
  rtcp_report2.SetSenderSsrc(kSenderSsrc);
  rtcp_report2.AddReportBlock(rtcp_block2);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report2.Build());

  // Only the latest block should be returned.
  auto report_block_datas = receiver.GetLatestReportBlockData();
  ASSERT_THAT(report_block_datas, SizeIs(1));
  EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
  EXPECT_EQ(kSequenceNumber2,
            report_block_datas[0].extended_highest_sequence_number());
}

TEST(RtcpReceiverTest, GetReportBlockDataAfterTwoReportBlocksOfDifferentSsrcs) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kSequenceNumber1 = 1234;
  const uint16_t kSequenceNumber2 = 42;

  rtcp::ReportBlock rtcp_block1;
  rtcp_block1.SetMediaSsrc(kReceiverMainSsrc);
  rtcp_block1.SetExtHighestSeqNum(kSequenceNumber1);

  rtcp::ReceiverReport rtcp_report1;
  rtcp_report1.SetSenderSsrc(kSenderSsrc);
  rtcp_report1.AddReportBlock(rtcp_block1);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report1.Build());

  // Inject a report block for a different source SSRC.
  rtcp::ReportBlock rtcp_block2;
  rtcp_block2.SetMediaSsrc(kReceiverExtraSsrc);
  rtcp_block2.SetExtHighestSeqNum(kSequenceNumber2);

  rtcp::ReceiverReport rtcp_report2;
  rtcp_report2.SetSenderSsrc(kSenderSsrc);
  rtcp_report2.AddReportBlock(rtcp_block2);
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedRtcpReportBlocks);
  receiver.IncomingPacket(rtcp_report2.Build());

  // Both report blocks should be returned.
  auto report_block_datas = receiver.GetLatestReportBlockData();
  ASSERT_THAT(report_block_datas, SizeIs(2));
  EXPECT_EQ(kReceiverMainSsrc, report_block_datas[0].source_ssrc());
  EXPECT_EQ(kSequenceNumber1,
            report_block_datas[0].extended_highest_sequence_number());
  EXPECT_EQ(kReceiverExtraSsrc, report_block_datas[1].source_ssrc());
  EXPECT_EQ(kSequenceNumber2,
            report_block_datas[1].extended_highest_sequence_number());
}

TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnTransportFeedback) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::TransportFeedback packet;
  packet.SetMediaSsrc(mocks.config.local_media_ssrc);
  packet.SetSenderSsrc(kSenderSsrc);
  packet.SetBase(123, Timestamp::Millis(1));
  packet.AddReceivedPacket(123, Timestamp::Millis(1));

  EXPECT_CALL(
      mocks.network_link_rtcp_observer,
      OnTransportFeedback(
          mocks.clock.CurrentTime(),
          AllOf(Property(&rtcp::TransportFeedback::GetBaseSequence, 123),
                Property(&rtcp::TransportFeedback::GetReceivedPackets,
                         SizeIs(1)))));

  receiver.IncomingPacket(packet.Build());
}

TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnCongestionControlFeedback) {
  ReceiverMocks mocks;
  mocks.field_trials = "WebRTC-RFC8888CongestionControlFeedback/Enabled/";
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::CongestionControlFeedback packet({{
                                             .ssrc = 123,
                                             .sequence_number = 1,
                                         }},
                                         /*report_timestamp_compact_ntp=*/324);
  packet.SetSenderSsrc(kSenderSsrc);

  EXPECT_CALL(
      mocks.network_link_rtcp_observer,
      OnCongestionControlFeedback(
          mocks.clock.CurrentTime(),
          Property(&rtcp::CongestionControlFeedback::packets, SizeIs(1))));
  receiver.IncomingPacket(packet.Build());
}

TEST(RtcpReceiverTest, HandlesInvalidCongestionControlFeedback) {
  ReceiverMocks mocks;
  mocks.field_trials = "WebRTC-RFC8888CongestionControlFeedback/Enabled/";
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::CongestionControlFeedback packet({{
                                             .ssrc = 123,
                                             .sequence_number = 1,
                                         }},
                                         /*report_timestamp_compact_ntp=*/324);
  packet.SetSenderSsrc(kSenderSsrc);
  rtc::Buffer built_packet = packet.Build();
  // Modify the CongestionControlFeedback packet so that it is invalid.
  const size_t kNumReportsOffset = 14;
  ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kNumReportsOffset],
                                       42);

  EXPECT_CALL(mocks.network_link_rtcp_observer, OnCongestionControlFeedback)
      .Times(0);
  receiver.IncomingPacket(built_packet);
}

TEST(RtcpReceiverTest,
     NotifiesNetworkLinkObserverOnTransportFeedbackOnRtxSsrc) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::TransportFeedback packet;
  packet.SetMediaSsrc(*mocks.config.rtx_send_ssrc);
  packet.SetSenderSsrc(kSenderSsrc);
  packet.SetBase(1, Timestamp::Millis(1));
  packet.AddReceivedPacket(1, Timestamp::Millis(1));

  EXPECT_CALL(mocks.network_link_rtcp_observer, OnTransportFeedback);
  receiver.IncomingPacket(packet.Build());
}

TEST(RtcpReceiverTest,
     DoesNotNotifyNetworkLinkObserverOnTransportFeedbackForUnregistedSsrc) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::TransportFeedback packet;
  packet.SetMediaSsrc(kNotToUsSsrc);
  packet.SetSenderSsrc(kSenderSsrc);
  packet.SetBase(1, Timestamp::Millis(1));
  packet.AddReceivedPacket(1, Timestamp::Millis(1));

  EXPECT_CALL(mocks.network_link_rtcp_observer, OnTransportFeedback).Times(0);
  receiver.IncomingPacket(packet.Build());
}

TEST(RtcpReceiverTest, NotifiesNetworkLinkObserverOnRemb) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::Remb remb;
  remb.SetSenderSsrc(kSenderSsrc);
  remb.SetBitrateBps(500'000);

  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnReceiverEstimatedMaxBitrate(mocks.clock.CurrentTime(),
                                            DataRate::BitsPerSec(500'000)));
  receiver.IncomingPacket(remb.Build());
}

TEST(RtcpReceiverTest, HandlesInvalidTransportFeedback) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  // Send a compound packet with a TransportFeedback followed by something else.
  auto packet = std::make_unique<rtcp::TransportFeedback>();
  packet->SetMediaSsrc(kReceiverMainSsrc);
  packet->SetSenderSsrc(kSenderSsrc);
  packet->SetBase(1, Timestamp::Millis(1));
  packet->AddReceivedPacket(1, Timestamp::Millis(1));

  static constexpr DataRate kBitrate = DataRate::BitsPerSec(50'000);
  auto remb = std::make_unique<rtcp::Remb>();
  remb->SetSenderSsrc(kSenderSsrc);
  remb->SetBitrateBps(kBitrate.bps());
  rtcp::CompoundPacket compound;
  compound.Append(std::move(packet));
  compound.Append(std::move(remb));
  rtc::Buffer built_packet = compound.Build();

  // Modify the TransportFeedback packet so that it is invalid.
  const size_t kStatusCountOffset = 14;
  ByteWriter<uint16_t>::WriteBigEndian(&built_packet.data()[kStatusCountOffset],
                                       42);

  // Stress no transport feedback is expected.
  EXPECT_CALL(mocks.network_link_rtcp_observer, OnTransportFeedback).Times(0);
  // But remb should be processed and cause a callback
  EXPECT_CALL(mocks.network_link_rtcp_observer,
              OnReceiverEstimatedMaxBitrate(_, kBitrate));
  receiver.IncomingPacket(built_packet);
}

TEST(RtcpReceiverTest, Nack) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kNackList1[] = {1, 2, 3, 5};
  const uint16_t kNackList23[] = {5, 7, 30, 40, 41, 58, 59, 61, 63};
  const size_t kNackListLength2 = 4;
  const size_t kNackListLength3 = arraysize(kNackList23) - kNackListLength2;
  std::set<uint16_t> nack_set;
  nack_set.insert(std::begin(kNackList1), std::end(kNackList1));
  nack_set.insert(std::begin(kNackList23), std::end(kNackList23));

  auto nack1 = std::make_unique<rtcp::Nack>();
  nack1->SetSenderSsrc(kSenderSsrc);
  nack1->SetMediaSsrc(kReceiverMainSsrc);
  nack1->SetPacketIds(kNackList1, arraysize(kNackList1));

  EXPECT_CALL(mocks.rtp_rtcp_impl,
              OnReceivedNack(ElementsAreArray(kNackList1)));
  EXPECT_CALL(mocks.packet_type_counter_observer,
              RtcpPacketTypesCounterUpdated(
                  kReceiverMainSsrc,
                  AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
                              arraysize(kNackList1)),
                        Field(&RtcpPacketTypeCounter::unique_nack_requests,
                              arraysize(kNackList1)))));
  receiver.IncomingPacket(nack1->Build());

  auto nack2 = std::make_unique<rtcp::Nack>();
  nack2->SetSenderSsrc(kSenderSsrc);
  nack2->SetMediaSsrc(kReceiverMainSsrc);
  nack2->SetPacketIds(kNackList23, kNackListLength2);

  auto nack3 = std::make_unique<rtcp::Nack>();
  nack3->SetSenderSsrc(kSenderSsrc);
  nack3->SetMediaSsrc(kReceiverMainSsrc);
  nack3->SetPacketIds(kNackList23 + kNackListLength2, kNackListLength3);

  rtcp::CompoundPacket two_nacks;
  two_nacks.Append(std::move(nack2));
  two_nacks.Append(std::move(nack3));

  EXPECT_CALL(mocks.rtp_rtcp_impl,
              OnReceivedNack(ElementsAreArray(kNackList23)));
  EXPECT_CALL(mocks.packet_type_counter_observer,
              RtcpPacketTypesCounterUpdated(
                  kReceiverMainSsrc,
                  AllOf(Field(&RtcpPacketTypeCounter::nack_requests,
                              arraysize(kNackList1) + arraysize(kNackList23)),
                        Field(&RtcpPacketTypeCounter::unique_nack_requests,
                              nack_set.size()))));
  receiver.IncomingPacket(two_nacks.Build());
}

TEST(RtcpReceiverTest, NackNotForUsIgnored) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  const uint16_t kNackList1[] = {1, 2, 3, 5};
  const size_t kNackListLength1 = std::end(kNackList1) - std::begin(kNackList1);

  rtcp::Nack nack;
  nack.SetSenderSsrc(kSenderSsrc);
  nack.SetMediaSsrc(kNotToUsSsrc);
  nack.SetPacketIds(kNackList1, kNackListLength1);

  EXPECT_CALL(mocks.packet_type_counter_observer,
              RtcpPacketTypesCounterUpdated(
                  _, Field(&RtcpPacketTypeCounter::nack_requests, 0)));
  receiver.IncomingPacket(nack.Build());
}

TEST(RtcpReceiverTest, ForceSenderReport) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  rtcp::RapidResyncRequest rr;
  rr.SetSenderSsrc(kSenderSsrc);
  rr.SetMediaSsrc(kReceiverMainSsrc);

  EXPECT_CALL(mocks.rtp_rtcp_impl, OnRequestSendReport());
  receiver.IncomingPacket(rr.Build());
}

TEST(RtcpReceiverTest, ReceivesTargetBitrate) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  VideoBitrateAllocation expected_allocation;
  expected_allocation.SetBitrate(0, 0, 10000);
  expected_allocation.SetBitrate(0, 1, 20000);
  expected_allocation.SetBitrate(1, 0, 40000);
  expected_allocation.SetBitrate(1, 1, 80000);

  rtcp::TargetBitrate bitrate;
  bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
  bitrate.AddTargetBitrate(0, 1, expected_allocation.GetBitrate(0, 1) / 1000);
  bitrate.AddTargetBitrate(1, 0, expected_allocation.GetBitrate(1, 0) / 1000);
  bitrate.AddTargetBitrate(1, 1, expected_allocation.GetBitrate(1, 1) / 1000);

  rtcp::ExtendedReports xr;
  xr.SetTargetBitrate(bitrate);

  // Wrong sender ssrc, target bitrate should be discarded.
  xr.SetSenderSsrc(kSenderSsrc + 1);
  EXPECT_CALL(mocks.bitrate_allocation_observer,
              OnBitrateAllocationUpdated(expected_allocation))
      .Times(0);
  receiver.IncomingPacket(xr.Build());

  // Set correct ssrc, callback should be called once.
  xr.SetSenderSsrc(kSenderSsrc);
  EXPECT_CALL(mocks.bitrate_allocation_observer,
              OnBitrateAllocationUpdated(expected_allocation));
  receiver.IncomingPacket(xr.Build());
}

TEST(RtcpReceiverTest, HandlesIncorrectTargetBitrate) {
  ReceiverMocks mocks;
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  VideoBitrateAllocation expected_allocation;
  expected_allocation.SetBitrate(0, 0, 10000);

  rtcp::TargetBitrate bitrate;
  bitrate.AddTargetBitrate(0, 0, expected_allocation.GetBitrate(0, 0) / 1000);
  bitrate.AddTargetBitrate(0, kMaxTemporalStreams, 20000);
  bitrate.AddTargetBitrate(kMaxSpatialLayers, 0, 40000);

  rtcp::ExtendedReports xr;
  xr.SetTargetBitrate(bitrate);
  xr.SetSenderSsrc(kSenderSsrc);

  EXPECT_CALL(mocks.bitrate_allocation_observer,
              OnBitrateAllocationUpdated(expected_allocation));
  receiver.IncomingPacket(xr.Build());
}

TEST(RtcpReceiverTest, ChangeLocalMediaSsrc) {
  ReceiverMocks mocks;
  // Construct a receiver with `kReceiverMainSsrc` (default) local media ssrc.
  RTCPReceiver receiver = Create(mocks);
  receiver.SetRemoteSSRC(kSenderSsrc);

  constexpr uint32_t kSecondarySsrc = kReceiverMainSsrc + 1;

  // Expect to only get the `OnReceivedNack()` callback once since we'll
  // configure it for the `kReceiverMainSsrc` media ssrc.
  EXPECT_CALL(mocks.rtp_rtcp_impl, OnReceivedNack);

  // We'll get two callbacks to RtcpPacketTypesCounterUpdated, one for each
  // call to `IncomingPacket`, differentiated by the local media ssrc.
  EXPECT_CALL(mocks.packet_type_counter_observer,
              RtcpPacketTypesCounterUpdated(kReceiverMainSsrc, _));
  EXPECT_CALL(mocks.packet_type_counter_observer,
              RtcpPacketTypesCounterUpdated(kSecondarySsrc, _));

  // Construct a test nack packet with media ssrc set to `kReceiverMainSsrc`.
  rtcp::Nack nack;
  nack.SetSenderSsrc(kSenderSsrc);
  nack.SetMediaSsrc(kReceiverMainSsrc);
  const uint16_t kNackList[] = {1, 2, 3, 5};
  nack.SetPacketIds(kNackList, std::size(kNackList));

  // Deliver the first callback.
  receiver.IncomingPacket(nack.Build());

  // Change the set local media ssrc.
  receiver.set_local_media_ssrc(kSecondarySsrc);

  // Deliver another packet - this time there will be no callback to
  // OnReceivedNack due to the ssrc not matching.
  receiver.IncomingPacket(nack.Build());
}

}  // namespace webrtc
