bitrate_adjuster_unittest.cc (6881B)
1 /* 2 * Copyright 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "common_video/include/bitrate_adjuster.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 16 #include "api/units/time_delta.h" 17 #include "rtc_base/fake_clock.h" 18 #include "test/gtest.h" 19 20 namespace webrtc { 21 22 class BitrateAdjusterTest : public ::testing::Test { 23 public: 24 BitrateAdjusterTest() 25 : adjuster_(kMinAdjustedBitratePct, kMaxAdjustedBitratePct) {} 26 27 // Simulate an output bitrate for one update cycle of BitrateAdjuster. 28 void SimulateBitrateBps(uint32_t bitrate_bps) { 29 const uint32_t update_interval_ms = 30 BitrateAdjuster::kBitrateUpdateIntervalMs; 31 const uint32_t update_frame_interval = 32 BitrateAdjuster::kBitrateUpdateFrameInterval; 33 // Round up frame interval so we get one cycle passes. 34 const uint32_t frame_interval_ms = 35 (update_interval_ms + update_frame_interval - 1) / 36 update_frame_interval; 37 const size_t frame_size_bytes = 38 (bitrate_bps * frame_interval_ms) / (8 * 1000); 39 for (size_t i = 0; i < update_frame_interval; ++i) { 40 clock_.AdvanceTime(TimeDelta::Millis(frame_interval_ms)); 41 adjuster_.Update(frame_size_bytes); 42 } 43 } 44 45 uint32_t GetTargetBitrateBpsPct(float pct) { 46 return pct * adjuster_.GetTargetBitrateBps(); 47 } 48 49 void VerifyAdjustment() { 50 // The adjusted bitrate should be between the estimated bitrate and the 51 // target bitrate within clamp. 52 uint32_t target_bitrate_bps = adjuster_.GetTargetBitrateBps(); 53 uint32_t adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps(); 54 uint32_t estimated_bitrate_bps = 55 adjuster_.GetEstimatedBitrateBps().value_or(target_bitrate_bps); 56 uint32_t adjusted_lower_bound_bps = 57 GetTargetBitrateBpsPct(kMinAdjustedBitratePct); 58 uint32_t adjusted_upper_bound_bps = 59 GetTargetBitrateBpsPct(kMaxAdjustedBitratePct); 60 EXPECT_LE(adjusted_bitrate_bps, adjusted_upper_bound_bps); 61 EXPECT_GE(adjusted_bitrate_bps, adjusted_lower_bound_bps); 62 if (estimated_bitrate_bps > target_bitrate_bps) { 63 EXPECT_LT(adjusted_bitrate_bps, target_bitrate_bps); 64 } 65 } 66 67 protected: 68 static const float kMinAdjustedBitratePct; 69 static const float kMaxAdjustedBitratePct; 70 ScopedFakeClock clock_; 71 BitrateAdjuster adjuster_; 72 }; 73 74 const float BitrateAdjusterTest::kMinAdjustedBitratePct = .5f; 75 const float BitrateAdjusterTest::kMaxAdjustedBitratePct = .95f; 76 77 TEST_F(BitrateAdjusterTest, VaryingBitrates) { 78 const uint32_t target_bitrate_bps = 640000; 79 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 80 81 // Grossly overshoot for a little while. Adjusted bitrate should decrease. 82 uint32_t actual_bitrate_bps = 2 * target_bitrate_bps; 83 uint32_t last_adjusted_bitrate_bps = 0; 84 uint32_t adjusted_bitrate_bps = 0; 85 86 SimulateBitrateBps(actual_bitrate_bps); 87 VerifyAdjustment(); 88 last_adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps(); 89 90 SimulateBitrateBps(actual_bitrate_bps); 91 VerifyAdjustment(); 92 adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps(); 93 EXPECT_LE(adjusted_bitrate_bps, last_adjusted_bitrate_bps); 94 last_adjusted_bitrate_bps = adjusted_bitrate_bps; 95 // After two cycles we should've stabilized and hit the lower bound. 96 EXPECT_EQ(GetTargetBitrateBpsPct(kMinAdjustedBitratePct), 97 adjusted_bitrate_bps); 98 99 // Simulate encoder settling down. Adjusted bitrate should increase. 100 SimulateBitrateBps(target_bitrate_bps); 101 adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps(); 102 VerifyAdjustment(); 103 EXPECT_GT(adjusted_bitrate_bps, last_adjusted_bitrate_bps); 104 last_adjusted_bitrate_bps = adjusted_bitrate_bps; 105 106 SimulateBitrateBps(target_bitrate_bps); 107 adjusted_bitrate_bps = adjuster_.GetAdjustedBitrateBps(); 108 VerifyAdjustment(); 109 EXPECT_GT(adjusted_bitrate_bps, last_adjusted_bitrate_bps); 110 last_adjusted_bitrate_bps = adjusted_bitrate_bps; 111 // After two cycles we should've stabilized and hit the upper bound. 112 EXPECT_EQ(GetTargetBitrateBpsPct(kMaxAdjustedBitratePct), 113 adjusted_bitrate_bps); 114 } 115 116 // Tests that large changes in target bitrate will result in immediate change 117 // in adjusted bitrate. 118 TEST_F(BitrateAdjusterTest, LargeTargetDelta) { 119 uint32_t target_bitrate_bps = 640000; 120 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 121 EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 122 123 float delta_pct = BitrateAdjuster::kBitrateTolerancePct * 2; 124 125 target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps; 126 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 127 EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 128 129 target_bitrate_bps = (1 - delta_pct) * target_bitrate_bps; 130 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 131 EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 132 } 133 134 // Tests that small changes in target bitrate within tolerance will not affect 135 // adjusted bitrate immediately. 136 TEST_F(BitrateAdjusterTest, SmallTargetDelta) { 137 const uint32_t initial_target_bitrate_bps = 640000; 138 uint32_t target_bitrate_bps = initial_target_bitrate_bps; 139 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 140 EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 141 142 float delta_pct = BitrateAdjuster::kBitrateTolerancePct / 2; 143 144 target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps; 145 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 146 EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 147 148 target_bitrate_bps = (1 - delta_pct) * target_bitrate_bps; 149 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 150 EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 151 } 152 153 TEST_F(BitrateAdjusterTest, SmallTargetDeltaOverflow) { 154 const uint32_t initial_target_bitrate_bps = 640000; 155 uint32_t target_bitrate_bps = initial_target_bitrate_bps; 156 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 157 EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 158 159 float delta_pct = BitrateAdjuster::kBitrateTolerancePct / 2; 160 161 target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps; 162 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 163 EXPECT_EQ(initial_target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 164 165 // 1.05 * 1.05 is 1.1 which is greater than tolerance for the initial target 166 // bitrate. Since we didn't advance the clock the adjuster never updated. 167 target_bitrate_bps = (1 + delta_pct) * target_bitrate_bps; 168 adjuster_.SetTargetBitrateBps(target_bitrate_bps); 169 EXPECT_EQ(target_bitrate_bps, adjuster_.GetAdjustedBitrateBps()); 170 } 171 172 } // namespace webrtc