Auto pause video streams based on encoder target bitrate.
This CL changes the auto-pause logic to suspend a stream based on the encoder target bitrate instead of the allocated bitrate for a stream, to account for possible protection, e.g. FEC and NACK. This CL also adds periodic logging of the current BWE and possibility to run with suspension in video loopback test. BUG=webrtc:5868 R=stefan@webrtc.org Review URL: https://codereview.webrtc.org/2117493002 . Cr-Commit-Position: refs/heads/master@{#13360}
This commit is contained in:
parent
6907d04f90
commit
48a4beb7a4
@ -15,7 +15,10 @@
|
||||
#include <utility>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/modules/bitrate_controller/include/bitrate_controller.h"
|
||||
#include "webrtc/system_wrappers/include/clock.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
@ -28,13 +31,35 @@ const int kDefaultBitrateBps = 300000;
|
||||
const double kToggleFactor = 0.1;
|
||||
const uint32_t kMinToggleBitrateBps = 20000;
|
||||
|
||||
const int64_t kBweLogIntervalMs = 5000;
|
||||
|
||||
namespace {
|
||||
|
||||
double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) {
|
||||
RTC_DCHECK_GT(allocated_bitrate, 0u);
|
||||
if (protection_bitrate == 0)
|
||||
return 1.0;
|
||||
|
||||
uint32_t media_bitrate = allocated_bitrate - protection_bitrate;
|
||||
return media_bitrate / static_cast<double>(allocated_bitrate);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
BitrateAllocator::BitrateAllocator(LimitObserver* limit_observer)
|
||||
: limit_observer_(limit_observer),
|
||||
bitrate_observer_configs_(),
|
||||
last_bitrate_bps_(kDefaultBitrateBps),
|
||||
last_non_zero_bitrate_bps_(kDefaultBitrateBps),
|
||||
last_fraction_loss_(0),
|
||||
last_rtt_(0) {}
|
||||
last_rtt_(0),
|
||||
num_pause_events_(0),
|
||||
clock_(Clock::GetRealTimeClock()),
|
||||
last_bwe_log_time_(0) {}
|
||||
|
||||
BitrateAllocator::~BitrateAllocator() {
|
||||
RTC_LOGGED_HISTOGRAM_COUNTS_100("WebRTC.Call.NumberOfPauseEvents",
|
||||
num_pause_events_);
|
||||
}
|
||||
|
||||
void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
@ -46,11 +71,45 @@ void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
last_fraction_loss_ = fraction_loss;
|
||||
last_rtt_ = rtt;
|
||||
|
||||
ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps);
|
||||
for (const auto& kv : allocation) {
|
||||
kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_);
|
||||
// Periodically log the incoming BWE.
|
||||
int64_t now = clock_->TimeInMilliseconds();
|
||||
if (now > last_bwe_log_time_ + kBweLogIntervalMs) {
|
||||
LOG(LS_INFO) << "Current BWE " << target_bitrate_bps;
|
||||
last_bwe_log_time_ = now;
|
||||
}
|
||||
|
||||
ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps);
|
||||
|
||||
for (auto& config : bitrate_observer_configs_) {
|
||||
uint32_t allocated_bitrate = allocation[config.observer];
|
||||
uint32_t protection_bitrate = config.observer->OnBitrateUpdated(
|
||||
allocated_bitrate, last_fraction_loss_, last_rtt_);
|
||||
|
||||
if (allocated_bitrate == 0 && config.allocated_bitrate_bps > 0) {
|
||||
if (target_bitrate_bps > 0)
|
||||
++num_pause_events_;
|
||||
// The protection bitrate is an estimate based on the ratio between media
|
||||
// and protection used before this observer was muted.
|
||||
uint32_t predicted_protection_bps =
|
||||
(1.0 - config.media_ratio) * config.min_bitrate_bps;
|
||||
LOG(LS_INFO) << "Pausing observer " << config.observer
|
||||
<< " with configured min bitrate " << config.min_bitrate_bps
|
||||
<< " and current estimate of " << target_bitrate_bps
|
||||
<< " and protection bitrate " << predicted_protection_bps;
|
||||
} else if (allocated_bitrate > 0 && config.allocated_bitrate_bps == 0) {
|
||||
if (target_bitrate_bps > 0)
|
||||
++num_pause_events_;
|
||||
LOG(LS_INFO) << "Resuming observer " << config.observer
|
||||
<< ", configured min bitrate " << config.min_bitrate_bps
|
||||
<< ", current allocation " << allocated_bitrate
|
||||
<< " and protection bitrate " << protection_bitrate;
|
||||
}
|
||||
|
||||
// Only update the media ratio if the observer got an allocation.
|
||||
if (allocated_bitrate > 0)
|
||||
config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate);
|
||||
config.allocated_bitrate_bps = allocated_bitrate;
|
||||
}
|
||||
last_allocation_ = allocation;
|
||||
}
|
||||
|
||||
void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
|
||||
@ -77,8 +136,14 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
|
||||
if (last_bitrate_bps_ > 0) {
|
||||
// Calculate a new allocation and update all observers.
|
||||
allocation = AllocateBitrates(last_bitrate_bps_);
|
||||
for (const auto& kv : allocation)
|
||||
kv.first->OnBitrateUpdated(kv.second, last_fraction_loss_, last_rtt_);
|
||||
for (auto& config : bitrate_observer_configs_) {
|
||||
uint32_t allocated_bitrate = allocation[config.observer];
|
||||
uint32_t protection_bitrate = config.observer->OnBitrateUpdated(
|
||||
allocated_bitrate, last_fraction_loss_, last_rtt_);
|
||||
config.allocated_bitrate_bps = allocated_bitrate;
|
||||
if (allocated_bitrate > 0)
|
||||
config.media_ratio = MediaRatio(allocated_bitrate, protection_bitrate);
|
||||
}
|
||||
} else {
|
||||
// Currently, an encoder is not allowed to produce frames.
|
||||
// But we still have to return the initial config bitrate + let the
|
||||
@ -87,8 +152,6 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
|
||||
observer->OnBitrateUpdated(0, last_fraction_loss_, last_rtt_);
|
||||
}
|
||||
UpdateAllocationLimits();
|
||||
|
||||
last_allocation_ = allocation;
|
||||
}
|
||||
|
||||
void BitrateAllocator::UpdateAllocationLimits() {
|
||||
@ -122,17 +185,22 @@ void BitrateAllocator::RemoveObserver(BitrateAllocatorObserver* observer) {
|
||||
|
||||
int BitrateAllocator::GetStartBitrate(BitrateAllocatorObserver* observer) {
|
||||
rtc::CritScope lock(&crit_sect_);
|
||||
const auto& it = last_allocation_.find(observer);
|
||||
if (it != last_allocation_.end())
|
||||
return it->second;
|
||||
|
||||
// This is a new observer that has not yet been started. Assume that if it is
|
||||
// added, all observers would split the available bitrate evenly.
|
||||
return last_non_zero_bitrate_bps_ /
|
||||
static_cast<int>((bitrate_observer_configs_.size() + 1));
|
||||
const auto& it = FindObserverConfig(observer);
|
||||
if (it == bitrate_observer_configs_.end()) {
|
||||
// This observer hasn't been added yet, just give it its fair share.
|
||||
return last_non_zero_bitrate_bps_ /
|
||||
static_cast<int>((bitrate_observer_configs_.size() + 1));
|
||||
} else if (it->allocated_bitrate_bps == -1) {
|
||||
// This observer hasn't received an allocation yet, so do the same.
|
||||
return last_non_zero_bitrate_bps_ /
|
||||
static_cast<int>(bitrate_observer_configs_.size());
|
||||
} else {
|
||||
// This observer already has an allocation.
|
||||
return it->allocated_bitrate_bps;
|
||||
}
|
||||
}
|
||||
|
||||
BitrateAllocator::ObserverConfigList::iterator
|
||||
BitrateAllocator::ObserverConfigs::iterator
|
||||
BitrateAllocator::FindObserverConfig(
|
||||
const BitrateAllocatorObserver* observer) {
|
||||
for (auto it = bitrate_observer_configs_.begin();
|
||||
@ -202,9 +270,10 @@ BitrateAllocator::ObserverAllocation BitrateAllocator::LowRateAllocation(
|
||||
LastAllocatedBitrate(observer_config) == 0)
|
||||
continue;
|
||||
|
||||
if (remaining_bitrate >= observer_config.min_bitrate_bps) {
|
||||
allocation[observer_config.observer] = observer_config.min_bitrate_bps;
|
||||
remaining_bitrate -= observer_config.min_bitrate_bps;
|
||||
uint32_t required_bitrate = MinBitrateWithHysteresis(observer_config);
|
||||
if (remaining_bitrate >= required_bitrate) {
|
||||
allocation[observer_config.observer] = required_bitrate;
|
||||
remaining_bitrate -= required_bitrate;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -263,14 +332,11 @@ BitrateAllocator::ObserverAllocation BitrateAllocator::MaxRateAllocation(
|
||||
uint32_t BitrateAllocator::LastAllocatedBitrate(
|
||||
const ObserverConfig& observer_config) {
|
||||
|
||||
const auto& it = last_allocation_.find(observer_config.observer);
|
||||
if (it != last_allocation_.end())
|
||||
return it->second;
|
||||
|
||||
// Return the configured minimum bitrate for newly added observers, to avoid
|
||||
// requiring an extra high bitrate for the observer to get an allocated
|
||||
// bitrate.
|
||||
return observer_config.min_bitrate_bps;
|
||||
return observer_config.allocated_bitrate_bps == -1 ?
|
||||
observer_config.min_bitrate_bps : observer_config.allocated_bitrate_bps;
|
||||
}
|
||||
|
||||
uint32_t BitrateAllocator::MinBitrateWithHysteresis(
|
||||
@ -280,6 +346,15 @@ uint32_t BitrateAllocator::MinBitrateWithHysteresis(
|
||||
min_bitrate += std::max(static_cast<uint32_t>(kToggleFactor * min_bitrate),
|
||||
kMinToggleBitrateBps);
|
||||
}
|
||||
// Account for protection bitrate used by this observer in the previous
|
||||
// allocation.
|
||||
// Note: the ratio will only be updated when the stream is active, meaning a
|
||||
// paused stream won't get any ratio updates. This might lead to waiting a bit
|
||||
// longer than necessary if the network condition improves, but this is to
|
||||
// avoid too much toggling.
|
||||
if (observer_config.media_ratio > 0.0 && observer_config.media_ratio < 1.0)
|
||||
min_bitrate += min_bitrate * (1.0 - observer_config.media_ratio);
|
||||
|
||||
return min_bitrate;
|
||||
}
|
||||
|
||||
|
||||
@ -13,25 +13,28 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class Clock;
|
||||
|
||||
// Used by all send streams with adaptive bitrate, to get the currently
|
||||
// allocated bitrate for the send stream. The current network properties are
|
||||
// given at the same time, to let the send stream decide about possible loss
|
||||
// protection.
|
||||
class BitrateAllocatorObserver {
|
||||
public:
|
||||
virtual void OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) = 0;
|
||||
|
||||
// Returns the amount of protection used by the BitrateAllocatorObserver
|
||||
// implementation, as bitrate in bps.
|
||||
virtual uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) = 0;
|
||||
protected:
|
||||
virtual ~BitrateAllocatorObserver() {}
|
||||
};
|
||||
@ -54,6 +57,7 @@ class BitrateAllocator {
|
||||
};
|
||||
|
||||
explicit BitrateAllocator(LimitObserver* limit_observer);
|
||||
~BitrateAllocator();
|
||||
|
||||
// Allocate target_bitrate across the registered BitrateAllocatorObservers.
|
||||
void OnNetworkChanged(uint32_t target_bitrate_bps,
|
||||
@ -98,20 +102,25 @@ class BitrateAllocator {
|
||||
min_bitrate_bps(min_bitrate_bps),
|
||||
max_bitrate_bps(max_bitrate_bps),
|
||||
pad_up_bitrate_bps(pad_up_bitrate_bps),
|
||||
enforce_min_bitrate(enforce_min_bitrate) {}
|
||||
BitrateAllocatorObserver* const observer;
|
||||
enforce_min_bitrate(enforce_min_bitrate),
|
||||
allocated_bitrate_bps(-1),
|
||||
media_ratio(1.0) {}
|
||||
|
||||
BitrateAllocatorObserver* observer;
|
||||
uint32_t min_bitrate_bps;
|
||||
uint32_t max_bitrate_bps;
|
||||
uint32_t pad_up_bitrate_bps;
|
||||
bool enforce_min_bitrate;
|
||||
int64_t allocated_bitrate_bps;
|
||||
double media_ratio; // Part of the total bitrate used for media [0.0, 1.0].
|
||||
};
|
||||
|
||||
// Calculates the minimum requested send bitrate and max padding bitrate and
|
||||
// calls LimitObserver::OnAllocationLimitsChanged.
|
||||
void UpdateAllocationLimits();
|
||||
|
||||
typedef std::list<ObserverConfig> ObserverConfigList;
|
||||
ObserverConfigList::iterator FindObserverConfig(
|
||||
typedef std::vector<ObserverConfig> ObserverConfigs;
|
||||
ObserverConfigs::iterator FindObserverConfig(
|
||||
const BitrateAllocatorObserver* observer)
|
||||
EXCLUSIVE_LOCKS_REQUIRED(crit_sect_);
|
||||
|
||||
@ -153,12 +162,15 @@ class BitrateAllocator {
|
||||
|
||||
rtc::CriticalSection crit_sect_;
|
||||
// Stored in a list to keep track of the insertion order.
|
||||
ObserverConfigList bitrate_observer_configs_ GUARDED_BY(crit_sect_);
|
||||
ObserverConfigs bitrate_observer_configs_ GUARDED_BY(crit_sect_);
|
||||
uint32_t last_bitrate_bps_ GUARDED_BY(crit_sect_);
|
||||
uint32_t last_non_zero_bitrate_bps_ GUARDED_BY(crit_sect_);
|
||||
uint8_t last_fraction_loss_ GUARDED_BY(crit_sect_);
|
||||
int64_t last_rtt_ GUARDED_BY(crit_sect_);
|
||||
ObserverAllocation last_allocation_ GUARDED_BY(crit_sect_);
|
||||
// Number of mute events based on too low BWE, not network up/down.
|
||||
int num_pause_events_ GUARDED_BY(crit_sect_);
|
||||
Clock* const clock_;
|
||||
int64_t last_bwe_log_time_;
|
||||
};
|
||||
} // namespace webrtc
|
||||
#endif // WEBRTC_CALL_BITRATE_ALLOCATOR_H_
|
||||
|
||||
@ -31,18 +31,27 @@ class MockLimitObserver : public BitrateAllocator::LimitObserver {
|
||||
class TestBitrateObserver : public BitrateAllocatorObserver {
|
||||
public:
|
||||
TestBitrateObserver()
|
||||
: last_bitrate_bps_(0), last_fraction_loss_(0), last_rtt_ms_(0) {}
|
||||
: last_bitrate_bps_(0),
|
||||
last_fraction_loss_(0),
|
||||
last_rtt_ms_(0),
|
||||
protection_ratio_(0.0) {}
|
||||
|
||||
void OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) override {
|
||||
void SetBitrateProtectionRatio(double protection_ratio) {
|
||||
protection_ratio_ = protection_ratio;
|
||||
}
|
||||
|
||||
uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) override {
|
||||
last_bitrate_bps_ = bitrate_bps;
|
||||
last_fraction_loss_ = fraction_loss;
|
||||
last_rtt_ms_ = rtt;
|
||||
return bitrate_bps * protection_ratio_;
|
||||
}
|
||||
uint32_t last_bitrate_bps_;
|
||||
uint8_t last_fraction_loss_;
|
||||
int64_t last_rtt_ms_;
|
||||
double protection_ratio_;
|
||||
};
|
||||
|
||||
class BitrateAllocatorTest : public ::testing::Test {
|
||||
@ -95,44 +104,44 @@ TEST_F(BitrateAllocatorTest, TwoBitrateObserversOneRtcpObserver) {
|
||||
TestBitrateObserver bitrate_observer_1;
|
||||
TestBitrateObserver bitrate_observer_2;
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(100000, 0));
|
||||
allocator_->AddObserver(&bitrate_observer_1, 100000, 300000, 0, true);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||
EXPECT_CALL(limit_observer_,
|
||||
OnAllocationLimitsChanged(100000 + 200000, 0));
|
||||
allocator_->AddObserver(&bitrate_observer_2, 200000, 300000, 0, true);
|
||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||
allocator_->AddObserver(&bitrate_observer_1, 100000, 300000, 0, true);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||
EXPECT_CALL(limit_observer_,
|
||||
OnAllocationLimitsChanged(100000 + 200000, 0));
|
||||
allocator_->AddObserver(&bitrate_observer_2, 200000, 300000, 0, true);
|
||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||
|
||||
// Test too low start bitrate, hence lower than sum of min. Min bitrates
|
||||
// will
|
||||
// be allocated to all observers.
|
||||
allocator_->OnNetworkChanged(200000, 0, 50);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
|
||||
EXPECT_EQ(50, bitrate_observer_1.last_rtt_ms_);
|
||||
EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
|
||||
EXPECT_EQ(50, bitrate_observer_2.last_rtt_ms_);
|
||||
// Test too low start bitrate, hence lower than sum of min. Min bitrates
|
||||
// will
|
||||
// be allocated to all observers.
|
||||
allocator_->OnNetworkChanged(200000, 0, 50);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0, bitrate_observer_1.last_fraction_loss_);
|
||||
EXPECT_EQ(50, bitrate_observer_1.last_rtt_ms_);
|
||||
EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
EXPECT_EQ(0, bitrate_observer_2.last_fraction_loss_);
|
||||
EXPECT_EQ(50, bitrate_observer_2.last_rtt_ms_);
|
||||
|
||||
// Test a bitrate which should be distributed equally.
|
||||
allocator_->OnNetworkChanged(500000, 0, 50);
|
||||
const uint32_t kBitrateToShare = 500000 - 200000 - 100000;
|
||||
EXPECT_EQ(100000u + kBitrateToShare / 2,
|
||||
bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(200000u + kBitrateToShare / 2,
|
||||
bitrate_observer_2.last_bitrate_bps_);
|
||||
// Test a bitrate which should be distributed equally.
|
||||
allocator_->OnNetworkChanged(500000, 0, 50);
|
||||
const uint32_t kBitrateToShare = 500000 - 200000 - 100000;
|
||||
EXPECT_EQ(100000u + kBitrateToShare / 2,
|
||||
bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(200000u + kBitrateToShare / 2,
|
||||
bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
// Limited by 2x max bitrates since we leave room for FEC and
|
||||
// retransmissions.
|
||||
allocator_->OnNetworkChanged(1500000, 0, 50);
|
||||
EXPECT_EQ(600000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(600000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
// Limited by 2x max bitrates since we leave room for FEC and
|
||||
// retransmissions.
|
||||
allocator_->OnNetworkChanged(1500000, 0, 50);
|
||||
EXPECT_EQ(600000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(600000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
// Verify that if the bandwidth estimate is set to zero, the allocated
|
||||
// rate is
|
||||
// zero.
|
||||
allocator_->OnNetworkChanged(0, 0, 50);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
// Verify that if the bandwidth estimate is set to zero, the allocated
|
||||
// rate is
|
||||
// zero.
|
||||
allocator_->OnNetworkChanged(0, 0, 50);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTest, RemoveObserverTriggersLimitObserver) {
|
||||
@ -167,19 +176,19 @@ TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserver) {
|
||||
// Expect OnAllocationLimitsChanged with |min_send_bitrate_bps| = 0 since
|
||||
// AddObserver is called with |enforce_min_bitrate| = false.
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
|
||||
allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||
allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||
|
||||
// High BWE.
|
||||
allocator_->OnNetworkChanged(150000, 0, 0);
|
||||
EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
// High BWE.
|
||||
allocator_->OnNetworkChanged(150000, 0, 0);
|
||||
EXPECT_EQ(150000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
|
||||
// Low BWE.
|
||||
allocator_->OnNetworkChanged(10000, 0, 0);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
// Low BWE.
|
||||
allocator_->OnNetworkChanged(10000, 0, 0);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
|
||||
allocator_->RemoveObserver(&bitrate_observer_1);
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
|
||||
allocator_->RemoveObserver(&bitrate_observer_1);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTestNoEnforceMin, ThreeBitrateObservers) {
|
||||
@ -243,6 +252,100 @@ TEST_F(BitrateAllocatorTestNoEnforceMin, ThreeBitrateObservers) {
|
||||
allocator_->RemoveObserver(&bitrate_observer_3);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTestNoEnforceMin, OneBitrateObserverWithPacketLoss) {
|
||||
TestBitrateObserver bitrate_observer;
|
||||
// Expect OnAllocationLimitsChanged with |min_send_bitrate_bps| = 0 since
|
||||
// AddObserver is called with |enforce_min_bitrate| = false.
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
|
||||
allocator_->AddObserver(
|
||||
&bitrate_observer, 100000, 400000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer));
|
||||
|
||||
// High BWE.
|
||||
allocator_->OnNetworkChanged(150000, 0, 0);
|
||||
EXPECT_EQ(150000u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
// Add loss and use a part of the bitrate for protection.
|
||||
double protection_ratio = 0.4;
|
||||
uint8_t fraction_loss = protection_ratio * 256;
|
||||
bitrate_observer.SetBitrateProtectionRatio(protection_ratio);
|
||||
allocator_->OnNetworkChanged(200000, 0, fraction_loss);
|
||||
EXPECT_EQ(200000u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
// Above the min threshold, but not enough given the protection used.
|
||||
allocator_->OnNetworkChanged(139000, 0, fraction_loss);
|
||||
EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
// Verify the hysteresis is added for the protection.
|
||||
allocator_->OnNetworkChanged(150000, 0, fraction_loss);
|
||||
EXPECT_EQ(0u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
// Just enough to enable video again.
|
||||
allocator_->OnNetworkChanged(168000, 0, fraction_loss);
|
||||
EXPECT_EQ(168000u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
// Remove all protection and make sure video is not paused as earlier.
|
||||
bitrate_observer.SetBitrateProtectionRatio(0.0);
|
||||
allocator_->OnNetworkChanged(140000, 0, 0);
|
||||
EXPECT_EQ(140000u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(139000, 0, 0);
|
||||
EXPECT_EQ(139000u, bitrate_observer.last_bitrate_bps_);
|
||||
|
||||
EXPECT_CALL(limit_observer_, OnAllocationLimitsChanged(0, 0));
|
||||
allocator_->RemoveObserver(&bitrate_observer);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTestNoEnforceMin, TwoBitrateObserverWithPacketLoss) {
|
||||
TestBitrateObserver bitrate_observer_1;
|
||||
TestBitrateObserver bitrate_observer_2;
|
||||
|
||||
allocator_->AddObserver(&bitrate_observer_1, 100000, 400000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_1));
|
||||
allocator_->AddObserver(&bitrate_observer_2, 200000, 400000, 0, false);
|
||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
|
||||
// Enough bitrate for both.
|
||||
bitrate_observer_2.SetBitrateProtectionRatio(0.5);
|
||||
allocator_->OnNetworkChanged(300000, 0, 0);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
// Above min for observer 2, but too little given the protection used.
|
||||
allocator_->OnNetworkChanged(330000, 0, 0);
|
||||
EXPECT_EQ(330000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(100000, 0, 0);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(99999, 0, 0);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(119000, 0, 0);
|
||||
EXPECT_EQ(0u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(120000, 0, 0);
|
||||
EXPECT_EQ(120000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
// Verify the protection is accounted for before resuming observer 2.
|
||||
allocator_->OnNetworkChanged(429000, 0, 0);
|
||||
EXPECT_EQ(400000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(430000, 0, 0);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
EXPECT_EQ(330000u, bitrate_observer_2.last_bitrate_bps_);
|
||||
|
||||
allocator_->RemoveObserver(&bitrate_observer_1);
|
||||
allocator_->RemoveObserver(&bitrate_observer_2);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowBweEnforceMin) {
|
||||
TestBitrateObserver bitrate_observer_1;
|
||||
TestBitrateObserver bitrate_observer_2;
|
||||
@ -255,21 +358,21 @@ TEST_F(BitrateAllocatorTest, ThreeBitrateObserversLowBweEnforceMin) {
|
||||
EXPECT_EQ(200000, allocator_->GetStartBitrate(&bitrate_observer_2));
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_);
|
||||
|
||||
allocator_->AddObserver(&bitrate_observer_3, 300000, 400000, 0, true);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
|
||||
EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
|
||||
EXPECT_EQ(200000, static_cast<int>(bitrate_observer_2.last_bitrate_bps_));
|
||||
allocator_->AddObserver(&bitrate_observer_3, 300000, 400000, 0, true);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&bitrate_observer_3));
|
||||
EXPECT_EQ(100000, static_cast<int>(bitrate_observer_1.last_bitrate_bps_));
|
||||
EXPECT_EQ(200000, static_cast<int>(bitrate_observer_2.last_bitrate_bps_));
|
||||
|
||||
// Low BWE. Verify that all observers still get their respective min
|
||||
// bitrate.
|
||||
allocator_->OnNetworkChanged(1000, 0, 0);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_); // Min cap.
|
||||
EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_); // Min cap.
|
||||
EXPECT_EQ(300000u, bitrate_observer_3.last_bitrate_bps_); // Min cap.
|
||||
// Low BWE. Verify that all observers still get their respective min
|
||||
// bitrate.
|
||||
allocator_->OnNetworkChanged(1000, 0, 0);
|
||||
EXPECT_EQ(100000u, bitrate_observer_1.last_bitrate_bps_); // Min cap.
|
||||
EXPECT_EQ(200000u, bitrate_observer_2.last_bitrate_bps_); // Min cap.
|
||||
EXPECT_EQ(300000u, bitrate_observer_3.last_bitrate_bps_); // Min cap.
|
||||
|
||||
allocator_->RemoveObserver(&bitrate_observer_1);
|
||||
allocator_->RemoveObserver(&bitrate_observer_2);
|
||||
allocator_->RemoveObserver(&bitrate_observer_3);
|
||||
allocator_->RemoveObserver(&bitrate_observer_1);
|
||||
allocator_->RemoveObserver(&bitrate_observer_2);
|
||||
allocator_->RemoveObserver(&bitrate_observer_3);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
|
||||
@ -303,96 +406,96 @@ TEST_F(BitrateAllocatorTest, AddObserverWhileNetworkDown) {
|
||||
|
||||
TEST_F(BitrateAllocatorTest, MixedEnforecedConfigs) {
|
||||
TestBitrateObserver enforced_observer;
|
||||
allocator_->AddObserver(&enforced_observer, 6000, 30000, 0, true);
|
||||
EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));
|
||||
allocator_->AddObserver(&enforced_observer, 6000, 30000, 0, true);
|
||||
EXPECT_EQ(60000, allocator_->GetStartBitrate(&enforced_observer));
|
||||
|
||||
TestBitrateObserver not_enforced_observer;
|
||||
allocator_->AddObserver(¬_enforced_observer, 30000, 2500000, 0, false);
|
||||
EXPECT_EQ(270000, allocator_->GetStartBitrate(¬_enforced_observer));
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
TestBitrateObserver not_enforced_observer;
|
||||
allocator_->AddObserver(¬_enforced_observer, 30000, 2500000, 0, false);
|
||||
EXPECT_EQ(270000, allocator_->GetStartBitrate(¬_enforced_observer));
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(36000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(30000u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(36000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(30000u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(35000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(35000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(5000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(5000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(36000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(36000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(55000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(55000, 0, 50);
|
||||
EXPECT_EQ(30000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(0u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(56000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(50000u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(56000, 0, 50);
|
||||
EXPECT_EQ(6000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(50000u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(56000, 0, 50);
|
||||
EXPECT_EQ(16000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(40000u, not_enforced_observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(56000, 0, 50);
|
||||
EXPECT_EQ(16000u, enforced_observer.last_bitrate_bps_);
|
||||
EXPECT_EQ(40000u, not_enforced_observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->RemoveObserver(&enforced_observer);
|
||||
allocator_->RemoveObserver(¬_enforced_observer);
|
||||
allocator_->RemoveObserver(&enforced_observer);
|
||||
allocator_->RemoveObserver(¬_enforced_observer);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTest, AvoidToggleAbsolute) {
|
||||
TestBitrateObserver observer;
|
||||
allocator_->AddObserver(&observer, 30000, 300000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||
allocator_->AddObserver(&observer, 30000, 300000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(30000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(30000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(20000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(20000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(49000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(49000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(50000, 0, 50);
|
||||
EXPECT_EQ(50000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(50000, 0, 50);
|
||||
EXPECT_EQ(50000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(30000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(30000, 0, 50);
|
||||
EXPECT_EQ(30000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->RemoveObserver(&observer);
|
||||
allocator_->RemoveObserver(&observer);
|
||||
}
|
||||
|
||||
TEST_F(BitrateAllocatorTest, AvoidTogglePercent) {
|
||||
TestBitrateObserver observer;
|
||||
allocator_->AddObserver(&observer, 300000, 600000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||
allocator_->AddObserver(&observer, 300000, 600000, 0, false);
|
||||
EXPECT_EQ(300000, allocator_->GetStartBitrate(&observer));
|
||||
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(300000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(300000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(200000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(200000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(329000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(329000, 0, 50);
|
||||
EXPECT_EQ(0u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(330000, 0, 50);
|
||||
EXPECT_EQ(330000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(330000, 0, 50);
|
||||
EXPECT_EQ(330000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(300000u, observer.last_bitrate_bps_);
|
||||
allocator_->OnNetworkChanged(300000, 0, 50);
|
||||
EXPECT_EQ(300000u, observer.last_bitrate_bps_);
|
||||
|
||||
allocator_->RemoveObserver(&observer);
|
||||
allocator_->RemoveObserver(&observer);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -25,7 +25,7 @@ class FullStackTest : public VideoQualityTest {
|
||||
void ForemanCifWithoutPacketLoss(const std::string& video_codec) {
|
||||
// TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif.
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 700000, 700000, 700000, video_codec, 1},
|
||||
{352, 288, 30, 700000, 700000, 700000, false, video_codec, 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_net_delay_0_0_plr_0_" + video_codec, 0.0, 0.0,
|
||||
@ -35,7 +35,7 @@ class FullStackTest : public VideoQualityTest {
|
||||
|
||||
void ForemanCifPlr5(const std::string& video_codec) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, video_codec, 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, video_codec, 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_delay_50_0_plr_5_" + video_codec, 0.0, 0.0,
|
||||
@ -68,7 +68,7 @@ TEST_F(FullStackTest, ForemanCifPlr5Vp9) {
|
||||
|
||||
TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) {
|
||||
VideoQualityTest::Params paris_qcif = {
|
||||
{176, 144, 30, 300000, 300000, 300000, "VP8", 1},
|
||||
{176, 144, 30, 300000, 300000, 300000, false, "VP8", 1},
|
||||
{"paris_qcif"},
|
||||
{},
|
||||
{"net_delay_0_0_plr_0", 36.0, 0.96, kFullStackTestDurationSecs}};
|
||||
@ -78,7 +78,7 @@ TEST_F(FullStackTest, ParisQcifWithoutPacketLoss) {
|
||||
TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) {
|
||||
// TODO(pbos): Decide on psnr/ssim thresholds for foreman_cif.
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 700000, 700000, 700000, "VP8", 1},
|
||||
{352, 288, 30, 700000, 700000, 700000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_net_delay_0_0_plr_0", 0.0, 0.0, kFullStackTestDurationSecs}
|
||||
@ -88,7 +88,7 @@ TEST_F(FullStackTest, ForemanCifWithoutPacketLoss) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCifPlr5) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_delay_50_0_plr_5", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -99,7 +99,7 @@ TEST_F(FullStackTest, ForemanCifPlr5) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCif500kbps) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_500kbps", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -111,7 +111,7 @@ TEST_F(FullStackTest, ForemanCif500kbps) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCif500kbpsLimitedQueue) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_500kbps_32pkts_queue", 0.0, 0.0, kFullStackTestDurationSecs}
|
||||
@ -124,7 +124,7 @@ TEST_F(FullStackTest, ForemanCif500kbpsLimitedQueue) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCif500kbps100ms) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_500kbps_100ms", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -136,7 +136,7 @@ TEST_F(FullStackTest, ForemanCif500kbps100ms) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 500000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 500000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_500kbps_100ms_32pkts_queue", 0.0, 0.0,
|
||||
@ -149,7 +149,7 @@ TEST_F(FullStackTest, ForemanCif500kbps100msLimitedQueue) {
|
||||
|
||||
TEST_F(FullStackTest, ForemanCif1000kbps100msLimitedQueue) {
|
||||
VideoQualityTest::Params foreman_cif = {
|
||||
{352, 288, 30, 30000, 2000000, 2000000, "VP8", 1},
|
||||
{352, 288, 30, 30000, 2000000, 2000000, false, "VP8", 1},
|
||||
{"foreman_cif"},
|
||||
{},
|
||||
{"foreman_cif_1000kbps_100ms_32pkts_queue", 0.0, 0.0,
|
||||
@ -162,7 +162,7 @@ TEST_F(FullStackTest, ForemanCif1000kbps100msLimitedQueue) {
|
||||
|
||||
TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL) {
|
||||
VideoQualityTest::Params screenshare = {
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, "VP8", 2, 1, 400000},
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, false, "VP8", 2, 1, 400000},
|
||||
{},
|
||||
{true, 10},
|
||||
{"screenshare_slides", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -171,7 +171,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL) {
|
||||
|
||||
TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_Scroll) {
|
||||
VideoQualityTest::Params config = {
|
||||
{1850, 1110 / 2, 5, 50000, 200000, 2000000, "VP8", 2, 1, 400000},
|
||||
{1850, 1110 / 2, 5, 50000, 200000, 2000000, false, "VP8", 2, 1, 400000},
|
||||
{},
|
||||
{true, 10, 2},
|
||||
{"screenshare_slides_scrolling", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -180,7 +180,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_Scroll) {
|
||||
|
||||
TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_LossyNet) {
|
||||
VideoQualityTest::Params screenshare = {
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, "VP8", 2, 1, 400000},
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, false, "VP8", 2, 1, 400000},
|
||||
{}, // Video-specific.
|
||||
{true, 10}, // Screenshare-specific.
|
||||
{"screenshare_slides_lossy_net", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -192,7 +192,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_LossyNet) {
|
||||
|
||||
TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_VeryLossyNet) {
|
||||
VideoQualityTest::Params screenshare = {
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, "VP8", 2, 1, 400000},
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, false, "VP8", 2, 1, 400000},
|
||||
{}, // Video-specific.
|
||||
{true, 10}, // Screenshare-specific.
|
||||
{"screenshare_slides_very_lossy", 0.0, 0.0, kFullStackTestDurationSecs}};
|
||||
@ -205,7 +205,7 @@ TEST_F(FullStackTest, ScreenshareSlidesVP8_2TL_VeryLossyNet) {
|
||||
#if !defined(RTC_DISABLE_VP9)
|
||||
TEST_F(FullStackTest, ScreenshareSlidesVP9_2SL) {
|
||||
VideoQualityTest::Params screenshare = {
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, "VP9", 1, 0, 400000},
|
||||
{1850, 1110, 5, 50000, 200000, 2000000, false, "VP9", 1, 0, 400000},
|
||||
{},
|
||||
{true, 10},
|
||||
{"screenshare_slides_vp9_2sl", 0.0, 0.0, kFullStackTestDurationSecs},
|
||||
|
||||
@ -226,7 +226,7 @@ void Loopback() {
|
||||
VideoQualityTest::Params params{
|
||||
{flags::Width(), flags::Height(), flags::Fps(),
|
||||
flags::MinBitrateKbps() * 1000, flags::TargetBitrateKbps() * 1000,
|
||||
flags::MaxBitrateKbps() * 1000, flags::Codec(),
|
||||
flags::MaxBitrateKbps() * 1000, false, flags::Codec(),
|
||||
flags::NumTemporalLayers(), flags::SelectedTL(),
|
||||
flags::MinTransmitBitrateKbps() * 1000, call_bitrate_config,
|
||||
flags::FLAGS_send_side_bwe},
|
||||
|
||||
@ -56,6 +56,10 @@ int MaxBitrateKbps() {
|
||||
return static_cast<int>(FLAGS_max_bitrate);
|
||||
}
|
||||
|
||||
DEFINE_bool(suspend_below_min_bitrate,
|
||||
false,
|
||||
"Suspends video below the configured min bitrate.");
|
||||
|
||||
DEFINE_int32(num_temporal_layers,
|
||||
1,
|
||||
"Number of temporal layers. Set to 1-4 to override.");
|
||||
@ -223,7 +227,9 @@ void Loopback() {
|
||||
VideoQualityTest::Params params{
|
||||
{flags::Width(), flags::Height(), flags::Fps(),
|
||||
flags::MinBitrateKbps() * 1000, flags::TargetBitrateKbps() * 1000,
|
||||
flags::MaxBitrateKbps() * 1000, flags::Codec(),
|
||||
flags::MaxBitrateKbps() * 1000,
|
||||
flags::FLAGS_suspend_below_min_bitrate,
|
||||
flags::Codec(),
|
||||
flags::NumTemporalLayers(), flags::SelectedTL(),
|
||||
0, // No min transmit bitrate.
|
||||
call_bitrate_config,
|
||||
|
||||
@ -1125,6 +1125,9 @@ void VideoQualityTest::RunWithVideoRenderer(const Params& params) {
|
||||
video_send_config_.local_renderer = local_preview.get();
|
||||
video_receive_configs_[stream_id].renderer = loopback_video.get();
|
||||
|
||||
video_send_config_.suspend_below_min_bitrate =
|
||||
params_.common.suspend_below_min_bitrate;
|
||||
|
||||
if (params.common.fec) {
|
||||
video_send_config_.rtp.fec.red_payload_type = kRedPayloadType;
|
||||
video_send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
|
||||
|
||||
@ -34,6 +34,7 @@ class VideoQualityTest : public test::CallTest {
|
||||
int min_bitrate_bps;
|
||||
int target_bitrate_bps;
|
||||
int max_bitrate_bps;
|
||||
bool suspend_below_min_bitrate;
|
||||
std::string codec;
|
||||
int num_temporal_layers;
|
||||
int selected_tl;
|
||||
|
||||
@ -866,15 +866,18 @@ void VideoSendStream::SignalNetworkState(NetworkState state) {
|
||||
}
|
||||
}
|
||||
|
||||
void VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) {
|
||||
uint32_t VideoSendStream::OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) {
|
||||
payload_router_.SetTargetSendBitrate(bitrate_bps);
|
||||
// Get the encoder target rate. It is the estimated network rate -
|
||||
// protection overhead.
|
||||
uint32_t encoder_target_rate = protection_bitrate_calculator_.SetTargetRates(
|
||||
bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt);
|
||||
vie_encoder_.OnBitrateUpdated(encoder_target_rate, fraction_loss, rtt);
|
||||
uint32_t encoder_target_rate_bps =
|
||||
protection_bitrate_calculator_.SetTargetRates(
|
||||
bitrate_bps, stats_proxy_.GetSendFrameRate(), fraction_loss, rtt);
|
||||
vie_encoder_.OnBitrateUpdated(encoder_target_rate_bps, fraction_loss, rtt);
|
||||
|
||||
return bitrate_bps - encoder_target_rate_bps;
|
||||
}
|
||||
|
||||
int VideoSendStream::ProtectionRequest(const FecProtectionParams* delta_params,
|
||||
|
||||
@ -87,9 +87,9 @@ class VideoSendStream : public webrtc::VideoSendStream,
|
||||
int GetPaddingNeededBps() const;
|
||||
|
||||
// Implements BitrateAllocatorObserver.
|
||||
void OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) override;
|
||||
uint32_t OnBitrateUpdated(uint32_t bitrate_bps,
|
||||
uint8_t fraction_loss,
|
||||
int64_t rtt) override;
|
||||
|
||||
protected:
|
||||
// Implements webrtc::VCMProtectionCallback.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user