Wire the stable target bitrate from GoogCC to the BitrateAllocator

Deprecated the field BitrateAllocationUpdate::link_capacity since it is only
used by the Opus codec in order to smooth the target bitrate, which is
equivalent to the stable_target_bitrate field.

The unused field trial WebRTC-Bwe-StableBandwidthEstimate is also removed.

Bug: webrtc:10126
Change-Id: Ic4a8a9ca4202136d011b91dc23c3a27cfd00d975
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/149839
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Reviewed-by: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28941}
This commit is contained in:
Florent Castelli 2019-08-22 16:09:06 +02:00 committed by Commit Bot
parent 3dd1985fe4
commit 4e615d590a
12 changed files with 62 additions and 61 deletions

View file

@ -27,12 +27,14 @@ struct BitrateAllocationUpdate {
// the target as it is based on the underlying link capacity estimate. This // the target as it is based on the underlying link capacity estimate. This
// should be used to change encoder configuration when the cost of change is // should be used to change encoder configuration when the cost of change is
// high. // high.
DataRate link_capacity = DataRate::Zero(); DataRate stable_target_bitrate = DataRate::Zero();
// Predicted packet loss ratio. // Predicted packet loss ratio.
double packet_loss_ratio = 0; double packet_loss_ratio = 0;
// Predicted round trip time. // Predicted round trip time.
TimeDelta round_trip_time = TimeDelta::PlusInfinity(); TimeDelta round_trip_time = TimeDelta::PlusInfinity();
// |bwe_period| is deprecated, use the link capacity allocation instead. // |link_capacity| is deprecated, use |stable_target_bitrate| instead.
DataRate link_capacity = DataRate::Zero();
// |bwe_period| is deprecated, use |stable_target_bitrate| allocation instead.
TimeDelta bwe_period = TimeDelta::PlusInfinity(); TimeDelta bwe_period = TimeDelta::PlusInfinity();
}; };

View file

@ -202,6 +202,7 @@ struct TargetTransferRate {
// The estimate on which the target rate is based on. // The estimate on which the target rate is based on.
NetworkEstimate network_estimate; NetworkEstimate network_estimate;
DataRate target_rate = DataRate::Zero(); DataRate target_rate = DataRate::Zero();
DataRate stable_target_rate = DataRate::Zero();
}; };
// Contains updates of network controller comand state. Using optionals to // Contains updates of network controller comand state. Using optionals to

View file

@ -53,7 +53,8 @@ double MediaRatio(uint32_t allocated_bitrate, uint32_t protection_bitrate) {
BitrateAllocator::BitrateAllocator(Clock* clock, LimitObserver* limit_observer) BitrateAllocator::BitrateAllocator(Clock* clock, LimitObserver* limit_observer)
: limit_observer_(limit_observer), : limit_observer_(limit_observer),
last_target_bps_(0), last_target_bps_(0),
last_link_capacity_bps_(0), last_stable_target_bps_(0),
last_bandwidth_bps_(0),
last_non_zero_bitrate_bps_(kDefaultBitrateBps), last_non_zero_bitrate_bps_(kDefaultBitrateBps),
last_fraction_loss_(0), last_fraction_loss_(0),
last_rtt_(0), last_rtt_(0),
@ -94,13 +95,15 @@ uint8_t BitrateAllocator::GetTransmissionMaxBitrateMultiplier() {
} }
void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps, void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
uint32_t link_capacity_bps, uint32_t stable_target_bitrate_bps,
uint32_t bandwidth_bps,
uint8_t fraction_loss, uint8_t fraction_loss,
int64_t rtt, int64_t rtt,
int64_t bwe_period_ms) { int64_t bwe_period_ms) {
RTC_DCHECK_RUN_ON(&sequenced_checker_); RTC_DCHECK_RUN_ON(&sequenced_checker_);
last_target_bps_ = target_bitrate_bps; last_target_bps_ = target_bitrate_bps;
last_link_capacity_bps_ = link_capacity_bps; last_bandwidth_bps_ = bandwidth_bps;
last_stable_target_bps_ = stable_target_bitrate_bps;
last_non_zero_bitrate_bps_ = last_non_zero_bitrate_bps_ =
target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_; target_bitrate_bps > 0 ? target_bitrate_bps : last_non_zero_bitrate_bps_;
last_fraction_loss_ = fraction_loss; last_fraction_loss_ = fraction_loss;
@ -115,13 +118,18 @@ void BitrateAllocator::OnNetworkChanged(uint32_t target_bitrate_bps,
} }
ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps); ObserverAllocation allocation = AllocateBitrates(target_bitrate_bps);
ObserverAllocation bandwidth_allocation = AllocateBitrates(link_capacity_bps); ObserverAllocation bandwidth_allocation = AllocateBitrates(bandwidth_bps);
ObserverAllocation stable_bitrate_allocation =
AllocateBitrates(stable_target_bitrate_bps);
for (auto& config : bitrate_observer_configs_) { for (auto& config : bitrate_observer_configs_) {
uint32_t allocated_bitrate = allocation[config.observer]; uint32_t allocated_bitrate = allocation[config.observer];
uint32_t allocated_bandwidth = bandwidth_allocation[config.observer]; uint32_t allocated_bandwidth = bandwidth_allocation[config.observer];
uint32_t allocated_stable_target_rate =
stable_bitrate_allocation[config.observer];
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::bps(allocated_bitrate); update.target_bitrate = DataRate::bps(allocated_bitrate);
update.stable_target_bitrate = DataRate::bps(allocated_stable_target_rate);
update.link_capacity = DataRate::bps(allocated_bandwidth); update.link_capacity = DataRate::bps(allocated_bandwidth);
update.packet_loss_ratio = last_fraction_loss_ / 256.0; update.packet_loss_ratio = last_fraction_loss_ / 256.0;
update.round_trip_time = TimeDelta::ms(last_rtt_); update.round_trip_time = TimeDelta::ms(last_rtt_);
@ -183,12 +191,17 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
ObserverAllocation allocation = AllocateBitrates(last_target_bps_); ObserverAllocation allocation = AllocateBitrates(last_target_bps_);
ObserverAllocation bandwidth_allocation = ObserverAllocation bandwidth_allocation =
AllocateBitrates(last_link_capacity_bps_); AllocateBitrates(last_bandwidth_bps_);
ObserverAllocation stable_bitrate_allocation =
AllocateBitrates(last_stable_target_bps_);
for (auto& config : bitrate_observer_configs_) { for (auto& config : bitrate_observer_configs_) {
uint32_t allocated_bitrate = allocation[config.observer]; uint32_t allocated_bitrate = allocation[config.observer];
uint32_t allocated_stable_bitrate =
stable_bitrate_allocation[config.observer];
uint32_t bandwidth = bandwidth_allocation[config.observer]; uint32_t bandwidth = bandwidth_allocation[config.observer];
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::bps(allocated_bitrate); update.target_bitrate = DataRate::bps(allocated_bitrate);
update.stable_target_bitrate = DataRate::bps(allocated_stable_bitrate);
update.link_capacity = DataRate::bps(bandwidth); update.link_capacity = DataRate::bps(bandwidth);
update.packet_loss_ratio = last_fraction_loss_ / 256.0; update.packet_loss_ratio = last_fraction_loss_ / 256.0;
update.round_trip_time = TimeDelta::ms(last_rtt_); update.round_trip_time = TimeDelta::ms(last_rtt_);
@ -205,6 +218,7 @@ void BitrateAllocator::AddObserver(BitrateAllocatorObserver* observer,
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = DataRate::Zero(); update.target_bitrate = DataRate::Zero();
update.stable_target_bitrate = DataRate::Zero();
update.link_capacity = DataRate::Zero(); update.link_capacity = DataRate::Zero();
update.packet_loss_ratio = last_fraction_loss_ / 256.0; update.packet_loss_ratio = last_fraction_loss_ / 256.0;
update.round_trip_time = TimeDelta::ms(last_rtt_); update.round_trip_time = TimeDelta::ms(last_rtt_);

View file

@ -95,7 +95,8 @@ class BitrateAllocator : public BitrateAllocatorInterface {
// Allocate target_bitrate across the registered BitrateAllocatorObservers. // Allocate target_bitrate across the registered BitrateAllocatorObservers.
void OnNetworkChanged(uint32_t target_bitrate_bps, void OnNetworkChanged(uint32_t target_bitrate_bps,
uint32_t link_capacity_bps, uint32_t stable_target_bitrate_bps,
uint32_t bandwidth_bps,
uint8_t fraction_loss, uint8_t fraction_loss,
int64_t rtt, int64_t rtt,
int64_t bwe_period_ms); int64_t bwe_period_ms);
@ -228,7 +229,8 @@ class BitrateAllocator : public BitrateAllocatorInterface {
// Stored in a list to keep track of the insertion order. // Stored in a list to keep track of the insertion order.
ObserverConfigs bitrate_observer_configs_ RTC_GUARDED_BY(&sequenced_checker_); ObserverConfigs bitrate_observer_configs_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_target_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_stable_target_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_bandwidth_bps_ RTC_GUARDED_BY(&sequenced_checker_);
uint32_t last_non_zero_bitrate_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_); uint8_t last_fraction_loss_ RTC_GUARDED_BY(&sequenced_checker_);
int64_t last_rtt_ RTC_GUARDED_BY(&sequenced_checker_); int64_t last_rtt_ RTC_GUARDED_BY(&sequenced_checker_);

View file

@ -75,7 +75,8 @@ class BitrateAllocatorForTest : public BitrateAllocator {
int64_t rtt, int64_t rtt,
int64_t bwe_period_ms) { int64_t bwe_period_ms) {
BitrateAllocator::OnNetworkChanged(target_bitrate_bps, target_bitrate_bps, BitrateAllocator::OnNetworkChanged(target_bitrate_bps, target_bitrate_bps,
fraction_loss, rtt, bwe_period_ms); target_bitrate_bps, fraction_loss, rtt,
bwe_period_ms);
} }
}; };

View file

@ -1082,15 +1082,16 @@ void Call::OnTargetTransferRate(TargetTransferRate msg) {
int64_t rtt_ms = msg.network_estimate.round_trip_time.ms(); int64_t rtt_ms = msg.network_estimate.round_trip_time.ms();
int64_t probing_interval_ms = msg.network_estimate.bwe_period.ms(); int64_t probing_interval_ms = msg.network_estimate.bwe_period.ms();
uint32_t bandwidth_bps = msg.network_estimate.bandwidth.bps(); uint32_t bandwidth_bps = msg.network_estimate.bandwidth.bps();
uint32_t stable_target_rate_bps = msg.stable_target_rate.bps();
{ {
rtc::CritScope cs(&last_bandwidth_bps_crit_); rtc::CritScope cs(&last_bandwidth_bps_crit_);
last_bandwidth_bps_ = bandwidth_bps; last_bandwidth_bps_ = bandwidth_bps;
} }
// For controlling the rate of feedback messages. // For controlling the rate of feedback messages.
receive_side_cc_.OnBitrateChanged(target_bitrate_bps); receive_side_cc_.OnBitrateChanged(target_bitrate_bps);
bitrate_allocator_->OnNetworkChanged(target_bitrate_bps, bandwidth_bps, bitrate_allocator_->OnNetworkChanged(
fraction_loss, rtt_ms, target_bitrate_bps, stable_target_rate_bps, bandwidth_bps, fraction_loss,
probing_interval_ms); rtt_ms, probing_interval_ms);
// Ignore updates if bitrate is zero (the aggregate network state is down). // Ignore updates if bitrate is zero (the aggregate network state is down).
if (target_bitrate_bps == 0) { if (target_bitrate_bps == 0) {

View file

@ -67,8 +67,6 @@ GoogCcNetworkController::GoogCcNetworkController(NetworkControllerConfig config,
packet_feedback_only_(goog_cc_config.feedback_only), packet_feedback_only_(goog_cc_config.feedback_only),
safe_reset_on_route_change_("Enabled"), safe_reset_on_route_change_("Enabled"),
safe_reset_acknowledged_rate_("ack"), safe_reset_acknowledged_rate_("ack"),
use_stable_bandwidth_estimate_(
IsEnabled(key_value_config_, "WebRTC-Bwe-StableBandwidthEstimate")),
use_downlink_delay_for_congestion_window_( use_downlink_delay_for_congestion_window_(
IsEnabled(key_value_config_, IsEnabled(key_value_config_,
"WebRTC-Bwe-CongestionWindowDownlinkDelay")), "WebRTC-Bwe-CongestionWindowDownlinkDelay")),
@ -571,14 +569,11 @@ NetworkControlUpdate GoogCcNetworkController::OnNetworkStateEstimate(
NetworkControlUpdate GoogCcNetworkController::GetNetworkState( NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
Timestamp at_time) const { Timestamp at_time) const {
DataRate bandwidth = use_stable_bandwidth_estimate_
? bandwidth_estimation_->GetEstimatedLinkCapacity()
: last_raw_target_rate_;
TimeDelta rtt = TimeDelta::ms(last_estimated_rtt_ms_); TimeDelta rtt = TimeDelta::ms(last_estimated_rtt_ms_);
NetworkControlUpdate update; NetworkControlUpdate update;
update.target_rate = TargetTransferRate(); update.target_rate = TargetTransferRate();
update.target_rate->network_estimate.at_time = at_time; update.target_rate->network_estimate.at_time = at_time;
update.target_rate->network_estimate.bandwidth = bandwidth; update.target_rate->network_estimate.bandwidth = last_raw_target_rate_;
update.target_rate->network_estimate.loss_rate_ratio = update.target_rate->network_estimate.loss_rate_ratio =
last_estimated_fraction_loss_ / 255.0; last_estimated_fraction_loss_ / 255.0;
update.target_rate->network_estimate.round_trip_time = rtt; update.target_rate->network_estimate.round_trip_time = rtt;
@ -586,7 +581,9 @@ NetworkControlUpdate GoogCcNetworkController::GetNetworkState(
delay_based_bwe_->GetExpectedBwePeriod(); delay_based_bwe_->GetExpectedBwePeriod();
update.target_rate->at_time = at_time; update.target_rate->at_time = at_time;
update.target_rate->target_rate = bandwidth; update.target_rate->target_rate = last_raw_target_rate_;
update.target_rate->stable_target_rate =
bandwidth_estimation_->GetEstimatedLinkCapacity();
update.pacer_config = GetPacingRates(at_time); update.pacer_config = GetPacingRates(at_time);
update.congestion_window = current_data_window_; update.congestion_window = current_data_window_;
return update; return update;
@ -629,18 +626,17 @@ void GoogCcNetworkController::MaybeTriggerOnNetworkChanged(
alr_detector_->SetEstimatedBitrate(estimated_bitrate_bps); alr_detector_->SetEstimatedBitrate(estimated_bitrate_bps);
last_raw_target_rate_ = DataRate::bps(estimated_bitrate_bps); last_raw_target_rate_ = DataRate::bps(estimated_bitrate_bps);
DataRate bandwidth = use_stable_bandwidth_estimate_
? bandwidth_estimation_->GetEstimatedLinkCapacity()
: last_raw_target_rate_;
TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod(); TimeDelta bwe_period = delay_based_bwe_->GetExpectedBwePeriod();
TargetTransferRate target_rate_msg; TargetTransferRate target_rate_msg;
target_rate_msg.at_time = at_time; target_rate_msg.at_time = at_time;
target_rate_msg.target_rate = target_rate; target_rate_msg.target_rate = target_rate;
target_rate_msg.stable_target_rate =
bandwidth_estimation_->GetEstimatedLinkCapacity();
target_rate_msg.network_estimate.at_time = at_time; target_rate_msg.network_estimate.at_time = at_time;
target_rate_msg.network_estimate.round_trip_time = TimeDelta::ms(rtt_ms); target_rate_msg.network_estimate.round_trip_time = TimeDelta::ms(rtt_ms);
target_rate_msg.network_estimate.bandwidth = bandwidth; target_rate_msg.network_estimate.bandwidth = last_raw_target_rate_;
target_rate_msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0f; target_rate_msg.network_estimate.loss_rate_ratio = fraction_loss / 255.0f;
target_rate_msg.network_estimate.bwe_period = bwe_period; target_rate_msg.network_estimate.bwe_period = bwe_period;

View file

@ -85,7 +85,6 @@ class GoogCcNetworkController : public NetworkControllerInterface {
const bool packet_feedback_only_; const bool packet_feedback_only_;
FieldTrialFlag safe_reset_on_route_change_; FieldTrialFlag safe_reset_on_route_change_;
FieldTrialFlag safe_reset_acknowledged_rate_; FieldTrialFlag safe_reset_acknowledged_rate_;
const bool use_stable_bandwidth_estimate_;
const bool use_downlink_delay_for_congestion_window_; const bool use_downlink_delay_for_congestion_window_;
const bool fall_back_to_probe_rate_; const bool fall_back_to_probe_rate_;
const bool use_min_allocatable_as_lower_bound_; const bool use_min_allocatable_as_lower_bound_;

View file

@ -487,37 +487,9 @@ TEST_F(GoogCcNetworkControllerTest, UpdatesTargetRateBasedOnLinkCapacity) {
UpdatesTargetRateBasedOnLinkCapacity(); UpdatesTargetRateBasedOnLinkCapacity();
} }
TEST_F(GoogCcNetworkControllerTest, DefaultEstimateVariesInSteadyState) {
auto factory = CreateFeedbackOnlyFactory();
ScopedFieldTrials trial("WebRTC-Bwe-StableBandwidthEstimate/Disabled/");
Scenario s("googcc_unit/no_stable_varies", false);
CallClientConfig config;
config.transport.cc_factory = &factory;
NetworkSimulationConfig net_conf;
net_conf.bandwidth = DataRate::kbps(500);
net_conf.delay = TimeDelta::ms(100);
auto send_net = s.CreateSimulationNode(net_conf);
auto ret_net = s.CreateSimulationNode(net_conf);
auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net});
// Run for a while to allow the estimate to stabilize.
s.RunFor(TimeDelta::seconds(20));
DataRate min_estimate = DataRate::PlusInfinity();
DataRate max_estimate = DataRate::MinusInfinity();
// Measure variation in steady state.
for (int i = 0; i < 20; ++i) {
min_estimate = std::min(min_estimate, client->link_capacity());
max_estimate = std::max(max_estimate, client->link_capacity());
s.RunFor(TimeDelta::seconds(1));
}
// We should expect drops by at least 15% (default backoff.)
EXPECT_LT(min_estimate / max_estimate, 0.85);
}
TEST_F(GoogCcNetworkControllerTest, StableEstimateDoesNotVaryInSteadyState) { TEST_F(GoogCcNetworkControllerTest, StableEstimateDoesNotVaryInSteadyState) {
auto factory = CreateFeedbackOnlyFactory(); auto factory = CreateFeedbackOnlyFactory();
ScopedFieldTrials trial("WebRTC-Bwe-StableBandwidthEstimate/Enabled/"); Scenario s("googcc_unit/stable_target", false);
Scenario s("googcc_unit/stable_is_stable", false);
CallClientConfig config; CallClientConfig config;
config.transport.cc_factory = &factory; config.transport.cc_factory = &factory;
NetworkSimulationConfig net_conf; NetworkSimulationConfig net_conf;
@ -529,16 +501,25 @@ TEST_F(GoogCcNetworkControllerTest, StableEstimateDoesNotVaryInSteadyState) {
auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net}); auto* client = CreateVideoSendingClient(&s, config, {send_net}, {ret_net});
// Run for a while to allow the estimate to stabilize. // Run for a while to allow the estimate to stabilize.
s.RunFor(TimeDelta::seconds(30)); s.RunFor(TimeDelta::seconds(30));
DataRate min_estimate = DataRate::PlusInfinity(); DataRate min_stable_target = DataRate::PlusInfinity();
DataRate max_estimate = DataRate::MinusInfinity(); DataRate max_stable_target = DataRate::MinusInfinity();
DataRate min_target = DataRate::PlusInfinity();
DataRate max_target = DataRate::MinusInfinity();
// Measure variation in steady state. // Measure variation in steady state.
for (int i = 0; i < 20; ++i) { for (int i = 0; i < 20; ++i) {
min_estimate = std::min(min_estimate, client->link_capacity()); min_stable_target =
max_estimate = std::max(max_estimate, client->link_capacity()); std::min(min_stable_target, client->stable_target_rate());
max_stable_target =
std::max(max_stable_target, client->stable_target_rate());
min_target = std::min(min_target, client->link_capacity());
max_target = std::max(max_target, client->link_capacity());
s.RunFor(TimeDelta::seconds(1)); s.RunFor(TimeDelta::seconds(1));
} }
// We expect no variation under the trial in steady state. // We expect no variation under the trial in steady state.
EXPECT_GT(min_estimate / max_estimate, 0.95); EXPECT_GT(min_stable_target / max_stable_target, 0.95);
// We should expect drops by at least 15% (default backoff.)
EXPECT_LT(min_target / max_target, 0.85);
} }
TEST_F(GoogCcNetworkControllerTest, TEST_F(GoogCcNetworkControllerTest,

View file

@ -256,6 +256,11 @@ DataRate CallClient::link_capacity() const {
.target_rate->network_estimate.bandwidth; .target_rate->network_estimate.bandwidth;
} }
DataRate CallClient::stable_target_rate() const {
return network_controller_factory_.GetUpdate()
.target_rate->stable_target_rate;
}
DataRate CallClient::padding_rate() const { DataRate CallClient::padding_rate() const {
return network_controller_factory_.GetUpdate().pacer_config->pad_rate(); return network_controller_factory_.GetUpdate().pacer_config->pad_rate();
} }

View file

@ -107,6 +107,7 @@ class CallClient : public EmulatedNetworkReceiverInterface {
return DataRate::bps(GetStats().send_bandwidth_bps); return DataRate::bps(GetStats().send_bandwidth_bps);
} }
DataRate target_rate() const; DataRate target_rate() const;
DataRate stable_target_rate() const;
DataRate link_capacity() const; DataRate link_capacity() const;
DataRate padding_rate() const; DataRate padding_rate() const;

View file

@ -659,7 +659,6 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
DataRate::bps(qvga_stream.target_bitrate_bps); DataRate::bps(qvga_stream.target_bitrate_bps);
BitrateAllocationUpdate update; BitrateAllocationUpdate update;
update.target_bitrate = network_constrained_rate; update.target_bitrate = network_constrained_rate;
update.link_capacity = network_constrained_rate;
update.round_trip_time = TimeDelta::ms(1); update.round_trip_time = TimeDelta::ms(1);
EXPECT_CALL(rtp_video_sender_, EXPECT_CALL(rtp_video_sender_,
OnBitrateUpdated(network_constrained_rate.bps(), _, OnBitrateUpdated(network_constrained_rate.bps(), _,
@ -686,7 +685,6 @@ TEST_F(VideoSendStreamImplTest, CallsVideoStreamEncoderOnBitrateUpdate) {
EXPECT_CALL(video_stream_encoder_, EXPECT_CALL(video_stream_encoder_,
OnBitrateUpdated(qvga_max_bitrate, rate_with_headroom, 0, _)); OnBitrateUpdated(qvga_max_bitrate, rate_with_headroom, 0, _));
update.target_bitrate = rate_with_headroom; update.target_bitrate = rate_with_headroom;
update.link_capacity = rate_with_headroom;
static_cast<BitrateAllocatorObserver*>(vss_impl.get()) static_cast<BitrateAllocatorObserver*>(vss_impl.get())
->OnBitrateUpdated(update); ->OnBitrateUpdated(update);