/*
 * libjingle
 * Copyright 2010 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

// If we don't have a WebRtcVideoFrame, just skip all of these tests.
#if defined(HAVE_WEBRTC_VIDEO)
#include <limits.h>  // For INT_MAX
#include <string>
#include <vector>

#include "talk/media/base/mediachannel.h"
#include "talk/media/base/testutils.h"
#include "talk/media/base/videoadapter.h"
#include "talk/media/devices/filevideocapturer.h"
#include "talk/media/webrtc/webrtcvideoframe.h"
#include "webrtc/base/gunit.h"
#include "webrtc/base/logging.h"
#include "webrtc/base/sigslot.h"

namespace cricket {

namespace {
  static const uint32 kWaitTimeout = 3000U;  // 3 seconds.
  static const uint32 kShortWaitTimeout = 1000U;  // 1 second.
  void UpdateCpuLoad(CoordinatedVideoAdapter* adapter,
    int current_cpus, int max_cpus, float process_load, float system_load) {
    adapter->set_cpu_load_min_samples(1);
    adapter->OnCpuLoadUpdated(current_cpus, max_cpus,
                              process_load, system_load);
  }
}

class VideoAdapterTest : public testing::Test {
 public:
  virtual void SetUp() {
    capturer_.reset(new FileVideoCapturer);
    EXPECT_TRUE(capturer_->Init(GetTestFilePath(
        "captured-320x240-2s-48.frames")));
    capture_format_ = capturer_->GetSupportedFormats()->at(0);
    capture_format_.interval = VideoFormat::FpsToInterval(50);
    adapter_.reset(new VideoAdapter());
    adapter_->SetInputFormat(capture_format_);

    listener_.reset(new VideoCapturerListener(adapter_.get()));
    capturer_->SignalFrameCaptured.connect(
        listener_.get(), &VideoCapturerListener::OnFrameCaptured);
  }

  void VerifyAdaptedResolution(int width, int height) {
    EXPECT_TRUE(NULL != listener_->adapted_frame());
    EXPECT_EQ(static_cast<size_t>(width),
              listener_->adapted_frame()->GetWidth());
    EXPECT_EQ(static_cast<size_t>(height),
              listener_->adapted_frame()->GetHeight());
  }

 protected:
  class VideoCapturerListener: public sigslot::has_slots<> {
   public:
    explicit VideoCapturerListener(VideoAdapter* adapter)
        : video_adapter_(adapter),
          adapted_frame_(NULL),
          copied_output_frame_(),
          captured_frames_(0),
          dropped_frames_(0),
          last_adapt_was_no_op_(false) {
    }

    void OnFrameCaptured(VideoCapturer* capturer,
                         const CapturedFrame* captured_frame) {
      WebRtcVideoFrame temp_i420;
      EXPECT_TRUE(temp_i420.Init(captured_frame,
          captured_frame->width, abs(captured_frame->height)));
      VideoFrame* out_frame = NULL;
      EXPECT_TRUE(video_adapter_->AdaptFrame(&temp_i420, &out_frame));
      if (out_frame) {
        if (out_frame == &temp_i420) {
          last_adapt_was_no_op_ = true;
          copied_output_frame_.reset(temp_i420.Copy());
          adapted_frame_ = copied_output_frame_.get();
        } else {
          last_adapt_was_no_op_ = false;
          adapted_frame_ = out_frame;
          copied_output_frame_.reset();
        }
      } else {
        ++dropped_frames_;
      }
      ++captured_frames_;
    }

    const VideoFrame* adapted_frame() const { return adapted_frame_; }
    int captured_frames() const { return captured_frames_; }
    int dropped_frames() const { return dropped_frames_; }
    bool last_adapt_was_no_op() const { return last_adapt_was_no_op_; }

   private:
    VideoAdapter* video_adapter_;
    const VideoFrame* adapted_frame_;
    rtc::scoped_ptr<VideoFrame> copied_output_frame_;
    int captured_frames_;
    int dropped_frames_;
    bool last_adapt_was_no_op_;
  };

  class CpuAdapterListener: public sigslot::has_slots<> {
   public:
    CpuAdapterListener() : received_cpu_signal_(false) {}
    void OnCpuAdaptationSignalled() { received_cpu_signal_ = true; }
    bool received_cpu_signal() { return received_cpu_signal_; }
   private:
    bool received_cpu_signal_;
  };

  rtc::scoped_ptr<FileVideoCapturer> capturer_;
  rtc::scoped_ptr<VideoAdapter> adapter_;
  rtc::scoped_ptr<VideoCapturerListener> listener_;
  VideoFormat capture_format_;
};


// Test adapter remembers exact pixel count
TEST_F(VideoAdapterTest, AdaptNumPixels) {
  adapter_->SetOutputNumPixels(123456);
  EXPECT_EQ(123456, adapter_->GetOutputNumPixels());
}

// Test adapter is constructed but not activated. Expect no frame drop and no
// resolution change.
TEST_F(VideoAdapterTest, AdaptInactive) {
  // Output resolution is not set.
  EXPECT_EQ(INT_MAX, adapter_->GetOutputNumPixels());

  // Call Adapter with some frames.
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no frame drop and no resolution change.
  EXPECT_GE(listener_->captured_frames(), 10);
  EXPECT_EQ(0, listener_->dropped_frames());
  VerifyAdaptedResolution(capture_format_.width, capture_format_.height);
}

// Do not adapt the frame rate or the resolution. Expect no frame drop and no
// resolution change.
TEST_F(VideoAdapterTest, AdaptNothing) {
  adapter_->SetOutputFormat(capture_format_);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no frame drop and no resolution change.
  EXPECT_GE(listener_->captured_frames(), 10);
  EXPECT_EQ(0, listener_->dropped_frames());
  VerifyAdaptedResolution(capture_format_.width, capture_format_.height);
  EXPECT_TRUE(listener_->last_adapt_was_no_op());
}

TEST_F(VideoAdapterTest, AdaptZeroInterval) {
  VideoFormat format = capturer_->GetSupportedFormats()->at(0);
  format.interval = 0;
  adapter_->SetInputFormat(format);
  adapter_->SetOutputFormat(format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no crash and that frames aren't dropped.
  EXPECT_GE(listener_->captured_frames(), 10);
  EXPECT_EQ(0, listener_->dropped_frames());
  VerifyAdaptedResolution(capture_format_.width, capture_format_.height);
}

// Adapt the frame rate to be half of the capture rate at the beginning. Expect
// the number of dropped frames to be half of the number the captured frames.
TEST_F(VideoAdapterTest, AdaptFramerate) {
  VideoFormat request_format = capture_format_;
  request_format.interval *= 2;
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify frame drop and no resolution change.
  EXPECT_GE(listener_->captured_frames(), 10);
  EXPECT_EQ(listener_->captured_frames() / 2, listener_->dropped_frames());
  VerifyAdaptedResolution(capture_format_.width, capture_format_.height);
}

// Adapt the frame rate to be half of the capture rate at the beginning. Expect
// the number of dropped frames to be half of the number the captured frames.
TEST_F(VideoAdapterTest, AdaptFramerateVariable) {
  VideoFormat request_format = capture_format_;
  request_format.interval = request_format.interval * 3 / 2;
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 30, kWaitTimeout);

  // Verify frame drop and no resolution change.
  EXPECT_GE(listener_->captured_frames(), 30);
  // Verify 2 / 3 kept (20) and 1 / 3 dropped (10).
  EXPECT_EQ(listener_->captured_frames() * 1 / 3, listener_->dropped_frames());
  VerifyAdaptedResolution(capture_format_.width, capture_format_.height);
}

// Adapt the frame rate to be half of the capture rate after capturing no less
// than 10 frames. Expect no frame dropped before adaptation and frame dropped
// after adaptation.
TEST_F(VideoAdapterTest, AdaptFramerateOntheFly) {
  VideoFormat request_format = capture_format_;
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no frame drop before adaptation.
  EXPECT_EQ(0, listener_->dropped_frames());

  // Adapat the frame rate.
  request_format.interval *= 2;
  adapter_->SetOutputFormat(request_format);

  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 20, kWaitTimeout);

  // Verify frame drop after adaptation.
  EXPECT_GT(listener_->dropped_frames(), 0);
}

// Adapt the frame resolution to be a quarter of the capture resolution at the
// beginning. Expect resolution change.
TEST_F(VideoAdapterTest, AdaptResolution) {
  VideoFormat request_format = capture_format_;
  request_format.width /= 2;
  request_format.height /= 2;
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no frame drop and resolution change.
  EXPECT_EQ(0, listener_->dropped_frames());
  VerifyAdaptedResolution(request_format.width, request_format.height);
}

// Adapt the frame resolution to half width. Expect resolution change.
TEST_F(VideoAdapterTest, AdaptResolutionNarrow) {
  VideoFormat request_format = capture_format_;
  request_format.width /= 2;
  adapter_->set_scale_third(true);
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify resolution change.
  VerifyAdaptedResolution(213, 160);
}

// Adapt the frame resolution to half height. Expect resolution change.
TEST_F(VideoAdapterTest, AdaptResolutionWide) {
  VideoFormat request_format = capture_format_;
  request_format.height /= 2;
  adapter_->set_scale_third(true);
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify resolution change.
  VerifyAdaptedResolution(213, 160);
}

// Adapt the frame resolution to be a quarter of the capture resolution after
// capturing no less than 10 frames. Expect no resolution change before
// adaptation and resolution change after adaptation.
TEST_F(VideoAdapterTest, AdaptResolutionOnTheFly) {
  VideoFormat request_format = capture_format_;
  adapter_->SetOutputFormat(request_format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify no resolution change before adaptation.
  VerifyAdaptedResolution(request_format.width, request_format.height);

  // Adapt the frame resolution.
  request_format.width /= 2;
  request_format.height /= 2;
  adapter_->SetOutputFormat(request_format);
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 20, kWaitTimeout);


  // Verify resolution change after adaptation.
  VerifyAdaptedResolution(request_format.width, request_format.height);
}

// Black the output frame.
TEST_F(VideoAdapterTest, BlackOutput) {
  adapter_->SetOutputFormat(capture_format_);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);
  // Verify that the output frame is not black.
  EXPECT_NE(16, *listener_->adapted_frame()->GetYPlane());
  EXPECT_NE(128, *listener_->adapted_frame()->GetUPlane());
  EXPECT_NE(128, *listener_->adapted_frame()->GetVPlane());

  adapter_->SetBlackOutput(true);
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 20, kWaitTimeout);
  // Verify that the output frame is black.
  EXPECT_EQ(16, *listener_->adapted_frame()->GetYPlane());
  EXPECT_EQ(128, *listener_->adapted_frame()->GetUPlane());
  EXPECT_EQ(128, *listener_->adapted_frame()->GetVPlane());

  // Verify that the elapsed time and timestamp of the black frame increase.
  int64 elapsed_time = listener_->adapted_frame()->GetElapsedTime();
  int64 timestamp = listener_->adapted_frame()->GetTimeStamp();
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 22, kWaitTimeout);
  EXPECT_GT(listener_->adapted_frame()->GetElapsedTime(), elapsed_time);
  EXPECT_GT(listener_->adapted_frame()->GetTimeStamp(), timestamp);

  // Change the output size
  VideoFormat request_format = capture_format_;
  request_format.width /= 2;
  request_format.height /= 2;
  adapter_->SetOutputFormat(request_format);

  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 40, kWaitTimeout);
  // Verify resolution change after adaptation.
  VerifyAdaptedResolution(request_format.width, request_format.height);
  // Verify that the output frame is black.
  EXPECT_EQ(16, *listener_->adapted_frame()->GetYPlane());
  EXPECT_EQ(128, *listener_->adapted_frame()->GetUPlane());
  EXPECT_EQ(128, *listener_->adapted_frame()->GetVPlane());
}

// Drop all frames.
TEST_F(VideoAdapterTest, DropAllFrames) {
  VideoFormat format;  // with resolution 0x0.
  adapter_->SetOutputFormat(format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  EXPECT_TRUE_WAIT(!capturer_->IsRunning() ||
                   listener_->captured_frames() >= 10, kWaitTimeout);

  // Verify all frames are dropped.
  EXPECT_GE(listener_->captured_frames(), 10);
  EXPECT_EQ(listener_->captured_frames(), listener_->dropped_frames());
}

TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithoutCpuAdaptation) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(false);

  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.set_scale_third(true);
  EXPECT_EQ(format, adapter.input_format());
  EXPECT_TRUE(adapter.output_format().IsSize0x0());

  // Server format request 640x400.
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Server format request 1280x720, higher than input. Adapt nothing.
  format.width = 1280;
  format.height = 720;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Cpu load is high, but cpu adaptation is disabled. Adapt nothing.
  adapter.OnCpuLoadUpdated(1, 1, 0.99f, 0.99f);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Encoder resolution request: downgrade with different size. Adapt nothing.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Encoder resolution request: downgrade.
  adapter.OnEncoderResolutionRequest(640, 400,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Encoder resolution request: downgrade. But GD off. Adapt nothing.
  adapter.set_gd_adaptation(false);
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);
  adapter.set_gd_adaptation(true);

  // Encoder resolution request: downgrade.
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request: keep. Adapt nothing.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::KEEP);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request: upgrade.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Server format request 0x0.
  format.width = 0;
  format.height = 0;
  adapter.OnOutputFormatRequest(format);
  EXPECT_TRUE(adapter.output_format().IsSize0x0());

  // Server format request 320x200.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Server format request 160x100. But view disabled. Adapt nothing.
  adapter.set_view_adaptation(false);
  format.width = 160;
  format.height = 100;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);
  adapter.set_view_adaptation(true);

  // Enable View Switch. Expect adapt down.
  adapter.set_view_switch(true);
  format.width = 160;
  format.height = 100;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(160, adapter.output_format().width);
  EXPECT_EQ(100, adapter.output_format().height);

  // Encoder resolution request: upgrade. Adapt nothing.
  adapter.OnEncoderResolutionRequest(160, 100,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(160, adapter.output_format().width);
  EXPECT_EQ(100, adapter.output_format().height);

  // Request View of 2 / 3. Expect adapt down.
  adapter.set_view_switch(true);
  format.width = (640 * 2 + 1) / 3;
  format.height = (400 * 2 + 1) / 3;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ((640 * 2 + 1) / 3, adapter.output_format().width);
  EXPECT_EQ((400 * 2 + 1) / 3, adapter.output_format().height);


  // Request View of 3 / 8. Expect adapt down.
  adapter.set_view_switch(true);
  format.width = 640 * 3 / 8;
  format.height = 400 * 3 / 8;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640 * 3 / 8, adapter.output_format().width);
  EXPECT_EQ(400 * 3 / 8, adapter.output_format().height);

  // View Switch back up. Expect adapt.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  adapter.set_view_switch(false);

  // Encoder resolution request: upgrade. Constrained by server request.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Server format request 480x300.
  format.width = 480;
  format.height = 300;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);
}

TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuAdaptation) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  EXPECT_FALSE(adapter.cpu_smoothing());
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Process load is medium, but system load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // CPU high, but cpu adaptation disabled. Adapt nothing.
  adapter.set_cpu_adaptation(false);
  adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);
  adapter.set_cpu_adaptation(true);

  // System load is high, but time has not elaspsed. Adapt nothing.
  adapter.set_cpu_load_min_samples(2);
  adapter.OnCpuLoadUpdated(1, 1, 0.55f, 0.98f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Process load is medium, but system load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.55f, 0.98f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is CPU.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
            adapter.adapt_reason());

  // Server format request 320x200. Same as CPU. Do nothing.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is CPU and VIEW.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU +
            CoordinatedVideoAdapter::ADAPTREASON_VIEW,
            adapter.adapt_reason());

  // Process load and system load are normal. Adapt nothing.
  UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.8f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Process load and system load are low, but view is still low. Adapt nothing.
  UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is VIEW.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW,
            adapter.adapt_reason());

  // Server format request 640x400. Cpu is still low.  Upgrade.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Test reason for adapting is CPU.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
            adapter.adapt_reason());

  // Encoder resolution request: downgrade.
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is BANDWIDTH.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
            adapter.adapt_reason());

  // Process load and system load are low. Constrained by GD. Adapt nothing
  adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request: upgrade.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Encoder resolution request: upgrade. Constrained by CPU.
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Server format request 640x400. Constrained by CPU.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);
}

TEST(CoordinatedVideoAdapterTest, TestCoordinatedWithCpuRequest) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  EXPECT_FALSE(adapter.cpu_smoothing());
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // CPU resolution request: downgrade.  Adapt down.
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // CPU resolution request: keep. Do nothing.
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::KEEP);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // CPU resolution request: downgrade, but cpu adaptation disabled.
  // Adapt nothing.
  adapter.set_cpu_adaptation(false);
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // CPU resolution request: downgrade.  Adapt down.
  adapter.set_cpu_adaptation(true);
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is CPU.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
            adapter.adapt_reason());

  // CPU resolution request: downgrade, but already at minimum.  Do nothing.
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Server format request 320x200. Same as CPU. Do nothing.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is CPU and VIEW.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU +
            CoordinatedVideoAdapter::ADAPTREASON_VIEW,
            adapter.adapt_reason());

  // CPU resolution request: upgrade, but view request still low. Do nothing.
  adapter.OnCpuResolutionRequest(CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is VIEW.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW,
            adapter.adapt_reason());

  // Server format request 640x400. Cpu is still low.  Upgrade.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Test reason for adapting is CPU.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU,
            adapter.adapt_reason());

  // Encoder resolution request: downgrade.
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Test reason for adapting is BANDWIDTH.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
            adapter.adapt_reason());

  // Process load and system load are low. Constrained by GD. Adapt nothing
  adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request: upgrade.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Encoder resolution request: upgrade. Constrained by CPU.
  adapter.OnEncoderResolutionRequest(480, 300,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Server format request 640x400. Constrained by CPU.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);
}

TEST(CoordinatedVideoAdapterTest, TestViewRequestPlusCameraSwitch) {
  CoordinatedVideoAdapter adapter;
  adapter.set_view_switch(true);

  // Start at HD.
  VideoFormat format(1280, 720, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  EXPECT_EQ(format, adapter.input_format());
  EXPECT_TRUE(adapter.output_format().IsSize0x0());

  // View request for VGA.
  format.width = 640;
  format.height = 360;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason());

  // Now, the camera reopens at VGA.
  // Both the frame and the output format should be 640x360.
  WebRtcVideoFrame in_frame;
  in_frame.InitToBlack(640, 360, 1, 1, 33, 33);
  VideoFrame* out_frame;
  adapter.AdaptFrame(&in_frame, &out_frame);
  EXPECT_EQ(640u, out_frame->GetWidth());
  EXPECT_EQ(360u, out_frame->GetHeight());
  // At this point, the view is no longer adapted, since the input has resized
  // small enough to fit the last view request.
  EXPECT_EQ(0, adapter.adapt_reason());

  // And another view request comes in for 640x360, which should have no
  // real impact.
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);
  EXPECT_EQ(0, adapter.adapt_reason());
}

TEST(CoordinatedVideoAdapterTest, TestVGAWidth) {
  CoordinatedVideoAdapter adapter;
  adapter.set_view_switch(true);

  // Start at 640x480, for cameras that don't support 640x360.
  VideoFormat format(640, 480, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  EXPECT_EQ(format, adapter.input_format());
  EXPECT_TRUE(adapter.output_format().IsSize0x0());

  // Output format is 640x360, though.
  format.width = 640;
  format.height = 360;
  adapter.SetOutputFormat(format);

  // And also a view request comes for 640x360.
  adapter.OnOutputFormatRequest(format);
  // At this point, we have to adapt down to something lower.
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);

  // But if frames come in at 640x360, we shouldn't adapt them down.
  // Fake a 640x360 frame.
  WebRtcVideoFrame in_frame;
  in_frame.InitToBlack(640, 360, 1, 1, 33, 33);
  VideoFrame* out_frame;
  adapter.AdaptFrame(&in_frame, &out_frame);

  EXPECT_EQ(640u, out_frame->GetWidth());
  EXPECT_EQ(360u, out_frame->GetHeight());

  // Similarly, no-op adapt requests for other reasons shouldn't change
  // adaptation state (before a previous bug, the previous EXPECTs would
  // fail and the following would succeed, as the no-op CPU request would
  // fix the adaptation state).
  adapter.set_cpu_adaptation(true);
  UpdateCpuLoad(&adapter, 1, 1, 0.7f, 0.7f);
  adapter.AdaptFrame(&in_frame, &out_frame);

  EXPECT_EQ(640u, out_frame->GetWidth());
  EXPECT_EQ(360u, out_frame->GetHeight());
}

// When adapting resolution for CPU or GD, the quantity of pixels that the
// request is based on is reduced to half or double, and then an actual
// resolution is snapped to, rounding to the closest actual resolution.
// This works well for some tolerance to 3/4, odd widths and aspect ratios
// that dont exactly match, but is not best behavior for ViewRequests which
// need to be be strictly respected to avoid going over the resolution budget
// given to the codec - 854x480 total pixels.
// ViewRequest must find a lower resolution.
TEST(CoordinatedVideoAdapterTest, TestCoordinatedViewRequestDown) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(false);

  VideoFormat format(960, 540, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.set_scale_third(true);
  EXPECT_EQ(format, adapter.input_format());
  EXPECT_TRUE(adapter.output_format().IsSize0x0());

  // Server format request 640x400. Expect HVGA.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);

  // Test reason for adapting is VIEW.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW, adapter.adapt_reason());
}

// Test that we downgrade video for cpu up to two times.
TEST(CoordinatedVideoAdapterTest, TestCpuDowngradeTimes) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  EXPECT_FALSE(adapter.cpu_smoothing());
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Process load and system load are low. Do not change the cpu desired format
  // and do not adapt.
  adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // System load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // System load is high. Downgrade again.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // System load is still high. Do not downgrade any more.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Process load and system load are low. Upgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // System load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // System load is still high. Do not downgrade any more.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);
}

// Test that we respect CPU adapter threshold values.
TEST(CoordinatedVideoAdapterTest, TestAdapterCpuThreshold) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  EXPECT_FALSE(adapter.cpu_smoothing());
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Process load and system load are low. Do not change the cpu desired format
  // and do not adapt.
  adapter.OnCpuLoadUpdated(1, 1, 0.2f, 0.3f);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // System load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Test reason for adapting is CPU.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_CPU, adapter.adapt_reason());

  // System load is high. Normally downgrade but threshold is high. Do nothing.
  adapter.set_high_system_threshold(0.98f);  // Set threshold high.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // System load is medium. Normally do nothing, threshold is low. Adapt down.
  adapter.set_high_system_threshold(0.75f);  // Set threshold low.
  UpdateCpuLoad(&adapter, 1, 1, 0.8f, 0.8f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);
}


// Test that for an upgrade cpu request, we actually upgrade the desired format;
// for a downgrade request, we downgrade from the output format.
TEST(CoordinatedVideoAdapterTest, TestRealCpuUpgrade) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  adapter.set_cpu_smoothing(true);
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Process load and system load are low. Do not change the cpu desired format
  // and do not adapt.
  UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Server format request 320x200.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Process load and system load are low. Do not change the cpu desired format
  // and do not adapt.
  UpdateCpuLoad(&adapter, 1, 1, 0.2f, 0.3f);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Server format request 640x400. Set to 640x400 immediately.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Server format request 320x200.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Process load is high, but system is not. Do not change the cpu desired
  // format and do not adapt.
  for (size_t i = 0; i < 10; ++i) {
    UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.8f);
  }
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);
}

// Test that for an upgrade encoder request, we actually upgrade the desired
//  format; for a downgrade request, we downgrade from the output format.
TEST(CoordinatedVideoAdapterTest, TestRealEncoderUpgrade) {
  CoordinatedVideoAdapter adapter;
  adapter.set_cpu_adaptation(true);
  adapter.set_cpu_smoothing(true);
  VideoFormat format(640, 400, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  // Server format request 640x400.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Encoder resolution request. Do not change the encoder desired format and
  // do not adapt.
  adapter.OnEncoderResolutionRequest(640, 400,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(400, adapter.output_format().height);

  // Server format request 320x200.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request. Do not change the encoder desired format and
  // do not adapt.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::UPGRADE);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Server format request 640x400. Set to 640x400 immediately.
  format.width = 640;
  format.height = 400;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(300, adapter.output_format().height);

  // Test reason for adapting is BANDWIDTH.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_BANDWIDTH,
            adapter.adapt_reason());

  // Server format request 320x200.
  format.width = 320;
  format.height = 200;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(200, adapter.output_format().height);

  // Encoder resolution request. Downgrade from 320x200.
  adapter.OnEncoderResolutionRequest(320, 200,
                                     CoordinatedVideoAdapter::DOWNGRADE);
  EXPECT_EQ(240, adapter.output_format().width);
  EXPECT_EQ(150, adapter.output_format().height);
}

TEST(CoordinatedVideoAdapterTest, TestNormalizeOutputFormat) {
  CoordinatedVideoAdapter adapter;
  // The input format is 640x360 and the output is limited to 16:9.
  VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);

  format.width = 320;
  format.height = 180;
  format.interval = VideoFormat::FpsToInterval(15);
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(180, adapter.output_format().height);
  EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval);

  format.width = 320;
  format.height = 200;
  format.interval = VideoFormat::FpsToInterval(40);
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(180, adapter.output_format().height);
  EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval);

  // Test reason for adapting is VIEW. Should work even with normalization.
  EXPECT_EQ(CoordinatedVideoAdapter::ADAPTREASON_VIEW,
            adapter.adapt_reason());

  format.width = 320;
  format.height = 240;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(180, adapter.output_format().height);

  // The input format is 640x480 and the output will be 4:3.
  format.width = 640;
  format.height = 480;
  adapter.SetInputFormat(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(240, adapter.output_format().height);

  format.width = 320;
  format.height = 240;
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(240, adapter.output_format().height);

  // The input format is initialized after the output. At that time, the output
  // height is adjusted.
  format.width = 0;
  format.height = 0;
  adapter.SetInputFormat(format);

  format.width = 320;
  format.height = 240;
  format.interval = VideoFormat::FpsToInterval(30);
  adapter.OnOutputFormatRequest(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(240, adapter.output_format().height);
  EXPECT_EQ(VideoFormat::FpsToInterval(30), adapter.output_format().interval);

  format.width = 640;
  format.height = 480;
  format.interval = VideoFormat::FpsToInterval(15);
  adapter.SetInputFormat(format);
  EXPECT_EQ(320, adapter.output_format().width);
  EXPECT_EQ(240, adapter.output_format().height);
  EXPECT_EQ(VideoFormat::FpsToInterval(15), adapter.output_format().interval);
}

// Test that we downgrade video for cpu up to two times.
TEST_F(VideoAdapterTest, CpuDowngradeAndSignal) {
  CoordinatedVideoAdapter adapter;
  CpuAdapterListener cpu_listener;
  adapter.SignalCpuAdaptationUnable.connect(
      &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled);

  adapter.set_cpu_adaptation(true);
  EXPECT_FALSE(adapter.cpu_smoothing());
  VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.OnOutputFormatRequest(format);

  // System load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);

  // System load is high. Downgrade again.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);

  // System load is still high. Do not downgrade any more. Ensure we have not
  // signalled until after the cpu warning though.
  EXPECT_TRUE(!cpu_listener.received_cpu_signal());
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  EXPECT_TRUE_WAIT(cpu_listener.received_cpu_signal(), kWaitTimeout);
}

// Test that we downgrade video for cpu up to two times.
TEST_F(VideoAdapterTest, CpuDowngradeAndDontSignal) {
  CoordinatedVideoAdapter adapter;
  CpuAdapterListener cpu_listener;
  adapter.SignalCpuAdaptationUnable.connect(
      &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled);

  adapter.set_cpu_adaptation(true);
  adapter.set_cpu_smoothing(true);
  VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.OnOutputFormatRequest(format);

  // System load is high. Downgrade.
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);

  // System load is high, process is not, Do not downgrade again.
  UpdateCpuLoad(&adapter, 1, 1, 0.25f, 0.95f);

  // System load is high, process is not, Do not downgrade again and do not
  // signal.
  adapter.set_cpu_adaptation(false);
  UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  rtc::Thread::Current()->ProcessMessages(kShortWaitTimeout);
  EXPECT_TRUE(!cpu_listener.received_cpu_signal());
  adapter.set_cpu_adaptation(true);
}

// Test that we require enough time before we downgrade.
TEST_F(VideoAdapterTest, CpuMinTimeRequirement) {
  CoordinatedVideoAdapter adapter;
  CpuAdapterListener cpu_listener;
  adapter.SignalCpuAdaptationUnable.connect(
      &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled);

  adapter.set_cpu_adaptation(true);
  adapter.set_cpu_smoothing(true);
  VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.OnOutputFormatRequest(format);

  EXPECT_EQ(3, adapter.cpu_load_min_samples());
  adapter.set_cpu_load_min_samples(5);

  for (size_t i = 0; i < 4; ++i) {
    adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f);
    EXPECT_EQ(640, adapter.output_format().width);
    EXPECT_EQ(360, adapter.output_format().height);
  }
  // The computed cpu load should now be around 93.5%, with the coefficient of
  // 0.4 and a seed value of 0.5. That should be high enough to adapt, but it
  // isn't enough samples, so we shouldn't have adapted on any of the previous
  // samples.

  // One more sample is enough, though, once enough time has passed.
  adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(270, adapter.output_format().height);

  // Now the cpu is lower, but we still need enough samples to upgrade.
  for (size_t i = 0; i < 4; ++i) {
    adapter.OnCpuLoadUpdated(1, 1, 0.1f, 0.1f);
    EXPECT_EQ(480, adapter.output_format().width);
    EXPECT_EQ(270, adapter.output_format().height);
  }

  // One more sample is enough, once time has elapsed.
  adapter.OnCpuLoadUpdated(1, 1, 1.0f, 1.0f);
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);
}

TEST_F(VideoAdapterTest, CpuIgnoresSpikes) {
  CoordinatedVideoAdapter adapter;
  CpuAdapterListener cpu_listener;
  adapter.SignalCpuAdaptationUnable.connect(
      &cpu_listener, &CpuAdapterListener::OnCpuAdaptationSignalled);

  adapter.set_cpu_adaptation(true);
  adapter.set_cpu_smoothing(true);
  VideoFormat format(640, 360, VideoFormat::FpsToInterval(30), FOURCC_I420);
  adapter.SetInputFormat(format);
  adapter.OnOutputFormatRequest(format);

  // System load is high. Downgrade.
  for (size_t i = 0; i < 5; ++i) {
    UpdateCpuLoad(&adapter, 1, 1, 0.95f, 0.95f);
  }
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(270, adapter.output_format().height);

  // Now we're in a state where we could upgrade or downgrade, so get to a
  // steady state of about 75% cpu usage.
  for (size_t i = 0; i < 5; ++i) {
    UpdateCpuLoad(&adapter, 1, 1, 0.75f, 0.75f);
    EXPECT_EQ(480, adapter.output_format().width);
    EXPECT_EQ(270, adapter.output_format().height);
  }

  // Now, the cpu spikes for two samples, but then goes back to
  // normal. This shouldn't cause adaptation.
  UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f);
  UpdateCpuLoad(&adapter, 1, 1, 0.90f, 0.90f);
  EXPECT_EQ(480, adapter.output_format().width);
  EXPECT_EQ(270, adapter.output_format().height);
  // Back to the steady state for awhile.
  for (size_t i = 0; i < 5; ++i) {
    UpdateCpuLoad(&adapter, 1, 1, 0.75, 0.75);
    EXPECT_EQ(480, adapter.output_format().width);
    EXPECT_EQ(270, adapter.output_format().height);
  }

  // Now, system cpu usage is starting to drop down. But it takes a bit before
  // it gets all the way there.
  for (size_t i = 0; i < 10; ++i) {
    UpdateCpuLoad(&adapter, 1, 1, 0.5f, 0.5f);
  }
  EXPECT_EQ(640, adapter.output_format().width);
  EXPECT_EQ(360, adapter.output_format().height);
}

}  // namespace cricket
#endif  // HAVE_WEBRTC_VIDEO
