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

#include "testing/gtest/include/gtest/gtest.h"

namespace webrtc {
namespace {
static const int kNumSeconds = 10;
static const int kWidth = 1920;
static const int kHeight = 1080;
static const int kFramerate = 30;
static const int kLowQp = 15;
static const int kNormalQp = 30;
static const int kLowQpThreshold = 18;
static const int kHighQp = 40;
static const int kDisabledBadQpThreshold = 64;
static const int kLowInitialBitrateKbps = 300;
// These values need to be in sync with corresponding constants
// in quality_scaler.cc
static const int kMeasureSecondsFastUpscale = 2;
static const int kMeasureSecondsUpscale = 5;
static const int kMeasureSecondsDownscale = 5;
static const int kMinDownscaleDimension = 140;
}  // namespace

class QualityScalerTest : public ::testing::Test {
 protected:
  enum ScaleDirection {
    kKeepScaleAtHighQp,
    kScaleDown,
    kScaleDownAboveHighQp,
    kScaleUp
  };

  QualityScalerTest() {
    input_frame_ = I420Buffer::Create(kWidth, kHeight);
    qs_.Init(kLowQpThreshold, kHighQp, 0, 0, 0, kFramerate);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  }

  bool TriggerScale(ScaleDirection scale_direction) {
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    int initial_width = qs_.GetScaledResolution().width;
    for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
      switch (scale_direction) {
        case kScaleUp:
          qs_.ReportQP(kLowQp);
          break;
        case kScaleDown:
          qs_.ReportDroppedFrame();
          break;
        case kKeepScaleAtHighQp:
          qs_.ReportQP(kHighQp);
          break;
        case kScaleDownAboveHighQp:
          qs_.ReportQP(kHighQp + 1);
          break;
      }
      qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
      if (qs_.GetScaledResolution().width != initial_width)
        return true;
    }

    return false;
  }

  void ExpectOriginalFrame() {
    EXPECT_EQ(input_frame_, qs_.GetScaledBuffer(input_frame_))
        << "Using scaled frame instead of original input.";
  }

  void ExpectScaleUsingReportedResolution() {
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    QualityScaler::Resolution res = qs_.GetScaledResolution();
    rtc::scoped_refptr<VideoFrameBuffer> scaled_frame =
        qs_.GetScaledBuffer(input_frame_);
    EXPECT_EQ(res.width, scaled_frame->width());
    EXPECT_EQ(res.height, scaled_frame->height());
  }

  void ContinuouslyDownscalesByHalfDimensionsAndBackUp();

  void DoesNotDownscaleFrameDimensions(int width, int height);

  void DownscaleEndsAt(int input_width,
                       int input_height,
                       int end_width,
                       int end_height);

  QualityScaler qs_;
  rtc::scoped_refptr<VideoFrameBuffer> input_frame_;
};

TEST_F(QualityScalerTest, UsesOriginalFrameInitially) {
  ExpectOriginalFrame();
}

TEST_F(QualityScalerTest, ReportsOriginalResolutionInitially) {
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  QualityScaler::Resolution res = qs_.GetScaledResolution();
  EXPECT_EQ(input_frame_->width(), res.width);
  EXPECT_EQ(input_frame_->height(), res.height);
}

TEST_F(QualityScalerTest, DownscalesAfterContinuousFramedrop) {
  EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within " << kNumSeconds
                                        << " seconds.";
  QualityScaler::Resolution res = qs_.GetScaledResolution();
  EXPECT_LT(res.width, input_frame_->width());
  EXPECT_LT(res.height, input_frame_->height());
}

TEST_F(QualityScalerTest, KeepsScaleAtHighQp) {
  EXPECT_FALSE(TriggerScale(kKeepScaleAtHighQp))
      << "Downscale at high threshold which should keep scale.";
  QualityScaler::Resolution res = qs_.GetScaledResolution();
  EXPECT_EQ(res.width, input_frame_->width());
  EXPECT_EQ(res.height, input_frame_->height());
}

TEST_F(QualityScalerTest, DownscalesAboveHighQp) {
  EXPECT_TRUE(TriggerScale(kScaleDownAboveHighQp))
      << "No downscale within " << kNumSeconds << " seconds.";
  QualityScaler::Resolution res = qs_.GetScaledResolution();
  EXPECT_LT(res.width, input_frame_->width());
  EXPECT_LT(res.height, input_frame_->height());
}

TEST_F(QualityScalerTest, DownscalesAfterTwoThirdsFramedrop) {
  for (int i = 0; i < kFramerate * kNumSeconds / 3; ++i) {
    qs_.ReportQP(kNormalQp);
    qs_.ReportDroppedFrame();
    qs_.ReportDroppedFrame();
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    if (qs_.GetScaledResolution().width < input_frame_->width())
      return;
  }

  FAIL() << "No downscale within " << kNumSeconds << " seconds.";
}

TEST_F(QualityScalerTest, DoesNotDownscaleOnNormalQp) {
  for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
    qs_.ReportQP(kNormalQp);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
        << "Unexpected scale on half framedrop.";
  }
}

TEST_F(QualityScalerTest, DoesNotDownscaleAfterHalfFramedrop) {
  for (int i = 0; i < kFramerate * kNumSeconds / 2; ++i) {
    qs_.ReportQP(kNormalQp);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
        << "Unexpected scale on half framedrop.";

    qs_.ReportDroppedFrame();
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
        << "Unexpected scale on half framedrop.";
  }
}

void QualityScalerTest::ContinuouslyDownscalesByHalfDimensionsAndBackUp() {
  const int initial_min_dimension =
      input_frame_->width() < input_frame_->height() ? input_frame_->width()
                                                     : input_frame_->height();
  int min_dimension = initial_min_dimension;
  int current_shift = 0;
  // Drop all frames to force-trigger downscaling.
  while (min_dimension >= 2 * kMinDownscaleDimension) {
    EXPECT_TRUE(TriggerScale(kScaleDown)) << "No downscale within "
                                          << kNumSeconds << " seconds.";
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    QualityScaler::Resolution res = qs_.GetScaledResolution();
    min_dimension = res.width < res.height ? res.width : res.height;
    ++current_shift;
    ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
    ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
    ExpectScaleUsingReportedResolution();
  }

  // Make sure we can scale back with good-quality frames.
  while (min_dimension < initial_min_dimension) {
    EXPECT_TRUE(TriggerScale(kScaleUp)) << "No upscale within " << kNumSeconds
                                        << " seconds.";
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    QualityScaler::Resolution res = qs_.GetScaledResolution();
    min_dimension = res.width < res.height ? res.width : res.height;
    --current_shift;
    ASSERT_EQ(input_frame_->width() >> current_shift, res.width);
    ASSERT_EQ(input_frame_->height() >> current_shift, res.height);
    ExpectScaleUsingReportedResolution();
  }

  // Verify we don't start upscaling after further low use.
  for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
    qs_.ReportQP(kLowQp);
    ExpectOriginalFrame();
  }
}

TEST_F(QualityScalerTest, ContinuouslyDownscalesByHalfDimensionsAndBackUp) {
  ContinuouslyDownscalesByHalfDimensionsAndBackUp();
}

TEST_F(QualityScalerTest,
       ContinuouslyDownscalesOddResolutionsByHalfDimensionsAndBackUp) {
  const int kOddWidth = 517;
  const int kOddHeight = 1239;
  input_frame_ = I420Buffer::Create(kOddWidth, kOddHeight);
  ContinuouslyDownscalesByHalfDimensionsAndBackUp();
}

void QualityScalerTest::DoesNotDownscaleFrameDimensions(int width, int height) {
  input_frame_ = I420Buffer::Create(width, height);

  for (int i = 0; i < kFramerate * kNumSeconds; ++i) {
    qs_.ReportDroppedFrame();
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
    ASSERT_EQ(input_frame_->width(), qs_.GetScaledResolution().width)
        << "Unexpected scale of minimal-size frame.";
  }
}

TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxWidth) {
  DoesNotDownscaleFrameDimensions(1, kHeight);
}

TEST_F(QualityScalerTest, DoesNotDownscaleFrom1PxHeight) {
  DoesNotDownscaleFrameDimensions(kWidth, 1);
}

TEST_F(QualityScalerTest, DoesNotDownscaleFrom1Px) {
  DoesNotDownscaleFrameDimensions(1, 1);
}

TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsWidth) {
  DoesNotDownscaleFrameDimensions(
      2 * kMinDownscaleDimension - 1, 1000);
}

TEST_F(QualityScalerTest, DoesNotDownscaleBelow2xDefaultMinDimensionsHeight) {
  DoesNotDownscaleFrameDimensions(
      1000, 2 * kMinDownscaleDimension - 1);
}

TEST_F(QualityScalerTest, DownscaleToVgaOnLowInitialBitrate) {
  static const int kWidth720p = 1280;
  static const int kHeight720p = 720;
  static const int kInitialBitrateKbps = 300;
  input_frame_ = I420Buffer::Create(kWidth720p, kHeight720p);
  qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
           kWidth720p, kHeight720p, kFramerate);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  int init_width = qs_.GetScaledResolution().width;
  int init_height = qs_.GetScaledResolution().height;
  EXPECT_EQ(640, init_width);
  EXPECT_EQ(360, init_height);
}

TEST_F(QualityScalerTest, DownscaleToQvgaOnLowerInitialBitrate) {
  static const int kWidth720p = 1280;
  static const int kHeight720p = 720;
  static const int kInitialBitrateKbps = 200;
  input_frame_ = I420Buffer::Create(kWidth720p, kHeight720p);
  qs_.Init(kLowQpThreshold, kDisabledBadQpThreshold, kInitialBitrateKbps,
           kWidth720p, kHeight720p, kFramerate);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  int init_width = qs_.GetScaledResolution().width;
  int init_height = qs_.GetScaledResolution().height;
  EXPECT_EQ(320, init_width);
  EXPECT_EQ(180, init_height);
}

TEST_F(QualityScalerTest, DownscaleAfterMeasuredSecondsThenSlowerBackUp) {
  qs_.Init(kLowQpThreshold, kHighQp, 0, kWidth, kHeight, kFramerate);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  QualityScaler::Resolution initial_res = qs_.GetScaledResolution();

  // Should not downscale if less than kMeasureSecondsDownscale seconds passed.
  for (int i = 0; i < kFramerate * kMeasureSecondsDownscale - 1; ++i) {
    qs_.ReportQP(kHighQp + 1);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  }
  EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);

  // Should downscale if more than kMeasureSecondsDownscale seconds passed (add
  // last frame).
  qs_.ReportQP(kHighQp + 1);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);

  // Should not upscale if less than kMeasureSecondsUpscale seconds passed since
  // we saw issues initially (have already gone down).
  for (int i = 0; i < kFramerate * kMeasureSecondsUpscale - 1; ++i) {
    qs_.ReportQP(kLowQp);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  }
  EXPECT_GT(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_GT(initial_res.height, qs_.GetScaledResolution().height);

  // Should upscale (back to initial) if kMeasureSecondsUpscale seconds passed
  // (add last frame).
  qs_.ReportQP(kLowQp);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);
}

TEST_F(QualityScalerTest, UpscaleQuicklyInitiallyAfterMeasuredSeconds) {
  qs_.Init(kLowQpThreshold, kHighQp, kLowInitialBitrateKbps, kWidth, kHeight,
           kFramerate);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  QualityScaler::Resolution initial_res = qs_.GetScaledResolution();

  // Should not upscale if less than kMeasureSecondsFastUpscale seconds passed.
  for (int i = 0; i < kFramerate * kMeasureSecondsFastUpscale - 1; ++i) {
    qs_.ReportQP(kLowQp);
    qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  }
  EXPECT_EQ(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_EQ(initial_res.height, qs_.GetScaledResolution().height);

  // Should upscale if kMeasureSecondsFastUpscale seconds passed (add last
  // frame).
  qs_.ReportQP(kLowQp);
  qs_.OnEncodeFrame(input_frame_->width(), input_frame_->height());
  EXPECT_LT(initial_res.width, qs_.GetScaledResolution().width);
  EXPECT_LT(initial_res.height, qs_.GetScaledResolution().height);
}

void QualityScalerTest::DownscaleEndsAt(int input_width,
                                        int input_height,
                                        int end_width,
                                        int end_height) {
  // Create a frame with 2x expected end width/height to verify that we can
  // scale down to expected end width/height.
  input_frame_ = I420Buffer::Create(input_width, input_height);

  int last_width = input_width;
  int last_height = input_height;
  // Drop all frames to force-trigger downscaling.
  while (true) {
    TriggerScale(kScaleDown);
    QualityScaler::Resolution res = qs_.GetScaledResolution();
    if (last_width == res.width) {
      EXPECT_EQ(last_height, res.height);
      EXPECT_EQ(end_width, res.width);
      EXPECT_EQ(end_height, res.height);
      break;
    }
    last_width = res.width;
    last_height = res.height;
  }
}

TEST_F(QualityScalerTest, DownscalesTo320x180) {
  DownscaleEndsAt(640, 360, 320, 180);
}

TEST_F(QualityScalerTest, DownscalesTo180x320) {
  DownscaleEndsAt(360, 640, 180, 320);
}

TEST_F(QualityScalerTest, DownscalesFrom1280x720To320x180) {
  DownscaleEndsAt(1280, 720, 320, 180);
}

TEST_F(QualityScalerTest, DoesntDownscaleInitialQvga) {
  DownscaleEndsAt(320, 180, 320, 180);
}

}  // namespace webrtc
