/*
 *  Copyright (c) 2016 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 "modules/video_coding/utility/simulcast_rate_allocator.h"

#include <limits>
#include <memory>
#include <utility>
#include <vector>

#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/video_codecs/vp8_frame_buffer_controller.h"
#include "api/video_codecs/vp8_frame_config.h"
#include "api/video_codecs/vp8_temporal_layers.h"
#include "rtc_base/checks.h"
#include "test/explicit_key_value_config.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {
using test::ExplicitKeyValueConfig;
using ::testing::_;

constexpr uint32_t kFramerateFps = 5;
constexpr uint32_t kMinBitrateKbps = 50;
// These correspond to kLegacyScreenshareTl(0|1)BitrateKbps in cc.
constexpr uint32_t kLegacyScreenshareTargetBitrateKbps = 200;
constexpr uint32_t kLegacyScreenshareMaxBitrateKbps = 1000;
// Bitrates for upper simulcast screenshare layer.
constexpr uint32_t kSimulcastScreenshareMinBitrateKbps = 600;
constexpr uint32_t kSimulcastScreenshareMaxBitrateKbps = 1250;
// Default video hysteresis factor: allocatable bitrate for next layer must
// exceed 20% of min setting in order to be initially turned on.
const double kDefaultHysteresis = 1.2;

class MockTemporalLayers : public Vp8FrameBufferController {
 public:
  MOCK_METHOD(Vp8FrameConfig, NextFrameConfig, (size_t, uint32_t), (override));
  MOCK_METHOD(void,
              OnRatesUpdated,
              (size_t, const std::vector<uint32_t>&, int),
              (override));
  MOCK_METHOD(Vp8EncoderConfig, UpdateConfiguration, (size_t), (override));
  MOCK_METHOD(void,
              OnEncodeDone,
              (size_t, uint32_t, size_t, bool, int, CodecSpecificInfo*),
              (override));
};
}  // namespace

class SimulcastRateAllocatorTest : public ::testing::TestWithParam<bool> {
 public:
  SimulcastRateAllocatorTest() {
    codec_.codecType = kVideoCodecVP8;
    codec_.minBitrate = kMinBitrateKbps;
    codec_.maxBitrate = kLegacyScreenshareMaxBitrateKbps;
    codec_.active = true;
    CreateAllocator();
  }
  virtual ~SimulcastRateAllocatorTest() {}

  template <size_t S>
  void ExpectEqual(uint32_t (&expected)[S],
                   const std::vector<uint32_t>& actual) {
    EXPECT_EQ(S, actual.size());
    for (size_t i = 0; i < S; ++i)
      EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i;
  }

  template <size_t S>
  void ExpectEqual(uint32_t (&expected)[S],
                   const VideoBitrateAllocation& actual) {
    // EXPECT_EQ(S, actual.size());
    uint32_t sum = 0;
    for (size_t i = 0; i < S; ++i) {
      uint32_t layer_bitrate = actual.GetSpatialLayerSum(i);
      if (layer_bitrate == 0) {
        EXPECT_FALSE(actual.IsSpatialLayerUsed(i));
      }
      EXPECT_EQ(expected[i] * 1000U, layer_bitrate)
          << "Mismatch at index " << i;
      sum += layer_bitrate;
    }
    EXPECT_EQ(sum, actual.get_sum_bps());
  }

  void CreateAllocator(Environment env = CreateEnvironment()) {
    allocator_ = std::make_unique<SimulcastRateAllocator>(env, codec_);
  }

  void SetupCodec3SL3TL(const std::vector<bool>& active_streams) {
    const size_t num_simulcast_layers = 3;
    RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
    SetupCodec2SL3TL(active_streams);
    codec_.numberOfSimulcastStreams = num_simulcast_layers;
    codec_.simulcastStream[2].numberOfTemporalLayers = 3;
    codec_.simulcastStream[2].maxBitrate = 4000;
    codec_.simulcastStream[2].targetBitrate = 3000;
    codec_.simulcastStream[2].minBitrate = 2000;
    codec_.simulcastStream[2].active = active_streams[2];
  }

  void SetupCodec2SL3TL(const std::vector<bool>& active_streams) {
    const size_t num_simulcast_layers = 2;
    RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
    SetupCodec1SL3TL(active_streams);
    codec_.numberOfSimulcastStreams = num_simulcast_layers;
    codec_.simulcastStream[1].numberOfTemporalLayers = 3;
    codec_.simulcastStream[1].maxBitrate = 1000;
    codec_.simulcastStream[1].targetBitrate = 500;
    codec_.simulcastStream[1].minBitrate = 50;
    codec_.simulcastStream[1].active = active_streams[1];
  }

  void SetupCodec1SL3TL(const std::vector<bool>& active_streams) {
    const size_t num_simulcast_layers = 2;
    RTC_DCHECK_GE(active_streams.size(), num_simulcast_layers);
    SetupCodec3TL();
    codec_.numberOfSimulcastStreams = num_simulcast_layers;
    codec_.simulcastStream[0].numberOfTemporalLayers = 3;
    codec_.simulcastStream[0].maxBitrate = 500;
    codec_.simulcastStream[0].targetBitrate = 100;
    codec_.simulcastStream[0].minBitrate = 10;
    codec_.simulcastStream[0].active = active_streams[0];
  }

  void SetupCodec3TL() {
    codec_.maxBitrate = 0;
    codec_.VP8()->numberOfTemporalLayers = 3;
  }

  VideoBitrateAllocation GetAllocation(uint32_t target_bitrate) {
    return allocator_->Allocate(VideoBitrateAllocationParameters(
        DataRate::KilobitsPerSec(target_bitrate), kDefaultFrameRate));
  }

  VideoBitrateAllocation GetAllocation(DataRate target_rate,
                                       DataRate stable_rate) {
    return allocator_->Allocate(VideoBitrateAllocationParameters(
        target_rate, stable_rate, kDefaultFrameRate));
  }

  DataRate MinRate(size_t layer_index) const {
    return DataRate::KilobitsPerSec(
        codec_.simulcastStream[layer_index].minBitrate);
  }

  DataRate TargetRate(size_t layer_index) const {
    return DataRate::KilobitsPerSec(
        codec_.simulcastStream[layer_index].targetBitrate);
  }

  DataRate MaxRate(size_t layer_index) const {
    return DataRate::KilobitsPerSec(
        codec_.simulcastStream[layer_index].maxBitrate);
  }

 protected:
  static const int kDefaultFrameRate = 30;
  VideoCodec codec_;
  std::unique_ptr<SimulcastRateAllocator> allocator_;
};

TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) {
  uint32_t expected[] = {codec_.minBitrate};
  codec_.active = true;
  ExpectEqual(expected, GetAllocation(codec_.minBitrate - 1));
  ExpectEqual(expected, GetAllocation(1));
  ExpectEqual(expected, GetAllocation(0));
}

TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) {
  uint32_t expected[] = {codec_.maxBitrate};
  codec_.active = true;
  ExpectEqual(expected, GetAllocation(codec_.maxBitrate + 1));
  ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}

TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) {
  const uint32_t kMax = VideoBitrateAllocation::kMaxBitrateBps / 1000;
  codec_.active = true;
  codec_.maxBitrate = 0;
  CreateAllocator();

  uint32_t expected[] = {kMax};
  ExpectEqual(expected, GetAllocation(kMax));
}

TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) {
  codec_.active = true;
  for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate;
       ++bitrate) {
    uint32_t expected[] = {bitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }
}

// Tests that when we aren't using simulcast and the codec is marked inactive no
// bitrate will be allocated.
TEST_F(SimulcastRateAllocatorTest, NoSimulcastInactive) {
  codec_.active = false;
  uint32_t expected[] = {0};
  CreateAllocator();

  ExpectEqual(expected, GetAllocation(kMinBitrateKbps - 10));
  ExpectEqual(expected, GetAllocation(kLegacyScreenshareTargetBitrateKbps));
  ExpectEqual(expected, GetAllocation(kLegacyScreenshareMaxBitrateKbps + 10));
}

TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) {
  // With simulcast, use the min bitrate from the ss spec instead of the global.
  codec_.numberOfSimulcastStreams = 1;
  const uint32_t kMin = codec_.minBitrate - 10;
  codec_.simulcastStream[0].minBitrate = kMin;
  codec_.simulcastStream[0].targetBitrate = kLegacyScreenshareTargetBitrateKbps;
  codec_.simulcastStream[0].active = true;
  CreateAllocator();

  uint32_t expected[] = {kMin};
  ExpectEqual(expected, GetAllocation(kMin - 1));
  ExpectEqual(expected, GetAllocation(1));
  ExpectEqual(expected, GetAllocation(0));
}

TEST_F(SimulcastRateAllocatorTest, SignalsBwLimited) {
  // Enough to enable all layers.
  const int kVeryBigBitrate = 100000;

  // With simulcast, use the min bitrate from the ss spec instead of the global.
  SetupCodec3SL3TL({true, true, true});
  CreateAllocator();

  EXPECT_TRUE(
      GetAllocation(codec_.simulcastStream[0].minBitrate - 10).is_bw_limited());
  EXPECT_TRUE(
      GetAllocation(codec_.simulcastStream[0].targetBitrate).is_bw_limited());
  EXPECT_TRUE(GetAllocation(codec_.simulcastStream[0].targetBitrate +
                            codec_.simulcastStream[1].minBitrate)
                  .is_bw_limited());
  EXPECT_FALSE(
      GetAllocation(
          codec_.simulcastStream[0].targetBitrate +
          codec_.simulcastStream[1].targetBitrate +
          static_cast<uint32_t>(
              codec_.simulcastStream[2].minBitrate * kDefaultHysteresis + 0.5))
          .is_bw_limited());
  EXPECT_FALSE(GetAllocation(kVeryBigBitrate).is_bw_limited());
}

TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) {
  codec_.numberOfSimulcastStreams = 1;
  codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
  const uint32_t kMax = codec_.simulcastStream[0].maxBitrate + 1000;
  codec_.simulcastStream[0].maxBitrate = kMax;
  codec_.simulcastStream[0].active = true;
  CreateAllocator();

  uint32_t expected[] = {kMax};
  ExpectEqual(expected, GetAllocation(kMax));
  ExpectEqual(expected, GetAllocation(kMax + 1));
  ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
}

TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) {
  codec_.numberOfSimulcastStreams = 1;
  codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
  codec_.simulcastStream[0].targetBitrate = kLegacyScreenshareTargetBitrateKbps;
  codec_.simulcastStream[0].maxBitrate = kLegacyScreenshareMaxBitrateKbps;
  codec_.simulcastStream[0].active = true;
  CreateAllocator();

  for (uint32_t bitrate = kMinBitrateKbps;
       bitrate <= kLegacyScreenshareMaxBitrateKbps; ++bitrate) {
    uint32_t expected[] = {bitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }
}

TEST_F(SimulcastRateAllocatorTest, Regular3TLTemporalRateAllocation) {
  SetupCodec3SL3TL({true, true, true});
  CreateAllocator();

  const VideoBitrateAllocation alloc = GetAllocation(kMinBitrateKbps);
  // 40/20/40.
  EXPECT_EQ(static_cast<uint32_t>(0.4 * kMinBitrateKbps),
            alloc.GetBitrate(0, 0) / 1000);
  EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
            alloc.GetBitrate(0, 1) / 1000);
  EXPECT_EQ(static_cast<uint32_t>(0.4 * kMinBitrateKbps),
            alloc.GetBitrate(0, 2) / 1000);
}

TEST_F(SimulcastRateAllocatorTest, BaseHeavy3TLTemporalRateAllocation) {
  ExplicitKeyValueConfig field_trials(
      "WebRTC-UseBaseHeavyVP8TL3RateAllocation/Enabled/");

  SetupCodec3SL3TL({true, true, true});
  CreateAllocator(CreateEnvironment(&field_trials));

  const VideoBitrateAllocation alloc = GetAllocation(kMinBitrateKbps);
  // 60/20/20.
  EXPECT_EQ(static_cast<uint32_t>(0.6 * kMinBitrateKbps),
            alloc.GetBitrate(0, 0) / 1000);
  EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
            alloc.GetBitrate(0, 1) / 1000);
  EXPECT_EQ(static_cast<uint32_t>(0.2 * kMinBitrateKbps),
            alloc.GetBitrate(0, 2) / 1000);
}

TEST_F(SimulcastRateAllocatorTest, SingleSimulcastInactive) {
  codec_.numberOfSimulcastStreams = 1;
  codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
  codec_.simulcastStream[0].targetBitrate = kLegacyScreenshareTargetBitrateKbps;
  codec_.simulcastStream[0].maxBitrate = kLegacyScreenshareMaxBitrateKbps;
  codec_.simulcastStream[0].active = false;
  CreateAllocator();

  uint32_t expected[] = {0};
  ExpectEqual(expected, GetAllocation(kMinBitrateKbps - 10));
  ExpectEqual(expected, GetAllocation(kLegacyScreenshareTargetBitrateKbps));
  ExpectEqual(expected, GetAllocation(kLegacyScreenshareMaxBitrateKbps + 10));
}

TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) {
  SetupCodec3SL3TL({true, true, true});
  CreateAllocator();

  {
    // Single stream, min bitrate.
    const uint32_t bitrate = codec_.simulcastStream[0].minBitrate;
    uint32_t expected[] = {bitrate, 0, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Single stream at target bitrate.
    const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate;
    uint32_t expected[] = {bitrate, 0, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  uint32_t kMinInitialRateTwoLayers =
      codec_.simulcastStream[0].targetBitrate +
      static_cast<uint32_t>(codec_.simulcastStream[1].minBitrate *
                            kDefaultHysteresis);
  {
    // Bitrate above target for first stream, but below min for the next one.
    const uint32_t bitrate = kMinInitialRateTwoLayers - 1;
    uint32_t expected[] = {bitrate, 0, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Just enough for two streams.
    const uint32_t bitrate = kMinInitialRateTwoLayers;
    uint32_t expected[] = {
        codec_.simulcastStream[0].targetBitrate,
        kMinInitialRateTwoLayers - codec_.simulcastStream[0].targetBitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Second stream maxed out, but not enough for third.
    const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
                             codec_.simulcastStream[1].maxBitrate;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].maxBitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  uint32_t kMinInitialRateThreeLayers =
      codec_.simulcastStream[0].targetBitrate +
      codec_.simulcastStream[1].targetBitrate +
      static_cast<uint32_t>(codec_.simulcastStream[2].minBitrate *
                            kDefaultHysteresis);
  {
    // First two streams maxed out, but not enough for third. Nowhere to put
    // remaining bits.
    const uint32_t bitrate = kMinInitialRateThreeLayers - 1;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].maxBitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Just enough for all three streams.
    const uint32_t bitrate = kMinInitialRateThreeLayers;
    uint32_t expected[] = {
        codec_.simulcastStream[0].targetBitrate,
        codec_.simulcastStream[1].targetBitrate,
        static_cast<uint32_t>(codec_.simulcastStream[2].minBitrate *
                              kDefaultHysteresis)};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Third maxed out.
    const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
                             codec_.simulcastStream[1].targetBitrate +
                             codec_.simulcastStream[2].maxBitrate;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].targetBitrate,
                           codec_.simulcastStream[2].maxBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Enough to max out all streams which will allocate the target amount to
    // the lower streams.
    const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate +
                             codec_.simulcastStream[1].maxBitrate +
                             codec_.simulcastStream[2].maxBitrate;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].targetBitrate,
                           codec_.simulcastStream[2].maxBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }
}

// If three simulcast streams that are all inactive, none of them should be
// allocated bitrate.
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsInactive) {
  SetupCodec3SL3TL({false, false, false});
  CreateAllocator();

  // Just enough to allocate the min.
  const uint32_t min_bitrate = codec_.simulcastStream[0].minBitrate +
                               codec_.simulcastStream[1].minBitrate +
                               codec_.simulcastStream[2].minBitrate;
  // Enough bitrate to allocate target to all streams.
  const uint32_t target_bitrate = codec_.simulcastStream[0].targetBitrate +
                                  codec_.simulcastStream[1].targetBitrate +
                                  codec_.simulcastStream[2].targetBitrate;
  // Enough bitrate to allocate max to all streams.
  const uint32_t max_bitrate = codec_.simulcastStream[0].maxBitrate +
                               codec_.simulcastStream[1].maxBitrate +
                               codec_.simulcastStream[2].maxBitrate;
  uint32_t expected[] = {0, 0, 0};
  ExpectEqual(expected, GetAllocation(0));
  ExpectEqual(expected, GetAllocation(min_bitrate));
  ExpectEqual(expected, GetAllocation(target_bitrate));
  ExpectEqual(expected, GetAllocation(max_bitrate));
}

// If there are two simulcast streams, we expect the high active stream to be
// allocated as if it is a single active stream.
TEST_F(SimulcastRateAllocatorTest, TwoStreamsLowInactive) {
  SetupCodec2SL3TL({false, true});
  CreateAllocator();

  const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[1].minBitrate;
  const uint32_t kActiveStreamTargetBitrate =
      codec_.simulcastStream[1].targetBitrate;
  const uint32_t kActiveStreamMaxBitrate = codec_.simulcastStream[1].maxBitrate;
  {
    // Expect that the stream is always allocated its min bitrate.
    uint32_t expected[] = {0, kActiveStreamMinBitrate};
    ExpectEqual(expected, GetAllocation(0));
    ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate - 10));
    ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate));
  }

  {
    // The stream should be allocated its target bitrate.
    uint32_t expected[] = {0, kActiveStreamTargetBitrate};
    ExpectEqual(expected, GetAllocation(kActiveStreamTargetBitrate));
  }

  {
    // The stream should be allocated its max if the target input is sufficient.
    uint32_t expected[] = {0, kActiveStreamMaxBitrate};
    ExpectEqual(expected, GetAllocation(kActiveStreamMaxBitrate));
    ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
  }
}

// If there are two simulcast streams, we expect the low active stream to be
// allocated as if it is a single active stream.
TEST_F(SimulcastRateAllocatorTest, TwoStreamsHighInactive) {
  SetupCodec2SL3TL({true, false});
  CreateAllocator();

  const uint32_t kActiveStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
  const uint32_t kActiveStreamTargetBitrate =
      codec_.simulcastStream[0].targetBitrate;
  const uint32_t kActiveStreamMaxBitrate = codec_.simulcastStream[0].maxBitrate;
  {
    // Expect that the stream is always allocated its min bitrate.
    uint32_t expected[] = {kActiveStreamMinBitrate, 0};
    ExpectEqual(expected, GetAllocation(0));
    ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate - 10));
    ExpectEqual(expected, GetAllocation(kActiveStreamMinBitrate));
  }

  {
    // The stream should be allocated its target bitrate.
    uint32_t expected[] = {kActiveStreamTargetBitrate, 0};
    ExpectEqual(expected, GetAllocation(kActiveStreamTargetBitrate));
  }

  {
    // The stream should be allocated its max if the target input is sufficent.
    uint32_t expected[] = {kActiveStreamMaxBitrate, 0};
    ExpectEqual(expected, GetAllocation(kActiveStreamMaxBitrate));
    ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
  }
}

// If there are three simulcast streams and the middle stream is inactive, the
// other two streams should be allocated bitrate the same as if they are two
// active simulcast streams.
TEST_F(SimulcastRateAllocatorTest, ThreeStreamsMiddleInactive) {
  SetupCodec3SL3TL({true, false, true});
  CreateAllocator();

  {
    const uint32_t kLowStreamMinBitrate = codec_.simulcastStream[0].minBitrate;
    // The lowest stream should always be allocated its minimum bitrate.
    uint32_t expected[] = {kLowStreamMinBitrate, 0, 0};
    ExpectEqual(expected, GetAllocation(0));
    ExpectEqual(expected, GetAllocation(kLowStreamMinBitrate - 10));
    ExpectEqual(expected, GetAllocation(kLowStreamMinBitrate));
  }

  {
    // The lowest stream gets its target bitrate.
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0, 0};
    ExpectEqual(expected,
                GetAllocation(codec_.simulcastStream[0].targetBitrate));
  }

  {
    // The lowest stream gets its max bitrate, but not enough for the high
    // stream.
    const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
                             codec_.simulcastStream[2].minBitrate - 1;
    uint32_t expected[] = {codec_.simulcastStream[0].maxBitrate, 0, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Both active streams get allocated target bitrate.
    const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
                             codec_.simulcastStream[2].targetBitrate;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0,
                           codec_.simulcastStream[2].targetBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Lowest stream gets its target bitrate, high stream gets its max bitrate.
    uint32_t bitrate = codec_.simulcastStream[0].targetBitrate +
                       codec_.simulcastStream[2].maxBitrate;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, 0,
                           codec_.simulcastStream[2].maxBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
    ExpectEqual(expected, GetAllocation(bitrate + 10));
    ExpectEqual(expected, GetAllocation(std::numeric_limits<uint32_t>::max()));
  }
}

TEST_F(SimulcastRateAllocatorTest, NonConferenceModeScreenshare) {
  codec_.mode = VideoCodecMode::kScreensharing;
  SetupCodec3SL3TL({true, true, true});
  CreateAllocator();

  // Make sure we have enough bitrate for all 3 simulcast layers
  const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate +
                           codec_.simulcastStream[1].maxBitrate +
                           codec_.simulcastStream[2].maxBitrate;
  const VideoBitrateAllocation alloc = GetAllocation(bitrate);

  EXPECT_EQ(alloc.GetTemporalLayerAllocation(0).size(), 3u);
  EXPECT_EQ(alloc.GetTemporalLayerAllocation(1).size(), 3u);
  EXPECT_EQ(alloc.GetTemporalLayerAllocation(2).size(), 3u);
}

TEST_F(SimulcastRateAllocatorTest, StableRate) {
  ExplicitKeyValueConfig field_trials(
      "WebRTC-StableTargetRate/"
      "enabled:true,"
      "video_hysteresis_factor:1.1/");

  SetupCodec3SL3TL({true, true, true});
  CreateAllocator(CreateEnvironment(&field_trials));

  // Let the volatile rate always be be enough for all streams, in this test we
  // are only interested in how the stable rate affects enablement.
  const DataRate volatile_rate =
      (TargetRate(0) + TargetRate(1) + MinRate(2)) * 1.1;

  {
    // On the first call to a new SimulcastRateAllocator instance, hysteresis
    // is disabled, but stable rate still caps layers.
    uint32_t expected[] = {TargetRate(0).kbps<uint32_t>(),
                           MaxRate(1).kbps<uint32_t>()};
    ExpectEqual(expected,
                GetAllocation(volatile_rate, TargetRate(0) + MinRate(1)));
  }

  {
    // Let stable rate go to a bitrate below what is needed for two streams.
    uint32_t expected[] = {MaxRate(0).kbps<uint32_t>(), 0};
    ExpectEqual(expected,
                GetAllocation(volatile_rate, TargetRate(0) + MinRate(1) -
                                                 DataRate::BitsPerSec(1)));
  }

  {
    // Don't enable stream as we need to get up above hysteresis threshold.
    uint32_t expected[] = {MaxRate(0).kbps<uint32_t>(), 0};
    ExpectEqual(expected,
                GetAllocation(volatile_rate, TargetRate(0) + MinRate(1)));
  }

  {
    // Above threshold with hysteresis, enable second stream.
    uint32_t expected[] = {TargetRate(0).kbps<uint32_t>(),
                           MaxRate(1).kbps<uint32_t>()};
    ExpectEqual(expected, GetAllocation(volatile_rate,
                                        (TargetRate(0) + MinRate(1)) * 1.1));
  }

  {
    // Enough to enable all thee layers.
    uint32_t expected[] = {
        TargetRate(0).kbps<uint32_t>(), TargetRate(1).kbps<uint32_t>(),
        (volatile_rate - TargetRate(0) - TargetRate(1)).kbps<uint32_t>()};
    ExpectEqual(expected, GetAllocation(volatile_rate, volatile_rate));
  }

  {
    // Drop hysteresis, all three still on.
    uint32_t expected[] = {
        TargetRate(0).kbps<uint32_t>(), TargetRate(1).kbps<uint32_t>(),
        (volatile_rate - TargetRate(0) - TargetRate(1)).kbps<uint32_t>()};
    ExpectEqual(expected,
                GetAllocation(volatile_rate,
                              TargetRate(0) + TargetRate(1) + MinRate(2)));
  }
}

class ScreenshareRateAllocationTest : public SimulcastRateAllocatorTest {
 public:
  void SetupConferenceScreenshare(bool use_simulcast, bool active = true) {
    codec_.mode = VideoCodecMode::kScreensharing;
    codec_.minBitrate = kMinBitrateKbps;
    codec_.maxBitrate =
        kLegacyScreenshareMaxBitrateKbps + kSimulcastScreenshareMaxBitrateKbps;
    if (use_simulcast) {
      codec_.numberOfSimulcastStreams = 2;
      codec_.simulcastStream[0].minBitrate = kMinBitrateKbps;
      codec_.simulcastStream[0].targetBitrate =
          kLegacyScreenshareTargetBitrateKbps;
      codec_.simulcastStream[0].maxBitrate = kLegacyScreenshareMaxBitrateKbps;
      codec_.simulcastStream[0].numberOfTemporalLayers = 2;
      codec_.simulcastStream[0].active = active;

      codec_.simulcastStream[1].minBitrate =
          kSimulcastScreenshareMinBitrateKbps;
      codec_.simulcastStream[1].targetBitrate =
          kSimulcastScreenshareMaxBitrateKbps;
      codec_.simulcastStream[1].maxBitrate =
          kSimulcastScreenshareMaxBitrateKbps;
      codec_.simulcastStream[1].numberOfTemporalLayers = 2;
      codec_.simulcastStream[1].active = active;
    } else {
      codec_.numberOfSimulcastStreams = 0;
      codec_.VP8()->numberOfTemporalLayers = 2;
      codec_.active = active;
    }
  }
};

INSTANTIATE_TEST_SUITE_P(ScreenshareTest,
                         ScreenshareRateAllocationTest,
                         ::testing::Bool());

TEST_P(ScreenshareRateAllocationTest, ConferenceBitrateBelowTl0) {
  SetupConferenceScreenshare(GetParam());
  CreateAllocator();
  allocator_->SetLegacyConferenceMode(true);

  VideoBitrateAllocation allocation =
      allocator_->Allocate(VideoBitrateAllocationParameters(
          kLegacyScreenshareTargetBitrateKbps * 1000, kFramerateFps));

  // All allocation should go in TL0.
  EXPECT_EQ(kLegacyScreenshareTargetBitrateKbps, allocation.get_sum_kbps());
  EXPECT_EQ(kLegacyScreenshareTargetBitrateKbps,
            allocation.GetBitrate(0, 0) / 1000);
  EXPECT_EQ(allocation.is_bw_limited(), GetParam());
}

TEST_P(ScreenshareRateAllocationTest, ConferenceBitrateAboveTl0) {
  SetupConferenceScreenshare(GetParam());
  CreateAllocator();
  allocator_->SetLegacyConferenceMode(true);

  uint32_t target_bitrate_kbps =
      (kLegacyScreenshareTargetBitrateKbps + kLegacyScreenshareMaxBitrateKbps) /
      2;
  VideoBitrateAllocation allocation =
      allocator_->Allocate(VideoBitrateAllocationParameters(
          target_bitrate_kbps * 1000, kFramerateFps));

  // Fill TL0, then put the rest in TL1.
  EXPECT_EQ(target_bitrate_kbps, allocation.get_sum_kbps());
  EXPECT_EQ(kLegacyScreenshareTargetBitrateKbps,
            allocation.GetBitrate(0, 0) / 1000);
  EXPECT_EQ(target_bitrate_kbps - kLegacyScreenshareTargetBitrateKbps,
            allocation.GetBitrate(0, 1) / 1000);
  EXPECT_EQ(allocation.is_bw_limited(), GetParam());
}

TEST_F(ScreenshareRateAllocationTest, ConferenceBitrateAboveTl1) {
  // This test is only for the non-simulcast case.
  SetupConferenceScreenshare(false);
  CreateAllocator();
  allocator_->SetLegacyConferenceMode(true);

  VideoBitrateAllocation allocation =
      allocator_->Allocate(VideoBitrateAllocationParameters(
          kLegacyScreenshareMaxBitrateKbps * 2000, kFramerateFps));

  // Fill both TL0 and TL1, but no more.
  EXPECT_EQ(kLegacyScreenshareMaxBitrateKbps, allocation.get_sum_kbps());
  EXPECT_EQ(kLegacyScreenshareTargetBitrateKbps,
            allocation.GetBitrate(0, 0) / 1000);
  EXPECT_EQ(
      kLegacyScreenshareMaxBitrateKbps - kLegacyScreenshareTargetBitrateKbps,
      allocation.GetBitrate(0, 1) / 1000);
  EXPECT_FALSE(allocation.is_bw_limited());
}

// This tests when the screenshare is inactive it should be allocated 0 bitrate
// for all layers.
TEST_P(ScreenshareRateAllocationTest, InactiveScreenshare) {
  SetupConferenceScreenshare(GetParam(), false);
  CreateAllocator();

  // Enough bitrate for TL0 and TL1.
  uint32_t target_bitrate_kbps =
      (kLegacyScreenshareTargetBitrateKbps + kLegacyScreenshareMaxBitrateKbps) /
      2;
  VideoBitrateAllocation allocation =
      allocator_->Allocate(VideoBitrateAllocationParameters(
          target_bitrate_kbps * 1000, kFramerateFps));

  EXPECT_EQ(0U, allocation.get_sum_kbps());
}

TEST_F(ScreenshareRateAllocationTest, Hysteresis) {
  // This test is only for the simulcast case.
  SetupConferenceScreenshare(true);
  CreateAllocator();

  // The bitrate at which we would normally enable the upper simulcast stream.
  const uint32_t default_enable_rate_bps =
      codec_.simulcastStream[0].targetBitrate +
      codec_.simulcastStream[1].minBitrate;
  const uint32_t enable_rate_with_hysteresis_bps =
      (default_enable_rate_bps * 135) / 100;

  {
    // On the first call to a new SimulcastRateAllocator instance, hysteresis
    // is disabled.
    const uint32_t bitrate = default_enable_rate_bps;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].minBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Go down to a bitrate below what is needed for two streams.
    const uint32_t bitrate = default_enable_rate_bps - 1;
    uint32_t expected[] = {bitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Don't enable stream as we need to get up above hysteresis threshold.
    const uint32_t bitrate = default_enable_rate_bps;
    uint32_t expected[] = {bitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Above threshold, enable second stream.
    const uint32_t bitrate = enable_rate_with_hysteresis_bps;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           enable_rate_with_hysteresis_bps -
                               codec_.simulcastStream[0].targetBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Go down again, still keep the second stream alive.
    const uint32_t bitrate = default_enable_rate_bps;
    uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate,
                           codec_.simulcastStream[1].minBitrate};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Go down below default enable, second stream is shut down again.
    const uint32_t bitrate = default_enable_rate_bps - 1;
    uint32_t expected[] = {bitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }

  {
    // Go up, hysteresis is blocking us again.
    const uint32_t bitrate = default_enable_rate_bps;
    uint32_t expected[] = {bitrate, 0};
    ExpectEqual(expected, GetAllocation(bitrate));
  }
}

}  // namespace webrtc
