普通文本  |  587行  |  20.49 KB

// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/memory/scoped_ptr.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/cast/cast_environment.h"
#include "media/cast/rtcp/mock_rtcp_receiver_feedback.h"
#include "media/cast/rtcp/mock_rtcp_sender_feedback.h"
#include "media/cast/rtcp/rtcp_receiver.h"
#include "media/cast/rtcp/rtcp_utility.h"
#include "media/cast/rtcp/test_rtcp_packet_builder.h"
#include "media/cast/test/fake_task_runner.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace media {
namespace cast {

using testing::_;

static const uint32 kSenderSsrc = 0x10203;
static const uint32 kSourceSsrc = 0x40506;
static const uint32 kUnknownSsrc = 0xDEAD;
static const std::string kCName("test@10.1.1.1");

namespace {
class SenderFeedbackCastVerification : public RtcpSenderFeedback {
 public:
  SenderFeedbackCastVerification() : called_(false) {}

  virtual void OnReceivedCastFeedback(
      const RtcpCastMessage& cast_feedback) OVERRIDE {
    EXPECT_EQ(cast_feedback.media_ssrc_, kSenderSsrc);
    EXPECT_EQ(cast_feedback.ack_frame_id_, kAckFrameId);

    MissingFramesAndPacketsMap::const_iterator frame_it =
        cast_feedback.missing_frames_and_packets_.begin();

    EXPECT_TRUE(frame_it != cast_feedback.missing_frames_and_packets_.end());
    EXPECT_EQ(kLostFrameId, frame_it->first);
    EXPECT_TRUE(frame_it->second.empty());
    ++frame_it;
    EXPECT_TRUE(frame_it != cast_feedback.missing_frames_and_packets_.end());
    EXPECT_EQ(kFrameIdWithLostPackets, frame_it->first);
    EXPECT_EQ(3UL, frame_it->second.size());
    PacketIdSet::const_iterator packet_it = frame_it->second.begin();
    EXPECT_EQ(kLostPacketId1, *packet_it);
    ++packet_it;
    EXPECT_EQ(kLostPacketId2, *packet_it);
    ++packet_it;
    EXPECT_EQ(kLostPacketId3, *packet_it);
    ++frame_it;
    EXPECT_EQ(frame_it, cast_feedback.missing_frames_and_packets_.end());
    called_ = true;
  }

  bool called() const { return called_; }

 private:
  bool called_;
};

class RtcpReceiverCastLogVerification : public RtcpReceiverFeedback {
 public:
  RtcpReceiverCastLogVerification()
      : called_on_received_sender_log_(false),
        called_on_received_receiver_log_(false) {}

  virtual void OnReceivedSenderReport(
      const RtcpSenderInfo& remote_sender_info) OVERRIDE {};

  virtual void OnReceiverReferenceTimeReport(
      const RtcpReceiverReferenceTimeReport& remote_time_report) OVERRIDE {};

  virtual void OnReceivedSendReportRequest() OVERRIDE {};

  virtual void OnReceivedReceiverLog(
      const RtcpReceiverLogMessage& receiver_log) OVERRIDE {
    EXPECT_EQ(expected_receiver_log_.size(), receiver_log.size());
    RtcpReceiverLogMessage::const_iterator expected_it =
       expected_receiver_log_.begin();
    RtcpReceiverLogMessage::const_iterator incoming_it = receiver_log.begin();
    for (; incoming_it != receiver_log.end(); ++incoming_it) {
      EXPECT_EQ(expected_it->rtp_timestamp_, incoming_it->rtp_timestamp_);
      EXPECT_EQ(expected_it->event_log_messages_.size(),
                incoming_it->event_log_messages_.size());

      RtcpReceiverEventLogMessages::const_iterator event_incoming_it =
          incoming_it->event_log_messages_.begin();
      RtcpReceiverEventLogMessages::const_iterator event_expected_it =
          expected_it->event_log_messages_.begin();
      for (; event_incoming_it != incoming_it->event_log_messages_.end();
           ++event_incoming_it, ++event_expected_it) {
        EXPECT_EQ(event_expected_it->type, event_incoming_it->type);
        EXPECT_EQ(event_expected_it->event_timestamp,
                  event_incoming_it->event_timestamp);
        if (event_expected_it->type == kPacketReceived) {
          EXPECT_EQ(event_expected_it->packet_id, event_incoming_it->packet_id);
        } else {
          EXPECT_EQ(event_expected_it->delay_delta,
                    event_incoming_it->delay_delta);
        }
      }
      expected_receiver_log_.pop_front();
      expected_it = expected_receiver_log_.begin();
    }
    called_on_received_receiver_log_ = true;
  }

  virtual void OnReceivedSenderLog(
      const RtcpSenderLogMessage& sender_log) OVERRIDE {
    EXPECT_EQ(expected_sender_log_.size(), sender_log.size());

    RtcpSenderLogMessage::const_iterator expected_it =
       expected_sender_log_.begin();
    RtcpSenderLogMessage::const_iterator incoming_it = sender_log.begin();
    for (; expected_it != expected_sender_log_.end();
        ++expected_it, ++incoming_it) {
      EXPECT_EQ(expected_it->frame_status, incoming_it->frame_status);
      EXPECT_EQ(0xffffff & expected_it->rtp_timestamp,
                incoming_it->rtp_timestamp);
    }
    called_on_received_sender_log_ = true;
  }

  bool OnReceivedSenderLogCalled() {
    return called_on_received_sender_log_;
  }

  bool OnReceivedReceiverLogCalled() {
    return called_on_received_receiver_log_ && expected_receiver_log_.empty();
  }

  void SetExpectedReceiverLog(const RtcpReceiverLogMessage& receiver_log) {
    expected_receiver_log_ = receiver_log;
  }

  void SetExpectedSenderLog(const RtcpSenderLogMessage& sender_log) {
    expected_sender_log_ = sender_log;
  }

 private:
  RtcpReceiverLogMessage expected_receiver_log_;
  RtcpSenderLogMessage expected_sender_log_;
  bool called_on_received_sender_log_;
  bool called_on_received_receiver_log_;
};

}  // namespace

class RtcpReceiverTest : public ::testing::Test {
 protected:
  RtcpReceiverTest()
      : task_runner_(new test::FakeTaskRunner(&testing_clock_)),
        cast_environment_(new CastEnvironment(&testing_clock_, task_runner_,
            task_runner_, task_runner_, task_runner_, task_runner_,
            GetDefaultCastLoggingConfig())),
        rtcp_receiver_(new RtcpReceiver(cast_environment_,
                                        &mock_sender_feedback_,
                                        &mock_receiver_feedback_,
                                        &mock_rtt_feedback_,
                                        kSourceSsrc)) {
  }

  virtual ~RtcpReceiverTest() {}

  virtual void SetUp() OVERRIDE {
    EXPECT_CALL(mock_receiver_feedback_, OnReceivedSenderReport(_)).Times(0);
    EXPECT_CALL(mock_receiver_feedback_,
                OnReceiverReferenceTimeReport(_)).Times(0);
    EXPECT_CALL(mock_receiver_feedback_,
                OnReceivedSendReportRequest()).Times(0);
    EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(0);
    EXPECT_CALL(mock_rtt_feedback_,
                OnReceivedDelaySinceLastReport(_, _, _)).Times(0);

    expected_sender_info_.ntp_seconds = kNtpHigh;
    expected_sender_info_.ntp_fraction = kNtpLow;
    expected_sender_info_.rtp_timestamp = kRtpTimestamp;
    expected_sender_info_.send_packet_count = kSendPacketCount;
    expected_sender_info_.send_octet_count = kSendOctetCount;

    expected_report_block_.remote_ssrc = kSenderSsrc;
    expected_report_block_.media_ssrc = kSourceSsrc;
    expected_report_block_.fraction_lost = kLoss >> 24;
    expected_report_block_.cumulative_lost = kLoss & 0xffffff;
    expected_report_block_.extended_high_sequence_number = kExtendedMax;
    expected_report_block_.jitter = kTestJitter;
    expected_report_block_.last_sr = kLastSr;
    expected_report_block_.delay_since_last_sr = kDelayLastSr;
    expected_receiver_reference_report_.remote_ssrc = kSenderSsrc;
    expected_receiver_reference_report_.ntp_seconds = kNtpHigh;
    expected_receiver_reference_report_.ntp_fraction = kNtpLow;
  }

  // Injects an RTCP packet into the receiver.
  void InjectRtcpPacket(const uint8* packet, uint16 length) {
    RtcpParser rtcp_parser(packet, length);
    rtcp_receiver_->IncomingRtcpPacket(&rtcp_parser);
  }

  base::SimpleTestTickClock testing_clock_;
  scoped_refptr<test::FakeTaskRunner> task_runner_;
  scoped_refptr<CastEnvironment> cast_environment_;
  MockRtcpReceiverFeedback mock_receiver_feedback_;
  MockRtcpRttFeedback mock_rtt_feedback_;
  MockRtcpSenderFeedback mock_sender_feedback_;
  scoped_ptr<RtcpReceiver> rtcp_receiver_;
  RtcpSenderInfo expected_sender_info_;
  RtcpReportBlock expected_report_block_;
  RtcpReceiverReferenceTimeReport expected_receiver_reference_report_;
};

TEST_F(RtcpReceiverTest, BrokenPacketIsIgnored) {
  const uint8 bad_packet[] = {0, 0, 0, 0};
  InjectRtcpPacket(bad_packet, sizeof(bad_packet));
}

TEST_F(RtcpReceiverTest, InjectSenderReportPacket) {
  TestRtcpPacketBuilder p;
  p.AddSr(kSenderSsrc, 0);

  // Expected to be ignored since the sender ssrc does not match our
  // remote ssrc.
  InjectRtcpPacket(p.Packet(), p.Length());

  EXPECT_CALL(mock_receiver_feedback_,
              OnReceivedSenderReport(expected_sender_info_)).Times(1);
  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  // Expected to be pass through since the sender ssrc match our remote ssrc.
  InjectRtcpPacket(p.Packet(), p.Length());
}

TEST_F(RtcpReceiverTest, InjectReceiveReportPacket) {
  TestRtcpPacketBuilder p1;
  p1.AddRr(kSenderSsrc, 1);
  p1.AddRb(kUnknownSsrc);

  // Expected to be ignored since the source ssrc does not match our
  // local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);

  TestRtcpPacketBuilder p2;
  p2.AddRr(kSenderSsrc, 1);
  p2.AddRb(kSourceSsrc);

  // Expected to be pass through since the sender ssrc match our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());
}

TEST_F(RtcpReceiverTest, InjectSenderReportWithReportBlockPacket) {
  TestRtcpPacketBuilder p1;
  p1.AddSr(kSenderSsrc, 1);
  p1.AddRb(kUnknownSsrc);

  // Sender report expected to be ignored since the sender ssrc does not match
  // our remote ssrc.
  // Report block expected to be ignored since the source ssrc does not match
  // our local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_receiver_feedback_,
              OnReceivedSenderReport(expected_sender_info_)).Times(1);
  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  // Sender report expected to be pass through since the sender ssrc match our
  // remote ssrc.
  // Report block expected to be ignored since the source ssrc does not match
  // our local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_receiver_feedback_, OnReceivedSenderReport(_)).Times(0);
  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
        kLastSr,
        kDelayLastSr)).Times(1);

  rtcp_receiver_->SetRemoteSSRC(0);

  TestRtcpPacketBuilder p2;
  p2.AddSr(kSenderSsrc, 1);
  p2.AddRb(kSourceSsrc);

  // Sender report expected to be ignored since the sender ssrc does not match
  // our remote ssrc.
  // Receiver report expected to be pass through since the sender ssrc match
  // our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());

  EXPECT_CALL(mock_receiver_feedback_,
              OnReceivedSenderReport(expected_sender_info_)).Times(1);
  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);

  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  // Sender report expected to be pass through since the sender ssrc match our
  // remote ssrc.
  // Receiver report expected to be pass through since the sender ssrc match
  // our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());
}

TEST_F(RtcpReceiverTest, InjectSenderReportPacketWithDlrr) {
  TestRtcpPacketBuilder p;
  p.AddSr(kSenderSsrc, 0);
  p.AddXrHeader(kSenderSsrc);
  p.AddXrUnknownBlock();
  p.AddXrExtendedDlrrBlock(kSenderSsrc);
  p.AddXrUnknownBlock();
  p.AddSdesCname(kSenderSsrc, kCName);

  // Expected to be ignored since the source ssrc does not match our
  // local ssrc.
  InjectRtcpPacket(p.Packet(), p.Length());

  EXPECT_CALL(mock_receiver_feedback_,
              OnReceivedSenderReport(expected_sender_info_)).Times(1);
  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSenderSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);

  // Enable receiving sender report.
  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  // Expected to be pass through since the sender ssrc match our local ssrc.
  InjectRtcpPacket(p.Packet(), p.Length());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportPacketWithRrtr) {
  TestRtcpPacketBuilder p1;
  p1.AddRr(kSenderSsrc, 1);
  p1.AddRb(kUnknownSsrc);
  p1.AddXrHeader(kSenderSsrc);
  p1.AddXrRrtrBlock();

  // Expected to be ignored since the source ssrc does not match our
  // local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);
  EXPECT_CALL(mock_receiver_feedback_, OnReceiverReferenceTimeReport(
      expected_receiver_reference_report_)).Times(1);

  // Enable receiving reference time report.
  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  TestRtcpPacketBuilder p2;
  p2.AddRr(kSenderSsrc, 1);
  p2.AddRb(kSourceSsrc);
  p2.AddXrHeader(kSenderSsrc);
  p2.AddXrRrtrBlock();

  // Expected to be pass through since the sender ssrc match our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportPacketWithIntraFrameRequest) {
  TestRtcpPacketBuilder p1;
  p1.AddRr(kSenderSsrc, 1);
  p1.AddRb(kUnknownSsrc);
  p1.AddPli(kSenderSsrc, kUnknownSsrc);

  // Expected to be ignored since the source ssrc does not match our
  // local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);

  TestRtcpPacketBuilder p2;
  p2.AddRr(kSenderSsrc, 1);
  p2.AddRb(kSourceSsrc);
  p2.AddPli(kSenderSsrc, kSourceSsrc);

  // Expected to be pass through since the sender ssrc match our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportPacketWithCastFeedback) {
  TestRtcpPacketBuilder p1;
  p1.AddRr(kSenderSsrc, 1);
  p1.AddRb(kUnknownSsrc);
  p1.AddCast(kSenderSsrc, kUnknownSsrc);

  // Expected to be ignored since the source ssrc does not match our
  // local ssrc.
  InjectRtcpPacket(p1.Packet(), p1.Length());

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);
  EXPECT_CALL(mock_sender_feedback_, OnReceivedCastFeedback(_)).Times(1);

  // Enable receiving the cast feedback.
  rtcp_receiver_->SetRemoteSSRC(kSenderSsrc);

  TestRtcpPacketBuilder p2;
  p2.AddRr(kSenderSsrc, 1);
  p2.AddRb(kSourceSsrc);
  p2.AddCast(kSenderSsrc, kSourceSsrc);

  // Expected to be pass through since the sender ssrc match our local ssrc.
  InjectRtcpPacket(p2.Packet(), p2.Length());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportPacketWithCastVerification) {
  SenderFeedbackCastVerification sender_feedback_cast_verification;
  RtcpReceiver rtcp_receiver(cast_environment_,
                             &sender_feedback_cast_verification,
                             &mock_receiver_feedback_,
                             &mock_rtt_feedback_,
                             kSourceSsrc);

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc,
          kLastSr,
          kDelayLastSr)).Times(1);

  // Enable receiving the cast feedback.
  rtcp_receiver.SetRemoteSSRC(kSenderSsrc);

  TestRtcpPacketBuilder p;
  p.AddRr(kSenderSsrc, 1);
  p.AddRb(kSourceSsrc);
  p.AddCast(kSenderSsrc, kSourceSsrc);

  // Expected to be pass through since the sender ssrc match our local ssrc.
  RtcpParser rtcp_parser(p.Packet(), p.Length());
  rtcp_receiver.IncomingRtcpPacket(&rtcp_parser);

  EXPECT_TRUE(sender_feedback_cast_verification.called());
}

TEST_F(RtcpReceiverTest, InjectSenderReportWithCastSenderLogVerification) {
  RtcpReceiverCastLogVerification cast_log_verification;
  RtcpReceiver rtcp_receiver(cast_environment_,
                             &mock_sender_feedback_,
                             &cast_log_verification,
                             &mock_rtt_feedback_,
                             kSourceSsrc);
  rtcp_receiver.SetRemoteSSRC(kSenderSsrc);

  RtcpSenderLogMessage sender_log;
  for (int j = 0; j < 359; ++j) {
    RtcpSenderFrameLogMessage sender_frame_log;
    sender_frame_log.frame_status = kRtcpSenderFrameStatusSentToNetwork;
    sender_frame_log.rtp_timestamp = kRtpTimestamp + j * 90;
    sender_log.push_back(sender_frame_log);
  }
  cast_log_verification.SetExpectedSenderLog(sender_log);

  TestRtcpPacketBuilder p;
  p.AddSr(kSenderSsrc, 0);
  p.AddSdesCname(kSenderSsrc, kCName);
  p.AddSenderLog(kSenderSsrc);

  for (int i = 0; i < 359; ++i) {
    p.AddSenderFrameLog(kRtcpSenderFrameStatusSentToNetwork,
                        kRtpTimestamp + i * 90);
  }
  RtcpParser rtcp_parser(p.Packet(), p.Length());
  rtcp_receiver.IncomingRtcpPacket(&rtcp_parser);

  EXPECT_TRUE(cast_log_verification.OnReceivedSenderLogCalled());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportWithReceiverLogVerificationBase) {
  static const uint32 kTimeBaseMs = 12345678;
  static const uint32 kTimeDelayMs = 10;
  static const uint32 kDelayDeltaMs = 123;
  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));

  RtcpReceiverCastLogVerification cast_log_verification;
  RtcpReceiver rtcp_receiver(cast_environment_,
                             &mock_sender_feedback_,
                             &cast_log_verification,
                             &mock_rtt_feedback_,
                             kSourceSsrc);
  rtcp_receiver.SetRemoteSSRC(kSenderSsrc);

  RtcpReceiverLogMessage receiver_log;
  RtcpReceiverFrameLogMessage frame_log(kRtpTimestamp);
  RtcpReceiverEventLogMessage event_log;

  event_log.type = kAckSent;
  event_log.event_timestamp = testing_clock.NowTicks();
  event_log.delay_delta = base::TimeDelta::FromMilliseconds(kDelayDeltaMs);
  frame_log.event_log_messages_.push_back(event_log);

  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs));
  event_log.type = kPacketReceived;
  event_log.event_timestamp = testing_clock.NowTicks();
  event_log.packet_id = kLostPacketId1;
  frame_log.event_log_messages_.push_back(event_log);
  receiver_log.push_back(frame_log);

  cast_log_verification.SetExpectedReceiverLog(receiver_log);

  TestRtcpPacketBuilder p;
  p.AddRr(kSenderSsrc, 1);
  p.AddRb(kSourceSsrc);
  p.AddReceiverLog(kSenderSsrc);
  p.AddReceiverFrameLog(kRtpTimestamp, 2, kTimeBaseMs);
  p.AddReceiverEventLog(kDelayDeltaMs, 1, 0);
  p.AddReceiverEventLog(kLostPacketId1, 6, kTimeDelayMs);

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc, kLastSr, kDelayLastSr)).
          Times(1);

  RtcpParser rtcp_parser(p.Packet(), p.Length());
  rtcp_receiver.IncomingRtcpPacket(&rtcp_parser);

  EXPECT_TRUE(cast_log_verification.OnReceivedReceiverLogCalled());
}

TEST_F(RtcpReceiverTest, InjectReceiverReportWithReceiverLogVerificationMulti) {
  static const uint32 kTimeBaseMs = 12345678;
  static const uint32 kTimeDelayMs = 10;
  static const uint32 kDelayDeltaMs = 123;
  base::SimpleTestTickClock testing_clock;
  testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeBaseMs));

  RtcpReceiverCastLogVerification cast_log_verification;
  RtcpReceiver rtcp_receiver(cast_environment_,
                             &mock_sender_feedback_,
                             &cast_log_verification,
                             &mock_rtt_feedback_,
                             kSourceSsrc);
  rtcp_receiver.SetRemoteSSRC(kSenderSsrc);

  RtcpReceiverLogMessage receiver_log;

  for (int j = 0; j < 100; ++j) {
    RtcpReceiverFrameLogMessage frame_log(kRtpTimestamp);
    RtcpReceiverEventLogMessage event_log;
    event_log.type = kAckSent;
    event_log.event_timestamp = testing_clock.NowTicks();
    event_log.delay_delta = base::TimeDelta::FromMilliseconds(kDelayDeltaMs);
    frame_log.event_log_messages_.push_back(event_log);
    receiver_log.push_back(frame_log);
    testing_clock.Advance(base::TimeDelta::FromMilliseconds(kTimeDelayMs));
  }

  cast_log_verification.SetExpectedReceiverLog(receiver_log);

  TestRtcpPacketBuilder p;
  p.AddRr(kSenderSsrc, 1);
  p.AddRb(kSourceSsrc);
  p.AddReceiverLog(kSenderSsrc);
  for (int i = 0; i < 100; ++i) {
    p.AddReceiverFrameLog(kRtpTimestamp, 1, kTimeBaseMs +  i * kTimeDelayMs);
    p.AddReceiverEventLog(kDelayDeltaMs, 1, 0);
  }

  EXPECT_CALL(mock_rtt_feedback_,
      OnReceivedDelaySinceLastReport(kSourceSsrc, kLastSr, kDelayLastSr)).
          Times(1);

  RtcpParser rtcp_parser(p.Packet(), p.Length());
  rtcp_receiver.IncomingRtcpPacket(&rtcp_parser);

  EXPECT_TRUE(cast_log_verification.OnReceivedReceiverLogCalled());
}



}  // namespace cast
}  // namespace media