Round down when converting allocated bitrate from bits to kilobits.

With rounding to the nearest the result can exceed the allocated
bitrate.

Bug: none
Change-Id: I0260a1640a1454951ca8e48fd447e047ef0271ee
Reviewed-on: https://webrtc-review.googlesource.com/69982
Reviewed-by: Erik Språng <sprang@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22879}
This commit is contained in:
Sergey Silkin 2018-04-14 22:25:22 +02:00 committed by Commit Bot
parent 64051d4975
commit 098f8d2c1c
3 changed files with 18 additions and 9 deletions

View file

@ -570,7 +570,10 @@ class BitrateAllocation {
std::vector<uint32_t> GetTemporalLayerAllocation(size_t spatial_index) const; std::vector<uint32_t> GetTemporalLayerAllocation(size_t spatial_index) const;
uint32_t get_sum_bps() const { return sum_; } // Sum of all bitrates. uint32_t get_sum_bps() const { return sum_; } // Sum of all bitrates.
uint32_t get_sum_kbps() const { return (sum_ + 500) / 1000; } uint32_t get_sum_kbps() const {
// Round down to not exceed the allocated bitrate.
return sum_ / 1000;
}
inline bool operator==(const BitrateAllocation& other) const { inline bool operator==(const BitrateAllocation& other) const {
return memcmp(bitrates_, other.bitrates_, sizeof(bitrates_)) == 0; return memcmp(bitrates_, other.bitrates_, sizeof(bitrates_)) == 0;

View file

@ -12,6 +12,7 @@
#include <algorithm> #include <algorithm>
#include <cmath> #include <cmath>
#include <numeric>
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
@ -132,17 +133,25 @@ std::vector<size_t> SvcRateAllocator::SplitBitrate(size_t num_layers,
float rate_scaling_factor) { float rate_scaling_factor) {
std::vector<size_t> bitrates; std::vector<size_t> bitrates;
float denominator = 0.0f; double denominator = 0.0;
for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) {
denominator += std::pow(rate_scaling_factor, layer_idx); denominator += std::pow(rate_scaling_factor, layer_idx);
} }
float numerator = std::pow(rate_scaling_factor, num_layers - 1); double numerator = std::pow(rate_scaling_factor, num_layers - 1);
for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) { for (size_t layer_idx = 0; layer_idx < num_layers; ++layer_idx) {
bitrates.push_back(numerator * total_bitrate / denominator); bitrates.push_back(numerator * total_bitrate / denominator);
numerator /= rate_scaling_factor; numerator /= rate_scaling_factor;
} }
const size_t sum = std::accumulate(bitrates.begin(), bitrates.end(), 0);
// Ensure the sum of split bitrates doesn't exceed the total bitrate.
RTC_DCHECK_LE(sum, total_bitrate);
// Keep the sum of split bitrates equal to the total bitrate by adding bits,
// which were lost due to rounding, to the latest layer.
bitrates.back() += total_bitrate - sum;
return bitrates; return bitrates;
} }

View file

@ -134,12 +134,9 @@ TEST(SvcRateAllocatorTest, BitrateIsCapped) {
EXPECT_EQ(allocation.get_sum_kbps(), EXPECT_EQ(allocation.get_sum_kbps(),
layers[0].maxBitrate + layers[1].maxBitrate + layers[2].maxBitrate); layers[0].maxBitrate + layers[1].maxBitrate + layers[2].maxBitrate);
EXPECT_EQ((allocation.GetSpatialLayerSum(0) + 500) / 1000, EXPECT_EQ(allocation.GetSpatialLayerSum(0) / 1000, layers[0].maxBitrate);
layers[0].maxBitrate); EXPECT_EQ(allocation.GetSpatialLayerSum(1) / 1000, layers[1].maxBitrate);
EXPECT_EQ((allocation.GetSpatialLayerSum(1) + 500) / 1000, EXPECT_EQ(allocation.GetSpatialLayerSum(2) / 1000, layers[2].maxBitrate);
layers[1].maxBitrate);
EXPECT_EQ((allocation.GetSpatialLayerSum(2) + 500) / 1000,
layers[2].maxBitrate);
} }
} // namespace webrtc } // namespace webrtc