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

#include "call/adaptation/video_stream_adapter.h"

#include <cstddef>
#include <optional>
#include <string>

#include "absl/strings/str_cat.h"
#include "api/adaptation/resource.h"
#include "api/rtp_parameters.h"
#include "api/scoped_refptr.h"
#include "api/video/video_adaptation_counters.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/video_codec.h"
#include "api/video_codecs/video_encoder.h"
#include "call/adaptation/adaptation_constraint.h"
#include "call/adaptation/test/fake_frame_rate_provider.h"
#include "call/adaptation/test/fake_resource.h"
#include "call/adaptation/test/fake_video_stream_input_state_provider.h"
#include "call/adaptation/video_source_restrictions.h"
#include "call/adaptation/video_stream_input_state.h"
#include "rtc_base/checks.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {

using ::testing::_;
using ::testing::Return;

namespace {

constexpr int kBalancedHighResolutionPixels = 1280 * 720;
constexpr int kBalancedHighFrameRateFps = 30;

constexpr int kBalancedMediumResolutionPixels = 640 * 480;
constexpr int kBalancedMediumFrameRateFps = 20;

constexpr int kBalancedLowResolutionPixels = 320 * 240;
constexpr int kBalancedLowFrameRateFps = 10;

std::string BalancedFieldTrialConfig() {
  return "WebRTC-Video-BalancedDegradationSettings/pixels:" +
         absl::StrCat(kBalancedLowResolutionPixels) + "|" +
         absl::StrCat(kBalancedMediumResolutionPixels) + "|" +
         absl::StrCat(kBalancedHighResolutionPixels) +
         ",fps:" + absl::StrCat(kBalancedLowFrameRateFps) + "|" +
         absl::StrCat(kBalancedMediumFrameRateFps) + "|" +
         absl::StrCat(kBalancedHighFrameRateFps) + "/";
}

// Responsible for adjusting the inputs to VideoStreamAdapter (SetInput), such
// as pixels and frame rate, according to the most recent source restrictions.
// This helps tests that apply adaptations multiple times: if the input is not
// adjusted between adaptations, the subsequent adaptations fail with
// kAwaitingPreviousAdaptation.
class FakeVideoStream {
 public:
  FakeVideoStream(VideoStreamAdapter* adapter,
                  FakeVideoStreamInputStateProvider* provider,
                  int input_pixels,
                  int input_fps,
                  int min_pixels_per_frame)
      : adapter_(adapter),
        provider_(provider),
        input_pixels_(input_pixels),
        input_fps_(input_fps),
        min_pixels_per_frame_(min_pixels_per_frame) {
    provider_->SetInputState(input_pixels_, input_fps_, min_pixels_per_frame_);
  }

  int input_pixels() const { return input_pixels_; }
  int input_fps() const { return input_fps_; }

  // Performs ApplyAdaptation() followed by SetInput() with input pixels and
  // frame rate adjusted according to the resulting restrictions.
  void ApplyAdaptation(Adaptation adaptation) {
    adapter_->ApplyAdaptation(adaptation, nullptr);
    // Update input pixels and fps according to the resulting restrictions.
    auto restrictions = adapter_->source_restrictions();
    if (restrictions.target_pixels_per_frame().has_value()) {
      RTC_DCHECK(!restrictions.max_pixels_per_frame().has_value() ||
                 restrictions.max_pixels_per_frame().value() >=
                     restrictions.target_pixels_per_frame().value());
      input_pixels_ = restrictions.target_pixels_per_frame().value();
    } else if (restrictions.max_pixels_per_frame().has_value()) {
      input_pixels_ = restrictions.max_pixels_per_frame().value();
    }
    if (restrictions.max_frame_rate().has_value()) {
      input_fps_ = restrictions.max_frame_rate().value();
    }
    provider_->SetInputState(input_pixels_, input_fps_, min_pixels_per_frame_);
  }

 private:
  VideoStreamAdapter* adapter_;
  FakeVideoStreamInputStateProvider* provider_;
  int input_pixels_;
  int input_fps_;
  int min_pixels_per_frame_;
};

class FakeVideoStreamAdapterListner : public VideoSourceRestrictionsListener {
 public:
  void OnVideoSourceRestrictionsUpdated(
      VideoSourceRestrictions /* restrictions */,
      const VideoAdaptationCounters& /* adaptation_counters */,
      scoped_refptr<Resource> /* reason */,
      const VideoSourceRestrictions& unfiltered_restrictions) override {
    calls_++;
    last_restrictions_ = unfiltered_restrictions;
  }

  int calls() const { return calls_; }

  VideoSourceRestrictions last_restrictions() const {
    return last_restrictions_;
  }

 private:
  int calls_ = 0;
  VideoSourceRestrictions last_restrictions_;
};

class MockAdaptationConstraint : public AdaptationConstraint {
 public:
  MOCK_METHOD(bool,
              IsAdaptationUpAllowed,
              (const VideoStreamInputState& input_state,
               const VideoSourceRestrictions& restrictions_before,
               const VideoSourceRestrictions& restrictions_after),
              (const, override));

  // MOCK_METHOD(std::string, Name, (), (const, override));
  std::string Name() const override { return "MockAdaptationConstraint"; }
};

}  // namespace

class VideoStreamAdapterTest : public ::testing::Test {
 public:
  VideoStreamAdapterTest()
      : resource_(FakeResource::Create("FakeResource")),
        adapter_(&input_state_provider_,
                 &encoder_stats_observer_,
                 CreateTestFieldTrials(BalancedFieldTrialConfig())) {}

 protected:
  FakeVideoStreamInputStateProvider input_state_provider_;
  scoped_refptr<Resource> resource_;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter_;
};

TEST_F(VideoStreamAdapterTest, NoRestrictionsByDefault) {
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_DecreasesPixelsToThreeFifths) {
  const int kInputPixels = 1280 * 720;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(kInputPixels, 30,
                                      kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(static_cast<size_t>((kInputPixels * 3) / 5),
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_DecreasesPixelsToLimitReached) {
  const int kMinPixelsPerFrame = 640 * 480;

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(kMinPixelsPerFrame + 1, 30,
                                      kMinPixelsPerFrame);
  EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached());
  // Even though we are above kMinPixelsPerFrame, because adapting down would
  // have exceeded the limit, we are said to have reached the limit already.
  // This differs from the frame rate adaptation logic, which would have clamped
  // to the limit in the first step and reported kLimitReached in the second
  // step.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kLimitReached, adaptation.status());
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_IncreasePixelsToFiveThirds) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Go down twice, ensuring going back up is still a restricted resolution.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  int input_pixels = fake_stream.input_pixels();
  // Go up once. The target is 5/3 and the max is 12/5 of the target.
  const int target = (input_pixels * 5) / 3;
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(static_cast<size_t>((target * 12) / 5),
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(static_cast<size_t>(target),
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainFramerate_IncreasePixelsToUnrestricted) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // We are unrestricted by default and should not be able to adapt up.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // If we go down once and then back up we should not have any restrictions.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_DecreasesFpsToTwoThirds) {
  const int kInputFps = 30;

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  input_state_provider_.SetInputState(1280 * 720, kInputFps,
                                      kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>((kInputFps * 2) / 3),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_DecreasesFpsToLimitReached) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720,
                              kMinFrameRateFps + 1, kDefaultMinPixelsPerFrame);
  // If we are not yet at the limit and the next step would exceed it, the step
  // is clamped such that we end up exactly on the limit.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(static_cast<double>(kMinFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Having reached the limit, the next adaptation down is not valid.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationDown().status());
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_IncreaseFpsToThreeHalves) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Go down twice, ensuring going back up is still a restricted frame rate.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().fps_adaptations);
  int input_fps = fake_stream.input_fps();
  // Go up once. The target is 3/2 of the input.
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>((input_fps * 3) / 2),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, MaintainResolution_IncreaseFpsToUnrestricted) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // We are unrestricted by default and should not be able to adapt up.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // If we go down once and then back up we should not have any restrictions.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest, Balanced_DecreaseFrameRate) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(kBalancedMediumResolutionPixels,
                                      kBalancedHighFrameRateFps,
                                      kDefaultMinPixelsPerFrame);
  // If our frame rate is higher than the frame rate associated with our
  // resolution we should try to adapt to the frame rate associated with our
  // resolution: kBalancedMediumFrameRateFps.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  adapter_.ApplyAdaptation(adaptation, nullptr);
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedMediumFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest, Balanced_DecreaseResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedHighResolutionPixels,
      kBalancedHighFrameRateFps, kDefaultMinPixelsPerFrame);
  // If we are not below the current resolution's frame rate limit, we should
  // adapt resolution according to "maintain-framerate" logic (three fifths).
  //
  // However, since we are unlimited at the start and input frame rate is not
  // below kBalancedHighFrameRateFps, we first restrict the frame rate to
  // kBalancedHighFrameRateFps even though that is our current frame rate. This
  // does prevent the source from going higher, though, so it's technically not
  // a NO-OP.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Verify "maintain-framerate" logic the second time we adapt: Frame rate
  // restrictions remains the same and resolution goes down.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  constexpr size_t kReducedPixelsFirstStep =
      static_cast<size_t>((kBalancedHighResolutionPixels * 3) / 5);
  EXPECT_EQ(kReducedPixelsFirstStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // If we adapt again, because the balanced settings' proposed frame rate is
  // still kBalancedHighFrameRateFps, "maintain-framerate" will trigger again.
  static_assert(kReducedPixelsFirstStep > kBalancedMediumResolutionPixels,
                "The reduced resolution is still greater than the next lower "
                "balanced setting resolution");
  constexpr size_t kReducedPixelsSecondStep = (kReducedPixelsFirstStep * 3) / 5;
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
  }
  EXPECT_EQ(kReducedPixelsSecondStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  EXPECT_EQ(std::nullopt,
            adapter_.source_restrictions().target_pixels_per_frame());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

// Testing when to adapt frame rate and when to adapt resolution is quite
// entangled, so this test covers both cases.
//
// There is an asymmetry: When we adapt down we do it in one order, but when we
// adapt up we don't do it in the reverse order. Instead we always try to adapt
// frame rate first according to balanced settings' configs and only when the
// frame rate is already achieved do we adjust the resolution.
TEST_F(VideoStreamAdapterTest, Balanced_IncreaseFrameRateAndResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedHighResolutionPixels,
      kBalancedHighFrameRateFps, kDefaultMinPixelsPerFrame);
  // The desired starting point of this test is having adapted frame rate twice.
  // This requires performing a number of adaptations.
  constexpr size_t kReducedPixelsFirstStep =
      static_cast<size_t>((kBalancedHighResolutionPixels * 3) / 5);
  constexpr size_t kReducedPixelsSecondStep = (kReducedPixelsFirstStep * 3) / 5;
  constexpr size_t kReducedPixelsThirdStep = (kReducedPixelsSecondStep * 3) / 5;
  static_assert(kReducedPixelsFirstStep > kBalancedMediumResolutionPixels,
                "The first pixel reduction is greater than the balanced "
                "settings' medium pixel configuration");
  static_assert(kReducedPixelsSecondStep > kBalancedMediumResolutionPixels,
                "The second pixel reduction is greater than the balanced "
                "settings' medium pixel configuration");
  static_assert(kReducedPixelsThirdStep <= kBalancedMediumResolutionPixels,
                "The third pixel reduction is NOT greater than the balanced "
                "settings' medium pixel configuration");
  // The first adaptation should affect the frame rate: See
  // Balanced_DecreaseResolution for explanation why.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  // The next three adaptations affects the resolution, because we have to reach
  // kBalancedMediumResolutionPixels before a lower frame rate is considered by
  // BalancedDegradationSettings. The number three is derived from the
  // static_asserts above.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsFirstStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsSecondStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(kReducedPixelsThirdStep,
            adapter_.source_restrictions().max_pixels_per_frame());
  // Thus, the next adaptation will reduce frame rate to
  // kBalancedMediumFrameRateFps.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedMediumFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(3, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(2, adapter_.adaptation_counters().fps_adaptations);
  // Adapt up!
  // While our resolution is in the medium-range, the frame rate associated with
  // the next resolution configuration up ("high") is kBalancedHighFrameRateFps
  // and "balanced" prefers adapting frame rate if not already applied.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(static_cast<double>(kBalancedHighFrameRateFps),
              adapter_.source_restrictions().max_frame_rate());
    EXPECT_EQ(3, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now that we have already achieved the next frame rate up, we act according
  // to "maintain-framerate". We go back up in resolution. Due to rounding
  // errors we don't end up back at kReducedPixelsSecondStep. Rather we get to
  // kReducedPixelsSecondStepUp, which is off by one compared to
  // kReducedPixelsSecondStep.
  constexpr size_t kReducedPixelsSecondStepUp =
      (kReducedPixelsThirdStep * 5) / 3;
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(kReducedPixelsSecondStepUp,
              adapter_.source_restrictions().target_pixels_per_frame());
    EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now that our resolution is back in the high-range, the next frame rate to
  // try out is "unlimited".
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(std::nullopt, adapter_.source_restrictions().max_frame_rate());
    EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
  }
  // Now only adapting resolution remains.
  constexpr size_t kReducedPixelsFirstStepUp =
      (kReducedPixelsSecondStepUp * 5) / 3;
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(kReducedPixelsFirstStepUp,
              adapter_.source_restrictions().target_pixels_per_frame());
    EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
    EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
  }
  // The last step up should make us entirely unrestricted.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
    EXPECT_EQ(0, adapter_.adaptation_counters().Total());
  }
}

TEST_F(VideoStreamAdapterTest, Balanced_LimitReached) {
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  FakeVideoStream fake_stream(
      &adapter_, &input_state_provider_, kBalancedLowResolutionPixels,
      kBalancedLowFrameRateFps, kDefaultMinPixelsPerFrame);
  // Attempting to adapt up while unrestricted should result in kLimitReached.
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptationUp().status());
  // Adapting down once result in restricted frame rate, in this case we reach
  // the lowest possible frame rate immediately: kBalancedLowFrameRateFps.
  EXPECT_CALL(encoder_stats_observer_, OnMinPixelLimitReached()).Times(2);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(static_cast<double>(kBalancedLowFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  // Any further adaptation must follow "maintain-framerate" rules (these are
  // covered in more depth by the MaintainFramerate tests). This test does not
  // assert exactly how resolution is adjusted, only that resolution always
  // decreases and that we eventually reach kLimitReached.
  size_t previous_resolution = kBalancedLowResolutionPixels;
  bool did_reach_limit = false;
  // If we have not reached the limit within 5 adaptations something is wrong...
  for (int i = 0; i < 5; i++) {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    if (adaptation.status() == Adaptation::Status::kLimitReached) {
      did_reach_limit = true;
      break;
    }
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_LT(adapter_.source_restrictions().max_pixels_per_frame().value(),
              previous_resolution);
    previous_resolution =
        adapter_.source_restrictions().max_pixels_per_frame().value();
  }
  EXPECT_TRUE(did_reach_limit);
  // Frame rate restrictions are the same as before.
  EXPECT_EQ(static_cast<double>(kBalancedLowFrameRateFps),
            adapter_.source_restrictions().max_frame_rate());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
}

// kAwaitingPreviousAdaptation is only supported in "maintain-framerate".
TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AwaitingPreviousAdaptationDown) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  // Adapt down once, but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  {
    // Having performed the adaptation, but not updated the input based on the
    // new restrictions, adapting again in the same direction will not work.
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
              adaptation.status());
  }
}

// kAwaitingPreviousAdaptation is only supported in "maintain-framerate".
TEST_F(VideoStreamAdapterTest, MaintainFramerate_AwaitingPreviousAdaptationUp) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Perform two adaptation down so that adapting up twice is possible.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(2, adapter_.adaptation_counters().resolution_adaptations);
  // Adapt up once, but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationUp(), nullptr);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  {
    // Having performed the adaptation, but not updated the input based on the
    // new restrictions, adapting again in the same direction will not work.
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
              adaptation.status());
  }
}

TEST_F(VideoStreamAdapterTest,
       MaintainResolution_AdaptsUpAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down in fps for later.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);

  // We should be able to adapt in framerate one last time after the change of
  // degradation preference.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AdaptsUpAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down in resolution for later.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
  EXPECT_EQ(0, adapter_.adaptation_counters().fps_adaptations);

  // We should be able to adapt in framerate one last time after the change of
  // degradation preference.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationUp());
  EXPECT_EQ(0, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       PendingResolutionIncreaseAllowsAdaptUpAfterSwitchToMaintainResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt fps down so we can adapt up later in the test.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  // Apply adaptation up but don't update input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationUp(), nullptr);
  EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
            adapter_.GetAdaptationUp().status());

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationUp();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
}

TEST_F(VideoStreamAdapterTest,
       MaintainFramerate_AdaptsDownAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once, should change FPS.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  // Adaptation down should apply after the degradation prefs change.
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);
  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       MaintainResolution_AdaptsDownAfterSwitchingDegradationPreference) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once, should change FPS.
  fake_stream.ApplyAdaptation(adapter_.GetAdaptationDown());
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);

  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  fake_stream.ApplyAdaptation(adaptation);

  EXPECT_EQ(1, adapter_.adaptation_counters().fps_adaptations);
  EXPECT_EQ(1, adapter_.adaptation_counters().resolution_adaptations);
}

TEST_F(
    VideoStreamAdapterTest,
    PendingResolutionDecreaseAllowsAdaptDownAfterSwitchToMaintainResolution) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Apply adaptation but don't update the input.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_EQ(Adaptation::Status::kAwaitingPreviousAdaptation,
            adapter_.GetAdaptationDown().status());
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  Adaptation adaptation = adapter_.GetAdaptationDown();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
}

TEST_F(VideoStreamAdapterTest, RestrictionBroadcasted) {
  FakeVideoStreamAdapterListner listener;
  adapter_.AddRestrictionsListener(&listener);
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Not broadcast on invalid ApplyAdaptation.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    adapter_.ApplyAdaptation(adaptation, nullptr);
    EXPECT_EQ(0, listener.calls());
  }

  // Broadcast on ApplyAdaptation.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(1, listener.calls());
    EXPECT_EQ(adaptation.restrictions(), listener.last_restrictions());
  }

  // Broadcast on ClearRestrictions().
  adapter_.ClearRestrictions();
  EXPECT_EQ(2, listener.calls());
  EXPECT_EQ(VideoSourceRestrictions(), listener.last_restrictions());
}

TEST_F(VideoStreamAdapterTest, AdaptationHasNextRestrcitions) {
  // Any non-disabled DegradationPreference will do.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // When adaptation is not possible.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kLimitReached, adaptation.status());
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(0, adaptation.counters().Total());
  }
  // When we adapt down.
  {
    Adaptation adaptation = adapter_.GetAdaptationDown();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(adaptation.counters(), adapter_.adaptation_counters());
  }
  // When we adapt up.
  {
    Adaptation adaptation = adapter_.GetAdaptationUp();
    EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
    fake_stream.ApplyAdaptation(adaptation);
    EXPECT_EQ(adaptation.restrictions(), adapter_.source_restrictions());
    EXPECT_EQ(adaptation.counters(), adapter_.adaptation_counters());
  }
}

TEST_F(VideoStreamAdapterTest,
       SetDegradationPreferenceToOrFromBalancedClearsRestrictions) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_NE(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_NE(0, adapter_.adaptation_counters().Total());
  // Changing from non-balanced to balanced clears the restrictions.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
  // Apply adaptation again.
  adapter_.ApplyAdaptation(adapter_.GetAdaptationDown(), nullptr);
  EXPECT_NE(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_NE(0, adapter_.adaptation_counters().Total());
  // Changing from balanced to non-balanced clears the restrictions.
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_EQ(VideoSourceRestrictions(), adapter_.source_restrictions());
  EXPECT_EQ(0, adapter_.adaptation_counters().Total());
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsResolutionInMaintainFramerate) {
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(0, adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionReturnsWithStatusInDisabledAndMaintainResolution) {
  adapter_.SetDegradationPreference(
      DegradationPreference::MAINTAIN_FRAMERATE_AND_RESOLUTION);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptDownResolution().status());
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_EQ(Adaptation::Status::kLimitReached,
            adapter_.GetAdaptDownResolution().status());
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsFpsAndResolutionInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution and
  // frame rate once.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(1, adaptation.counters().fps_adaptations);
}

TEST_F(
    VideoStreamAdapterTest,
    GetAdaptDownResolutionAdaptsOnlyResolutionIfFpsAlreadyAdapterInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution
  // only.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(1280 * 720, 5, kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);

  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(1, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(first_adaptation.counters().fps_adaptations,
            adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       GetAdaptDownResolutionAdaptsOnlyFpsIfResolutionLowInBalanced) {
  // Note: This test depends on BALANCED implementation, but with current
  // implementation and input state settings, BALANCED will adapt resolution
  // only.
  adapter_.SetDegradationPreference(DegradationPreference::BALANCED);
  input_state_provider_.SetInputState(kDefaultMinPixelsPerFrame, 30,
                                      kDefaultMinPixelsPerFrame);

  auto adaptation = adapter_.GetAdaptDownResolution();
  EXPECT_EQ(Adaptation::Status::kValid, adaptation.status());
  EXPECT_EQ(0, adaptation.counters().resolution_adaptations);
  EXPECT_EQ(1, adaptation.counters().fps_adaptations);
}

TEST_F(VideoStreamAdapterTest,
       AdaptationDisabledStatusWhenPreferenceIsMaintainFramerateAndResolution) {
  adapter_.SetDegradationPreference(
      DegradationPreference::MAINTAIN_FRAMERATE_AND_RESOLUTION);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptationDown().status());
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptationUp().status());
  EXPECT_EQ(Adaptation::Status::kAdaptationDisabled,
            adapter_.GetAdaptDownResolution().status());
}

TEST_F(VideoStreamAdapterTest, AdaptationConstraintAllowsAdaptationsUp) {
  testing::StrictMock<MockAdaptationConstraint> adaptation_constraint;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  adapter_.AddAdaptationConstraint(&adaptation_constraint);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once so we can adapt up later.
  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  EXPECT_CALL(adaptation_constraint,
              IsAdaptationUpAllowed(_, first_adaptation.restrictions(), _))
      .WillOnce(Return(true));
  EXPECT_EQ(Adaptation::Status::kValid, adapter_.GetAdaptationUp().status());
  adapter_.RemoveAdaptationConstraint(&adaptation_constraint);
}

TEST_F(VideoStreamAdapterTest, AdaptationConstraintDisallowsAdaptationsUp) {
  testing::StrictMock<MockAdaptationConstraint> adaptation_constraint;
  adapter_.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  adapter_.AddAdaptationConstraint(&adaptation_constraint);
  input_state_provider_.SetInputState(1280 * 720, 30,
                                      kDefaultMinPixelsPerFrame);
  FakeVideoStream fake_stream(&adapter_, &input_state_provider_, 1280 * 720, 30,
                              kDefaultMinPixelsPerFrame);
  // Adapt down once so we can adapt up later.
  auto first_adaptation = adapter_.GetAdaptationDown();
  fake_stream.ApplyAdaptation(first_adaptation);

  EXPECT_CALL(adaptation_constraint,
              IsAdaptationUpAllowed(_, first_adaptation.restrictions(), _))
      .WillOnce(Return(false));
  EXPECT_EQ(Adaptation::Status::kRejectedByConstraint,
            adapter_.GetAdaptationUp().status());
  adapter_.RemoveAdaptationConstraint(&adaptation_constraint);
}

using VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest =
    ::testing::TestWithParam<VideoCodecType>;

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
       SimulcastNoActiveStreams) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = false;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = false;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
       SimulcastOneActiveStream) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = false;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = true;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec), 640 * 360u);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
       SimulcastMultipleActiveStreams) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = true;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = true;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
       SinglecastOneActiveSpatialLayer) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 1;
  codec.spatialLayers[0].active = false;
  codec.spatialLayers[0].width = 320;
  codec.spatialLayers[0].height = 180;
  codec.spatialLayers[1].active = true;
  codec.spatialLayers[1].width = 640;
  codec.spatialLayers[1].height = 360;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec), 640 * 360u);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
       SinglecastMultipleActiveSpatialLayers) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 1;
  codec.spatialLayers[0].active = true;
  codec.spatialLayers[0].width = 320;
  codec.spatialLayers[0].height = 180;
  codec.spatialLayers[1].active = true;
  codec.spatialLayers[1].width = 640;
  codec.spatialLayers[1].height = 360;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

INSTANTIATE_TEST_SUITE_P(VideoStreamAdapterGetSingleActiveLayerPixelsTest,
                         VideoStreamAdapterGetSingleActiveLayerPixelsSvcTest,
                         ::testing::Values(VideoCodecType::kVideoCodecVP9,
                                           VideoCodecType::kVideoCodecAV1));

using VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest =
    ::testing::TestWithParam<VideoCodecType>;

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
       SimulcastNoActiveStreams) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = false;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = false;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
       SimulcastOneActiveStream) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = false;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = true;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec), 640 * 360u);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
       SimulcastMultipleActiveStreams) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 3;
  codec.simulcastStream[0].active = true;
  codec.simulcastStream[0].width = 320;
  codec.simulcastStream[0].height = 180;
  codec.simulcastStream[1].active = true;
  codec.simulcastStream[1].width = 640;
  codec.simulcastStream[1].height = 360;
  codec.simulcastStream[2].active = false;
  codec.simulcastStream[2].width = 1280;
  codec.simulcastStream[2].height = 720;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
       SinglecastOneActiveStream) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 1;
  codec.simulcastStream[0].active = true;
  codec.simulcastStream[0].width = 640;
  codec.simulcastStream[0].height = 360;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec), 640 * 360u);
}

TEST_P(VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
       SinglecastSpatialLayersAreIgnored) {
  VideoCodec codec;
  codec.codecType = GetParam();
  codec.numberOfSimulcastStreams = 1;
  codec.spatialLayers[0].active = true;
  codec.spatialLayers[0].width = 640;
  codec.spatialLayers[0].height = 360;

  EXPECT_EQ(VideoStreamAdapter::GetSingleActiveLayerPixels(codec),
            std::nullopt);
}

INSTANTIATE_TEST_SUITE_P(VideoStreamAdapterGetSingleActiveLayerPixelsTest,
                         VideoStreamAdapterGetSingleActiveLayerPixelsNonSvcTest,
                         ::testing::Values(VideoCodecType::kVideoCodecVP8,
                                           VideoCodecType::kVideoCodecH264,
                                           VideoCodecType::kVideoCodecH265));

// Death tests.
// Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h.
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(VideoStreamAdapterDeathTest,
     SetDegradationPreferenceInvalidatesAdaptations) {
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_,
                             CreateTestFieldTrials());
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_FRAMERATE);
  input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter.GetAdaptationDown();
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  EXPECT_DEATH(adapter.ApplyAdaptation(adaptation, nullptr), "");
}

TEST(VideoStreamAdapterDeathTest, AdaptDownInvalidatesAdaptations) {
  FakeVideoStreamInputStateProvider input_state_provider;
  testing::StrictMock<MockVideoStreamEncoderObserver> encoder_stats_observer_;
  VideoStreamAdapter adapter(&input_state_provider, &encoder_stats_observer_,
                             CreateTestFieldTrials());
  adapter.SetDegradationPreference(DegradationPreference::MAINTAIN_RESOLUTION);
  input_state_provider.SetInputState(1280 * 720, 30, kDefaultMinPixelsPerFrame);
  Adaptation adaptation = adapter.GetAdaptationDown();
  adapter.GetAdaptationDown();
  EXPECT_DEATH(adapter.ApplyAdaptation(adaptation, nullptr), "");
}

#endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

}  // namespace webrtc
