Adds target bandwidth to BitrateAllocator.

The target bandwidth is a more stable target rate as it does not follow
the variation in the control signal directly. It's intended to be used to
configure the audio frame length.

Bug: webrtc:9718
Change-Id: Idcc83ba0fef90e0ead2926d18ba6893a2b0f085f
Reviewed-on: https://webrtc-review.googlesource.com/c/107729
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25718}
This commit is contained in:
Sebastian Jansson 2018-11-20 17:16:36 +01:00
parent 66eedce30a
commit 89c94b9aea
4 changed files with 47 additions and 20 deletions

View file

@ -50,7 +50,8 @@ double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) {
BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer)
: limit_observer_(limit_observer),
last_bitrate_bps_(0),
last_target_bps_(0),
last_link_capacity_bps_(0),
last_non_zero_bitrate_bps_(kDefaultBitrateBps),
last_fraction_loss_(0),
last_rtt_(0),
@ -88,11 +89,13 @@ uint8_t BitrateAllocator::GetTransmissionMaxBitrateMultiplier() {
}
void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
uint32_t link_capacity_bps,
uint8_t fraction_loss,
int64_t rtt,
int64_t bwe_period_ms) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&sequenced_checker_);
last_bitrate_bps_ = target_bitrate_bps;
last_target_bps_ = target_bitrate_bps;
last_link_capacity_bps_ = link_capacity_bps;
last_non_zero_bitrate_bps_ =
target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_;
last_fraction_loss_ = fraction_loss;
@ -107,12 +110,15 @@ void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
}
ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps);
ObserverAllocation bandwidth_allocation = AllocateBitrates(link_capacity_bps);
for (auto& config : bitrate_observer_configs_) {
uint32_t allocated_bitrate = allocation[config.observer];
uint32_t protection_bitrate = config.observer->OnBitrateUpdated(
BitrateAllocationUpdate{allocated_bitrate, last_fraction_loss_,
last_rtt_, last_bwe_period_ms_});
uint32_t allocated_bandwidth = bandwidth_allocation[config.observer];
uint32_t protection_bitrate =
config.observer->OnBitrateUpdated(BitrateAllocationUpdate{
allocated_bitrate, allocated_bandwidth, last_fraction_loss_,
last_rtt_, last_bwe_period_ms_});
if (allocated_bitrate == 0 && config.allocated_bitrate_bps > 0) {
if (target_bitrate_bps > 0)
@ -164,15 +170,19 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
config.bitrate_priority, config.has_packet_feedback));
}
ObserverAllocation allocation;
if (last_bitrate_bps_ > 0) {
if (last_target_bps_ > 0) {
// Calculate a new allocation and update all observers.
allocation = AllocateBitrates(last_bitrate_bps_);
ObserverAllocation allocation = AllocateBitrates(last_target_bps_);
ObserverAllocation bandwidth_allocation =
AllocateBitrates(last_link_capacity_bps_);
for (auto& config : bitrate_observer_configs_) {
uint32_t allocated_bitrate = allocation[config.observer];
uint32_t protection_bitrate = config.observer->OnBitrateUpdated(
BitrateAllocationUpdate{allocated_bitrate, last_fraction_loss_,
last_rtt_, last_bwe_period_ms_});
uint32_t bandwidth = bandwidth_allocation[config.observer];
uint32_t protection_bitrate =
config.observer->OnBitrateUpdated(BitrateAllocationUpdate{
allocated_bitrate, bandwidth, last_fraction_loss_, last_rtt_,
last_bwe_period_ms_});
config.allocated_bitrate_bps = allocated_bitrate;
if (allocated_bitrate > 0)
config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate);
@ -181,9 +191,8 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
// Currently, an encoder is not allowed to produce frames.
// But we still have to return the initial config bitrate + let the
// observer know that it can not produce frames.
allocation = AllocateBitrates(last_non_zero_bitrate_bps_);
observer->OnBitrateUpdated(BitrateAllocationUpdate{
0, last_fraction_loss_, last_rtt_, last_bwe_period_ms_});
0, 0, last_fraction_loss_, last_rtt_, last_bwe_period_ms_});
}
UpdateAllocationLimits();
}

View file

@ -27,7 +27,9 @@ namespace webrtc {
class Clock;
struct BitrateAllocationUpdate {
// TODO(srte): Rename to target_bitrate.
uint32_t bitrate_bps;
uint32_t link_capacity_bps;
uint8_t fraction_loss;
int64_t rtt;
int64_t bwe_period_ms;
@ -107,6 +109,7 @@ class BitrateAllocator : public BitrateAllocatorInterface {
// Allocate target_bitrate across the registered BitrateAllocatorObservers.
void OnNetworkChanged(uint32_t target_bitrate_bps,
uint32_t link_capacity_bps,
uint8_t fraction_loss,
int64_t rtt,
int64_t bwe_period_ms);
@ -239,7 +242,8 @@ class BitrateAllocator : public BitrateAllocatorInterface {
LimitObserver* const limit_observer_ RTC_GUARDED_BY(&sequenced_checker_);
// Stored in a list to keep track of the insertion order.
ObserverConfigs bitrate_observer_configs_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_bitrate_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_target_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_link_capacity_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_non_zero_bitrate_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint8_t last_fraction_loss_ RTC_GUARDED_BY(&sequenced_checker_);
int64_t last_rtt_ RTC_GUARDED_BY(&sequenced_checker_);

View file

@ -73,6 +73,18 @@ class TestBitrateObserver : public BitrateAllocatorObserver {
double protection_ratio_;
};
class BitrateAllocatorForTest : public BitrateAllocator {
public:
using BitrateAllocator::BitrateAllocator;
void OnNetworkChanged(uint32_t target_bitrate_bps,
uint8_t fraction_loss,
int64_t rtt,
int64_t bwe_period_ms) {
BitrateAllocator::OnNetworkChanged(target_bitrate_bps, target_bitrate_bps,
fraction_loss, rtt, bwe_period_ms);
}
};
namespace {
constexpr int64_t kDefaultProbingIntervalMs = 3000;
const double kDefaultBitratePriority = 1.0;
@ -80,7 +92,8 @@ const double kDefaultBitratePriority = 1.0;
class BitrateAllocatorTest : public ::testing::Test {
protected:
BitrateAllocatorTest() : allocator_(new BitrateAllocator(&limit_observer_)) {
BitrateAllocatorTest()
: allocator_(new BitrateAllocatorForTest(&limit_observer_)) {
allocator_->OnNetworkChanged(300000u, 0, 0, kDefaultProbingIntervalMs);
}
~BitrateAllocatorTest() {}
@ -97,7 +110,7 @@ class BitrateAllocatorTest : public ::testing::Test {
}
NiceMock<MockLimitObserver> limit_observer_;
std::unique_ptr<BitrateAllocator> allocator_;
std::unique_ptr<BitrateAllocatorForTest> allocator_;
};
TEST_F(BitrateAllocatorTest, UpdatingBitrateObserver) {
@ -213,7 +226,7 @@ TEST_F(BitrateAllocatorTest, RemoveObserverTriggersLimitObserver) {
class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
protected:
BitrateAllocatorTestNoEnforceMin()
: allocator_(new BitrateAllocator(&limit_observer_)) {
: allocator_(new BitrateAllocatorForTest(&limit_observer_)) {
allocator_->OnNetworkChanged(300000u, 0, 0, kDefaultProbingIntervalMs);
}
~BitrateAllocatorTestNoEnforceMin() {}
@ -229,7 +242,7 @@ class BitrateAllocatorTestNoEnforceMin : public ::testing::Test {
enforce_min_bitrate, track_id, bitrate_priority, false});
}
NiceMock<MockLimitObserver> limit_observer_;
std::unique_ptr<BitrateAllocator> allocator_;
std::unique_ptr<BitrateAllocatorForTest> allocator_;
};
// The following three tests verify enforcing a minimum bitrate works as

View file

@ -1124,8 +1124,9 @@ void Call::OnTargetTransferRate(TargetTransferRate msg) {
}
// For controlling the rate of feedback messages.
receive_side_cc_.OnBitrateChanged(target_bitrate_bps);
bitrate_allocator_->OnNetworkChanged(target_bitrate_bps, fraction_loss,
rtt_ms, probing_interval_ms);
bitrate_allocator_->OnNetworkChanged(target_bitrate_bps, bandwidth_bps,
fraction_loss, rtt_ms,
probing_interval_ms);
// Ignore updates if bitrate is zero (the aggregate network state is down).
if (target_bitrate_bps == 0) {