/*
 *  Copyright (c) 2019 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 "video/encoder_overshoot_detector.h"

#include <string>

#include "api/units/data_rate.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/time_utils.h"
#include "system_wrappers/include/metrics.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

using ::testing::TestWithParam;
using ::testing::ValuesIn;

static std::string CodecTypeToHistogramSuffix(VideoCodecType codec) {
  switch (codec) {
    case kVideoCodecVP8:
      return "Vp8";
    case kVideoCodecVP9:
      return "Vp9";
    case kVideoCodecAV1:
      return "Av1";
    case kVideoCodecH264:
      return "H264";
    case kVideoCodecH265:
      return "H265";
    case kVideoCodecGeneric:
      return "Generic";
  }
}

struct TestParams {
  VideoCodecType codec_type;
  bool is_screenshare;
};

}  // namespace

class EncoderOvershootDetectorTest : public TestWithParam<TestParams> {
 public:
  static constexpr int kDefaultBitrateBps = 300000;
  static constexpr double kDefaultFrameRateFps = 15;
  EncoderOvershootDetectorTest()
      : detector_(kWindowSizeMs,
                  GetParam().codec_type,
                  GetParam().is_screenshare),
        target_bitrate_(DataRate::BitsPerSec(kDefaultBitrateBps)),
        target_framerate_fps_(kDefaultFrameRateFps) {}

 protected:
  void SetUp() override { metrics::Reset(); }
  void RunConstantUtilizationTest(double actual_utilization_factor,
                                  double expected_utilization_factor,
                                  double allowed_error,
                                  int64_t test_duration_ms) {
    const int frame_size_bytes =
        static_cast<int>(actual_utilization_factor *
                         (target_bitrate_.bps() / target_framerate_fps_) / 8);
    detector_.SetTargetRate(target_bitrate_, target_framerate_fps_,
                            rtc::TimeMillis());

    if (rtc::TimeMillis() == 0) {
      // Encode a first frame which by definition has no overuse factor.
      detector_.OnEncodedFrame(frame_size_bytes, rtc::TimeMillis());
      clock_.AdvanceTime(TimeDelta::Seconds(1) / target_framerate_fps_);
    }

    int64_t runtime_us = 0;
    while (runtime_us < test_duration_ms * 1000) {
      detector_.OnEncodedFrame(frame_size_bytes, rtc::TimeMillis());
      runtime_us += rtc::kNumMicrosecsPerSec / target_framerate_fps_;
      clock_.AdvanceTime(TimeDelta::Seconds(1) / target_framerate_fps_);
    }

    // At constant utilization, both network and media utilization should be
    // close to expected.
    const std::optional<double> network_utilization_factor =
        detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis());
    EXPECT_NEAR(network_utilization_factor.value_or(-1),
                expected_utilization_factor, allowed_error);

    const std::optional<double> media_utilization_factor =
        detector_.GetMediaRateUtilizationFactor(rtc::TimeMillis());
    EXPECT_NEAR(media_utilization_factor.value_or(-1),
                expected_utilization_factor, allowed_error);
  }

  static constexpr int64_t kWindowSizeMs = 3000;
  EncoderOvershootDetector detector_;
  rtc::ScopedFakeClock clock_;
  DataRate target_bitrate_;
  double target_framerate_fps_;
};

TEST_P(EncoderOvershootDetectorTest, NoUtilizationIfNoRate) {
  const int frame_size_bytes = 1000;
  const int64_t time_interval_ms = 33;
  detector_.SetTargetRate(target_bitrate_, target_framerate_fps_,
                          rtc::TimeMillis());

  // No data points, can't determine overshoot rate.
  EXPECT_FALSE(
      detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis()).has_value());

  detector_.OnEncodedFrame(frame_size_bytes, rtc::TimeMillis());
  clock_.AdvanceTime(TimeDelta::Millis(time_interval_ms));
  EXPECT_TRUE(
      detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis()).has_value());
}

TEST_P(EncoderOvershootDetectorTest, OptimalSize) {
  // Optimally behaved encoder.
  // Allow some error margin due to rounding errors, eg due to frame
  // interval not being an integer.
  RunConstantUtilizationTest(1.0, 1.0, 0.01, kWindowSizeMs);
}

TEST_P(EncoderOvershootDetectorTest, Undershoot) {
  // Undershoot, reported utilization factor should be capped to 1.0 so
  // that we don't incorrectly boost encoder bitrate during movement.
  RunConstantUtilizationTest(0.5, 1.0, 0.00, kWindowSizeMs);
}

TEST_P(EncoderOvershootDetectorTest, Overshoot) {
  // Overshoot by 20%.
  // Allow some error margin due to rounding errors.
  RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs);
}

TEST_P(EncoderOvershootDetectorTest, ConstantOvershootVaryingRates) {
  // Overshoot by 20%, but vary framerate and bitrate.
  // Allow some error margin due to rounding errors.
  RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs);
  target_framerate_fps_ /= 2;
  RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs / 2);
  target_bitrate_ = DataRate::BitsPerSec(target_bitrate_.bps() / 2);
  RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs / 2);
}

TEST_P(EncoderOvershootDetectorTest, ConstantRateVaryingOvershoot) {
  // Overshoot by 10%, keep framerate and bitrate constant.
  // Allow some error margin due to rounding errors.
  RunConstantUtilizationTest(1.1, 1.1, 0.01, kWindowSizeMs);
  // Change overshoot to 20%, run for half window and expect overshoot
  // to be 15%.
  RunConstantUtilizationTest(1.2, 1.15, 0.01, kWindowSizeMs / 2);
  // Keep running at 20% overshoot, after window is full that should now
  // be the reported overshoot.
  RunConstantUtilizationTest(1.2, 1.2, 0.01, kWindowSizeMs / 2);
}

TEST_P(EncoderOvershootDetectorTest, PartialOvershoot) {
  const int ideal_frame_size_bytes =
      (target_bitrate_.bps() / target_framerate_fps_) / 8;
  detector_.SetTargetRate(target_bitrate_, target_framerate_fps_,
                          rtc::TimeMillis());

  // Test scenario with average bitrate matching the target bitrate, but
  // with some utilization factor penalty as the frames can't be paced out
  // on the network at the target rate.
  // Insert a series of four frames:
  //   1) 20% overshoot, not penalized as buffer if empty.
  //   2) 20% overshoot, the 20% overshoot from the first frame is penalized.
  //   3) 20% undershoot, negating the overshoot from the last frame.
  //   4) 20% undershoot, no penalty.
  // On average then utilization penalty is thus 5%.

  int64_t runtime_us = 0;
  int i = 0;
  while (runtime_us < kWindowSizeMs * rtc::kNumMicrosecsPerMillisec) {
    runtime_us += rtc::kNumMicrosecsPerSec / target_framerate_fps_;
    clock_.AdvanceTime(TimeDelta::Seconds(1) / target_framerate_fps_);
    int frame_size_bytes = (i++ % 4 < 2) ? (ideal_frame_size_bytes * 120) / 100
                                         : (ideal_frame_size_bytes * 80) / 100;
    detector_.OnEncodedFrame(frame_size_bytes, rtc::TimeMillis());
  }

  // Expect 5% overshoot for network rate, see above.
  const std::optional<double> network_utilization_factor =
      detector_.GetNetworkRateUtilizationFactor(rtc::TimeMillis());
  EXPECT_NEAR(network_utilization_factor.value_or(-1), 1.05, 0.01);

  // Expect media rate to be on average correct.
  const std::optional<double> media_utilization_factor =
      detector_.GetMediaRateUtilizationFactor(rtc::TimeMillis());
  EXPECT_NEAR(media_utilization_factor.value_or(-1), 1.00, 0.01);
}

TEST_P(EncoderOvershootDetectorTest, RecordsZeroErrorMetricWithNoOvershoot) {
  DataSize ideal_frame_size =
      target_bitrate_ / Frequency::Hertz(target_framerate_fps_);
  detector_.SetTargetRate(target_bitrate_, target_framerate_fps_,
                          rtc::TimeMillis());
  detector_.OnEncodedFrame(ideal_frame_size.bytes(), rtc::TimeMillis());
  detector_.Reset();

  const VideoCodecType codec = GetParam().codec_type;
  const bool is_screenshare = GetParam().is_screenshare;
  const std::string rmse_histogram_prefix =
      is_screenshare ? "WebRTC.Video.Screenshare.RMSEOfEncodingBitrateInKbps."
                     : "WebRTC.Video.RMSEOfEncodingBitrateInKbps.";
  const std::string overshoot_histogram_prefix =
      is_screenshare ? "WebRTC.Video.Screenshare.EncodingBitrateOvershoot."
                     : "WebRTC.Video.EncodingBitrateOvershoot.";
  // RMSE and overshoot percent = 0, since we used ideal frame size.
  EXPECT_METRIC_EQ(1, metrics::NumSamples(rmse_histogram_prefix +
                                          CodecTypeToHistogramSuffix(codec)));
  EXPECT_METRIC_EQ(
      1, metrics::NumEvents(
             rmse_histogram_prefix + CodecTypeToHistogramSuffix(codec), 0));

  EXPECT_METRIC_EQ(1, metrics::NumSamples(overshoot_histogram_prefix +
                                          CodecTypeToHistogramSuffix(codec)));
  EXPECT_METRIC_EQ(1, metrics::NumEvents(overshoot_histogram_prefix +
                                             CodecTypeToHistogramSuffix(codec),
                                         0));
}

TEST_P(EncoderOvershootDetectorTest,
       RecordScreenshareZeroMetricWithNoOvershoot) {
  DataSize ideal_frame_size =
      target_bitrate_ / Frequency::Hertz(target_framerate_fps_);
  // Use target frame size with 50% overshoot.
  DataSize target_frame_size = ideal_frame_size * 3 / 2;
  detector_.SetTargetRate(target_bitrate_, target_framerate_fps_,
                          rtc::TimeMillis());
  detector_.OnEncodedFrame(target_frame_size.bytes(), rtc::TimeMillis());
  detector_.Reset();

  const VideoCodecType codec = GetParam().codec_type;
  const bool is_screenshare = GetParam().is_screenshare;
  const std::string rmse_histogram_prefix =
      is_screenshare ? "WebRTC.Video.Screenshare.RMSEOfEncodingBitrateInKbps."
                     : "WebRTC.Video.RMSEOfEncodingBitrateInKbps.";
  const std::string overshoot_histogram_prefix =
      is_screenshare ? "WebRTC.Video.Screenshare.EncodingBitrateOvershoot."
                     : "WebRTC.Video.EncodingBitrateOvershoot.";
  // Use ideal_frame_size_kbits to represnt ideal_frame_size.bytes()*8/1000,
  // then rmse_in_kbps = ideal_frame_size_kbits/2
  // since we use target frame size with 50% overshoot.
  int64_t rmse_in_kbps = ideal_frame_size.bytes() * 8 / 1000 / 2;
  EXPECT_METRIC_EQ(1, metrics::NumSamples(rmse_histogram_prefix +
                                          CodecTypeToHistogramSuffix(codec)));
  EXPECT_METRIC_EQ(1, metrics::NumEvents(rmse_histogram_prefix +
                                             CodecTypeToHistogramSuffix(codec),
                                         rmse_in_kbps));
  // overshoot percent = 50, since we used ideal_frame_size * 3 / 2;
  EXPECT_METRIC_EQ(1, metrics::NumSamples(overshoot_histogram_prefix +
                                          CodecTypeToHistogramSuffix(codec)));
  EXPECT_METRIC_EQ(1, metrics::NumEvents(overshoot_histogram_prefix +
                                             CodecTypeToHistogramSuffix(codec),
                                         50));
}

INSTANTIATE_TEST_SUITE_P(
    PerCodecType,
    EncoderOvershootDetectorTest,
    ValuesIn<TestParams>({{VideoCodecType::kVideoCodecVP8, false},
                          {VideoCodecType::kVideoCodecVP8, true},
                          {VideoCodecType::kVideoCodecVP9, false},
                          {VideoCodecType::kVideoCodecVP9, true},
                          {VideoCodecType::kVideoCodecAV1, false},
                          {VideoCodecType::kVideoCodecAV1, true},
                          {VideoCodecType::kVideoCodecH264, false},
                          {VideoCodecType::kVideoCodecH264, true},
                          {VideoCodecType::kVideoCodecH265, false},
                          {VideoCodecType::kVideoCodecH265, true}}));

}  // namespace webrtc
