/*
 *  Copyright (c) 2016 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/utility/frame_dropper.h"

#include "test/gtest.h"

namespace webrtc {

namespace {

const float kTargetBitRateKbps = 300;
const float kIncomingFrameRate = 30;
const size_t kFrameSizeBytes = 1250;

const size_t kLargeFrameSizeBytes = 25000;

const bool kIncludeKeyFrame = true;
const bool kDoNotIncludeKeyFrame = false;

}  // namespace

class FrameDropperTest : public ::testing::Test {
 protected:
  void SetUp() override {
    frame_dropper_.SetRates(kTargetBitRateKbps, kIncomingFrameRate);
  }

  void OverflowLeakyBucket() {
    // Overflow bucket in frame dropper.
    for (int i = 0; i < kIncomingFrameRate; ++i) {
      frame_dropper_.Fill(kFrameSizeBytes, true);
    }
    frame_dropper_.Leak(kIncomingFrameRate);
  }

  void ValidateNoDropsAtTargetBitrate(int large_frame_size_bytes,
                                      int large_frame_rate,
                                      bool is_large_frame_delta) {
    // Smaller frame size is computed to meet |kTargetBitRateKbps|.
    int small_frame_size_bytes =
        kFrameSizeBytes -
        (large_frame_size_bytes * large_frame_rate) / kIncomingFrameRate;

    for (int i = 1; i <= 5 * large_frame_rate; ++i) {
      // Large frame. First frame is always a key frame.
      frame_dropper_.Fill(large_frame_size_bytes,
                          (i == 1) ? false : is_large_frame_delta);
      frame_dropper_.Leak(kIncomingFrameRate);
      EXPECT_FALSE(frame_dropper_.DropFrame());

      // Smaller frames.
      for (int j = 1; j < kIncomingFrameRate / large_frame_rate; ++j) {
        frame_dropper_.Fill(small_frame_size_bytes, true);
        frame_dropper_.Leak(kIncomingFrameRate);
        EXPECT_FALSE(frame_dropper_.DropFrame());
      }
    }
  }

  void ValidateThroughputMatchesTargetBitrate(int bitrate_kbps,
                                              bool include_keyframe) {
    int delta_frame_size;
    int total_bytes = 0;

    if (include_keyframe) {
      delta_frame_size = ((1000.0 / 8 * bitrate_kbps) - kLargeFrameSizeBytes) /
                         (kIncomingFrameRate - 1);
    } else {
      delta_frame_size = bitrate_kbps * 1000.0 / (8 * kIncomingFrameRate);
    }
    const int kNumIterations = 1000;
    for (int i = 1; i <= kNumIterations; ++i) {
      int j = 0;
      if (include_keyframe) {
        if (!frame_dropper_.DropFrame()) {
          frame_dropper_.Fill(kLargeFrameSizeBytes, false);
          total_bytes += kLargeFrameSizeBytes;
        }
        frame_dropper_.Leak(kIncomingFrameRate);
        j++;
      }
      for (; j < kIncomingFrameRate; ++j) {
        if (!frame_dropper_.DropFrame()) {
          frame_dropper_.Fill(delta_frame_size, true);
          total_bytes += delta_frame_size;
        }
        frame_dropper_.Leak(kIncomingFrameRate);
      }
    }
    float throughput_kbps = total_bytes * 8.0 / (1000 * kNumIterations);
    float deviation_from_target =
        (throughput_kbps - kTargetBitRateKbps) * 100.0 / kTargetBitRateKbps;
    if (deviation_from_target < 0) {
      deviation_from_target = -deviation_from_target;
    }

    // Variation is < 0.1%
    EXPECT_LE(deviation_from_target, 0.1);
  }

  FrameDropper frame_dropper_;
};

TEST_F(FrameDropperTest, NoDropsWhenDisabled) {
  frame_dropper_.Enable(false);
  OverflowLeakyBucket();
  EXPECT_FALSE(frame_dropper_.DropFrame());
}

TEST_F(FrameDropperTest, DropsByDefaultWhenBucketOverflows) {
  OverflowLeakyBucket();
  EXPECT_TRUE(frame_dropper_.DropFrame());
}

TEST_F(FrameDropperTest, NoDropsWhenFillRateMatchesLeakRate) {
  for (int i = 0; i < 5 * kIncomingFrameRate; ++i) {
    frame_dropper_.Fill(kFrameSizeBytes, true);
    frame_dropper_.Leak(kIncomingFrameRate);
    EXPECT_FALSE(frame_dropper_.DropFrame());
  }
}

TEST_F(FrameDropperTest, LargeKeyFrames) {
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes, 1, false);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 2, 2, false);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 4, 4, false);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 8, 8, false);
}

TEST_F(FrameDropperTest, LargeDeltaFrames) {
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes, 1, true);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 2, 2, true);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 4, 4, true);
  frame_dropper_.Reset();
  ValidateNoDropsAtTargetBitrate(kLargeFrameSizeBytes / 8, 8, true);
}

TEST_F(FrameDropperTest, TrafficVolumeAboveAvailableBandwidth) {
  ValidateThroughputMatchesTargetBitrate(700, kIncludeKeyFrame);
  ValidateThroughputMatchesTargetBitrate(700, kDoNotIncludeKeyFrame);
  ValidateThroughputMatchesTargetBitrate(600, kIncludeKeyFrame);
  ValidateThroughputMatchesTargetBitrate(600, kDoNotIncludeKeyFrame);
  ValidateThroughputMatchesTargetBitrate(500, kIncludeKeyFrame);
  ValidateThroughputMatchesTargetBitrate(500, kDoNotIncludeKeyFrame);
}

}  // namespace webrtc
