/*
 *  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, /*first_active_layer=*/0,
                   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::BitsPerSec(299150);
  const DataRate kThreeLayerMinRate = DataRate::BitsPerSec(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::KilobitsPerSec(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::KilobitsPerSec(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::KilobitsPerSec(codec.spatialLayers[0].maxBitrate);
  const DataRate max_rate_two_layers =
      is_screen_sharing_
          ? DataRate::KilobitsPerSec(codec.spatialLayers[0].targetBitrate +
                                     codec.spatialLayers[1].maxBitrate)
          : DataRate::KilobitsPerSec(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::BitsPerSec(1),
      /*fps=*/30.0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(1));
  EXPECT_EQ(DataRate::BitsPerSec(allocation.get_sum_bps()),
            std::min(min_rate_two_layers - DataRate::BitsPerSec(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::BitsPerSec(1),
      /*fps=*/30.0));
  EXPECT_FALSE(allocation.IsSpatialLayerUsed(2));
  EXPECT_EQ(DataRate::BitsPerSec(allocation.get_sum_bps()),
            std::min(min_rate_three_layers - DataRate::BitsPerSec(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::BitsPerSec(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::BitsPerSec(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
