OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 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 "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" |
| 12 |
| 13 #include <limits> |
| 14 #include <memory> |
| 15 |
| 16 #include "testing/gtest/include/gtest/gtest.h" |
| 17 |
| 18 namespace webrtc { |
| 19 namespace { |
| 20 constexpr uint32_t kMinBitrate = 50; |
| 21 constexpr uint32_t kTargetBitrate = 100; |
| 22 constexpr uint32_t kMaxBitrate = 1000; |
| 23 } // namespace |
| 24 |
| 25 class SimulcastRateAllocatorTest : public ::testing::Test { |
| 26 public: |
| 27 SimulcastRateAllocatorTest() { |
| 28 memset(&codec_, 0, sizeof(VideoCodec)); |
| 29 codec_.minBitrate = kMinBitrate; |
| 30 codec_.targetBitrate = kTargetBitrate; |
| 31 codec_.maxBitrate = kMaxBitrate; |
| 32 CreateAllocator(); |
| 33 } |
| 34 virtual ~SimulcastRateAllocatorTest() {} |
| 35 |
| 36 template <size_t S> |
| 37 void ExpectEqual(uint32_t (&expected)[S], |
| 38 const std::vector<uint32_t>& actual) { |
| 39 EXPECT_EQ(S, actual.size()); |
| 40 for (size_t i = 0; i < S; ++i) |
| 41 EXPECT_EQ(expected[i], actual[i]) << "Mismatch at index " << i; |
| 42 } |
| 43 |
| 44 void CreateAllocator() { |
| 45 allocator_.reset(new SimulcastRateAllocator(codec_)); |
| 46 } |
| 47 |
| 48 protected: |
| 49 VideoCodec codec_; |
| 50 std::unique_ptr<SimulcastRateAllocator> allocator_; |
| 51 }; |
| 52 |
| 53 TEST_F(SimulcastRateAllocatorTest, NoSimulcastBelowMin) { |
| 54 uint32_t expected[] = {codec_.minBitrate}; |
| 55 ExpectEqual(expected, allocator_->GetAllocation(codec_.minBitrate - 1)); |
| 56 ExpectEqual(expected, allocator_->GetAllocation(1)); |
| 57 ExpectEqual(expected, allocator_->GetAllocation(0)); |
| 58 } |
| 59 |
| 60 TEST_F(SimulcastRateAllocatorTest, NoSimulcastAboveMax) { |
| 61 uint32_t expected[] = {codec_.maxBitrate}; |
| 62 ExpectEqual(expected, allocator_->GetAllocation(codec_.maxBitrate + 1)); |
| 63 ExpectEqual(expected, |
| 64 allocator_->GetAllocation(std::numeric_limits<uint32_t>::max())); |
| 65 } |
| 66 |
| 67 TEST_F(SimulcastRateAllocatorTest, NoSimulcastNoMax) { |
| 68 constexpr uint32_t kMax = std::numeric_limits<uint32_t>::max(); |
| 69 codec_.maxBitrate = 0; |
| 70 CreateAllocator(); |
| 71 |
| 72 uint32_t expected[] = {kMax}; |
| 73 ExpectEqual(expected, allocator_->GetAllocation(kMax)); |
| 74 } |
| 75 |
| 76 TEST_F(SimulcastRateAllocatorTest, NoSimulcastWithinLimits) { |
| 77 for (uint32_t bitrate = codec_.minBitrate; bitrate <= codec_.maxBitrate; |
| 78 ++bitrate) { |
| 79 uint32_t expected[] = {bitrate}; |
| 80 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 81 } |
| 82 } |
| 83 |
| 84 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastBelowMin) { |
| 85 // With simulcast, use the min bitrate from the ss spec instead of the global. |
| 86 codec_.numberOfSimulcastStreams = 1; |
| 87 const uint32_t kMin = codec_.minBitrate - 10; |
| 88 codec_.simulcastStream[0].minBitrate = kMin; |
| 89 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; |
| 90 CreateAllocator(); |
| 91 |
| 92 uint32_t expected[] = {kMin}; |
| 93 ExpectEqual(expected, allocator_->GetAllocation(kMin - 1)); |
| 94 ExpectEqual(expected, allocator_->GetAllocation(1)); |
| 95 ExpectEqual(expected, allocator_->GetAllocation(0)); |
| 96 } |
| 97 |
| 98 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastAboveMax) { |
| 99 codec_.numberOfSimulcastStreams = 1; |
| 100 codec_.simulcastStream[0].minBitrate = kMinBitrate; |
| 101 const uint32_t kMax = codec_.simulcastStream[0].maxBitrate + 1000; |
| 102 codec_.simulcastStream[0].maxBitrate = kMax; |
| 103 CreateAllocator(); |
| 104 |
| 105 uint32_t expected[] = {kMax}; |
| 106 ExpectEqual(expected, allocator_->GetAllocation(kMax + 1)); |
| 107 ExpectEqual(expected, |
| 108 allocator_->GetAllocation(std::numeric_limits<uint32_t>::max())); |
| 109 } |
| 110 |
| 111 TEST_F(SimulcastRateAllocatorTest, SingleSimulcastWithinLimits) { |
| 112 codec_.numberOfSimulcastStreams = 1; |
| 113 codec_.simulcastStream[0].minBitrate = kMinBitrate; |
| 114 codec_.simulcastStream[0].targetBitrate = kTargetBitrate; |
| 115 codec_.simulcastStream[0].maxBitrate = kMaxBitrate; |
| 116 CreateAllocator(); |
| 117 |
| 118 for (uint32_t bitrate = kMinBitrate; bitrate <= kMaxBitrate; ++bitrate) { |
| 119 uint32_t expected[] = {bitrate}; |
| 120 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 121 } |
| 122 } |
| 123 |
| 124 TEST_F(SimulcastRateAllocatorTest, OneToThreeStreams) { |
| 125 codec_.numberOfSimulcastStreams = 3; |
| 126 codec_.maxBitrate = 0; |
| 127 codec_.simulcastStream[0].minBitrate = 10; |
| 128 codec_.simulcastStream[0].targetBitrate = 100; |
| 129 codec_.simulcastStream[0].maxBitrate = 500; |
| 130 codec_.simulcastStream[1].minBitrate = 50; |
| 131 codec_.simulcastStream[1].targetBitrate = 500; |
| 132 codec_.simulcastStream[1].maxBitrate = 1000; |
| 133 codec_.simulcastStream[2].minBitrate = 2000; |
| 134 codec_.simulcastStream[2].targetBitrate = 3000; |
| 135 codec_.simulcastStream[2].maxBitrate = 4000; |
| 136 CreateAllocator(); |
| 137 |
| 138 { |
| 139 // Single stream, min bitrate. |
| 140 const uint32_t bitrate = codec_.simulcastStream[0].minBitrate; |
| 141 uint32_t expected[] = {bitrate, 0, 0}; |
| 142 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 143 } |
| 144 |
| 145 { |
| 146 // Single stream at target bitrate. |
| 147 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate; |
| 148 uint32_t expected[] = {bitrate, 0, 0}; |
| 149 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 150 } |
| 151 |
| 152 { |
| 153 // Bitrate above target for first stream, but below min for the next one. |
| 154 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 155 codec_.simulcastStream[1].minBitrate - 1; |
| 156 uint32_t expected[] = {bitrate, 0, 0}; |
| 157 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 158 } |
| 159 |
| 160 { |
| 161 // Just enough for two streams. |
| 162 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 163 codec_.simulcastStream[1].minBitrate; |
| 164 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
| 165 codec_.simulcastStream[1].minBitrate, 0}; |
| 166 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 167 } |
| 168 |
| 169 { |
| 170 // Second stream maxed out, but not enough for third. |
| 171 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 172 codec_.simulcastStream[1].maxBitrate; |
| 173 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
| 174 codec_.simulcastStream[1].maxBitrate, 0}; |
| 175 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 176 } |
| 177 |
| 178 { |
| 179 // First two streams maxed out, but not enough for third. |
| 180 const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate + |
| 181 codec_.simulcastStream[1].maxBitrate; |
| 182 uint32_t expected[] = {codec_.simulcastStream[0].maxBitrate, |
| 183 codec_.simulcastStream[1].maxBitrate, 0}; |
| 184 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 185 } |
| 186 |
| 187 { |
| 188 // First two streams maxed out, but not enough for third. Nowhere to put |
| 189 // remaining bits. |
| 190 const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate + |
| 191 codec_.simulcastStream[1].maxBitrate + 499; |
| 192 uint32_t expected[] = {codec_.simulcastStream[0].maxBitrate, |
| 193 codec_.simulcastStream[1].maxBitrate, 0}; |
| 194 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 195 } |
| 196 |
| 197 { |
| 198 // Just enough for all three streams. |
| 199 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 200 codec_.simulcastStream[1].targetBitrate + |
| 201 codec_.simulcastStream[2].minBitrate; |
| 202 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
| 203 codec_.simulcastStream[1].targetBitrate, |
| 204 codec_.simulcastStream[2].minBitrate}; |
| 205 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 206 } |
| 207 |
| 208 { |
| 209 // Third maxed out. |
| 210 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 211 codec_.simulcastStream[1].targetBitrate + |
| 212 codec_.simulcastStream[2].maxBitrate; |
| 213 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
| 214 codec_.simulcastStream[1].targetBitrate, |
| 215 codec_.simulcastStream[2].maxBitrate}; |
| 216 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 217 } |
| 218 |
| 219 { |
| 220 // Layer 2, 3 maxed out. |
| 221 const uint32_t bitrate = codec_.simulcastStream[0].targetBitrate + |
| 222 codec_.simulcastStream[1].maxBitrate + |
| 223 codec_.simulcastStream[2].maxBitrate; |
| 224 uint32_t expected[] = {codec_.simulcastStream[0].targetBitrate, |
| 225 codec_.simulcastStream[1].maxBitrate, |
| 226 codec_.simulcastStream[2].maxBitrate}; |
| 227 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 228 } |
| 229 |
| 230 { |
| 231 // All three maxed out. |
| 232 const uint32_t bitrate = codec_.simulcastStream[0].maxBitrate + |
| 233 codec_.simulcastStream[1].maxBitrate + |
| 234 codec_.simulcastStream[2].maxBitrate; |
| 235 uint32_t expected[] = {codec_.simulcastStream[0].maxBitrate, |
| 236 codec_.simulcastStream[1].maxBitrate, |
| 237 codec_.simulcastStream[2].maxBitrate}; |
| 238 ExpectEqual(expected, allocator_->GetAllocation(bitrate)); |
| 239 |
| 240 // Can't go any higher. |
| 241 ExpectEqual(expected, allocator_->GetAllocation( |
| 242 std::numeric_limits<uint32_t>::max())); |
| 243 } |
| 244 } |
| 245 |
| 246 } // namespace webrtc |
OLD | NEW |