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

#include "testing/gtest/include/gtest/gtest.h"

#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/base/thread_annotations.h"
#include "webrtc/call.h"
#include "webrtc/call/transport_adapter.h"
#include "webrtc/modules/audio_coding/main/include/audio_coding_module.h"
#include "webrtc/modules/rtp_rtcp/include/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/rtp_to_ntp.h"
#include "webrtc/test/call_test.h"
#include "webrtc/test/direct_transport.h"
#include "webrtc/test/encoder_settings.h"
#include "webrtc/test/fake_audio_device.h"
#include "webrtc/test/fake_decoder.h"
#include "webrtc/test/fake_encoder.h"
#include "webrtc/test/frame_generator.h"
#include "webrtc/test/frame_generator_capturer.h"
#include "webrtc/test/rtp_rtcp_observer.h"
#include "webrtc/test/testsupport/fileutils.h"
#include "webrtc/test/testsupport/perf_test.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/include/voe_video_sync.h"

namespace webrtc {

class CallPerfTest : public test::CallTest {
 protected:
  void TestAudioVideoSync(bool fec, bool create_audio_first);

  void TestCpuOveruse(LoadObserver::Load tested_load, int encode_delay_ms);

  void TestMinTransmitBitrate(bool pad_to_min_bitrate);

  void TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
                          int threshold_ms,
                          int start_time_ms,
                          int run_time_ms);
};

class SyncRtcpObserver : public test::RtpRtcpObserver {
 public:
  SyncRtcpObserver() : test::RtpRtcpObserver(CallPerfTest::kLongTimeoutMs) {}

  Action OnSendRtcp(const uint8_t* packet, size_t length) override {
    RTCPUtility::RTCPParserV2 parser(packet, length, true);
    EXPECT_TRUE(parser.IsValid());

    for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
         packet_type != RTCPUtility::RTCPPacketTypes::kInvalid;
         packet_type = parser.Iterate()) {
      if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) {
        const RTCPUtility::RTCPPacket& packet = parser.Packet();
        RtcpMeasurement ntp_rtp_pair(
            packet.SR.NTPMostSignificant,
            packet.SR.NTPLeastSignificant,
            packet.SR.RTPTimestamp);
        StoreNtpRtpPair(ntp_rtp_pair);
      }
    }
    return SEND_PACKET;
  }

  int64_t RtpTimestampToNtp(uint32_t timestamp) const {
    rtc::CritScope lock(&crit_);
    int64_t timestamp_in_ms = -1;
    if (ntp_rtp_pairs_.size() == 2) {
      // TODO(stefan): We can't EXPECT_TRUE on this call due to a bug in the
      // RTCP sender where it sends RTCP SR before any RTP packets, which leads
      // to a bogus NTP/RTP mapping.
      RtpToNtpMs(timestamp, ntp_rtp_pairs_, &timestamp_in_ms);
      return timestamp_in_ms;
    }
    return -1;
  }

 private:
  void StoreNtpRtpPair(RtcpMeasurement ntp_rtp_pair) {
    rtc::CritScope lock(&crit_);
    for (RtcpList::iterator it = ntp_rtp_pairs_.begin();
         it != ntp_rtp_pairs_.end();
         ++it) {
      if (ntp_rtp_pair.ntp_secs == it->ntp_secs &&
          ntp_rtp_pair.ntp_frac == it->ntp_frac) {
        // This RTCP has already been added to the list.
        return;
      }
    }
    // We need two RTCP SR reports to map between RTP and NTP. More than two
    // will not improve the mapping.
    if (ntp_rtp_pairs_.size() == 2) {
      ntp_rtp_pairs_.pop_back();
    }
    ntp_rtp_pairs_.push_front(ntp_rtp_pair);
  }

  mutable rtc::CriticalSection crit_;
  RtcpList ntp_rtp_pairs_ GUARDED_BY(crit_);
};

class VideoRtcpAndSyncObserver : public SyncRtcpObserver, public VideoRenderer {
  static const int kInSyncThresholdMs = 50;
  static const int kStartupTimeMs = 2000;
  static const int kMinRunTimeMs = 30000;

 public:
  VideoRtcpAndSyncObserver(Clock* clock,
                           int voe_channel,
                           VoEVideoSync* voe_sync,
                           SyncRtcpObserver* audio_observer)
      : clock_(clock),
        voe_channel_(voe_channel),
        voe_sync_(voe_sync),
        audio_observer_(audio_observer),
        creation_time_ms_(clock_->TimeInMilliseconds()),
        first_time_in_sync_(-1) {}

  void RenderFrame(const VideoFrame& video_frame,
                   int time_to_render_ms) override {
    int64_t now_ms = clock_->TimeInMilliseconds();
    uint32_t playout_timestamp = 0;
    if (voe_sync_->GetPlayoutTimestamp(voe_channel_, playout_timestamp) != 0)
      return;
    int64_t latest_audio_ntp =
        audio_observer_->RtpTimestampToNtp(playout_timestamp);
    int64_t latest_video_ntp = RtpTimestampToNtp(video_frame.timestamp());
    if (latest_audio_ntp < 0 || latest_video_ntp < 0)
      return;
    int time_until_render_ms =
        std::max(0, static_cast<int>(video_frame.render_time_ms() - now_ms));
    latest_video_ntp += time_until_render_ms;
    int64_t stream_offset = latest_audio_ntp - latest_video_ntp;
    std::stringstream ss;
    ss << stream_offset;
    webrtc::test::PrintResult("stream_offset",
                              "",
                              "synchronization",
                              ss.str(),
                              "ms",
                              false);
    int64_t time_since_creation = now_ms - creation_time_ms_;
    // During the first couple of seconds audio and video can falsely be
    // estimated as being synchronized. We don't want to trigger on those.
    if (time_since_creation < kStartupTimeMs)
      return;
    if (std::abs(latest_audio_ntp - latest_video_ntp) < kInSyncThresholdMs) {
      if (first_time_in_sync_ == -1) {
        first_time_in_sync_ = now_ms;
        webrtc::test::PrintResult("sync_convergence_time",
                                  "",
                                  "synchronization",
                                  time_since_creation,
                                  "ms",
                                  false);
      }
      if (time_since_creation > kMinRunTimeMs)
        observation_complete_->Set();
    }
  }

  bool IsTextureSupported() const override { return false; }

 private:
  Clock* const clock_;
  const int voe_channel_;
  VoEVideoSync* const voe_sync_;
  SyncRtcpObserver* const audio_observer_;
  const int64_t creation_time_ms_;
  int64_t first_time_in_sync_;
};

void CallPerfTest::TestAudioVideoSync(bool fec, bool create_audio_first) {
  const char* kSyncGroup = "av_sync";
  class AudioPacketReceiver : public PacketReceiver {
   public:
    AudioPacketReceiver(int channel, VoENetwork* voe_network)
        : channel_(channel),
          voe_network_(voe_network),
          parser_(RtpHeaderParser::Create()) {}
    DeliveryStatus DeliverPacket(MediaType media_type,
                                 const uint8_t* packet,
                                 size_t length,
                                 const PacketTime& packet_time) override {
      EXPECT_TRUE(media_type == MediaType::ANY ||
                  media_type == MediaType::AUDIO);
      int ret;
      if (parser_->IsRtcp(packet, length)) {
        ret = voe_network_->ReceivedRTCPPacket(channel_, packet, length);
      } else {
        ret = voe_network_->ReceivedRTPPacket(channel_, packet, length,
                                              PacketTime());
      }
      return ret == 0 ? DELIVERY_OK : DELIVERY_PACKET_ERROR;
    }

   private:
    int channel_;
    VoENetwork* voe_network_;
    rtc::scoped_ptr<RtpHeaderParser> parser_;
  };

  VoiceEngine* voice_engine = VoiceEngine::Create();
  VoEBase* voe_base = VoEBase::GetInterface(voice_engine);
  VoECodec* voe_codec = VoECodec::GetInterface(voice_engine);
  VoENetwork* voe_network = VoENetwork::GetInterface(voice_engine);
  VoEVideoSync* voe_sync = VoEVideoSync::GetInterface(voice_engine);
  const std::string audio_filename =
      test::ResourcePath("voice_engine/audio_long16", "pcm");
  ASSERT_STRNE("", audio_filename.c_str());
  test::FakeAudioDevice fake_audio_device(Clock::GetRealTimeClock(),
                                          audio_filename);
  EXPECT_EQ(0, voe_base->Init(&fake_audio_device, nullptr));
  int channel = voe_base->CreateChannel();

  SyncRtcpObserver audio_observer;

  Call::Config receiver_config;
  receiver_config.voice_engine = voice_engine;
  CreateCalls(Call::Config(), receiver_config);

  CodecInst isac = {103, "ISAC", 16000, 480, 1, 32000};
  EXPECT_EQ(0, voe_codec->SetSendCodec(channel, isac));

  AudioPacketReceiver voe_packet_receiver(channel, voe_network);

  FakeNetworkPipe::Config net_config;
  net_config.queue_delay_ms = 500;
  net_config.loss_percent = 5;
  test::PacketTransport audio_send_transport(
      nullptr, &audio_observer, test::PacketTransport::kSender, net_config);
  audio_send_transport.SetReceiver(&voe_packet_receiver);
  test::PacketTransport audio_receive_transport(
      nullptr, &audio_observer, test::PacketTransport::kReceiver, net_config);
  audio_receive_transport.SetReceiver(&voe_packet_receiver);

  internal::TransportAdapter transport_adapter(&audio_send_transport);
  transport_adapter.Enable();
  EXPECT_EQ(0,
            voe_network->RegisterExternalTransport(channel, transport_adapter));

  VideoRtcpAndSyncObserver observer(Clock::GetRealTimeClock(), channel,
                                    voe_sync, &audio_observer);

  test::PacketTransport sync_send_transport(sender_call_.get(), &observer,
                                            test::PacketTransport::kSender,
                                            FakeNetworkPipe::Config());
  sync_send_transport.SetReceiver(receiver_call_->Receiver());
  test::PacketTransport sync_receive_transport(receiver_call_.get(), &observer,
                                               test::PacketTransport::kReceiver,
                                               FakeNetworkPipe::Config());
  sync_receive_transport.SetReceiver(sender_call_->Receiver());

  test::FakeDecoder fake_decoder;

  CreateSendConfig(1, &sync_send_transport);
  CreateMatchingReceiveConfigs(&sync_receive_transport);

  send_config_.rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
  if (fec) {
    send_config_.rtp.fec.red_payload_type = kRedPayloadType;
    send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
    receive_configs_[0].rtp.fec.red_payload_type = kRedPayloadType;
    receive_configs_[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
  }
  receive_configs_[0].rtp.nack.rtp_history_ms = 1000;
  receive_configs_[0].renderer = &observer;
  receive_configs_[0].sync_group = kSyncGroup;

  AudioReceiveStream::Config audio_config;
  audio_config.voe_channel_id = channel;
  audio_config.sync_group = kSyncGroup;

  AudioReceiveStream* audio_receive_stream = nullptr;

  if (create_audio_first) {
    audio_receive_stream =
        receiver_call_->CreateAudioReceiveStream(audio_config);
    CreateStreams();
  } else {
    CreateStreams();
    audio_receive_stream =
        receiver_call_->CreateAudioReceiveStream(audio_config);
  }

  CreateFrameGeneratorCapturer();

  Start();

  fake_audio_device.Start();
  EXPECT_EQ(0, voe_base->StartPlayout(channel));
  EXPECT_EQ(0, voe_base->StartReceive(channel));
  EXPECT_EQ(0, voe_base->StartSend(channel));

  EXPECT_EQ(kEventSignaled, observer.Wait())
      << "Timed out while waiting for audio and video to be synchronized.";

  EXPECT_EQ(0, voe_base->StopSend(channel));
  EXPECT_EQ(0, voe_base->StopReceive(channel));
  EXPECT_EQ(0, voe_base->StopPlayout(channel));
  fake_audio_device.Stop();

  Stop();
  sync_send_transport.StopSending();
  sync_receive_transport.StopSending();
  audio_send_transport.StopSending();
  audio_receive_transport.StopSending();

  voe_base->DeleteChannel(channel);
  voe_base->Release();
  voe_codec->Release();
  voe_network->Release();
  voe_sync->Release();

  DestroyStreams();

  receiver_call_->DestroyAudioReceiveStream(audio_receive_stream);

  DestroyCalls();

  VoiceEngine::Delete(voice_engine);
}

TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithAudioCreatedFirst) {
  TestAudioVideoSync(false, true);
}

TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithVideoCreatedFirst) {
  TestAudioVideoSync(false, false);
}

TEST_F(CallPerfTest, PlaysOutAudioAndVideoInSyncWithFec) {
  TestAudioVideoSync(true, false);
}

void CallPerfTest::TestCaptureNtpTime(const FakeNetworkPipe::Config& net_config,
                                      int threshold_ms,
                                      int start_time_ms,
                                      int run_time_ms) {
  class CaptureNtpTimeObserver : public test::EndToEndTest,
                                 public VideoRenderer {
   public:
    CaptureNtpTimeObserver(int threshold_ms, int start_time_ms, int run_time_ms)
        : EndToEndTest(kLongTimeoutMs),
          clock_(Clock::GetRealTimeClock()),
          threshold_ms_(threshold_ms),
          start_time_ms_(start_time_ms),
          run_time_ms_(run_time_ms),
          creation_time_ms_(clock_->TimeInMilliseconds()),
          capturer_(nullptr),
          rtp_start_timestamp_set_(false),
          rtp_start_timestamp_(0) {}

   private:
    void RenderFrame(const VideoFrame& video_frame,
                     int time_to_render_ms) override {
      rtc::CritScope lock(&crit_);
      if (video_frame.ntp_time_ms() <= 0) {
        // Haven't got enough RTCP SR in order to calculate the capture ntp
        // time.
        return;
      }

      int64_t now_ms = clock_->TimeInMilliseconds();
      int64_t time_since_creation = now_ms - creation_time_ms_;
      if (time_since_creation < start_time_ms_) {
        // Wait for |start_time_ms_| before start measuring.
        return;
      }

      if (time_since_creation > run_time_ms_) {
        observation_complete_->Set();
      }

      FrameCaptureTimeList::iterator iter =
          capture_time_list_.find(video_frame.timestamp());
      EXPECT_TRUE(iter != capture_time_list_.end());

      // The real capture time has been wrapped to uint32_t before converted
      // to rtp timestamp in the sender side. So here we convert the estimated
      // capture time to a uint32_t 90k timestamp also for comparing.
      uint32_t estimated_capture_timestamp =
          90 * static_cast<uint32_t>(video_frame.ntp_time_ms());
      uint32_t real_capture_timestamp = iter->second;
      int time_offset_ms = real_capture_timestamp - estimated_capture_timestamp;
      time_offset_ms = time_offset_ms / 90;
      std::stringstream ss;
      ss << time_offset_ms;

      webrtc::test::PrintResult(
          "capture_ntp_time", "", "real - estimated", ss.str(), "ms", true);
      EXPECT_TRUE(std::abs(time_offset_ms) < threshold_ms_);
    }

    bool IsTextureSupported() const override { return false; }

    virtual Action OnSendRtp(const uint8_t* packet, size_t length) {
      rtc::CritScope lock(&crit_);
      RTPHeader header;
      EXPECT_TRUE(parser_->Parse(packet, length, &header));

      if (!rtp_start_timestamp_set_) {
        // Calculate the rtp timestamp offset in order to calculate the real
        // capture time.
        uint32_t first_capture_timestamp =
            90 * static_cast<uint32_t>(capturer_->first_frame_capture_time());
        rtp_start_timestamp_ = header.timestamp - first_capture_timestamp;
        rtp_start_timestamp_set_ = true;
      }

      uint32_t capture_timestamp = header.timestamp - rtp_start_timestamp_;
      capture_time_list_.insert(
          capture_time_list_.end(),
          std::make_pair(header.timestamp, capture_timestamp));
      return SEND_PACKET;
    }

    void OnFrameGeneratorCapturerCreated(
        test::FrameGeneratorCapturer* frame_generator_capturer) override {
      capturer_ = frame_generator_capturer;
    }

    void ModifyConfigs(VideoSendStream::Config* send_config,
                       std::vector<VideoReceiveStream::Config>* receive_configs,
                       VideoEncoderConfig* encoder_config) override {
      (*receive_configs)[0].renderer = this;
      // Enable the receiver side rtt calculation.
      (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = true;
    }

    void PerformTest() override {
      EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for "
                                           "estimated capture NTP time to be "
                                           "within bounds.";
    }

    rtc::CriticalSection crit_;
    Clock* const clock_;
    int threshold_ms_;
    int start_time_ms_;
    int run_time_ms_;
    int64_t creation_time_ms_;
    test::FrameGeneratorCapturer* capturer_;
    bool rtp_start_timestamp_set_;
    uint32_t rtp_start_timestamp_;
    typedef std::map<uint32_t, uint32_t> FrameCaptureTimeList;
    FrameCaptureTimeList capture_time_list_ GUARDED_BY(&crit_);
  } test(threshold_ms, start_time_ms, run_time_ms);

  RunBaseTest(&test, net_config);
}

TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkDelay) {
  FakeNetworkPipe::Config net_config;
  net_config.queue_delay_ms = 100;
  // TODO(wu): lower the threshold as the calculation/estimatation becomes more
  // accurate.
  const int kThresholdMs = 100;
  const int kStartTimeMs = 10000;
  const int kRunTimeMs = 20000;
  TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
}

TEST_F(CallPerfTest, CaptureNtpTimeWithNetworkJitter) {
  FakeNetworkPipe::Config net_config;
  net_config.queue_delay_ms = 100;
  net_config.delay_standard_deviation_ms = 10;
  // TODO(wu): lower the threshold as the calculation/estimatation becomes more
  // accurate.
  const int kThresholdMs = 100;
  const int kStartTimeMs = 10000;
  const int kRunTimeMs = 20000;
  TestCaptureNtpTime(net_config, kThresholdMs, kStartTimeMs, kRunTimeMs);
}

void CallPerfTest::TestCpuOveruse(LoadObserver::Load tested_load,
                                  int encode_delay_ms) {
  class LoadObserver : public test::SendTest, public webrtc::LoadObserver {
   public:
    LoadObserver(LoadObserver::Load tested_load, int encode_delay_ms)
        : SendTest(kLongTimeoutMs),
          tested_load_(tested_load),
          encoder_(Clock::GetRealTimeClock(), encode_delay_ms) {}

    void OnLoadUpdate(Load load) override {
      if (load == tested_load_)
        observation_complete_->Set();
    }

    void ModifyConfigs(VideoSendStream::Config* send_config,
                       std::vector<VideoReceiveStream::Config>* receive_configs,
                       VideoEncoderConfig* encoder_config) override {
      send_config->overuse_callback = this;
      send_config->encoder_settings.encoder = &encoder_;
    }

    void PerformTest() override {
      EXPECT_EQ(kEventSignaled, Wait())
          << "Timed out before receiving an overuse callback.";
    }

    LoadObserver::Load tested_load_;
    test::DelayedEncoder encoder_;
  } test(tested_load, encode_delay_ms);

  RunBaseTest(&test, FakeNetworkPipe::Config());
}

TEST_F(CallPerfTest, ReceivesCpuUnderuse) {
  const int kEncodeDelayMs = 2;
  TestCpuOveruse(LoadObserver::kUnderuse, kEncodeDelayMs);
}

TEST_F(CallPerfTest, ReceivesCpuOveruse) {
  const int kEncodeDelayMs = 35;
  TestCpuOveruse(LoadObserver::kOveruse, kEncodeDelayMs);
}

void CallPerfTest::TestMinTransmitBitrate(bool pad_to_min_bitrate) {
  static const int kMaxEncodeBitrateKbps = 30;
  static const int kMinTransmitBitrateBps = 150000;
  static const int kMinAcceptableTransmitBitrate = 130;
  static const int kMaxAcceptableTransmitBitrate = 170;
  static const int kNumBitrateObservationsInRange = 100;
  static const int kAcceptableBitrateErrorMargin = 15;  // +- 7
  class BitrateObserver : public test::EndToEndTest {
   public:
    explicit BitrateObserver(bool using_min_transmit_bitrate)
        : EndToEndTest(kLongTimeoutMs),
          send_stream_(nullptr),
          pad_to_min_bitrate_(using_min_transmit_bitrate),
          num_bitrate_observations_in_range_(0) {}

   private:
    // TODO(holmer): Run this with a timer instead of once per packet.
    Action OnSendRtp(const uint8_t* packet, size_t length) override {
      VideoSendStream::Stats stats = send_stream_->GetStats();
      if (stats.substreams.size() > 0) {
        RTC_DCHECK_EQ(1u, stats.substreams.size());
        int bitrate_kbps =
            stats.substreams.begin()->second.total_bitrate_bps / 1000;
        if (bitrate_kbps > 0) {
          test::PrintResult(
              "bitrate_stats_",
              (pad_to_min_bitrate_ ? "min_transmit_bitrate"
                                   : "without_min_transmit_bitrate"),
              "bitrate_kbps",
              static_cast<size_t>(bitrate_kbps),
              "kbps",
              false);
          if (pad_to_min_bitrate_) {
            if (bitrate_kbps > kMinAcceptableTransmitBitrate &&
                bitrate_kbps < kMaxAcceptableTransmitBitrate) {
              ++num_bitrate_observations_in_range_;
            }
          } else {
            // Expect bitrate stats to roughly match the max encode bitrate.
            if (bitrate_kbps > (kMaxEncodeBitrateKbps -
                                kAcceptableBitrateErrorMargin / 2) &&
                bitrate_kbps < (kMaxEncodeBitrateKbps +
                                kAcceptableBitrateErrorMargin / 2)) {
              ++num_bitrate_observations_in_range_;
            }
          }
          if (num_bitrate_observations_in_range_ ==
              kNumBitrateObservationsInRange)
            observation_complete_->Set();
        }
      }
      return SEND_PACKET;
    }

    void OnStreamsCreated(
        VideoSendStream* send_stream,
        const std::vector<VideoReceiveStream*>& receive_streams) override {
      send_stream_ = send_stream;
    }

    void ModifyConfigs(VideoSendStream::Config* send_config,
                       std::vector<VideoReceiveStream::Config>* receive_configs,
                       VideoEncoderConfig* encoder_config) override {
      if (pad_to_min_bitrate_) {
        encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps;
      } else {
        RTC_DCHECK_EQ(0, encoder_config->min_transmit_bitrate_bps);
      }
    }

    void PerformTest() override {
      EXPECT_EQ(kEventSignaled, Wait())
          << "Timeout while waiting for send-bitrate stats.";
    }

    VideoSendStream* send_stream_;
    const bool pad_to_min_bitrate_;
    int num_bitrate_observations_in_range_;
  } test(pad_to_min_bitrate);

  fake_encoder_.SetMaxBitrate(kMaxEncodeBitrateKbps);
  RunBaseTest(&test, FakeNetworkPipe::Config());
}

TEST_F(CallPerfTest, PadsToMinTransmitBitrate) { TestMinTransmitBitrate(true); }

TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) {
  TestMinTransmitBitrate(false);
}

TEST_F(CallPerfTest, KeepsHighBitrateWhenReconfiguringSender) {
  static const uint32_t kInitialBitrateKbps = 400;
  static const uint32_t kReconfigureThresholdKbps = 600;
  static const uint32_t kPermittedReconfiguredBitrateDiffKbps = 100;

  class BitrateObserver : public test::EndToEndTest, public test::FakeEncoder {
   public:
    BitrateObserver()
        : EndToEndTest(kDefaultTimeoutMs),
          FakeEncoder(Clock::GetRealTimeClock()),
          time_to_reconfigure_(webrtc::EventWrapper::Create()),
          encoder_inits_(0),
          last_set_bitrate_(0),
          send_stream_(nullptr) {}

    int32_t InitEncode(const VideoCodec* config,
                       int32_t number_of_cores,
                       size_t max_payload_size) override {
      if (encoder_inits_ == 0) {
        EXPECT_EQ(kInitialBitrateKbps, config->startBitrate)
            << "Encoder not initialized at expected bitrate.";
      }
      ++encoder_inits_;
      if (encoder_inits_ == 2) {
        EXPECT_GE(last_set_bitrate_, kReconfigureThresholdKbps);
        EXPECT_NEAR(config->startBitrate,
                    last_set_bitrate_,
                    kPermittedReconfiguredBitrateDiffKbps)
            << "Encoder reconfigured with bitrate too far away from last set.";
        observation_complete_->Set();
      }
      return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
    }

    int32_t SetRates(uint32_t new_target_bitrate_kbps,
                     uint32_t framerate) override {
      last_set_bitrate_ = new_target_bitrate_kbps;
      if (encoder_inits_ == 1 &&
          new_target_bitrate_kbps > kReconfigureThresholdKbps) {
        time_to_reconfigure_->Set();
      }
      return FakeEncoder::SetRates(new_target_bitrate_kbps, framerate);
    }

    Call::Config GetSenderCallConfig() override {
      Call::Config config = EndToEndTest::GetSenderCallConfig();
      config.bitrate_config.start_bitrate_bps = kInitialBitrateKbps * 1000;
      return config;
    }

    void ModifyConfigs(VideoSendStream::Config* send_config,
                       std::vector<VideoReceiveStream::Config>* receive_configs,
                       VideoEncoderConfig* encoder_config) override {
      send_config->encoder_settings.encoder = this;
      encoder_config->streams[0].min_bitrate_bps = 50000;
      encoder_config->streams[0].target_bitrate_bps =
          encoder_config->streams[0].max_bitrate_bps = 2000000;

      encoder_config_ = *encoder_config;
    }

    void OnStreamsCreated(
        VideoSendStream* send_stream,
        const std::vector<VideoReceiveStream*>& receive_streams) override {
      send_stream_ = send_stream;
    }

    void PerformTest() override {
      ASSERT_EQ(kEventSignaled, time_to_reconfigure_->Wait(kDefaultTimeoutMs))
          << "Timed out before receiving an initial high bitrate.";
      encoder_config_.streams[0].width *= 2;
      encoder_config_.streams[0].height *= 2;
      EXPECT_TRUE(send_stream_->ReconfigureVideoEncoder(encoder_config_));
      EXPECT_EQ(kEventSignaled, Wait())
          << "Timed out while waiting for a couple of high bitrate estimates "
             "after reconfiguring the send stream.";
    }

   private:
    rtc::scoped_ptr<webrtc::EventWrapper> time_to_reconfigure_;
    int encoder_inits_;
    uint32_t last_set_bitrate_;
    VideoSendStream* send_stream_;
    VideoEncoderConfig encoder_config_;
  } test;

  RunBaseTest(&test, FakeNetworkPipe::Config());
}

}  // namespace webrtc
