/*
 *  Copyright (c) 2018 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/codecs/vp9/svc_rate_allocator.h"

#include <algorithm>
#include <vector>

#include "modules/video_coding/codecs/vp9/svc_config.h"
#include "rtc_base/checks.h"
#include "test/field_trial.h"
#include "test/gtest.h"

namespace webrtc {
namespace test {
namespace {
static VideoCodec Configure(size_t width,
                            size_t height,
                            size_t num_spatial_layers,
                            size_t num_temporal_layers,
                            bool is_screen_sharing) {
  VideoCodec codec;
  codec.width = width;
  codec.height = height;
  codec.codecType = kVideoCodecVP9;
  codec.mode = is_screen_sharing ? VideoCodecMode::kScreensharing
                                 : VideoCodecMode::kRealtimeVideo;

  std::vector<SpatialLayer> spatial_layers =
      GetSvcConfig(width, height, 30, num_spatial_layers, num_temporal_layers,
                   is_screen_sharing);
  RTC_CHECK_LE(spatial_layers.size(), kMaxSpatialLayers);

  codec.VP9()->numberOfSpatialLayers =
      std::min<unsigned char>(num_spatial_layers, spatial_layers.size());
  codec.VP9()->numberOfTemporalLayers = std::min<unsigned char>(
      num_temporal_layers, spatial_layers.back().numberOfTemporalLayers);

  for (size_t sl_idx = 0; sl_idx < spatial_layers.size(); ++sl_idx) {
    codec.spatialLayers[sl_idx] = spatial_layers[sl_idx];
  }

  return codec;
}

}  // namespace

TEST(SvcRateAllocatorTest, SingleLayerFor320x180Input) {
  VideoCodec codec = Configure(320, 180, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
}

TEST(SvcRateAllocatorTest, TwoLayersFor640x360Input) {
  VideoCodec codec = Configure(640, 360, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0u);
}

TEST(SvcRateAllocatorTest, ThreeLayersFor1280x720Input) {
  VideoCodec codec = Configure(1280, 720, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(1000 * 1000, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
  EXPECT_GT(allocation.GetSpatialLayerSum(2), 0u);
}

TEST(SvcRateAllocatorTest,
     BaseLayerNonZeroBitrateEvenIfTotalIfLessThanMinimum) {
  VideoCodec codec = Configure(1280, 720, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  const SpatialLayer* layers = codec.spatialLayers;

  VideoBitrateAllocation allocation = allocator.Allocate(
      VideoBitrateAllocationParameters(layers[0].minBitrate * 1000 / 2, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_LT(allocation.GetSpatialLayerSum(0), layers[0].minBitrate * 1000);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
}

TEST(SvcRateAllocatorTest, Disable640x360Layer) {
  VideoCodec codec = Configure(1280, 720, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  const SpatialLayer* layers = codec.spatialLayers;

  size_t min_bitrate_for_640x360_layer_kbps =
      layers[0].minBitrate + layers[1].minBitrate;

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(
          min_bitrate_for_640x360_layer_kbps * 1000 - 1, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0u);
}

TEST(SvcRateAllocatorTest, Disable1280x720Layer) {
  VideoCodec codec = Configure(1280, 720, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  const SpatialLayer* layers = codec.spatialLayers;

  size_t min_bitrate_for_1280x720_layer_kbps =
      layers[0].minBitrate + layers[1].minBitrate + layers[2].minBitrate;

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(
          min_bitrate_for_1280x720_layer_kbps * 1000 - 1, 30));

  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0u);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0u);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0u);
}

TEST(SvcRateAllocatorTest, BitrateIsCapped) {
  VideoCodec codec = Configure(1280, 720, 3, 3, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  const SpatialLayer* layers = codec.spatialLayers;

  const uint32_t link_mbps = 100;
  VideoBitrateAllocation allocation = allocator.Allocate(
      VideoBitrateAllocationParameters(link_mbps * 1000000, 30));

  EXPECT_EQ(allocation.get_sum_kbps(),
            layers[0].maxBitrate + layers[1].maxBitrate + layers[2].maxBitrate);
  EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].maxBitrate);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1) / 1000, layers[1].maxBitrate);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2) / 1000, layers[2].maxBitrate);
}

TEST(SvcRateAllocatorTest, MinBitrateToGetQualityLayer) {
  VideoCodec codec = Configure(1280, 720, 3, 1, true);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  const SpatialLayer* layers = codec.spatialLayers;

  EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U);

  VideoBitrateAllocation allocation = allocator.Allocate(
      VideoBitrateAllocationParameters(layers[0].minBitrate * 1000, 30));
  EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].minBitrate);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL);

  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      (layers[0].targetBitrate + layers[1].minBitrate) * 1000, 30));
  EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].targetBitrate);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1) / 1000, layers[1].minBitrate);
}

TEST(SvcRateAllocatorTest, DeactivateHigherLayers) {
  for (int deactivated_idx = 2; deactivated_idx >= 0; --deactivated_idx) {
    VideoCodec codec = Configure(1280, 720, 3, 1, false);
    EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U);

    for (int i = deactivated_idx; i < 3; ++i)
      codec.spatialLayers[i].active = false;

    SvcRateAllocator allocator = SvcRateAllocator(codec);

    VideoBitrateAllocation allocation = allocator.Allocate(
        VideoBitrateAllocationParameters(10 * 1000 * 1000, 30));

    // Ensure layers spatial_idx < deactivated_idx are activated.
    for (int spatial_idx = 0; spatial_idx < deactivated_idx; ++spatial_idx) {
      EXPECT_GT(allocation.GetSpatialLayerSum(spatial_idx), 0UL);
    }

    // Ensure layers spatial_idx >= deactivated_idx are deactivated.
    for (int spatial_idx = deactivated_idx; spatial_idx < 3; ++spatial_idx) {
      EXPECT_EQ(allocation.GetSpatialLayerSum(spatial_idx), 0UL);
    }
  }
}

TEST(SvcRateAllocatorTest, DeactivateLowerLayers) {
  for (int deactivated_idx = 0; deactivated_idx < 3; ++deactivated_idx) {
    VideoCodec codec = Configure(1280, 720, 3, 1, false);
    EXPECT_LE(codec.VP9()->numberOfSpatialLayers, 3U);

    for (int i = deactivated_idx; i >= 0; --i)
      codec.spatialLayers[i].active = false;

    SvcRateAllocator allocator = SvcRateAllocator(codec);

    VideoBitrateAllocation allocation = allocator.Allocate(
        VideoBitrateAllocationParameters(10 * 1000 * 1000, 30));

    // Ensure layers spatial_idx <= deactivated_idx are deactivated.
    for (int spatial_idx = 0; spatial_idx <= deactivated_idx; ++spatial_idx) {
      EXPECT_EQ(allocation.GetSpatialLayerSum(spatial_idx), 0UL);
    }

    // Ensure layers spatial_idx > deactivated_idx are activated.
    for (int spatial_idx = deactivated_idx + 1; spatial_idx < 3;
         ++spatial_idx) {
      EXPECT_GT(allocation.GetSpatialLayerSum(spatial_idx), 0UL);
    }
  }
}

TEST(SvcRateAllocatorTest, SignalsBwLimited) {
  VideoCodec codec = Configure(1280, 720, 3, 1, false);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  // Rough estimate calculated by hand.
  uint32_t min_to_enable_all = 900000;

  EXPECT_TRUE(
      allocator
          .Allocate(VideoBitrateAllocationParameters(min_to_enable_all / 2, 30))
          .is_bw_limited());

  EXPECT_FALSE(
      allocator
          .Allocate(VideoBitrateAllocationParameters(min_to_enable_all, 30))
          .is_bw_limited());
}

TEST(SvcRateAllocatorTest, NoPaddingIfAllLayersAreDeactivated) {
  VideoCodec codec = Configure(1280, 720, 3, 1, false);
  EXPECT_EQ(codec.VP9()->numberOfSpatialLayers, 3U);
  // Deactivation of base layer deactivates all layers.
  codec.spatialLayers[0].active = false;
  codec.spatialLayers[1].active = false;
  codec.spatialLayers[2].active = false;
  DataRate padding_rate = SvcRateAllocator::GetPaddingBitrate(codec);
  EXPECT_EQ(padding_rate, DataRate::Zero());
}

TEST(SvcRateAllocatorTest, FindLayerTogglingThreshold) {
  // Let's unit test a utility method of the unit test...

  // Predetermined constants indicating the min bitrate needed for two and three
  // layers to be enabled respectively, using the config from Configure() with
  // 1280x720 resolution and three spatial layers.
  const DataRate kTwoLayerMinRate = DataRate::bps(299150);
  const DataRate kThreeLayerMinRate = DataRate::bps(891052);

  VideoCodec codec = Configure(1280, 720, 3, 1, false);
  absl::InlinedVector<DataRate, kMaxSpatialLayers> layer_start_bitrates =
      SvcRateAllocator::GetLayerStartBitrates(codec);
  ASSERT_EQ(layer_start_bitrates.size(), 3u);
  EXPECT_EQ(layer_start_bitrates[1], kTwoLayerMinRate);
  EXPECT_EQ(layer_start_bitrates[2], kThreeLayerMinRate);
}

class SvcRateAllocatorTestParametrizedContentType
    : public ::testing::Test,
      public ::testing::WithParamInterface<bool> {
 public:
  SvcRateAllocatorTestParametrizedContentType()
      : is_screen_sharing_(GetParam()) {}

  const bool is_screen_sharing_;
};

TEST_P(SvcRateAllocatorTestParametrizedContentType, MaxBitrate) {
  VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_);
  EXPECT_EQ(SvcRateAllocator::GetMaxBitrate(codec),
            DataRate::kbps(codec.spatialLayers[0].maxBitrate +
                           codec.spatialLayers[1].maxBitrate +
                           codec.spatialLayers[2].maxBitrate));

  // Deactivate middle layer. This causes deactivation of top layer as well.
  codec.spatialLayers[1].active = false;
  EXPECT_EQ(SvcRateAllocator::GetMaxBitrate(codec),
            DataRate::kbps(codec.spatialLayers[0].maxBitrate));
}

TEST_P(SvcRateAllocatorTestParametrizedContentType, PaddingBitrate) {
  VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_);
  SvcRateAllocator allocator = SvcRateAllocator(codec);

  DataRate padding_bitrate = SvcRateAllocator::GetPaddingBitrate(codec);

  VideoBitrateAllocation allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(padding_bitrate, 30));
  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
  EXPECT_GT(allocation.GetSpatialLayerSum(2), 0UL);

  // Allocate 90% of padding bitrate. Top layer should be disabled.
  allocation = allocator.Allocate(
      VideoBitrateAllocationParameters(9 * padding_bitrate / 10, 30));
  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);

  // Deactivate top layer.
  codec.spatialLayers[2].active = false;

  padding_bitrate = SvcRateAllocator::GetPaddingBitrate(codec);
  allocation =
      allocator.Allocate(VideoBitrateAllocationParameters(padding_bitrate, 30));
  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
  EXPECT_GT(allocation.GetSpatialLayerSum(1), 0UL);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);

  allocation = allocator.Allocate(
      VideoBitrateAllocationParameters(9 * padding_bitrate / 10, 30));
  EXPECT_GT(allocation.GetSpatialLayerSum(0), 0UL);
  EXPECT_EQ(allocation.GetSpatialLayerSum(1), 0UL);
  EXPECT_EQ(allocation.GetSpatialLayerSum(2), 0UL);

  // Deactivate all layers.
  codec.spatialLayers[0].active = false;
  codec.spatialLayers[1].active = false;
  codec.spatialLayers[2].active = false;

  padding_bitrate = SvcRateAllocator::GetPaddingBitrate(codec);
  // No padding expected.
  EXPECT_EQ(DataRate::Zero(), padding_bitrate);
}

TEST_P(SvcRateAllocatorTestParametrizedContentType, StableBitrate) {
  ScopedFieldTrials field_trial(
      "WebRTC-StableTargetRate/enabled:true,video_hysteresis_factor:1.0,"
      "screenshare_hysteresis_factor:1.0/");

  const VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_);
  const auto start_rates = SvcRateAllocator::GetLayerStartBitrates(codec);
  const DataRate min_rate_two_layers = start_rates[1];
  const DataRate min_rate_three_layers = start_rates[2];

  const DataRate max_rate_one_layer =
      DataRate::kbps(codec.spatialLayers[0].maxBitrate);
  const DataRate max_rate_two_layers =
      is_screen_sharing_ ? DataRate::kbps(codec.spatialLayers[0].targetBitrate +
                                          codec.spatialLayers[1].maxBitrate)
                         : DataRate::kbps(codec.spatialLayers[0].maxBitrate +
                                          codec.spatialLayers[1].maxBitrate);

  SvcRateAllocator allocator = SvcRateAllocator(codec);

  // Two layers, stable and target equal.
  auto allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/min_rate_two_layers,
      /*stable_bitrate=*/min_rate_two_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_EQ(allocation.get_sum_bps(), min_rate_two_layers.bps());

  // Two layers, stable bitrate too low for two layers.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/min_rate_two_layers,
      /*stable_bitrate=*/min_rate_two_layers - DataRate::bps(1),
      /*fps=*/30.0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(1));
  EXPECT_EQ(
      DataRate::bps(allocation.get_sum_bps()),
      std::min(min_rate_two_layers - DataRate::bps(1), max_rate_one_layer));

  // Three layers, stable and target equal.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/min_rate_three_layers,
      /*stable_bitrate=*/min_rate_three_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(2));
  EXPECT_EQ(allocation.get_sum_bps(), min_rate_three_layers.bps());

  // Three layers, stable bitrate too low for three layers.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/min_rate_three_layers,
      /*stable_bitrate=*/min_rate_three_layers - DataRate::bps(1),
      /*fps=*/30.0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));
  EXPECT_EQ(
      DataRate::bps(allocation.get_sum_bps()),
      std::min(min_rate_three_layers - DataRate::bps(1), max_rate_two_layers));
}

TEST_P(SvcRateAllocatorTestParametrizedContentType,
       StableBitrateWithHysteresis) {
  const VideoCodec codec = Configure(1280, 720, 3, 1, is_screen_sharing_);
  const auto start_rates = SvcRateAllocator::GetLayerStartBitrates(codec);
  const DataRate min_rate_single_layer = start_rates[0];
  const DataRate min_rate_two_layers = start_rates[1];
  const DataRate min_rate_three_layers = start_rates[2];

  ScopedFieldTrials field_trial(
      "WebRTC-StableTargetRate/enabled:true,video_hysteresis_factor:1.1,"
      "screenshare_hysteresis_factor:1.1/");
  SvcRateAllocator allocator = SvcRateAllocator(codec);
  // Always use max bitrate as target, verify only stable is used for layer
  // count selection.
  const DataRate max_bitrate = allocator.GetMaxBitrate(codec);

  // Start with a single layer.
  auto allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_single_layer, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Min bitrate not enough to enable second layer due to 10% hysteresis.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_two_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Add hysteresis, second layer should turn on.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_two_layers * 1.1, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Remove hysteresis, second layer should stay on.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_two_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Going below min for two layers, second layer should turn off again.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_two_layers - DataRate::bps(1), /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Min bitrate not enough to enable third layer due to 10% hysteresis.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_three_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));

  // Add hysteresis, third layer should turn on.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_three_layers * 1.1, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(2));

  // Remove hysteresis, third layer should stay on.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_three_layers, /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(2));

  // Going below min for three layers, third layer should turn off again.
  allocation = allocator.Allocate(VideoBitrateAllocationParameters(
      /*total_bitrate=*/max_bitrate,
      /*stable_bitrate=*/min_rate_three_layers - DataRate::bps(1),
      /*fps=*/30.0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(0));
  EXPECT_TRUE(allocation.IsSpatialLayerUsed(1));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));
}

INSTANTIATE_TEST_SUITE_P(_,
                         SvcRateAllocatorTestParametrizedContentType,
                         ::testing::Bool());

}  // namespace test
}  // namespace webrtc
