/*
 *  Copyright (c) 2012 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 <stdio.h>

#include <memory>

#include "api/test/mock_video_decoder.h"
#include "api/test/mock_video_encoder.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/vp8_temporal_layers.h"
#include "common_video/libyuv/include/webrtc_libyuv.h"
#include "common_video/test/utilities.h"
#include "modules/video_coding/codecs/test/video_codec_unittest.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "modules/video_coding/codecs/vp8/libvpx_vp8_encoder.h"
#include "modules/video_coding/codecs/vp8/test/mock_libvpx_interface.h"
#include "modules/video_coding/utility/vp8_header_parser.h"
#include "rtc_base/time_utils.h"
#include "test/field_trial.h"
#include "test/video_codec_settings.h"

namespace webrtc {

using ::testing::_;
using ::testing::AllOf;
using ::testing::ElementsAreArray;
using ::testing::Field;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using EncoderInfo = webrtc::VideoEncoder::EncoderInfo;
using FramerateFractions =
    absl::InlinedVector<uint8_t, webrtc::kMaxTemporalStreams>;

namespace {
constexpr uint32_t kLegacyScreenshareTl0BitrateKbps = 200;
constexpr uint32_t kLegacyScreenshareTl1BitrateKbps = 1000;
constexpr uint32_t kInitialTimestampRtp = 123;
constexpr int64_t kTestNtpTimeMs = 456;
constexpr int64_t kInitialTimestampMs = 789;
constexpr int kNumCores = 1;
constexpr size_t kMaxPayloadSize = 1440;
constexpr int kDefaultMinPixelsPerFrame = 320 * 180;
constexpr int kWidth = 172;
constexpr int kHeight = 144;
constexpr float kFramerateFps = 30;

const VideoEncoder::Capabilities kCapabilities(false);
const VideoEncoder::Settings kSettings(kCapabilities,
                                       kNumCores,
                                       kMaxPayloadSize);
}  // namespace

class TestVp8Impl : public VideoCodecUnitTest {
 protected:
  std::unique_ptr<VideoEncoder> CreateEncoder() override {
    return VP8Encoder::Create();
  }

  std::unique_ptr<VideoDecoder> CreateDecoder() override {
    return VP8Decoder::Create();
  }

  void ModifyCodecSettings(VideoCodec* codec_settings) override {
    webrtc::test::CodecSettings(kVideoCodecVP8, codec_settings);
    codec_settings->width = kWidth;
    codec_settings->height = kHeight;
    codec_settings->VP8()->denoisingOn = true;
    codec_settings->VP8()->frameDroppingOn = false;
    codec_settings->VP8()->automaticResizeOn = false;
    codec_settings->VP8()->complexity = VideoCodecComplexity::kComplexityNormal;
  }

  void EncodeAndWaitForFrame(const VideoFrame& input_frame,
                             EncodedImage* encoded_frame,
                             CodecSpecificInfo* codec_specific_info,
                             bool keyframe = false) {
    std::vector<VideoFrameType> frame_types;
    if (keyframe) {
      frame_types.emplace_back(VideoFrameType::kVideoFrameKey);
    } else {
      frame_types.emplace_back(VideoFrameType::kVideoFrameDelta);
    }
    EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
              encoder_->Encode(input_frame, &frame_types));
    ASSERT_TRUE(WaitForEncodedFrame(encoded_frame, codec_specific_info));
    VerifyQpParser(*encoded_frame);
    VideoEncoder::EncoderInfo encoder_info = encoder_->GetEncoderInfo();
    EXPECT_EQ("libvpx", encoder_info.implementation_name);
    EXPECT_EQ(false, encoder_info.is_hardware_accelerated);
    EXPECT_EQ(false, encoder_info.has_internal_source);
    EXPECT_EQ(kVideoCodecVP8, codec_specific_info->codecType);
    EXPECT_EQ(0, encoded_frame->SpatialIndex());
  }

  void EncodeAndExpectFrameWith(const VideoFrame& input_frame,
                                uint8_t temporal_idx,
                                bool keyframe = false) {
    EncodedImage encoded_frame;
    CodecSpecificInfo codec_specific_info;
    EncodeAndWaitForFrame(input_frame, &encoded_frame, &codec_specific_info,
                          keyframe);
    EXPECT_EQ(temporal_idx, codec_specific_info.codecSpecific.VP8.temporalIdx);
  }

  void VerifyQpParser(const EncodedImage& encoded_frame) const {
    int qp;
    EXPECT_GT(encoded_frame.size(), 0u);
    ASSERT_TRUE(vp8::GetQp(encoded_frame.data(), encoded_frame.size(), &qp));
    EXPECT_EQ(encoded_frame.qp_, qp) << "Encoder QP != parsed bitstream QP.";
  }
};

TEST_F(TestVp8Impl, ErrorResilienceDisabledForNoTemporalLayers) {
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 1;

  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
  EXPECT_CALL(*vpx,
              codec_enc_init(
                  _, _, Field(&vpx_codec_enc_cfg_t::g_error_resilient, 0), _));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_, kSettings));
}

TEST_F(TestVp8Impl, DefaultErrorResilienceEnabledForTemporalLayers) {
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
  codec_settings_.VP8()->numberOfTemporalLayers = 2;

  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
  EXPECT_CALL(*vpx,
              codec_enc_init(_, _,
                             Field(&vpx_codec_enc_cfg_t::g_error_resilient,
                                   VPX_ERROR_RESILIENT_DEFAULT),
                             _));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_, kSettings));
}

TEST_F(TestVp8Impl,
       PartitionErrorResilienceEnabledForTemporalLayersWithFieldTrial) {
  test::ScopedFieldTrials field_trials(
      "WebRTC-VP8-ForcePartitionResilience/Enabled/");
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
  codec_settings_.VP8()->numberOfTemporalLayers = 2;

  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
  EXPECT_CALL(*vpx,
              codec_enc_init(_, _,
                             Field(&vpx_codec_enc_cfg_t::g_error_resilient,
                                   VPX_ERROR_RESILIENT_PARTITIONS),
                             _));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_, kSettings));
}

TEST_F(TestVp8Impl, SetRates) {
  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_,
                               VideoEncoder::Settings(kCapabilities, 1, 1000)));

  const uint32_t kBitrateBps = 300000;
  VideoBitrateAllocation bitrate_allocation;
  bitrate_allocation.SetBitrate(0, 0, kBitrateBps);
  EXPECT_CALL(
      *vpx,
      codec_enc_config_set(
          _, AllOf(Field(&vpx_codec_enc_cfg_t::rc_target_bitrate,
                         kBitrateBps / 1000),
                   Field(&vpx_codec_enc_cfg_t::rc_undershoot_pct, 100u),
                   Field(&vpx_codec_enc_cfg_t::rc_overshoot_pct, 15u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_sz, 1000u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_optimal_sz, 600u),
                   Field(&vpx_codec_enc_cfg_t::rc_dropframe_thresh, 30u))))
      .WillOnce(Return(VPX_CODEC_OK));
  encoder.SetRates(VideoEncoder::RateControlParameters(
      bitrate_allocation, static_cast<double>(codec_settings_.maxFramerate)));
}

TEST_F(TestVp8Impl, DynamicSetRates) {
  test::ScopedFieldTrials field_trials(
      "WebRTC-VideoRateControl/vp8_dynamic_rate:true/");
  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_,
                               VideoEncoder::Settings(kCapabilities, 1, 1000)));

  const uint32_t kBitrateBps = 300000;
  VideoEncoder::RateControlParameters rate_settings;
  rate_settings.bitrate.SetBitrate(0, 0, kBitrateBps);
  rate_settings.framerate_fps =
      static_cast<double>(codec_settings_.maxFramerate);

  // Set rates with no headroom.
  rate_settings.bandwidth_allocation = DataRate::bps(kBitrateBps);
  EXPECT_CALL(
      *vpx,
      codec_enc_config_set(
          _, AllOf(Field(&vpx_codec_enc_cfg_t::rc_target_bitrate,
                         kBitrateBps / 1000),
                   Field(&vpx_codec_enc_cfg_t::rc_undershoot_pct, 1000u),
                   Field(&vpx_codec_enc_cfg_t::rc_overshoot_pct, 0u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_sz, 100u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_optimal_sz, 30u),
                   Field(&vpx_codec_enc_cfg_t::rc_dropframe_thresh, 40u))))
      .WillOnce(Return(VPX_CODEC_OK));
  encoder.SetRates(rate_settings);

  // Set rates with max headroom.
  rate_settings.bandwidth_allocation = DataRate::bps(kBitrateBps * 2);
  EXPECT_CALL(
      *vpx, codec_enc_config_set(
                _, AllOf(Field(&vpx_codec_enc_cfg_t::rc_target_bitrate,
                               kBitrateBps / 1000),
                         Field(&vpx_codec_enc_cfg_t::rc_undershoot_pct, 100u),
                         Field(&vpx_codec_enc_cfg_t::rc_overshoot_pct, 15u),
                         Field(&vpx_codec_enc_cfg_t::rc_buf_sz, 1000u),
                         Field(&vpx_codec_enc_cfg_t::rc_buf_optimal_sz, 600u),
                         Field(&vpx_codec_enc_cfg_t::rc_dropframe_thresh, 5u))))
      .WillOnce(Return(VPX_CODEC_OK));
  encoder.SetRates(rate_settings);

  // Set rates with headroom half way.
  rate_settings.bandwidth_allocation = DataRate::bps((3 * kBitrateBps) / 2);
  EXPECT_CALL(
      *vpx,
      codec_enc_config_set(
          _, AllOf(Field(&vpx_codec_enc_cfg_t::rc_target_bitrate,
                         kBitrateBps / 1000),
                   Field(&vpx_codec_enc_cfg_t::rc_undershoot_pct, 550u),
                   Field(&vpx_codec_enc_cfg_t::rc_overshoot_pct, 8u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_sz, 550u),
                   Field(&vpx_codec_enc_cfg_t::rc_buf_optimal_sz, 315u),
                   Field(&vpx_codec_enc_cfg_t::rc_dropframe_thresh, 23u))))
      .WillOnce(Return(VPX_CODEC_OK));
  encoder.SetRates(rate_settings);
}

TEST_F(TestVp8Impl, EncodeFrameAndRelease) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame,
                        &codec_specific_info);

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
            encoder_->Encode(*NextInputFrame(), nullptr));
}

TEST_F(TestVp8Impl, InitDecode) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            decoder_->InitDecode(&codec_settings_, kNumCores));
}

TEST_F(TestVp8Impl, OnEncodedImageReportsInfo) {
  VideoFrame* input_frame = NextInputFrame();
  input_frame->set_timestamp(kInitialTimestampRtp);
  input_frame->set_timestamp_us(kInitialTimestampMs *
                                rtc::kNumMicrosecsPerMillisec);
  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);

  EXPECT_EQ(kInitialTimestampRtp, encoded_frame.Timestamp());
  EXPECT_EQ(kWidth, static_cast<int>(encoded_frame._encodedWidth));
  EXPECT_EQ(kHeight, static_cast<int>(encoded_frame._encodedHeight));
}

TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) {
  VideoFrame* input_frame = NextInputFrame();
  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);

  // First frame should be a key frame.
  encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
  std::unique_ptr<VideoFrame> decoded_frame;
  absl::optional<uint8_t> decoded_qp;
  ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
  ASSERT_TRUE(decoded_frame);
  ASSERT_TRUE(decoded_qp);
  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
  EXPECT_EQ(encoded_frame.qp_, *decoded_qp);
}

TEST_F(TestVp8Impl, ChecksSimulcastSettings) {
  codec_settings_.numberOfSimulcastStreams = 2;
  // Resolutions are not in ascending order, temporal layers do not match.
  codec_settings_.simulcastStream[0] = {kWidth, kHeight, kFramerateFps, 2,
                                        4000,   3000,    2000,          80};
  codec_settings_.simulcastStream[1] = {kWidth / 2, kHeight / 2, 30,   3,
                                        4000,       3000,        2000, 80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
            encoder_->InitEncode(&codec_settings_, kSettings));
  codec_settings_.numberOfSimulcastStreams = 3;
  // Resolutions are not in ascending order.
  codec_settings_.simulcastStream[0] = {
      kWidth / 2, kHeight / 2, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[1] = {
      kWidth / 2 - 1, kHeight / 2 - 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[2] = {kWidth, kHeight, 30,   1,
                                        4000,   3000,    2000, 80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
            encoder_->InitEncode(&codec_settings_, kSettings));
  // Resolutions are not in ascending order.
  codec_settings_.simulcastStream[0] = {kWidth, kHeight, kFramerateFps, 1,
                                        4000,   3000,    2000,          80};
  codec_settings_.simulcastStream[1] = {kWidth, kHeight, kFramerateFps, 1,
                                        4000,   3000,    2000,          80};
  codec_settings_.simulcastStream[2] = {
      kWidth - 1, kHeight - 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
            encoder_->InitEncode(&codec_settings_, kSettings));
  // Temporal layers do not match.
  codec_settings_.simulcastStream[0] = {
      kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[1] = {
      kWidth / 2, kHeight / 2, kFramerateFps, 2, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 3,
                                        4000,   3000,    2000,          80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
            encoder_->InitEncode(&codec_settings_, kSettings));
  // Resolutions do not match codec config.
  codec_settings_.simulcastStream[0] = {
      kWidth / 4 + 1, kHeight / 4 + 1, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[1] = {
      kWidth / 2 + 2, kHeight / 2 + 2, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[2] = {
      kWidth + 4, kHeight + 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED,
            encoder_->InitEncode(&codec_settings_, kSettings));
  // Everything fine: scaling by 2, top resolution matches video, temporal
  // settings are the same for all layers.
  codec_settings_.simulcastStream[0] = {
      kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[1] = {
      kWidth / 2, kHeight / 2, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
                                        4000,   3000,    2000,          80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));
  // Everything fine: custom scaling, top resolution matches video, temporal
  // settings are the same for all layers.
  codec_settings_.simulcastStream[0] = {
      kWidth / 4, kHeight / 4, kFramerateFps, 1, 4000, 3000, 2000, 80};
  codec_settings_.simulcastStream[1] = {kWidth, kHeight, kFramerateFps, 1,
                                        4000,   3000,    2000,          80};
  codec_settings_.simulcastStream[2] = {kWidth, kHeight, kFramerateFps, 1,
                                        4000,   3000,    2000,          80};
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_AlignedStrideEncodeDecode DISABLED_AlignedStrideEncodeDecode
#else
#define MAYBE_AlignedStrideEncodeDecode AlignedStrideEncodeDecode
#endif
TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) {
  VideoFrame* input_frame = NextInputFrame();
  input_frame->set_timestamp(kInitialTimestampRtp);
  input_frame->set_timestamp_us(kInitialTimestampMs *
                                rtc::kNumMicrosecsPerMillisec);
  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);

  // First frame should be a key frame.
  encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
  encoded_frame.ntp_time_ms_ = kTestNtpTimeMs;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));

  std::unique_ptr<VideoFrame> decoded_frame;
  absl::optional<uint8_t> decoded_qp;
  ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
  ASSERT_TRUE(decoded_frame);
  // Compute PSNR on all planes (faster than SSIM).
  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
  EXPECT_EQ(kInitialTimestampRtp, decoded_frame->timestamp());
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_DecodeWithACompleteKeyFrame DISABLED_DecodeWithACompleteKeyFrame
#else
#define MAYBE_DecodeWithACompleteKeyFrame DecodeWithACompleteKeyFrame
#endif
TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) {
  VideoFrame* input_frame = NextInputFrame();
  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*input_frame, &encoded_frame, &codec_specific_info);

  // Setting complete to false -> should return an error.
  encoded_frame._completeFrame = false;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
            decoder_->Decode(encoded_frame, false, -1));
  // Setting complete back to true. Forcing a delta frame.
  encoded_frame._frameType = VideoFrameType::kVideoFrameDelta;
  encoded_frame._completeFrame = true;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
            decoder_->Decode(encoded_frame, false, -1));
  // Now setting a key frame.
  encoded_frame._frameType = VideoFrameType::kVideoFrameKey;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1));
  std::unique_ptr<VideoFrame> decoded_frame;
  absl::optional<uint8_t> decoded_qp;
  ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp));
  ASSERT_TRUE(decoded_frame);
  EXPECT_GT(I420PSNR(input_frame, decoded_frame.get()), 36);
}

TEST_F(TestVp8Impl, EncoderWith2TemporalLayers) {
  codec_settings_.VP8()->numberOfTemporalLayers = 2;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  // Temporal layer 0.
  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame,
                        &codec_specific_info);

  EXPECT_EQ(0, codec_specific_info.codecSpecific.VP8.temporalIdx);
  // Temporal layer 1.
  EncodeAndExpectFrameWith(*NextInputFrame(), 1);
  // Temporal layer 0.
  EncodeAndExpectFrameWith(*NextInputFrame(), 0);
  // Temporal layer 1.
  EncodeAndExpectFrameWith(*NextInputFrame(), 1);
}

TEST_F(TestVp8Impl, ScalingDisabledIfAutomaticResizeOff) {
  codec_settings_.VP8()->frameDroppingOn = true;
  codec_settings_.VP8()->automaticResizeOn = false;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  VideoEncoder::ScalingSettings settings =
      encoder_->GetEncoderInfo().scaling_settings;
  EXPECT_FALSE(settings.thresholds.has_value());
}

TEST_F(TestVp8Impl, ScalingEnabledIfAutomaticResizeOn) {
  codec_settings_.VP8()->frameDroppingOn = true;
  codec_settings_.VP8()->automaticResizeOn = true;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  VideoEncoder::ScalingSettings settings =
      encoder_->GetEncoderInfo().scaling_settings;
  EXPECT_TRUE(settings.thresholds.has_value());
  EXPECT_EQ(kDefaultMinPixelsPerFrame, settings.min_pixels_per_frame);
}

TEST_F(TestVp8Impl, DontDropKeyframes) {
  // Set very high resolution to trigger overuse more easily.
  const int kScreenWidth = 1920;
  const int kScreenHeight = 1080;

  codec_settings_.width = kScreenWidth;
  codec_settings_.height = kScreenHeight;

  // Screensharing has the internal frame dropper off, and instead per frame
  // asks ScreenshareLayers to decide if it should be dropped or not.
  codec_settings_.VP8()->frameDroppingOn = false;
  codec_settings_.mode = VideoCodecMode::kScreensharing;
  // ScreenshareLayers triggers on 2 temporal layers and 1000kbps max bitrate.
  codec_settings_.VP8()->numberOfTemporalLayers = 2;
  codec_settings_.maxBitrate = 1000;

  // Reset the frame generator with large number of squares, leading to lots of
  // details and high probability of overshoot.
  input_frame_generator_ = test::FrameGenerator::CreateSquareGenerator(
      codec_settings_.width, codec_settings_.height,
      test::FrameGenerator::OutputType::kI420,
      /* num_squares = */ absl::optional<int>(300));

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  VideoBitrateAllocation bitrate_allocation;
  // Bitrate only enough for TL0.
  bitrate_allocation.SetBitrate(0, 0, 200000);
  encoder_->SetRates(
      VideoEncoder::RateControlParameters(bitrate_allocation, 5.0));

  EncodedImage encoded_frame;
  CodecSpecificInfo codec_specific_info;
  EncodeAndWaitForFrame(*NextInputFrame(), &encoded_frame, &codec_specific_info,
                        true);
  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
  EncodeAndExpectFrameWith(*NextInputFrame(), 0, true);
}

TEST_F(TestVp8Impl, KeepsTimestampOnReencode) {
  auto* const vpx = new NiceMock<MockLibvpxVp8Interface>();
  LibvpxVp8Encoder encoder((std::unique_ptr<LibvpxInterface>(vpx)));

  // Settings needed to trigger ScreenshareLayers usage, which is required for
  // overshoot-drop-reencode logic.
  codec_settings_.maxBitrate = 1000;
  codec_settings_.mode = VideoCodecMode::kScreensharing;
  codec_settings_.VP8()->numberOfTemporalLayers = 2;

  EXPECT_CALL(*vpx, img_wrap(_, _, _, _, _, _))
      .WillOnce(Invoke([](vpx_image_t* img, vpx_img_fmt_t fmt, unsigned int d_w,
                          unsigned int d_h, unsigned int stride_align,
                          unsigned char* img_data) {
        img->fmt = fmt;
        img->d_w = d_w;
        img->d_h = d_h;
        img->img_data = img_data;
        return img;
      }));
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder.InitEncode(&codec_settings_,
                               VideoEncoder::Settings(kCapabilities, 1, 1000)));
  MockEncodedImageCallback callback;
  encoder.RegisterEncodeCompleteCallback(&callback);

  // Simulate overshoot drop, re-encode: encode function will be called twice
  // with the same parameters. codec_get_cx_data() will by default return no
  // image data and be interpreted as drop.
  EXPECT_CALL(*vpx, codec_encode(_, _, /* pts = */ 0, _, _, _))
      .Times(2)
      .WillRepeatedly(Return(vpx_codec_err_t::VPX_CODEC_OK));

  auto delta_frame =
      std::vector<VideoFrameType>{VideoFrameType::kVideoFrameDelta};
  encoder.Encode(*NextInputFrame(), &delta_frame);
}

TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationNoLayers) {
  FramerateFractions expected_fps_allocation[kMaxSpatialLayers] = {
      FramerateFractions(1, EncoderInfo::kMaxFramerateFraction)};

  EXPECT_THAT(encoder_->GetEncoderInfo().fps_allocation,
              ::testing::ElementsAreArray(expected_fps_allocation));
}

TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationTwoTemporalLayers) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
  codec_settings_.numberOfSimulcastStreams = 1;
  codec_settings_.simulcastStream[0].active = true;
  codec_settings_.simulcastStream[0].targetBitrate = 100;
  codec_settings_.simulcastStream[0].maxBitrate = 100;
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2);
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction);

  EXPECT_THAT(encoder_->GetEncoderInfo().fps_allocation,
              ::testing::ElementsAreArray(expected_fps_allocation));
}

TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationThreeTemporalLayers) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
  codec_settings_.numberOfSimulcastStreams = 1;
  codec_settings_.simulcastStream[0].active = true;
  codec_settings_.simulcastStream[0].targetBitrate = 100;
  codec_settings_.simulcastStream[0].maxBitrate = 100;
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 3;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2);
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction);

  EXPECT_THAT(encoder_->GetEncoderInfo().fps_allocation,
              ::testing::ElementsAreArray(expected_fps_allocation));
}

TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationScreenshareLayers) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());
  codec_settings_.numberOfSimulcastStreams = 1;
  codec_settings_.mode = VideoCodecMode::kScreensharing;
  codec_settings_.simulcastStream[0].active = true;
  codec_settings_.simulcastStream[0].minBitrate = 30;
  codec_settings_.simulcastStream[0].targetBitrate =
      kLegacyScreenshareTl0BitrateKbps;
  codec_settings_.simulcastStream[0].maxBitrate =
      kLegacyScreenshareTl1BitrateKbps;
  codec_settings_.simulcastStream[0].numberOfTemporalLayers = 2;
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  // Expect empty vector, since this mode doesn't have a fixed framerate.
  FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
  EXPECT_THAT(encoder_->GetEncoderInfo().fps_allocation,
              ::testing::ElementsAreArray(expected_fps_allocation));
}

TEST_F(TestVp8Impl, GetEncoderInfoFpsAllocationSimulcastVideo) {
  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, encoder_->Release());

  // Set up three simulcast streams with three temporal layers each.
  codec_settings_.numberOfSimulcastStreams = 3;
  for (int i = 0; i < codec_settings_.numberOfSimulcastStreams; ++i) {
    codec_settings_.simulcastStream[i].active = true;
    codec_settings_.simulcastStream[i].minBitrate = 30;
    codec_settings_.simulcastStream[i].targetBitrate = 30;
    codec_settings_.simulcastStream[i].maxBitrate = 30;
    codec_settings_.simulcastStream[i].numberOfTemporalLayers = 3;
    codec_settings_.simulcastStream[i].width =
        codec_settings_.width >>
        (codec_settings_.numberOfSimulcastStreams - i - 1);
    codec_settings_.simulcastStream[i].height =
        codec_settings_.height >>
        (codec_settings_.numberOfSimulcastStreams - i - 1);
  }

  EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
            encoder_->InitEncode(&codec_settings_, kSettings));

  FramerateFractions expected_fps_allocation[kMaxSpatialLayers];
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 4);
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction / 2);
  expected_fps_allocation[0].push_back(EncoderInfo::kMaxFramerateFraction);
  expected_fps_allocation[1] = expected_fps_allocation[0];
  expected_fps_allocation[2] = expected_fps_allocation[0];
  EXPECT_THAT(encoder_->GetEncoderInfo().fps_allocation,
              ::testing::ElementsAreArray(expected_fps_allocation));
}

}  // namespace webrtc
