| Index: webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc
 | 
| diff --git a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc
 | 
| index e8214974402f5a6903e4f71b0d3ee64363b531d7..9c7a5b0d27c5c2aab97b025202c924ec73a4f72a 100644
 | 
| --- a/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc
 | 
| +++ b/webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc
 | 
| @@ -65,7 +65,8 @@ ScreenshareLayers::ScreenshareLayers(int num_temporal_layers,
 | 
|        min_qp_(-1),
 | 
|        max_qp_(-1),
 | 
|        max_debt_bytes_(0),
 | 
| -      frame_rate_(-1) {
 | 
| +      framerate_(-1),
 | 
| +      bitrate_updated_(false) {
 | 
|    RTC_CHECK_GT(num_temporal_layers, 0);
 | 
|    RTC_CHECK_LE(num_temporal_layers, 2);
 | 
|  }
 | 
| @@ -136,7 +137,7 @@ int ScreenshareLayers::EncodeFlags(uint32_t timestamp) {
 | 
|  
 | 
|    int64_t ts_diff;
 | 
|    if (last_timestamp_ == -1) {
 | 
| -    ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_);
 | 
| +    ts_diff = kOneSecond90Khz / (framerate_ <= 0 ? 5 : framerate_);
 | 
|    } else {
 | 
|      ts_diff = unwrapped_timestamp - last_timestamp_;
 | 
|    }
 | 
| @@ -147,47 +148,19 @@ int ScreenshareLayers::EncodeFlags(uint32_t timestamp) {
 | 
|    return flags;
 | 
|  }
 | 
|  
 | 
| -bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps,
 | 
| -                                          int max_bitrate_kbps,
 | 
| -                                          int framerate,
 | 
| -                                          vpx_codec_enc_cfg_t* cfg) {
 | 
| +std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps,
 | 
| +                                                        int max_bitrate_kbps,
 | 
| +                                                        int framerate) {
 | 
|    layers_[0].target_rate_kbps_ = bitrate_kbps;
 | 
|    layers_[1].target_rate_kbps_ = max_bitrate_kbps;
 | 
| -
 | 
| -  int target_bitrate_kbps = bitrate_kbps;
 | 
| -
 | 
| -  if (cfg != nullptr) {
 | 
| -    if (number_of_temporal_layers_ > 1) {
 | 
| -      // Calculate a codec target bitrate. This may be higher than TL0, gaining
 | 
| -      // quality at the expense of frame rate at TL0. Constraints:
 | 
| -      // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction.
 | 
| -      // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate.
 | 
| -      target_bitrate_kbps =
 | 
| -          std::min(bitrate_kbps * kMaxTL0FpsReduction,
 | 
| -                   max_bitrate_kbps / kAcceptableTargetOvershoot);
 | 
| -
 | 
| -      cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps);
 | 
| -    }
 | 
| -
 | 
| -    // Don't reconfigure qp limits during quality boost frames.
 | 
| -    if (active_layer_ == -1 ||
 | 
| -        layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) {
 | 
| -      min_qp_ = cfg->rc_min_quantizer;
 | 
| -      max_qp_ = cfg->rc_max_quantizer;
 | 
| -      // After a dropped frame, a frame with max qp will be encoded and the
 | 
| -      // quality will then ramp up from there. To boost the speed of recovery,
 | 
| -      // encode the next frame with lower max qp. TL0 is the most important to
 | 
| -      // improve since the errors in this layer will propagate to TL1.
 | 
| -      // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
 | 
| -      layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
 | 
| -      layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
 | 
| -    }
 | 
| -  }
 | 
| -
 | 
| -  int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate);
 | 
| -  max_debt_bytes_ = 4 * avg_frame_size;
 | 
| -
 | 
| -  return true;
 | 
| +  framerate_ = framerate;
 | 
| +  bitrate_updated_ = true;
 | 
| +
 | 
| +  std::vector<uint32_t> allocation;
 | 
| +  allocation.push_back(bitrate_kbps);
 | 
| +  if (max_bitrate_kbps > bitrate_kbps)
 | 
| +    allocation.push_back(max_bitrate_kbps - bitrate_kbps);
 | 
| +  return allocation;
 | 
|  }
 | 
|  
 | 
|  void ScreenshareLayers::FrameEncoded(unsigned int size,
 | 
| @@ -279,9 +252,52 @@ bool ScreenshareLayers::TimeToSync(int64_t timestamp) const {
 | 
|  }
 | 
|  
 | 
|  bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
 | 
| +  bool cfg_updated = false;
 | 
| +  if (bitrate_updated_) {
 | 
| +    uint32_t target_bitrate_kbps = layers_[0].target_rate_kbps_;
 | 
| +
 | 
| +    if (number_of_temporal_layers_ > 1) {
 | 
| +      // Calculate a codec target bitrate. This may be higher than TL0, gaining
 | 
| +      // quality at the expense of frame rate at TL0. Constraints:
 | 
| +      // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction.
 | 
| +      // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate.
 | 
| +      target_bitrate_kbps =
 | 
| +          std::min(layers_[0].target_rate_kbps_ * kMaxTL0FpsReduction,
 | 
| +                   layers_[1].target_rate_kbps_ / kAcceptableTargetOvershoot);
 | 
| +
 | 
| +      cfg->rc_target_bitrate =
 | 
| +          std::max(layers_[0].target_rate_kbps_, target_bitrate_kbps);
 | 
| +    }
 | 
| +
 | 
| +    // Don't reconfigure qp limits during quality boost frames.
 | 
| +    if (active_layer_ == -1 ||
 | 
| +        layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) {
 | 
| +      min_qp_ = cfg->rc_min_quantizer;
 | 
| +      max_qp_ = cfg->rc_max_quantizer;
 | 
| +      // After a dropped frame, a frame with max qp will be encoded and the
 | 
| +      // quality will then ramp up from there. To boost the speed of recovery,
 | 
| +      // encode the next frame with lower max qp. TL0 is the most important to
 | 
| +      // improve since the errors in this layer will propagate to TL1.
 | 
| +      // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
 | 
| +      layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
 | 
| +      layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
 | 
| +    }
 | 
| +
 | 
| +    if (framerate_ > 0) {
 | 
| +      int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate_);
 | 
| +      max_debt_bytes_ = 4 * avg_frame_size;
 | 
| +    }
 | 
| +
 | 
| +    bitrate_updated_ = false;
 | 
| +    cfg_updated = true;
 | 
| +  }
 | 
| +
 | 
| +  // Don't try to update boosts state if not active yet.
 | 
| +  if (active_layer_ == -1)
 | 
| +    return cfg_updated;
 | 
| +
 | 
|    if (max_qp_ == -1 || number_of_temporal_layers_ <= 1)
 | 
| -    return false;
 | 
| -  RTC_DCHECK_NE(-1, active_layer_);
 | 
| +    return cfg_updated;
 | 
|  
 | 
|    // If layer is in the quality boost state (following a dropped frame), update
 | 
|    // the configuration with the adjusted (lower) qp and set the state back to
 | 
| @@ -293,15 +309,16 @@ bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
 | 
|      layers_[active_layer_].state = TemporalLayer::State::kNormal;
 | 
|    } else {
 | 
|      if (max_qp_ == -1)
 | 
| -      return false;
 | 
| +      return cfg_updated;
 | 
|      adjusted_max_qp = max_qp_;  // Set the normal max qp.
 | 
|    }
 | 
|  
 | 
|    if (adjusted_max_qp == cfg->rc_max_quantizer)
 | 
| -    return false;
 | 
| +    return cfg_updated;
 | 
|  
 | 
|    cfg->rc_max_quantizer = adjusted_max_qp;
 | 
| -  return true;
 | 
| +  cfg_updated = true;
 | 
| +  return cfg_updated;
 | 
|  }
 | 
|  
 | 
|  void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) {
 | 
| 
 |