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 |