Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 1 /* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 2 * | 2 * |
| 3 * Use of this source code is governed by a BSD-style license | 3 * Use of this source code is governed by a BSD-style license |
| 4 * that can be found in the LICENSE file in the root of the source | 4 * that can be found in the LICENSE file in the root of the source |
| 5 * tree. An additional intellectual property rights grant can be found | 5 * tree. An additional intellectual property rights grant can be found |
| 6 * in the file PATENTS. All contributing project authors may | 6 * in the file PATENTS. All contributing project authors may |
| 7 * be found in the AUTHORS file in the root of the source tree. | 7 * be found in the AUTHORS file in the root of the source tree. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" | 10 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 } | 60 } |
| 61 | 61 |
| 62 int ScreenshareLayers::CurrentLayerId() const { | 62 int ScreenshareLayers::CurrentLayerId() const { |
| 63 // Codec does not use temporal layers for screenshare. | 63 // Codec does not use temporal layers for screenshare. |
| 64 return 0; | 64 return 0; |
| 65 } | 65 } |
| 66 | 66 |
| 67 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { | 67 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { |
| 68 if (number_of_temporal_layers_ <= 1) { | 68 if (number_of_temporal_layers_ <= 1) { |
| 69 // No flags needed for 1 layer screenshare. | 69 // No flags needed for 1 layer screenshare. |
| 70 return 0; | 70 return kTl0Flags; |
|
stefan-webrtc
2015/08/04 14:40:28
What does this change mean? That we constrain the
sprang_webrtc
2015/08/04 14:56:06
Yes. This was a hack I did to get overshoot detect
| |
| 71 } | 71 } |
| 72 | 72 |
| 73 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); | 73 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); |
| 74 int flags = 0; | 74 int flags = 0; |
| 75 | 75 |
| 76 if (active_layer_ == -1 || | 76 if (active_layer_ == -1 || |
| 77 layers_[active_layer_].state != TemporalLayer::State::kDropped) { | 77 layers_[active_layer_].state != TemporalLayer::State::kDropped) { |
| 78 if (layers_[0].debt_bytes_ > max_debt_bytes_) { | 78 if (layers_[0].debt_bytes_ > max_debt_bytes_) { |
| 79 // Must drop TL0, encode TL1 instead. | 79 // Must drop TL0, encode TL1 instead. |
| 80 if (layers_[1].debt_bytes_ > max_debt_bytes_) { | 80 if (layers_[1].debt_bytes_ > max_debt_bytes_) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, | 125 bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps, |
| 126 int max_bitrate_kbps, | 126 int max_bitrate_kbps, |
| 127 int framerate, | 127 int framerate, |
| 128 vpx_codec_enc_cfg_t* cfg) { | 128 vpx_codec_enc_cfg_t* cfg) { |
| 129 layers_[0].target_rate_kbps_ = bitrate_kbps; | 129 layers_[0].target_rate_kbps_ = bitrate_kbps; |
| 130 layers_[1].target_rate_kbps_ = max_bitrate_kbps; | 130 layers_[1].target_rate_kbps_ = max_bitrate_kbps; |
| 131 | 131 |
| 132 int target_bitrate_kbps = bitrate_kbps; | 132 int target_bitrate_kbps = bitrate_kbps; |
| 133 | 133 |
| 134 if (cfg != nullptr) { | 134 if (cfg != nullptr) { |
| 135 // Calculate a codec target bitrate. This may be higher than TL0, gaining | 135 if (number_of_temporal_layers_ > 1) { |
| 136 // quality at the expense of frame rate at TL0. Constraints: | 136 // Calculate a codec target bitrate. This may be higher than TL0, gaining |
| 137 // - TL0 frame rate should not be less than framerate / kMaxTL0FpsReduction. | 137 // quality at the expense of frame rate at TL0. Constraints: |
| 138 // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate. | 138 // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction. |
| 139 target_bitrate_kbps = | 139 // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate. |
| 140 std::min(bitrate_kbps * kMaxTL0FpsReduction, | 140 target_bitrate_kbps = |
| 141 max_bitrate_kbps / kAcceptableTargetOvershoot); | 141 std::min(bitrate_kbps * kMaxTL0FpsReduction, |
| 142 max_bitrate_kbps / kAcceptableTargetOvershoot); | |
| 143 | |
| 144 cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps); | |
| 145 } | |
| 142 | 146 |
| 143 // Don't reconfigure qp limits during quality boost frames. | 147 // Don't reconfigure qp limits during quality boost frames. |
| 144 if (layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) { | 148 if (layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) { |
| 145 min_qp_ = cfg->rc_min_quantizer; | 149 min_qp_ = cfg->rc_min_quantizer; |
| 146 max_qp_ = cfg->rc_max_quantizer; | 150 max_qp_ = cfg->rc_max_quantizer; |
| 147 // After a dropped frame, a frame with max qp will be encoded and the | 151 // After a dropped frame, a frame with max qp will be encoded and the |
| 148 // quality will then ramp up from there. To boost the speed of recovery, | 152 // quality will then ramp up from there. To boost the speed of recovery, |
| 149 // encode the next frame with lower max qp. TL0 is the most important to | 153 // encode the next frame with lower max qp. TL0 is the most important to |
| 150 // improve since the errors in this layer will propagate to TL1. | 154 // improve since the errors in this layer will propagate to TL1. |
| 151 // Currently, reduce max qp by 20% for TL0 and 15% for TL1. | 155 // Currently, reduce max qp by 20% for TL0 and 15% for TL1. |
| 152 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100); | 156 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100); |
| 153 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100); | 157 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100); |
| 154 } | 158 } |
| 155 | |
| 156 cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps); | |
| 157 } | 159 } |
| 158 | 160 |
| 159 int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate); | 161 int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate); |
| 160 max_debt_bytes_ = 4 * avg_frame_size; | 162 max_debt_bytes_ = 4 * avg_frame_size; |
| 161 | 163 |
| 162 return true; | 164 return true; |
| 163 } | 165 } |
| 164 | 166 |
| 165 void ScreenshareLayers::FrameEncoded(unsigned int size, | 167 void ScreenshareLayers::FrameEncoded(unsigned int size, |
| 166 uint32_t timestamp, | 168 uint32_t timestamp, |
| 167 int qp) { | 169 int qp) { |
| 168 if (size == 0) { | 170 if (size == 0) { |
| 169 layers_[active_layer_].state = TemporalLayer::State::kDropped; | 171 layers_[active_layer_].state = TemporalLayer::State::kDropped; |
| 170 return; | 172 return; |
| 171 } | 173 } |
| 174 | |
| 172 if (layers_[active_layer_].state == TemporalLayer::State::kDropped) { | 175 if (layers_[active_layer_].state == TemporalLayer::State::kDropped) { |
| 173 layers_[active_layer_].state = TemporalLayer::State::kQualityBoost; | 176 layers_[active_layer_].state = TemporalLayer::State::kQualityBoost; |
| 174 } | 177 } |
| 175 | 178 |
| 176 if (qp != -1) | 179 if (qp != -1) |
| 177 layers_[active_layer_].last_qp = qp; | 180 layers_[active_layer_].last_qp = qp; |
| 178 | 181 |
| 179 if (active_layer_ == 0) { | 182 if (active_layer_ == 0) { |
| 180 layers_[0].debt_bytes_ += size; | 183 layers_[0].debt_bytes_ += size; |
| 181 layers_[1].debt_bytes_ += size; | 184 layers_[1].debt_bytes_ += size; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 return false; | 237 return false; |
| 235 } | 238 } |
| 236 // Issue a sync frame if difference in quality between TL0 and TL1 isn't too | 239 // Issue a sync frame if difference in quality between TL0 and TL1 isn't too |
| 237 // large. | 240 // large. |
| 238 if (layers_[0].last_qp - layers_[1].last_qp < kQpDeltaThresholdForSync) | 241 if (layers_[0].last_qp - layers_[1].last_qp < kQpDeltaThresholdForSync) |
| 239 return true; | 242 return true; |
| 240 return false; | 243 return false; |
| 241 } | 244 } |
| 242 | 245 |
| 243 bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { | 246 bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { |
| 244 if (max_qp_ == -1) | 247 if (max_qp_ == -1 || number_of_temporal_layers_ <= 1) |
| 245 return false; | 248 return false; |
| 246 | 249 |
| 247 // If layer is in the quality boost state (following a dropped frame), update | 250 // If layer is in the quality boost state (following a dropped frame), update |
| 248 // the configuration with the adjusted (lower) qp and set the state back to | 251 // the configuration with the adjusted (lower) qp and set the state back to |
| 249 // normal. | 252 // normal. |
| 250 unsigned int adjusted_max_qp; | 253 unsigned int adjusted_max_qp; |
| 251 if (layers_[active_layer_].state == TemporalLayer::State::kQualityBoost && | 254 if (layers_[active_layer_].state == TemporalLayer::State::kQualityBoost && |
| 252 layers_[active_layer_].enhanced_max_qp != -1) { | 255 layers_[active_layer_].enhanced_max_qp != -1) { |
| 253 adjusted_max_qp = layers_[active_layer_].enhanced_max_qp; | 256 adjusted_max_qp = layers_[active_layer_].enhanced_max_qp; |
| 254 layers_[active_layer_].state = TemporalLayer::State::kNormal; | 257 layers_[active_layer_].state = TemporalLayer::State::kNormal; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 268 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) { | 271 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) { |
| 269 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8; | 272 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8; |
| 270 if (debt_reduction_bytes >= debt_bytes_) { | 273 if (debt_reduction_bytes >= debt_bytes_) { |
| 271 debt_bytes_ = 0; | 274 debt_bytes_ = 0; |
| 272 } else { | 275 } else { |
| 273 debt_bytes_ -= debt_reduction_bytes; | 276 debt_bytes_ -= debt_reduction_bytes; |
| 274 } | 277 } |
| 275 } | 278 } |
| 276 | 279 |
| 277 } // namespace webrtc | 280 } // namespace webrtc |
| OLD | NEW |