/*
 * 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/fakevideocapturer.h"
#include "talk/media/base/mediachannel.h"
#include "talk/media/base/testutils.h"
#include "talk/media/base/videoadapter.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 FakeVideoCapturer);
    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);
  }

  virtual void TearDown() {
    // Explicitly disconnect the VideoCapturer before to avoid data races
    // (frames delivered to VideoCapturerListener while it's being destructed).
    capturer_->SignalFrameCaptured.disconnect_all();
  }

 protected:
  class VideoCapturerListener: public sigslot::has_slots<> {
   public:
    struct Stats {
      int captured_frames;
      int dropped_frames;
      bool last_adapt_was_no_op;

      int adapted_width;
      int adapted_height;
    };

    explicit VideoCapturerListener(VideoAdapter* adapter)
        : video_adapter_(adapter),
          captured_frames_(0),
          dropped_frames_(0),
          last_adapt_was_no_op_(false) {
    }

    void OnFrameCaptured(VideoCapturer* capturer,
                         const CapturedFrame* captured_frame) {
      rtc::CritScope lock(&crit_);
      const int in_width = captured_frame->width;
      const int in_height = abs(captured_frame->height);
      const VideoFormat adapted_format =
          video_adapter_->AdaptFrameResolution(in_width, in_height);
      if (!adapted_format.IsSize0x0()) {
        adapted_format_ = adapted_format;
        last_adapt_was_no_op_ = (in_width == adapted_format.width &&
                                 in_height == adapted_format.height);
      } else {
        ++dropped_frames_;
      }
      ++captured_frames_;
    }

    Stats GetStats() {
      rtc::CritScope lock(&crit_);
      Stats stats;
      stats.captured_frames = captured_frames_;
      stats.dropped_frames = dropped_frames_;
      stats.last_adapt_was_no_op = last_adapt_was_no_op_;
      if (!adapted_format_.IsSize0x0()) {
        stats.adapted_width = adapted_format_.width;
        stats.adapted_height = adapted_format_.height;
      } else {
        stats.adapted_width = stats.adapted_height = -1;
      }

      return stats;
    }

   private:
    rtc::CriticalSection crit_;
    VideoAdapter* video_adapter_;
    VideoFormat adapted_format_;
    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_;
  };

  void VerifyAdaptedResolution(const VideoCapturerListener::Stats& stats,
                               int width,
                               int height) {
    EXPECT_EQ(width, stats.adapted_width);
    EXPECT_EQ(height, stats.adapted_height);
  }

  rtc::scoped_ptr<FakeVideoCapturer> 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify no frame drop and no resolution change.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 10);
  EXPECT_EQ(0, stats.dropped_frames);
  VerifyAdaptedResolution(stats, 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify no frame drop and no resolution change.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 10);
  EXPECT_EQ(0, stats.dropped_frames);
  VerifyAdaptedResolution(stats, capture_format_.width, capture_format_.height);
  EXPECT_TRUE(stats.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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify no crash and that frames aren't dropped.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 10);
  EXPECT_EQ(0, stats.dropped_frames);
  VerifyAdaptedResolution(stats, 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify frame drop and no resolution change.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 10);
  EXPECT_EQ(stats.captured_frames / 2, stats.dropped_frames);
  VerifyAdaptedResolution(stats, 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_));
  for (int i = 0; i < 30; ++i)
    capturer_->CaptureFrame();

  // Verify frame drop and no resolution change.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 30);
  // Verify 2 / 3 kept (20) and 1 / 3 dropped (10).
  EXPECT_EQ(stats.captured_frames * 1 / 3, stats.dropped_frames);
  VerifyAdaptedResolution(stats, 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

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

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

  for (int i = 0; i < 20; ++i)
    capturer_->CaptureFrame();

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

// Set a very high output pixel resolution. Expect no resolution change.
TEST_F(VideoAdapterTest, AdaptFrameResolutionHighLimit) {
  adapter_->SetOutputNumPixels(INT_MAX);
  VideoFormat adapted_format = adapter_->AdaptFrameResolution(
      capture_format_.width, capture_format_.height);
  EXPECT_EQ(capture_format_.width, adapted_format.width);
  EXPECT_EQ(capture_format_.height, adapted_format.height);

  adapter_->SetOutputNumPixels(987654321);
  adapted_format = capture_format_,
  adapter_->AdaptFrameResolution(capture_format_.width, capture_format_.height);
  EXPECT_EQ(capture_format_.width, adapted_format.width);
  EXPECT_EQ(capture_format_.height, adapted_format.height);
}

// Adapt the frame resolution to be the same as capture resolution. Expect no
// resolution change.
TEST_F(VideoAdapterTest, AdaptFrameResolutionIdentical) {
  adapter_->SetOutputFormat(capture_format_);
  const VideoFormat adapted_format = adapter_->AdaptFrameResolution(
      capture_format_.width, capture_format_.height);
  EXPECT_EQ(capture_format_.width, adapted_format.width);
  EXPECT_EQ(capture_format_.height, adapted_format.height);
}

// Adapt the frame resolution to be a quarter of the capture resolution. Expect
// resolution change.
TEST_F(VideoAdapterTest, AdaptFrameResolutionQuarter) {
  VideoFormat request_format = capture_format_;
  request_format.width /= 2;
  request_format.height /= 2;
  adapter_->SetOutputFormat(request_format);
  const VideoFormat adapted_format = adapter_->AdaptFrameResolution(
      request_format.width, request_format.height);
  EXPECT_EQ(request_format.width, adapted_format.width);
  EXPECT_EQ(request_format.height, adapted_format.height);
}

// Adapt the pixel resolution to 0. Expect frame drop.
TEST_F(VideoAdapterTest, AdaptFrameResolutionDrop) {
  adapter_->SetOutputNumPixels(0);
  EXPECT_TRUE(
      adapter_->AdaptFrameResolution(capture_format_.width,
                                     capture_format_.height).IsSize0x0());
}

// 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify no frame drop and resolution change.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_EQ(0, stats.dropped_frames);
  VerifyAdaptedResolution(stats, 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify resolution change.
  VerifyAdaptedResolution(listener_->GetStats(),
                          capture_format_.width * 2 / 3,
                          capture_format_.height * 2 / 3);
}

// 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify resolution change.
  VerifyAdaptedResolution(listener_->GetStats(),
                          capture_format_.width * 2 / 3,
                          capture_format_.height * 2 / 3);
}

// 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_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

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

  // Adapt the frame resolution.
  request_format.width /= 2;
  request_format.height /= 2;
  adapter_->SetOutputFormat(request_format);
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

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

// Drop all frames.
TEST_F(VideoAdapterTest, DropAllFrames) {
  VideoFormat format;  // with resolution 0x0.
  adapter_->SetOutputFormat(format);
  EXPECT_EQ(CS_RUNNING, capturer_->Start(capture_format_));
  for (int i = 0; i < 10; ++i)
    capturer_->CaptureFrame();

  // Verify all frames are dropped.
  VideoCapturerListener::Stats stats = listener_->GetStats();
  EXPECT_GE(stats.captured_frames, 10);
  EXPECT_EQ(stats.captured_frames, stats.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.
  const VideoFormat out_format = adapter.AdaptFrameResolution(640, 360);
  EXPECT_EQ(640, out_format.width);
  EXPECT_EQ(360, out_format.height);
  // 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.
  VideoFormat out_format = adapter.AdaptFrameResolution(640, 360);
  EXPECT_EQ(640, out_format.width);
  EXPECT_EQ(360, out_format.height);

  // 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);
  out_format = adapter.AdaptFrameResolution(640, 360);

  EXPECT_EQ(640, out_format.width);
  EXPECT_EQ(360, out_format.height);
}

// 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
