// Copyright 2014 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 "media/cast/sender/video_sender.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/test/simple_test_tick_clock.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_environment.h"
#include "media/cast/constants.h"
#include "media/cast/logging/simple_event_subscriber.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_impl.h"
#include "media/cast/net/pacing/paced_sender.h"
#include "media/cast/sender/fake_video_encode_accelerator_factory.h"
#include "media/cast/sender/video_frame_factory.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/video_utility.h"
#include "media/video/fake_video_encode_accelerator.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace cast {

namespace {
static const uint8_t kPixelValue = 123;
static const int kWidth = 320;
static const int kHeight = 240;

using testing::_;
using testing::AtLeast;

void SaveOperationalStatus(OperationalStatus* out_status,
                           OperationalStatus in_status) {
  DVLOG(1) << "OperationalStatus transitioning from " << *out_status << " to "
           << in_status;
  *out_status = in_status;
}

class TestPacketSender : public PacketTransport {
 public:
  TestPacketSender()
      : number_of_rtp_packets_(0), number_of_rtcp_packets_(0), paused_(false) {}

  // A singular packet implies a RTCP packet.
  bool SendPacket(PacketRef packet, base::OnceClosure cb) final {
    if (paused_) {
      stored_packet_ = packet;
      callback_ = std::move(cb);
      return false;
    }
    if (IsRtcpPacket(&packet->data[0], packet->data.size())) {
      ++number_of_rtcp_packets_;
    } else {
      // Check that at least one RTCP packet was sent before the first RTP
      // packet.  This confirms that the receiver will have the necessary lip
      // sync info before it has to calculate the playout time of the first
      // frame.
      if (number_of_rtp_packets_ == 0)
        EXPECT_LE(1, number_of_rtcp_packets_);
      ++number_of_rtp_packets_;
    }
    return true;
  }

  int64_t GetBytesSent() final { return 0; }

  void StartReceiving(PacketReceiverCallbackWithStatus packet_receiver) final {}

  void StopReceiving() final {}

  int number_of_rtp_packets() const { return number_of_rtp_packets_; }

  int number_of_rtcp_packets() const { return number_of_rtcp_packets_; }

  void SetPause(bool paused) {
    paused_ = paused;
    if (!paused && stored_packet_.get()) {
      SendPacket(stored_packet_, base::OnceClosure());
      std::move(callback_).Run();
    }
  }

 private:
  int number_of_rtp_packets_;
  int number_of_rtcp_packets_;
  bool paused_;
  base::OnceClosure callback_;
  PacketRef stored_packet_;

  DISALLOW_COPY_AND_ASSIGN(TestPacketSender);
};

void IgnorePlayoutDelayChanges(base::TimeDelta unused_playout_delay) {}

class PeerVideoSender : public VideoSender {
 public:
  PeerVideoSender(
      scoped_refptr<CastEnvironment> cast_environment,
      const FrameSenderConfig& video_config,
      const StatusChangeCallback& status_change_cb,
      const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
      CastTransport* const transport_sender)
      : VideoSender(cast_environment,
                    video_config,
                    status_change_cb,
                    create_vea_cb,
                    transport_sender,
                    base::BindRepeating(&IgnorePlayoutDelayChanges),
                    base::BindRepeating(&PeerVideoSender::ProcessFeedback,
                                        base::Unretained(this))) {}

  using VideoSender::OnReceivedCastFeedback;
  using VideoSender::OnReceivedPli;

  void ProcessFeedback(const media::VideoCaptureFeedback& feedback) {
    feedback_ = feedback;
  }

  VideoCaptureFeedback GetFeedback() { return feedback_; }

 private:
  VideoCaptureFeedback feedback_;
};

class TransportClient : public CastTransport::Client {
 public:
  TransportClient() = default;

  void OnStatusChanged(CastTransportStatus status) final {
    EXPECT_EQ(TRANSPORT_STREAM_INITIALIZED, status);
  }
  void OnLoggingEventsReceived(
      std::unique_ptr<std::vector<FrameEvent>> frame_events,
      std::unique_ptr<std::vector<PacketEvent>> packet_events) final {}
  void ProcessRtpPacket(std::unique_ptr<Packet> packet) final {}

  DISALLOW_COPY_AND_ASSIGN(TransportClient);
};

}  // namespace

class VideoSenderTest : public ::testing::Test {
 protected:
  VideoSenderTest()
      : task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)),
        cast_environment_(new CastEnvironment(&testing_clock_,
                                              task_runner_,
                                              task_runner_,
                                              task_runner_)),
        operational_status_(STATUS_UNINITIALIZED),
        vea_factory_(task_runner_) {
    testing_clock_.Advance(base::TimeTicks::Now() - base::TimeTicks());
    vea_factory_.SetAutoRespond(true);
    last_pixel_value_ = kPixelValue;
    transport_ = new TestPacketSender();
    transport_sender_ = std::make_unique<CastTransportImpl>(
        &testing_clock_, base::TimeDelta(), std::make_unique<TransportClient>(),
        base::WrapUnique(transport_), task_runner_);
  }

  ~VideoSenderTest() override = default;

  void TearDown() final {
    video_sender_.reset();
    task_runner_->RunTasks();
  }

  // If |external| is true then external video encoder (VEA) is used.
  // |expect_init_success| is true if initialization is expected to succeed.
  void InitEncoder(bool external, bool expect_init_success) {
    FrameSenderConfig video_config = GetDefaultVideoSenderConfig();
    video_config.use_external_encoder = external;

    ASSERT_EQ(operational_status_, STATUS_UNINITIALIZED);

    if (external) {
      vea_factory_.SetInitializationWillSucceed(expect_init_success);
      video_sender_ = std::make_unique<PeerVideoSender>(
          cast_environment_, video_config,
          base::BindRepeating(&SaveOperationalStatus, &operational_status_),
          base::BindRepeating(
              &FakeVideoEncodeAcceleratorFactory::CreateVideoEncodeAccelerator,
              base::Unretained(&vea_factory_)),
          transport_sender_.get());
    } else {
      video_sender_ = std::make_unique<PeerVideoSender>(
          cast_environment_, video_config,
          base::BindRepeating(&SaveOperationalStatus, &operational_status_),
          base::DoNothing(), transport_sender_.get());
    }
    task_runner_->RunTasks();
  }

  scoped_refptr<media::VideoFrame> GetNewVideoFrame() {
    if (first_frame_timestamp_.is_null())
      first_frame_timestamp_ = testing_clock_.NowTicks();
    gfx::Size size(kWidth, kHeight);
    scoped_refptr<media::VideoFrame> video_frame =
        media::VideoFrame::CreateFrame(
            PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
            testing_clock_.NowTicks() - first_frame_timestamp_);
    PopulateVideoFrame(video_frame.get(), last_pixel_value_++);
    return video_frame;
  }

  scoped_refptr<media::VideoFrame> GetLargeNewVideoFrame() {
    if (first_frame_timestamp_.is_null())
      first_frame_timestamp_ = testing_clock_.NowTicks();
    gfx::Size size(kWidth, kHeight);
    scoped_refptr<media::VideoFrame> video_frame =
        media::VideoFrame::CreateFrame(
            PIXEL_FORMAT_I420, size, gfx::Rect(size), size,
            testing_clock_.NowTicks() - first_frame_timestamp_);
    PopulateVideoFrameWithNoise(video_frame.get());
    return video_frame;
  }

  void RunTasks(int during_ms) {
    task_runner_->Sleep(base::Milliseconds(during_ms));
  }

  base::SimpleTestTickClock testing_clock_;
  const scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;
  const scoped_refptr<CastEnvironment> cast_environment_;
  OperationalStatus operational_status_;
  FakeVideoEncodeAcceleratorFactory vea_factory_;
  TestPacketSender* transport_;  // Owned by CastTransport.
  std::unique_ptr<CastTransportImpl> transport_sender_;
  std::unique_ptr<PeerVideoSender> video_sender_;
  int last_pixel_value_;
  base::TimeTicks first_frame_timestamp_;

 private:
  DISALLOW_COPY_AND_ASSIGN(VideoSenderTest);
};

TEST_F(VideoSenderTest, BuiltInEncoder) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

  const base::TimeTicks reference_time = testing_clock_.NowTicks();
  video_sender_->InsertRawVideoFrame(video_frame, reference_time);

  task_runner_->RunTasks();
  EXPECT_LE(1, transport_->number_of_rtp_packets());
  EXPECT_LE(1, transport_->number_of_rtcp_packets());
}

TEST_F(VideoSenderTest, ExternalEncoder) {
  InitEncoder(true, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
  // so that frames will be sent to it.  Therefore, no encoder activity should
  // have occurred at this point.  Send a frame to spurn creation of the
  // underlying ExternalVideoEncoder instance.
  if (vea_factory_.vea_response_count() == 0) {
    video_sender_->InsertRawVideoFrame(GetNewVideoFrame(),
                                       testing_clock_.NowTicks());
    task_runner_->RunTasks();
  }
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);
  RunTasks(33);

  // VideoSender created an encoder for 1280x720 frames, in order to provide the
  // INITIALIZED status.
  EXPECT_EQ(1, vea_factory_.vea_response_count());

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

  for (int i = 0; i < 3; ++i) {
    const base::TimeTicks reference_time = testing_clock_.NowTicks();
    video_sender_->InsertRawVideoFrame(video_frame, reference_time);
    RunTasks(33);
    // VideoSender re-created the encoder for the 320x240 frames we're
    // providing.
    EXPECT_EQ(1, vea_factory_.vea_response_count());
  }

  video_sender_.reset(NULL);
  task_runner_->RunTasks();
  EXPECT_EQ(1, vea_factory_.vea_response_count());
}

TEST_F(VideoSenderTest, ExternalEncoderInitFails) {
  InitEncoder(true, false);

  // The SizeAdaptableExternalVideoEncoder initally reports STATUS_INITIALIZED
  // so that frames will be sent to it.  Send a frame to spurn creation of the
  // underlying ExternalVideoEncoder instance, which should result in failure.
  if (operational_status_ == STATUS_INITIALIZED ||
      operational_status_ == STATUS_CODEC_REINIT_PENDING) {
    video_sender_->InsertRawVideoFrame(GetNewVideoFrame(),
                                       testing_clock_.NowTicks());
    task_runner_->RunTasks();
  }
  EXPECT_EQ(STATUS_CODEC_INIT_FAILED, operational_status_);

  video_sender_.reset(NULL);
  task_runner_->RunTasks();
}

TEST_F(VideoSenderTest, RtcpTimer) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

  const base::TimeTicks reference_time = testing_clock_.NowTicks();
  video_sender_->InsertRawVideoFrame(video_frame, reference_time);

  // Make sure that we send at least one RTCP packet.
  base::TimeDelta max_rtcp_timeout =
      base::Milliseconds(1 + kRtcpReportIntervalMs * 3 / 2);

  RunTasks(max_rtcp_timeout.InMilliseconds());
  EXPECT_LE(1, transport_->number_of_rtp_packets());
  EXPECT_LE(1, transport_->number_of_rtcp_packets());
  // Build Cast msg and expect RTCP packet.
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();
  video_sender_->OnReceivedCastFeedback(cast_feedback);
  RunTasks(max_rtcp_timeout.InMilliseconds());
  EXPECT_LE(1, transport_->number_of_rtcp_packets());
}

TEST_F(VideoSenderTest, ResendTimer) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

  const base::TimeTicks reference_time = testing_clock_.NowTicks();
  video_sender_->InsertRawVideoFrame(video_frame, reference_time);

  // ACK the key frame.
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();
  video_sender_->OnReceivedCastFeedback(cast_feedback);

  video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, reference_time);

  base::TimeDelta max_resend_timeout =
      base::Milliseconds(1 + kDefaultRtpMaxDelayMs);

  // Make sure that we do a re-send.
  RunTasks(max_resend_timeout.InMilliseconds());
  // Should have sent at least 3 packets.
  EXPECT_LE(3, transport_->number_of_rtp_packets() +
                   transport_->number_of_rtcp_packets());
}

TEST_F(VideoSenderTest, LogAckReceivedEvent) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  SimpleEventSubscriber event_subscriber;
  cast_environment_->logger()->Subscribe(&event_subscriber);

  int num_frames = 10;
  for (int i = 0; i < num_frames; i++) {
    scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

    const base::TimeTicks reference_time = testing_clock_.NowTicks();
    video_sender_->InsertRawVideoFrame(video_frame, reference_time);
    RunTasks(33);
  }

  task_runner_->RunTasks();

  RtcpCastMessage cast_feedback(1);
  cast_feedback.ack_frame_id = FrameId::first() + num_frames - 1;

  video_sender_->OnReceivedCastFeedback(cast_feedback);

  std::vector<FrameEvent> frame_events;
  event_subscriber.GetFrameEventsAndReset(&frame_events);

  ASSERT_TRUE(!frame_events.empty());
  EXPECT_EQ(FRAME_ACK_RECEIVED, frame_events.rbegin()->type);
  EXPECT_EQ(VIDEO_EVENT, frame_events.rbegin()->media_type);
  EXPECT_EQ(FrameId::first() + num_frames - 1, frame_events.rbegin()->frame_id);

  cast_environment_->logger()->Unsubscribe(&event_subscriber);
}

TEST_F(VideoSenderTest, StopSendingInTheAbsenceOfAck) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  // Send a stream of frames and don't ACK; by default we shouldn't have more
  // than 4 frames in flight.
  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);

  // Send 3 more frames and record the number of packets sent.
  for (int i = 0; i < 3; ++i) {
    video_frame = GetNewVideoFrame();
    video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
    RunTasks(33);
  }
  const int number_of_packets_sent = transport_->number_of_rtp_packets();

  // Send 3 more frames - they should not be encoded, as we have not received
  // any acks.
  for (int i = 0; i < 3; ++i) {
    video_frame = GetNewVideoFrame();
    video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
    RunTasks(33);
  }

  // We expect a frame to be retransmitted because of duplicated ACKs.
  // Only one packet of the frame is re-transmitted.
  EXPECT_EQ(number_of_packets_sent + 1, transport_->number_of_rtp_packets());

  // Start acking and make sure we're back to steady-state.
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();
  video_sender_->OnReceivedCastFeedback(cast_feedback);
  EXPECT_LE(4, transport_->number_of_rtp_packets() +
                   transport_->number_of_rtcp_packets());

  // Empty the pipeline.
  RunTasks(100);
  // Should have sent at least 7 packets.
  EXPECT_LE(7, transport_->number_of_rtp_packets() +
                   transport_->number_of_rtcp_packets());
}

TEST_F(VideoSenderTest, DuplicateAckRetransmit) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();

  // Send 3 more frames but don't ACK.
  for (int i = 0; i < 3; ++i) {
    video_frame = GetNewVideoFrame();
    video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
    RunTasks(33);
  }
  const int number_of_packets_sent = transport_->number_of_rtp_packets();

  // Send duplicated ACKs and mix some invalid NACKs.
  for (int i = 0; i < 10; ++i) {
    RtcpCastMessage ack_feedback(1);
    ack_feedback.remote_ssrc = 2;
    ack_feedback.ack_frame_id = FrameId::first();
    RtcpCastMessage nack_feedback(1);
    nack_feedback.remote_ssrc = 2;
    nack_feedback.missing_frames_and_packets[FrameId::first() + 255] =
        PacketIdSet();
    video_sender_->OnReceivedCastFeedback(ack_feedback);
    video_sender_->OnReceivedCastFeedback(nack_feedback);
  }
  EXPECT_EQ(number_of_packets_sent, transport_->number_of_rtp_packets());

  // Re-transmit one packet because of duplicated ACKs.
  for (int i = 0; i < 3; ++i) {
    RtcpCastMessage ack_feedback(1);
    ack_feedback.remote_ssrc = 2;
    ack_feedback.ack_frame_id = FrameId::first();
    video_sender_->OnReceivedCastFeedback(ack_feedback);
  }
  EXPECT_EQ(number_of_packets_sent + 1, transport_->number_of_rtp_packets());
}

TEST_F(VideoSenderTest, DuplicateAckRetransmitDoesNotCancelRetransmits) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();

  // Send 2 more frames but don't ACK.
  for (int i = 0; i < 2; ++i) {
    video_frame = GetNewVideoFrame();
    video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
    RunTasks(33);
  }
  // Pause the transport
  transport_->SetPause(true);

  // Insert one more video frame.
  video_frame = GetLargeNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);

  const int number_of_packets_sent = transport_->number_of_rtp_packets();

  // Send duplicated ACKs and mix some invalid NACKs.
  for (int i = 0; i < 10; ++i) {
    RtcpCastMessage ack_feedback(1);
    ack_feedback.remote_ssrc = 2;
    ack_feedback.ack_frame_id = FrameId::first();
    RtcpCastMessage nack_feedback(1);
    nack_feedback.remote_ssrc = 2;
    nack_feedback.missing_frames_and_packets[FrameId::first() + 255] =
        PacketIdSet();
    video_sender_->OnReceivedCastFeedback(ack_feedback);
    video_sender_->OnReceivedCastFeedback(nack_feedback);
  }
  EXPECT_EQ(number_of_packets_sent, transport_->number_of_rtp_packets());

  // Re-transmit one packet because of duplicated ACKs.
  for (int i = 0; i < 3; ++i) {
    RtcpCastMessage ack_feedback(1);
    ack_feedback.remote_ssrc = 2;
    ack_feedback.ack_frame_id = FrameId::first();
    video_sender_->OnReceivedCastFeedback(ack_feedback);
  }

  transport_->SetPause(false);
  RunTasks(100);
  EXPECT_LT(number_of_packets_sent + 1, transport_->number_of_rtp_packets());
}

TEST_F(VideoSenderTest, AcksCancelRetransmits) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  transport_->SetPause(true);
  scoped_refptr<media::VideoFrame> video_frame = GetLargeNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);

  // Frame should be in buffer, waiting. Now let's ack it.
  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();
  video_sender_->OnReceivedCastFeedback(cast_feedback);

  transport_->SetPause(false);
  RunTasks(33);
  EXPECT_EQ(0, transport_->number_of_rtp_packets());
}

TEST_F(VideoSenderTest, CheckVideoFrameFactoryIsNull) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  EXPECT_EQ(nullptr, video_sender_->CreateVideoFrameFactory().get());
}

TEST_F(VideoSenderTest, ReportsResourceUtilizationInCallback) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  for (int i = 0; i < 3; ++i) {
    scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();

    const base::TimeTicks reference_time = testing_clock_.NowTicks();
    video_sender_->InsertRawVideoFrame(video_frame, reference_time);

    // Run encode tasks.  VideoSender::OnEncodedVideoFrame() will be called once
    // encoding of the frame is complete, and this is when the
    // resource_utilization metadata is populated.
    RunTasks(33);

    // Check that the resource_utilization value is set and non-negative.  Don't
    // check for specific values because they are dependent on real-world CPU
    // encode time, which can vary across test runs.
    double utilization = video_sender_->GetFeedback().resource_utilization;
    EXPECT_LE(0.0, utilization);
    if (i == 0)
      EXPECT_GE(1.0, utilization);  // Key frames never exceed 1.0.
    DVLOG(1) << "Utilization computed by VideoSender is: " << utilization;
  }
}

TEST_F(VideoSenderTest, CancelSendingOnReceivingPli) {
  InitEncoder(false, true);
  ASSERT_EQ(STATUS_INITIALIZED, operational_status_);

  // Send a frame and ACK it.
  scoped_refptr<media::VideoFrame> video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
  RunTasks(33);

  RtcpCastMessage cast_feedback(1);
  cast_feedback.remote_ssrc = 2;
  cast_feedback.ack_frame_id = FrameId::first();
  video_sender_->OnReceivedCastFeedback(cast_feedback);

  transport_->SetPause(true);
  // Send three more frames.
  for (int i = 0; i < 3; i++) {
    video_frame = GetNewVideoFrame();
    video_sender_->InsertRawVideoFrame(video_frame, testing_clock_.NowTicks());
    RunTasks(33);
  }
  EXPECT_EQ(1, transport_->number_of_rtp_packets());

  // Frames should be in buffer, waiting.
  // Received PLI from receiver.
  video_sender_->OnReceivedPli();
  video_frame = GetNewVideoFrame();
  video_sender_->InsertRawVideoFrame(
      video_frame, testing_clock_.NowTicks() + base::Milliseconds(1000));
  RunTasks(33);
  transport_->SetPause(false);
  RunTasks(33);
  EXPECT_EQ(2, transport_->number_of_rtp_packets());
}

}  // namespace cast
}  // namespace media
