// 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 <math.h>
#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/sys_byteorder.h"
#include "base/test/simple_test_tick_clock.h"
#include "base/test/task_environment.h"
#include "base/time/tick_clock.h"
#include "build/build_config.h"
#include "media/base/audio_bus.h"
#include "media/base/fake_single_thread_task_runner.h"
#include "media/base/video_frame.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/cast_sender.h"
#include "media/cast/logging/simple_event_subscriber.h"
#include "media/cast/net/cast_transport.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/cast_transport_defines.h"
#include "media/cast/net/cast_transport_impl.h"
#include "media/cast/test/receiver/cast_receiver.h"
#include "media/cast/test/skewed_single_thread_task_runner.h"
#include "media/cast/test/skewed_tick_clock.h"
#include "media/cast/test/utility/audio_utility.h"
#include "media/cast/test/utility/default_config.h"
#include "media/cast/test/utility/udp_proxy.h"
#include "media/cast/test/utility/video_utility.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {
namespace cast {

namespace {

// This test suite generates synthetic data. For audio, it's a sinusoid waveform
// with frequency kSoundFrequency and different amplitudes. For video, it's a
// pattern that is shifting by one pixel per frame. Each pixels' neighbors right
// and down is incremented by one; since the pixel value is 8 bit it will wrap
// frequently within the image. Visually, this creates diagonal color bands that
// move across the screen.
static const int64_t kStartMillisecond = INT64_C(1245);
static const int kAudioChannels = 2;
static const double kSoundFrequency = 314.15926535897;  // Freq of sine wave.
static const float kSoundVolume = 0.5f;
static const int kVideoWidth = 320;
static const int kVideoHeight = 180;

// Since the video encoded and decoded an error will be introduced; when
// comparing individual pixels the error can be quite large; we allow a PSNR of
// at least |kVideoAcceptedPSNR|.
static const double kVideoAcceptedPSNR = 38.0;

// The tests are commonly implemented with |kFrameTimerMs| RunTask function;
// a normal video is 30 fps hence the 33 ms between frames.
//
// TODO(miu): The errors in timing will add up significantly.  Find an
// alternative approach that eliminates use of this constant.
static const int kFrameTimerMs = 33;

// The size of audio frames.  The encoder joins/breaks all inserted audio into
// chunks of this size.
static const int kAudioFrameDurationMs = 10;

// The amount of time between frame capture on the sender and playout on the
// receiver.
static const int kTargetPlayoutDelayMs = 100;

// The maximum amount of deviation expected in the playout times emitted by the
// receiver.
static const int kMaxAllowedPlayoutErrorMs = 30;

std::string ConvertFromBase16String(const std::string& base_16) {
  std::string compressed;
  DCHECK_EQ(base_16.size() % 2, 0u) << "Must be a multiple of 2";
  compressed.reserve(base_16.size() / 2);

  if (!base::HexStringToString(base_16, &compressed)) {
    NOTREACHED();
  }
  return compressed;
}

void ExpectSuccessOperationalStatus(OperationalStatus status) {
  EXPECT_EQ(STATUS_INITIALIZED, status);
}

// This is wrapped in a struct because it needs to be put into a std::map.
typedef struct {
  int counter[kNumOfLoggingEvents];
} LoggingEventCounts;

// Constructs a map from each frame (RTP timestamp) to counts of each event
// type logged for that frame.
std::map<RtpTimeTicks, LoggingEventCounts> GetEventCountsForFrameEvents(
    const std::vector<FrameEvent>& frame_events) {
  std::map<RtpTimeTicks, LoggingEventCounts> event_counter_for_frame;
  for (const FrameEvent& frame_event : frame_events) {
    auto map_it = event_counter_for_frame.find(frame_event.rtp_timestamp);
    if (map_it == event_counter_for_frame.end()) {
      LoggingEventCounts new_counter;
      memset(&new_counter, 0, sizeof(new_counter));
      ++(new_counter.counter[frame_event.type]);
      event_counter_for_frame.insert(
          std::make_pair(frame_event.rtp_timestamp, new_counter));
    } else {
      ++(map_it->second.counter[frame_event.type]);
    }
  }
  return event_counter_for_frame;
}

// Constructs a map from each packet (Packet ID) to counts of each event
// type logged for that packet.
std::map<uint16_t, LoggingEventCounts> GetEventCountsForPacketEvents(
    const std::vector<PacketEvent>& packet_events) {
  std::map<uint16_t, LoggingEventCounts> event_counter_for_packet;
  for (const PacketEvent& packet_event : packet_events) {
    auto map_it = event_counter_for_packet.find(packet_event.packet_id);
    if (map_it == event_counter_for_packet.end()) {
      LoggingEventCounts new_counter;
      memset(&new_counter, 0, sizeof(new_counter));
      ++(new_counter.counter[packet_event.type]);
      event_counter_for_packet.insert(
          std::make_pair(packet_event.packet_id, new_counter));
    } else {
      ++(map_it->second.counter[packet_event.type]);
    }
  }
  return event_counter_for_packet;
}

// Shim that turns forwards packets from a test::PacketPipe to a
// PacketReceiverCallback.
class LoopBackPacketPipe final : public test::PacketPipe {
 public:
  explicit LoopBackPacketPipe(const PacketReceiverCallback& packet_receiver)
      : packet_receiver_(packet_receiver) {}

  ~LoopBackPacketPipe() override = default;

  // PacketPipe implementations.
  void Send(std::unique_ptr<Packet> packet) override {
    packet_receiver_.Run(std::move(packet));
  }

 private:
  PacketReceiverCallback packet_receiver_;
};

// Class that sends the packet direct from sender into the receiver with the
// ability to drop packets between the two.
//
// TODO(miu): This should be reconciled/merged into
// media/cast/test/loopback_transport.*.  It's roughly the same class and has
// exactly the same name (and when it was outside of the anonymous namespace bad
// things happened when linking on Android!).
class LoopBackTransport : public PacketTransport {
 public:
  explicit LoopBackTransport(scoped_refptr<CastEnvironment> cast_environment)
      : send_packets_(true),
        drop_packets_belonging_to_odd_frames_(false),
        cast_environment_(cast_environment),
        bytes_sent_(0) {}

  void SetPacketReceiver(
      const PacketReceiverCallback& packet_receiver,
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
      const base::TickClock* clock) {
    std::unique_ptr<test::PacketPipe> loopback_pipe(
        new LoopBackPacketPipe(packet_receiver));
    if (packet_pipe_) {
      packet_pipe_->AppendToPipe(std::move(loopback_pipe));
    } else {
      packet_pipe_ = std::move(loopback_pipe);
    }
    packet_pipe_->InitOnIOThread(task_runner, clock);
  }

  bool SendPacket(PacketRef packet, base::OnceClosure cb) final {
    DCHECK(cast_environment_->CurrentlyOn(CastEnvironment::MAIN));
    if (!send_packets_)
      return true;

    bytes_sent_ += packet->data.size();
    if (drop_packets_belonging_to_odd_frames_) {
      const uint8_t truncated_frame_id = packet->data[13];
      if (truncated_frame_id % 2 == 1)
        return true;
    }

    std::unique_ptr<Packet> packet_copy(new Packet(packet->data));
    packet_pipe_->Send(std::move(packet_copy));
    return true;
  }

  int64_t GetBytesSent() final { return bytes_sent_; }

  void StartReceiving(PacketReceiverCallbackWithStatus packet_receiver) final {}

  void StopReceiving() final {}

  void SetSendPackets(bool send_packets) { send_packets_ = send_packets; }

  void DropAllPacketsBelongingToOddFrames() {
    drop_packets_belonging_to_odd_frames_ = true;
  }

  void SetPacketPipe(std::unique_ptr<test::PacketPipe> pipe) {
    // Append the loopback pipe to the end.
    pipe->AppendToPipe(std::move(packet_pipe_));
    packet_pipe_ = std::move(pipe);
  }

 private:
  bool send_packets_;
  bool drop_packets_belonging_to_odd_frames_;
  scoped_refptr<CastEnvironment> cast_environment_;
  std::unique_ptr<test::PacketPipe> packet_pipe_;
  int64_t bytes_sent_;
};

// Class that verifies the audio frames coming out of the receiver.
class TestReceiverAudioCallback
    : public base::RefCountedThreadSafe<TestReceiverAudioCallback> {
 public:
  struct ExpectedAudioFrame {
    std::unique_ptr<AudioBus> audio_bus;
    base::TimeTicks playout_time;
  };

  TestReceiverAudioCallback() : num_called_(0) {}

  void SetExpectedSamplingFrequency(int expected_sampling_frequency) {
    expected_sampling_frequency_ = expected_sampling_frequency;
  }

  void AddExpectedResult(const AudioBus& audio_bus,
                         base::TimeTicks playout_time) {
    std::unique_ptr<ExpectedAudioFrame> expected_audio_frame(
        new ExpectedAudioFrame());
    expected_audio_frame->audio_bus =
        AudioBus::Create(audio_bus.channels(), audio_bus.frames());
    audio_bus.CopyTo(expected_audio_frame->audio_bus.get());
    expected_audio_frame->playout_time = playout_time;
    expected_frames_.push_back(std::move(expected_audio_frame));
  }

  void IgnoreAudioFrame(std::unique_ptr<AudioBus> audio_bus,
                        base::TimeTicks playout_time,
                        bool is_continuous) {
    ++num_called_;
  }

  void CheckAudioFrame(std::unique_ptr<AudioBus> audio_bus,
                       base::TimeTicks playout_time,
                       bool is_continuous) {
    ++num_called_;

    ASSERT_TRUE(audio_bus);
    ASSERT_FALSE(expected_frames_.empty());
    const std::unique_ptr<ExpectedAudioFrame> expected_audio_frame =
        std::move(expected_frames_.front());
    expected_frames_.pop_front();

    EXPECT_EQ(audio_bus->channels(), kAudioChannels);
    EXPECT_EQ(audio_bus->frames(), expected_audio_frame->audio_bus->frames());
    for (int ch = 0; ch < audio_bus->channels(); ++ch) {
      EXPECT_NEAR(
          CountZeroCrossings(expected_audio_frame->audio_bus->channel(ch),
                             expected_audio_frame->audio_bus->frames()),
          CountZeroCrossings(audio_bus->channel(ch), audio_bus->frames()), 1);
    }

    EXPECT_NEAR(
        (playout_time - expected_audio_frame->playout_time).InMillisecondsF(),
        0.0, kMaxAllowedPlayoutErrorMs);
    VLOG_IF(1, !last_playout_time_.is_null())
        << "Audio frame playout time delta (compared to last frame) is "
        << (playout_time - last_playout_time_).InMicroseconds() << " usec.";
    last_playout_time_ = playout_time;

    EXPECT_TRUE(is_continuous);
  }

  int number_times_called() const { return num_called_; }

 protected:
  virtual ~TestReceiverAudioCallback() = default;

 private:
  friend class base::RefCountedThreadSafe<TestReceiverAudioCallback>;

  int num_called_;
  int expected_sampling_frequency_;
  std::list<std::unique_ptr<ExpectedAudioFrame>> expected_frames_;
  base::TimeTicks last_playout_time_;
};

// Class that verifies the video frames coming out of the receiver.
class TestReceiverVideoCallback
    : public base::RefCountedThreadSafe<TestReceiverVideoCallback> {
 public:
  struct ExpectedVideoFrame {
    int frame_number;
    gfx::Size size;
    base::TimeTicks playout_time;
    bool should_be_continuous;
  };

  TestReceiverVideoCallback() : num_called_(0) {}

  void AddExpectedResult(int frame_number,
                         const gfx::Size& size,
                         base::TimeTicks playout_time,
                         bool should_be_continuous) {
    ExpectedVideoFrame expected_video_frame;
    expected_video_frame.frame_number = frame_number;
    expected_video_frame.size = size;
    expected_video_frame.playout_time = playout_time;
    expected_video_frame.should_be_continuous = should_be_continuous;
    expected_frame_.push_back(expected_video_frame);
  }

  void CheckVideoFrame(bool examine_content,
                       scoped_refptr<media::VideoFrame> video_frame,
                       base::TimeTicks playout_time,
                       bool is_continuous) {
    ++num_called_;

    ASSERT_TRUE(video_frame);
    ASSERT_FALSE(expected_frame_.empty());
    ExpectedVideoFrame expected_video_frame = expected_frame_.front();
    expected_frame_.pop_front();

    EXPECT_EQ(expected_video_frame.size.width(),
              video_frame->visible_rect().width());
    EXPECT_EQ(expected_video_frame.size.height(),
              video_frame->visible_rect().height());

    if (examine_content && expected_video_frame.should_be_continuous) {
      scoped_refptr<media::VideoFrame> expected_I420_frame =
          media::VideoFrame::CreateFrame(
              PIXEL_FORMAT_I420, expected_video_frame.size,
              gfx::Rect(expected_video_frame.size), expected_video_frame.size,
              base::TimeDelta());
      PopulateVideoFrame(expected_I420_frame.get(),
                         expected_video_frame.frame_number);
      EXPECT_LE(kVideoAcceptedPSNR,
                I420PSNR(*expected_I420_frame, *video_frame));
    }

    EXPECT_NEAR(
        (playout_time - expected_video_frame.playout_time).InMillisecondsF(),
        0.0, kMaxAllowedPlayoutErrorMs);
    VLOG_IF(1, !last_playout_time_.is_null())
        << "Video frame playout time delta (compared to last frame) is "
        << (playout_time - last_playout_time_).InMicroseconds() << " usec.";
    last_playout_time_ = playout_time;

    EXPECT_EQ(expected_video_frame.should_be_continuous, is_continuous);
  }

  int number_times_called() const { return num_called_; }

 protected:
  virtual ~TestReceiverVideoCallback() = default;

 private:
  friend class base::RefCountedThreadSafe<TestReceiverVideoCallback>;

  int num_called_;
  std::list<ExpectedVideoFrame> expected_frame_;
  base::TimeTicks last_playout_time_;
};

}  // namespace

// The actual test class, generate synthetic data for both audio and video and
// send those through the sender and receiver and analyzes the result.
class End2EndTest : public ::testing::Test {
 public:
  void ReceivePacket(std::unique_ptr<media::cast::Packet> packet) {
    cast_receiver_->ReceivePacket(std::move(packet));
  }

 protected:
  End2EndTest()
      : start_time_(),
        task_runner_(new FakeSingleThreadTaskRunner(&testing_clock_)),
        testing_clock_sender_(&testing_clock_),
        task_runner_sender_(
            new test::SkewedSingleThreadTaskRunner(task_runner_)),
        testing_clock_receiver_(&testing_clock_),
        task_runner_receiver_(
            new test::SkewedSingleThreadTaskRunner(task_runner_)),
        cast_environment_sender_(new CastEnvironment(&testing_clock_sender_,
                                                     task_runner_sender_,
                                                     task_runner_sender_,
                                                     task_runner_sender_)),
        cast_environment_receiver_(new CastEnvironment(&testing_clock_receiver_,
                                                       task_runner_receiver_,
                                                       task_runner_receiver_,
                                                       task_runner_receiver_)),
        receiver_to_sender_(new LoopBackTransport(cast_environment_receiver_)),
        sender_to_receiver_(new LoopBackTransport(cast_environment_sender_)),
        test_receiver_audio_callback_(new TestReceiverAudioCallback()),
        test_receiver_video_callback_(new TestReceiverVideoCallback()) {
    testing_clock_.Advance(base::Milliseconds(kStartMillisecond));
    cast_environment_sender_->logger()->Subscribe(&event_subscriber_sender_);
  }

  void Configure(Codec video_codec, Codec audio_codec) {
    audio_sender_config_.sender_ssrc = 1;
    audio_sender_config_.receiver_ssrc = 2;
    audio_sender_config_.max_playout_delay =
        base::Milliseconds(kTargetPlayoutDelayMs);
    audio_sender_config_.rtp_payload_type = RtpPayloadType::AUDIO_OPUS;
    audio_sender_config_.use_external_encoder = false;
    audio_sender_config_.rtp_timebase = kDefaultAudioSamplingRate;
    audio_sender_config_.channels = kAudioChannels;
    audio_sender_config_.max_bitrate = kDefaultAudioEncoderBitrate;
    audio_sender_config_.codec = audio_codec;
    audio_sender_config_.aes_iv_mask =
        ConvertFromBase16String("abcdeffedcba12345678900987654321");
    audio_sender_config_.aes_key =
        ConvertFromBase16String("deadbeefcafecafedeadbeefb0b0b0b0");

    audio_receiver_config_.receiver_ssrc = audio_sender_config_.receiver_ssrc;
    audio_receiver_config_.sender_ssrc = audio_sender_config_.sender_ssrc;
    audio_receiver_config_.rtp_max_delay_ms = kTargetPlayoutDelayMs;
    audio_receiver_config_.rtp_payload_type =
        audio_sender_config_.rtp_payload_type;
    audio_receiver_config_.rtp_timebase = audio_sender_config_.rtp_timebase;
    audio_receiver_config_.channels = kAudioChannels;
    audio_receiver_config_.target_frame_rate = 100;
    audio_receiver_config_.codec = audio_sender_config_.codec;
    audio_receiver_config_.aes_iv_mask = audio_sender_config_.aes_iv_mask;
    audio_receiver_config_.aes_key = audio_sender_config_.aes_key;

    test_receiver_audio_callback_->SetExpectedSamplingFrequency(
        audio_receiver_config_.rtp_timebase);

    video_sender_config_.sender_ssrc = 3;
    video_sender_config_.receiver_ssrc = 4;
    video_sender_config_.max_playout_delay =
        base::Milliseconds(kTargetPlayoutDelayMs);
    video_sender_config_.rtp_payload_type = RtpPayloadType::VIDEO_VP8;
    video_sender_config_.use_external_encoder = false;
    video_sender_config_.rtp_timebase = kVideoFrequency;
    video_sender_config_.max_bitrate = 50000;
    video_sender_config_.min_bitrate = 10000;
    video_sender_config_.start_bitrate = 10000;
    video_sender_config_.video_codec_params.max_qp = 30;
    video_sender_config_.video_codec_params.min_qp = 4;
    video_sender_config_.max_frame_rate = 30;
    video_sender_config_.codec = video_codec;
    video_sender_config_.aes_iv_mask =
        ConvertFromBase16String("1234567890abcdeffedcba0987654321");
    video_sender_config_.aes_key =
        ConvertFromBase16String("deadbeefcafeb0b0b0b0cafedeadbeef");

    video_receiver_config_.receiver_ssrc = video_sender_config_.receiver_ssrc;
    video_receiver_config_.sender_ssrc = video_sender_config_.sender_ssrc;
    video_receiver_config_.rtp_max_delay_ms = kTargetPlayoutDelayMs;
    video_receiver_config_.rtp_payload_type =
        video_sender_config_.rtp_payload_type;
    video_receiver_config_.rtp_timebase = kVideoFrequency;
    video_receiver_config_.channels = 1;
    video_receiver_config_.target_frame_rate =
        video_sender_config_.max_frame_rate;
    video_receiver_config_.codec = video_sender_config_.codec;
    video_receiver_config_.aes_iv_mask = video_sender_config_.aes_iv_mask;
    video_receiver_config_.aes_key = video_sender_config_.aes_key;
  }

  void SetReceiverSkew(double skew, base::TimeDelta offset) {
    testing_clock_receiver_.SetSkew(skew, offset);
    task_runner_receiver_->SetSkew(1.0 / skew);
  }

  // Specify the minimum/maximum difference in playout times between two
  // consecutive frames.  Also, specify the maximum absolute rate of change over
  // each three consecutive frames.
  void SetExpectedVideoPlayoutSmoothness(base::TimeDelta min_delta,
                                         base::TimeDelta max_delta,
                                         base::TimeDelta max_curvature) {
    min_video_playout_delta_ = min_delta;
    max_video_playout_delta_ = max_delta;
    max_video_playout_curvature_ = max_curvature;
  }

  void FeedAudioFrames(int count, bool will_be_checked) {
    for (int i = 0; i < count; ++i) {
      std::unique_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus(
          base::Milliseconds(kAudioFrameDurationMs)));
      const base::TimeTicks reference_time =
          testing_clock_sender_.NowTicks() +
          i * base::Milliseconds(kAudioFrameDurationMs);
      if (will_be_checked) {
        test_receiver_audio_callback_->AddExpectedResult(
            *audio_bus,
            reference_time + base::Milliseconds(kTargetPlayoutDelayMs));
      }
      audio_frame_input_->InsertAudio(std::move(audio_bus), reference_time);
    }
  }

  void FeedAudioFramesWithExpectedDelay(int count, base::TimeDelta delay) {
    for (int i = 0; i < count; ++i) {
      std::unique_ptr<AudioBus> audio_bus(audio_bus_factory_->NextAudioBus(
          base::Milliseconds(kAudioFrameDurationMs)));
      const base::TimeTicks reference_time =
          testing_clock_sender_.NowTicks() +
          i * base::Milliseconds(kAudioFrameDurationMs);
      test_receiver_audio_callback_->AddExpectedResult(
          *audio_bus,
          reference_time + delay + base::Milliseconds(kTargetPlayoutDelayMs));
      audio_frame_input_->InsertAudio(std::move(audio_bus), reference_time);
    }
  }

  void RequestAudioFrames(int count, bool with_check) {
    for (int i = 0; i < count; ++i) {
      cast_receiver_->RequestDecodedAudioFrame(base::BindRepeating(
          with_check ? &TestReceiverAudioCallback::CheckAudioFrame
                     : &TestReceiverAudioCallback::IgnoreAudioFrame,
          test_receiver_audio_callback_));
    }
  }

  void Create();

  ~End2EndTest() override {
    cast_environment_sender_->logger()->Unsubscribe(&event_subscriber_sender_);
  }

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

  gfx::Size GetTestVideoFrameSize() const {
    if (video_sender_config_.codec == CODEC_VIDEO_FAKE)
      return gfx::Size(2, 2);
    else
      return gfx::Size(kVideoWidth, kVideoHeight);
  }

  void SendVideoFrame(int frame_number, base::TimeTicks reference_time) {
    if (start_time_.is_null())
      start_time_ = reference_time;
    const base::TimeDelta time_diff = reference_time - start_time_;
    scoped_refptr<media::VideoFrame> video_frame;
    if (video_sender_config_.codec == CODEC_VIDEO_FAKE) {
      video_frame =
          media::VideoFrame::CreateBlackFrame(GetTestVideoFrameSize());
    } else {
      const gfx::Size size = GetTestVideoFrameSize();
      video_frame = media::VideoFrame::CreateFrame(
          PIXEL_FORMAT_I420, size, gfx::Rect(size), size, time_diff);
      PopulateVideoFrame(video_frame.get(), frame_number);
    }
    video_frame->set_timestamp(reference_time - start_time_);
    video_frame_input_->InsertRawVideoFrame(video_frame, reference_time);
  }

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

  // Send and receive audio and video frames for the given |duration|.  Returns
  // the total number of audio and video frames sent.
  std::pair<int, int> RunAudioVideoLoop(base::TimeDelta duration) {
    base::TimeTicks next_video_frame_at = testing_clock_.NowTicks();
    base::TimeTicks video_reference_time;
    int audio_frames_sent = 0;
    int video_frames_sent = 0;
    const base::TimeTicks end_time = testing_clock_.NowTicks() + duration;
    while (testing_clock_.NowTicks() < end_time) {
      // Opus introduces a tiny delay before the sinewave starts; so don't
      // examine the first audio frame's data receiver-side.
      const bool verify_audio_data =
          audio_frames_sent > 0 ||
          audio_sender_config_.codec == CODEC_AUDIO_PCM16;
      FeedAudioFrames(1, verify_audio_data);
      ++audio_frames_sent;

      const bool send_and_receive_a_video_frame =
          testing_clock_.NowTicks() >= next_video_frame_at;
      if (send_and_receive_a_video_frame) {
        video_reference_time = next_video_frame_at;
        next_video_frame_at += base::Milliseconds(kFrameTimerMs);
        test_receiver_video_callback_->AddExpectedResult(
            video_frames_sent, GetTestVideoFrameSize(),
            testing_clock_.NowTicks() +
                base::Milliseconds(kTargetPlayoutDelayMs),
            true);
        SendVideoFrame(video_frames_sent, video_reference_time);
        ++video_frames_sent;
      }

      RunTasks(kAudioFrameDurationMs);

      RequestAudioFrames(1, verify_audio_data);
      if (send_and_receive_a_video_frame) {
        cast_receiver_->RequestDecodedVideoFrame(base::BindRepeating(
            &TestReceiverVideoCallback::CheckVideoFrame,
            test_receiver_video_callback_,
            video_sender_config_.codec != CODEC_VIDEO_FAKE));
      }
    }

    // Verify all audio and video frames were received.
    RunTasks(kFrameTimerMs + kTargetPlayoutDelayMs);  // Let the data flow.
    EXPECT_EQ(audio_frames_sent,
              test_receiver_audio_callback_->number_times_called());
    EXPECT_EQ(video_frames_sent,
              test_receiver_video_callback_->number_times_called());

    return std::make_pair(audio_frames_sent, video_frames_sent);
  }

  // Queries the EventSubscriber for all accumulated frame and packet events for
  // audio and video and verifies all logging information was captured
  // correctly.
  void VerifyLogging(int num_expected_audio_frames,
                     int num_expected_video_frames) {
    // Partition the frame and packet events into separate vectors for audio
    // versus video.
    std::vector<FrameEvent> all_frame_events;
    event_subscriber_sender_.GetFrameEventsAndReset(&all_frame_events);
    std::vector<FrameEvent> audio_frame_events;
    std::vector<FrameEvent> video_frame_events;
    for (const FrameEvent& event : all_frame_events) {
      switch (event.media_type) {
        case AUDIO_EVENT:
          audio_frame_events.push_back(event);
          break;
        case VIDEO_EVENT:
          video_frame_events.push_back(event);
          break;
        default:
          FAIL();
      }
    }
    std::vector<PacketEvent> all_packet_events;
    event_subscriber_sender_.GetPacketEventsAndReset(&all_packet_events);
    std::vector<PacketEvent> audio_packet_events;
    std::vector<PacketEvent> video_packet_events;
    for (const PacketEvent& event : all_packet_events) {
      switch (event.media_type) {
        case AUDIO_EVENT:
          audio_packet_events.push_back(event);
          break;
        case VIDEO_EVENT:
          video_packet_events.push_back(event);
          break;
        default:
          FAIL();
      }
    }

    // For each frame, count the number of events that occurred for each event
    // for that frame.
    std::map<RtpTimeTicks, LoggingEventCounts> audio_event_counts_by_frame =
        GetEventCountsForFrameEvents(audio_frame_events);
    EXPECT_EQ(static_cast<size_t>(num_expected_audio_frames),
              audio_event_counts_by_frame.size());
    std::map<RtpTimeTicks, LoggingEventCounts> video_event_counts_by_frame =
        GetEventCountsForFrameEvents(video_frame_events);
    EXPECT_EQ(static_cast<size_t>(num_expected_video_frames),
              video_event_counts_by_frame.size());

    // Examine the types of each frame and packet event and verify required
    // events are present and unknown ones are not.
    VerifyLoggingEventCounts(audio_event_counts_by_frame,
                             GetEventCountsForPacketEvents(audio_packet_events),
                             true);
    VerifyLoggingEventCounts(video_event_counts_by_frame,
                             GetEventCountsForPacketEvents(video_packet_events),
                             false);
  }

  // Examines histograms of event types to verify all logging information was
  // captured correctly.
  static void VerifyLoggingEventCounts(
      const std::map<RtpTimeTicks, LoggingEventCounts>& event_counts_by_frame,
      const std::map<uint16_t, LoggingEventCounts>& event_counts_by_packet,
      bool for_audio) {
    // Verify that each frame has the expected types of events logged.
    for (const auto& e : event_counts_by_frame) {
      int total_event_count_for_frame = 0;
      for (int i = 0; i < kNumOfLoggingEvents; ++i) {
        total_event_count_for_frame += e.second.counter[i];
      }

      int count_of_valid_events = 0;
      if (!for_audio) {
        EXPECT_EQ(1, e.second.counter[FRAME_CAPTURE_BEGIN]);
        ++count_of_valid_events;
        EXPECT_EQ(1, e.second.counter[FRAME_CAPTURE_END]);
        ++count_of_valid_events;
      }
      EXPECT_EQ(1, e.second.counter[FRAME_ENCODED]);
      ++count_of_valid_events;
      EXPECT_EQ(1, e.second.counter[FRAME_DECODED]);
      ++count_of_valid_events;
      EXPECT_EQ(1, e.second.counter[FRAME_PLAYOUT]);
      ++count_of_valid_events;

      // There is no guarantee that FRAME_ACK_SENT is logged exactly once per
      // frame.
      EXPECT_GT(e.second.counter[FRAME_ACK_SENT], 0);
      count_of_valid_events += e.second.counter[FRAME_ACK_SENT];

      // There is no guarantee that FRAME_ACK_RECEIVED is logged exactly once
      // per frame.
      EXPECT_GT(e.second.counter[FRAME_ACK_RECEIVED], 0);
      count_of_valid_events += e.second.counter[FRAME_ACK_RECEIVED];

      // Verify that there were no unexpected events logged with respect to this
      // frame.
      EXPECT_EQ(count_of_valid_events, total_event_count_for_frame);
    }

    // Verify that each packet has the expected types of events logged.
    for (const auto& e : event_counts_by_packet) {
      int total_event_count_for_packet = 0;
      for (int i = 0; i < kNumOfLoggingEvents; ++i) {
        total_event_count_for_packet += e.second.counter[i];
      }

      EXPECT_GT(e.second.counter[PACKET_RECEIVED], 0);
      const int packets_received = e.second.counter[PACKET_RECEIVED];
      const int packets_sent = e.second.counter[PACKET_SENT_TO_NETWORK];
      EXPECT_EQ(packets_sent, packets_received);

      // Verify that there were no other events logged with respect to this
      // packet.  An assumption here is that there was no packet loss nor
      // retransmits during the end-to-end run.
      EXPECT_EQ(packets_received + packets_sent, total_event_count_for_packet);
    }
  }

  void BasicPlayerGotVideoFrame(scoped_refptr<media::VideoFrame> video_frame,
                                base::TimeTicks playout_time,
                                bool continuous) {
    // The following tests that the sender and receiver clocks can be
    // out-of-sync, drift, and jitter with respect to one another; and depsite
    // this, the receiver will produce smoothly-progressing playout times.
    // Both first-order and second-order effects are tested.
    if (!last_video_playout_time_.is_null() &&
        min_video_playout_delta_ > base::TimeDelta()) {
      const base::TimeDelta delta = playout_time - last_video_playout_time_;
      VLOG(1) << "Video frame playout time delta (compared to last frame) is "
              << delta.InMicroseconds() << " usec.";
      EXPECT_LE(min_video_playout_delta_.InMicroseconds(),
                delta.InMicroseconds());
      EXPECT_GE(max_video_playout_delta_.InMicroseconds(),
                delta.InMicroseconds());
      if (last_video_playout_delta_ > base::TimeDelta()) {
        base::TimeDelta abs_curvature = delta - last_video_playout_delta_;
        if (abs_curvature < base::TimeDelta())
          abs_curvature = -abs_curvature;
        EXPECT_GE(max_video_playout_curvature_.InMicroseconds(),
                  abs_curvature.InMicroseconds());
      }
      last_video_playout_delta_ = delta;
    }
    last_video_playout_time_ = playout_time;

    video_ticks_.push_back(
        std::make_pair(testing_clock_receiver_.NowTicks(), playout_time));
    cast_receiver_->RequestDecodedVideoFrame(base::BindRepeating(
        &End2EndTest::BasicPlayerGotVideoFrame, base::Unretained(this)));
  }

  void BasicPlayerGotAudioFrame(std::unique_ptr<AudioBus> audio_bus,
                                base::TimeTicks playout_time,
                                bool is_continuous) {
    VLOG_IF(1, !last_audio_playout_time_.is_null())
        << "Audio frame playout time delta (compared to last frame) is "
        << (playout_time - last_audio_playout_time_).InMicroseconds()
        << " usec.";
    last_audio_playout_time_ = playout_time;

    audio_ticks_.push_back(
        std::make_pair(testing_clock_receiver_.NowTicks(), playout_time));
    cast_receiver_->RequestDecodedAudioFrame(base::BindRepeating(
        &End2EndTest::BasicPlayerGotAudioFrame, base::Unretained(this)));
  }

  void StartBasicPlayer() {
    cast_receiver_->RequestDecodedVideoFrame(base::BindRepeating(
        &End2EndTest::BasicPlayerGotVideoFrame, base::Unretained(this)));
    cast_receiver_->RequestDecodedAudioFrame(base::BindRepeating(
        &End2EndTest::BasicPlayerGotAudioFrame, base::Unretained(this)));
  }

  FrameReceiverConfig audio_receiver_config_;
  FrameReceiverConfig video_receiver_config_;
  FrameSenderConfig audio_sender_config_;
  FrameSenderConfig video_sender_config_;

  base::TimeTicks start_time_;

  // These run in "test time"
  base::SimpleTestTickClock testing_clock_;
  scoped_refptr<FakeSingleThreadTaskRunner> task_runner_;

  // These run on the sender timeline.
  test::SkewedTickClock testing_clock_sender_;
  scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_sender_;

  // These run on the receiver timeline.
  test::SkewedTickClock testing_clock_receiver_;
  scoped_refptr<test::SkewedSingleThreadTaskRunner> task_runner_receiver_;
  base::TimeDelta min_video_playout_delta_;
  base::TimeDelta max_video_playout_delta_;
  base::TimeDelta max_video_playout_curvature_;
  base::TimeTicks last_video_playout_time_;
  base::TimeDelta last_video_playout_delta_;
  base::TimeTicks last_audio_playout_time_;

  scoped_refptr<CastEnvironment> cast_environment_sender_;
  scoped_refptr<CastEnvironment> cast_environment_receiver_;

  LoopBackTransport* receiver_to_sender_;  // Owned by CastTransport.
  LoopBackTransport* sender_to_receiver_;  // Owned by CastTransport.

  std::unique_ptr<CastTransportImpl> transport_sender_;
  std::unique_ptr<CastTransportImpl> transport_receiver_;

  std::unique_ptr<CastReceiver> cast_receiver_;
  std::unique_ptr<CastSender> cast_sender_;
  scoped_refptr<AudioFrameInput> audio_frame_input_;
  scoped_refptr<VideoFrameInput> video_frame_input_;

  scoped_refptr<TestReceiverAudioCallback> test_receiver_audio_callback_;
  scoped_refptr<TestReceiverVideoCallback> test_receiver_video_callback_;

  std::unique_ptr<TestAudioBusFactory> audio_bus_factory_;

  SimpleEventSubscriber event_subscriber_sender_;

  std::vector<std::pair<base::TimeTicks, base::TimeTicks>> audio_ticks_;
  std::vector<std::pair<base::TimeTicks, base::TimeTicks>> video_ticks_;

  // |transport_sender_| has a RepeatingTimer which needs a MessageLoop.
  base::test::SingleThreadTaskEnvironment task_environment_;
};

namespace {

class TransportClient : public CastTransport::Client {
 public:
  TransportClient(LogEventDispatcher* log_event_dispatcher,
                  End2EndTest* e2e_test)
      : log_event_dispatcher_(log_event_dispatcher), e2e_test_(e2e_test) {}

  void OnStatusChanged(media::cast::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 {
    log_event_dispatcher_->DispatchBatchOfEvents(std::move(frame_events),
                                                 std::move(packet_events));
  }
  void ProcessRtpPacket(std::unique_ptr<Packet> packet) final {
    if (e2e_test_)
      e2e_test_->ReceivePacket(std::move(packet));
  }

 private:
  LogEventDispatcher* const log_event_dispatcher_;  // Not owned by this class.
  End2EndTest* const e2e_test_;                     // Not owned by this class.

  DISALLOW_COPY_AND_ASSIGN(TransportClient);
};

// Cast E2E tests are not designed to run on official builds, primarily due
// to using fake codecs that cause official failures.
#ifdef OFFICIAL_BUILD
#define CAST_E2E_TEST(name) DISABLED_##name
#else
#define CAST_E2E_TEST(name) name
#endif

}  // namespace

void End2EndTest::Create() {
  transport_sender_ = std::make_unique<CastTransportImpl>(
      &testing_clock_sender_, base::Milliseconds(1),
      std::make_unique<TransportClient>(cast_environment_sender_->logger(),
                                        nullptr),
      base::WrapUnique(sender_to_receiver_), task_runner_sender_);

  transport_receiver_ = std::make_unique<CastTransportImpl>(
      &testing_clock_sender_, base::Milliseconds(1),
      std::make_unique<TransportClient>(cast_environment_receiver_->logger(),
                                        this),
      base::WrapUnique(receiver_to_sender_), task_runner_sender_);

  cast_receiver_ =
      CastReceiver::Create(cast_environment_receiver_, audio_receiver_config_,
                           video_receiver_config_, transport_receiver_.get());

  cast_sender_ =
      CastSender::Create(cast_environment_sender_, transport_sender_.get());

  // Initializing audio and video senders.
  cast_sender_->InitializeAudio(
      audio_sender_config_, base::BindOnce(&ExpectSuccessOperationalStatus));
  cast_sender_->InitializeVideo(
      video_sender_config_,
      base::BindRepeating(&ExpectSuccessOperationalStatus), base::DoNothing());
  task_runner_->RunTasks();

  receiver_to_sender_->SetPacketReceiver(
      transport_sender_->PacketReceiverForTesting(), task_runner_,
      &testing_clock_);
  sender_to_receiver_->SetPacketReceiver(
      transport_receiver_->PacketReceiverForTesting(), task_runner_,
      &testing_clock_);

  audio_frame_input_ = cast_sender_->audio_frame_input();
  video_frame_input_ = cast_sender_->video_frame_input();

  audio_bus_factory_ = std::make_unique<TestAudioBusFactory>(
      audio_sender_config_.channels, audio_sender_config_.rtp_timebase,
      kSoundFrequency, kSoundVolume);
}

TEST_F(End2EndTest, CAST_E2E_TEST(LoopWithLosslessEncoding)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();

  const auto frames_sent = RunAudioVideoLoop(base::Seconds(3));

  // Make sure that we send a RTCP message containing receiver log data, then
  // verify the accumulated logging data.
  RunTasks(750);
  VerifyLogging(frames_sent.first, frames_sent.second);
}

TEST_F(End2EndTest, LoopWithLossyEncoding) {
  Configure(CODEC_VIDEO_VP8, CODEC_AUDIO_OPUS);
  Create();

  const auto frames_sent = RunAudioVideoLoop(base::Seconds(1));

  // Run tasks for 750 ms to ensure RTCP messages containing log data from the
  // receiver are sent and processed by the sender.  Then, verify the expected
  // logging data is present.
  RunTasks(750);
  VerifyLogging(frames_sent.first, frames_sent.second);
}

// This tests start sending audio and video at start-up time before the receiver
// is ready; it sends 2 frames before the receiver comes online.
//
// Test disabled due to flakiness: It appears that the RTCP synchronization
// sometimes kicks in, and sometimes doesn't.  When it does, there's a sharp
// discontinuity in the timeline, throwing off the test expectations.  See TODOs
// in audio_receiver.cc for likely cause(s) of this bug.
// http://crbug.com/573126 (history: http://crbug.com/314233)
TEST_F(End2EndTest, DISABLED_StartSenderBeforeReceiver) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();

  int frame_number = 0;
  int audio_diff = kFrameTimerMs;

  sender_to_receiver_->SetSendPackets(false);

  const int test_delay_ms = 100;

  const int kNumVideoFramesBeforeReceiverStarted = 2;
  const base::TimeTicks initial_send_time = testing_clock_sender_.NowTicks();
  const base::TimeDelta expected_delay =
      base::Milliseconds(test_delay_ms + kFrameTimerMs);
  for (int i = 0; i < kNumVideoFramesBeforeReceiverStarted; ++i) {
    const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
    audio_diff -= num_audio_frames * kAudioFrameDurationMs;

    if (num_audio_frames > 0)
      FeedAudioFramesWithExpectedDelay(1, expected_delay);

    // Frame will be rendered with 100mS delay, as the transmission is delayed.
    // The receiver at this point cannot be synced to the sender's clock, as no
    // packets, and specifically no RTCP packets were sent.
    test_receiver_video_callback_->AddExpectedResult(
        frame_number, GetTestVideoFrameSize(),
        initial_send_time + expected_delay +
            base::Milliseconds(kTargetPlayoutDelayMs),
        true);
    SendVideoFrame(frame_number++, testing_clock_sender_.NowTicks());

    if (num_audio_frames > 0)
      RunTasks(kAudioFrameDurationMs);  // Advance clock forward.
    if (num_audio_frames > 1)
      FeedAudioFramesWithExpectedDelay(num_audio_frames - 1, expected_delay);

    RunTasks(kFrameTimerMs - kAudioFrameDurationMs);
    audio_diff += kFrameTimerMs;
  }

  RunTasks(test_delay_ms);
  sender_to_receiver_->SetSendPackets(true);

  int num_audio_frames_requested = 0;
  for (int j = 0; j < 10; ++j) {
    const int num_audio_frames = audio_diff / kAudioFrameDurationMs;
    audio_diff -= num_audio_frames * kAudioFrameDurationMs;

    if (num_audio_frames > 0)
      FeedAudioFrames(1, true);

    test_receiver_video_callback_->AddExpectedResult(
        frame_number, GetTestVideoFrameSize(),
        testing_clock_sender_.NowTicks() +
            base::Milliseconds(kTargetPlayoutDelayMs),
        true);
    SendVideoFrame(frame_number++, testing_clock_sender_.NowTicks());

    if (num_audio_frames > 0)
      RunTasks(kAudioFrameDurationMs);  // Advance clock forward.
    if (num_audio_frames > 1)
      FeedAudioFrames(num_audio_frames - 1, true);

    RequestAudioFrames(num_audio_frames, true);
    num_audio_frames_requested += num_audio_frames;

    cast_receiver_->RequestDecodedVideoFrame(
        base::BindRepeating(&TestReceiverVideoCallback::CheckVideoFrame,
                            test_receiver_video_callback_,
                            video_sender_config_.codec != CODEC_VIDEO_FAKE));

    RunTasks(kFrameTimerMs - kAudioFrameDurationMs);
    audio_diff += kFrameTimerMs;
  }
  RunTasks(2 * kFrameTimerMs + 1);  // Empty the receiver pipeline.
  EXPECT_EQ(num_audio_frames_requested,
            test_receiver_audio_callback_->number_times_called());
  EXPECT_EQ(10, test_receiver_video_callback_->number_times_called());
}

TEST_F(End2EndTest, CAST_E2E_TEST(BasicFakeSoftwareVideo)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();
  StartBasicPlayer();
  SetReceiverSkew(1.0, base::Milliseconds(1));

  // Expect very smooth playout when there is no clock skew.
  SetExpectedVideoPlayoutSmoothness(
      base::Milliseconds(kFrameTimerMs) * 99 / 100,
      base::Milliseconds(kFrameTimerMs) * 101 / 100,
      base::Milliseconds(kFrameTimerMs) / 100);

  int frames_counter = 0;
  for (; frames_counter < 30; ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(2 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_EQ(30ul, video_ticks_.size());
}

// The following tests run many many iterations to make sure that buffers don't
// fill, timers don't go askew etc. However, these high-level tests are too
// expensive when running under sanitizers, or in non-optimized debug builds.
// In these cases, we reduce the number of iterations.
#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(UNDEFINED_SANITIZER)
const int kLongTestIterations = 500;  // http://crbug.com/487033
#elif defined(NDEBUG)
const int kLongTestIterations = 10000;
#else
const int kLongTestIterations = 1000;
#endif

TEST_F(End2EndTest, CAST_E2E_TEST(ReceiverClockFast)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();
  StartBasicPlayer();
  SetReceiverSkew(2.0, base::Microseconds(1234567));

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(2 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_EQ(static_cast<size_t>(kLongTestIterations), video_ticks_.size());
}

TEST_F(End2EndTest, CAST_E2E_TEST(ReceiverClockSlow)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();
  StartBasicPlayer();
  SetReceiverSkew(0.5, base::Microseconds(-765432));

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(2 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_EQ(static_cast<size_t>(kLongTestIterations), video_ticks_.size());
}

TEST_F(End2EndTest, CAST_E2E_TEST(SmoothPlayoutWithFivePercentClockRateSkew)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  Create();
  StartBasicPlayer();
  SetReceiverSkew(1.05, base::Milliseconds(-42));

  // Expect smooth playout when there is 5% skew.
  SetExpectedVideoPlayoutSmoothness(
      base::Milliseconds(kFrameTimerMs) * 90 / 100,
      base::Milliseconds(kFrameTimerMs) * 110 / 100,
      base::Milliseconds(kFrameTimerMs) / 10);

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(2 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_EQ(static_cast<size_t>(kLongTestIterations), video_ticks_.size());
}

TEST_F(End2EndTest, CAST_E2E_TEST(EvilNetwork)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  receiver_to_sender_->SetPacketPipe(test::EvilNetwork());
  sender_to_receiver_->SetPacketPipe(test::EvilNetwork());
  Create();
  StartBasicPlayer();

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  base::TimeTicks test_end = testing_clock_receiver_.NowTicks();
  RunTasks(100 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_LT(static_cast<size_t>(kLongTestIterations / 100),
            video_ticks_.size());
  VLOG(1) << "Fully transmitted " << video_ticks_.size() << " frames.";
  EXPECT_GT(1000, (video_ticks_.back().second - test_end).InMilliseconds());
}

// Tests that a system configured for 30 FPS drops frames when input is provided
// at a much higher frame rate.
TEST_F(End2EndTest, CAST_E2E_TEST(ShoveHighFrameRateDownYerThroat)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  receiver_to_sender_->SetPacketPipe(test::EvilNetwork());
  sender_to_receiver_->SetPacketPipe(test::EvilNetwork());
  Create();
  StartBasicPlayer();

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(10 /* 10 ms, but 33.3 expected by system */);
  }
  base::TimeTicks test_end = testing_clock_receiver_.NowTicks();
  RunTasks(100 * kFrameTimerMs + 1);  // Empty the pipeline.
  EXPECT_LT(static_cast<size_t>(kLongTestIterations / 100),
            video_ticks_.size());

#if defined(ADDRESS_SANITIZER) || defined(LEAK_SANITIZER) ||  \
    defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \
    defined(UNDEFINED_SANITIZER)
  // We want to ensure that at least one frame is dropped on ASAN builds.
  const size_t max_iterations = kLongTestIterations - 1;
#else
  const size_t max_iterations = kLongTestIterations / 3;
#endif
  EXPECT_GE(max_iterations, video_ticks_.size());

  VLOG(1) << "Fully transmitted " << video_ticks_.size() << " frames.";
  EXPECT_LT((video_ticks_.back().second - test_end).InMilliseconds(), 1000);
}

TEST_F(End2EndTest, CAST_E2E_TEST(OldPacketNetwork)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  sender_to_receiver_->SetPacketPipe(test::NewRandomDrop(0.01));
  std::unique_ptr<test::PacketPipe> echo_chamber(
      test::NewDuplicateAndDelay(1, 10 * kFrameTimerMs));
  echo_chamber->AppendToPipe(test::NewDuplicateAndDelay(1, 20 * kFrameTimerMs));
  echo_chamber->AppendToPipe(test::NewDuplicateAndDelay(1, 40 * kFrameTimerMs));
  echo_chamber->AppendToPipe(test::NewDuplicateAndDelay(1, 80 * kFrameTimerMs));
  echo_chamber->AppendToPipe(
      test::NewDuplicateAndDelay(1, 160 * kFrameTimerMs));

  receiver_to_sender_->SetPacketPipe(std::move(echo_chamber));
  Create();
  StartBasicPlayer();

  SetExpectedVideoPlayoutSmoothness(
      base::Milliseconds(kFrameTimerMs) * 90 / 100,
      base::Milliseconds(kFrameTimerMs) * 110 / 100,
      base::Milliseconds(kFrameTimerMs) / 10);

  for (int frames_counter = 0; frames_counter < kLongTestIterations;
       ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(100 * kFrameTimerMs + 1);  // Empty the pipeline.

  EXPECT_EQ(static_cast<size_t>(kLongTestIterations), video_ticks_.size());
}

TEST_F(End2EndTest, CAST_E2E_TEST(TestSetPlayoutDelay)) {
  Configure(CODEC_VIDEO_FAKE, CODEC_AUDIO_PCM16);
  video_sender_config_.min_playout_delay =
      video_sender_config_.max_playout_delay;
  audio_sender_config_.min_playout_delay =
      audio_sender_config_.max_playout_delay;
  video_sender_config_.max_playout_delay = base::Seconds(1);
  audio_sender_config_.max_playout_delay = base::Seconds(1);
  Create();
  StartBasicPlayer();
  const int kNewDelay = 600;

  int frames_counter = 0;
  for (; frames_counter < 50; ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  cast_sender_->SetTargetPlayoutDelay(base::Milliseconds(kNewDelay));
  for (; frames_counter < 100; ++frames_counter) {
    SendVideoFrame(frames_counter, testing_clock_sender_.NowTicks());
    RunTasks(kFrameTimerMs);
  }
  RunTasks(100 * kFrameTimerMs + 1);  // Empty the pipeline.
  size_t jump = 0;
  for (size_t i = 1; i < video_ticks_.size(); i++) {
    int64_t delta =
        (video_ticks_[i].second - video_ticks_[i - 1].second).InMilliseconds();
    if (delta > 100) {
      EXPECT_EQ(kNewDelay - kTargetPlayoutDelayMs + kFrameTimerMs, delta);
      EXPECT_EQ(0u, jump);
      jump = i;
    }
  }
  EXPECT_GT(jump, 49u);
  EXPECT_LT(jump, 120u);
}

}  // namespace cast
}  // namespace media

#undef CAST_E2E_TEST
