Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(458)

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/screenshare_layers.cc

Issue 2491393002: Revert of Issue 2434073003: Extract bitrate allocation ... (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 number_of_temporal_layers_(num_temporal_layers), 58 number_of_temporal_layers_(num_temporal_layers),
59 last_base_layer_sync_(false), 59 last_base_layer_sync_(false),
60 tl0_pic_idx_(initial_tl0_pic_idx), 60 tl0_pic_idx_(initial_tl0_pic_idx),
61 active_layer_(-1), 61 active_layer_(-1),
62 last_timestamp_(-1), 62 last_timestamp_(-1),
63 last_sync_timestamp_(-1), 63 last_sync_timestamp_(-1),
64 last_emitted_tl0_timestamp_(-1), 64 last_emitted_tl0_timestamp_(-1),
65 min_qp_(-1), 65 min_qp_(-1),
66 max_qp_(-1), 66 max_qp_(-1),
67 max_debt_bytes_(0), 67 max_debt_bytes_(0),
68 framerate_(-1), 68 frame_rate_(-1) {
69 bitrate_updated_(false) {
70 RTC_CHECK_GT(num_temporal_layers, 0); 69 RTC_CHECK_GT(num_temporal_layers, 0);
71 RTC_CHECK_LE(num_temporal_layers, 2); 70 RTC_CHECK_LE(num_temporal_layers, 2);
72 } 71 }
73 72
74 ScreenshareLayers::~ScreenshareLayers() { 73 ScreenshareLayers::~ScreenshareLayers() {
75 UpdateHistograms(); 74 UpdateHistograms();
76 } 75 }
77 76
78 int ScreenshareLayers::CurrentLayerId() const { 77 int ScreenshareLayers::CurrentLayerId() const {
79 // Codec does not use temporal layers for screenshare. 78 // Codec does not use temporal layers for screenshare.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 flags = -1; 129 flags = -1;
131 ++stats_.num_dropped_frames_; 130 ++stats_.num_dropped_frames_;
132 break; 131 break;
133 default: 132 default:
134 flags = -1; 133 flags = -1;
135 RTC_NOTREACHED(); 134 RTC_NOTREACHED();
136 } 135 }
137 136
138 int64_t ts_diff; 137 int64_t ts_diff;
139 if (last_timestamp_ == -1) { 138 if (last_timestamp_ == -1) {
140 ts_diff = kOneSecond90Khz / (framerate_ <= 0 ? 5 : framerate_); 139 ts_diff = kOneSecond90Khz / (frame_rate_ <= 0 ? 5 : frame_rate_);
141 } else { 140 } else {
142 ts_diff = unwrapped_timestamp - last_timestamp_; 141 ts_diff = unwrapped_timestamp - last_timestamp_;
143 } 142 }
144 // Make sure both frame droppers leak out bits. 143 // Make sure both frame droppers leak out bits.
145 layers_[0].UpdateDebt(ts_diff / 90); 144 layers_[0].UpdateDebt(ts_diff / 90);
146 layers_[1].UpdateDebt(ts_diff / 90); 145 layers_[1].UpdateDebt(ts_diff / 90);
147 last_timestamp_ = timestamp; 146 last_timestamp_ = timestamp;
148 return flags; 147 return flags;
149 } 148 }
150 149
151 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, 150 bool ScreenshareLayers::ConfigureBitrates(int bitrate_kbps,
152 int max_bitrate_kbps, 151 int max_bitrate_kbps,
153 int framerate) { 152 int framerate,
153 vpx_codec_enc_cfg_t* cfg) {
154 layers_[0].target_rate_kbps_ = bitrate_kbps; 154 layers_[0].target_rate_kbps_ = bitrate_kbps;
155 layers_[1].target_rate_kbps_ = max_bitrate_kbps; 155 layers_[1].target_rate_kbps_ = max_bitrate_kbps;
156 framerate_ = framerate;
157 bitrate_updated_ = true;
158 156
159 std::vector<uint32_t> allocation; 157 int target_bitrate_kbps = bitrate_kbps;
160 allocation.push_back(bitrate_kbps); 158
161 if (max_bitrate_kbps > bitrate_kbps) 159 if (cfg != nullptr) {
162 allocation.push_back(max_bitrate_kbps - bitrate_kbps); 160 if (number_of_temporal_layers_ > 1) {
163 return allocation; 161 // Calculate a codec target bitrate. This may be higher than TL0, gaining
162 // quality at the expense of frame rate at TL0. Constraints:
163 // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction.
164 // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate.
165 target_bitrate_kbps =
166 std::min(bitrate_kbps * kMaxTL0FpsReduction,
167 max_bitrate_kbps / kAcceptableTargetOvershoot);
168
169 cfg->rc_target_bitrate = std::max(bitrate_kbps, target_bitrate_kbps);
170 }
171
172 // Don't reconfigure qp limits during quality boost frames.
173 if (active_layer_ == -1 ||
174 layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) {
175 min_qp_ = cfg->rc_min_quantizer;
176 max_qp_ = cfg->rc_max_quantizer;
177 // After a dropped frame, a frame with max qp will be encoded and the
178 // quality will then ramp up from there. To boost the speed of recovery,
179 // encode the next frame with lower max qp. TL0 is the most important to
180 // improve since the errors in this layer will propagate to TL1.
181 // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
182 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
183 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
184 }
185 }
186
187 int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate);
188 max_debt_bytes_ = 4 * avg_frame_size;
189
190 return true;
164 } 191 }
165 192
166 void ScreenshareLayers::FrameEncoded(unsigned int size, 193 void ScreenshareLayers::FrameEncoded(unsigned int size,
167 uint32_t timestamp, 194 uint32_t timestamp,
168 int qp) { 195 int qp) {
169 if (number_of_temporal_layers_ == 1) 196 if (number_of_temporal_layers_ == 1)
170 return; 197 return;
171 198
172 RTC_DCHECK_NE(-1, active_layer_); 199 RTC_DCHECK_NE(-1, active_layer_);
173 if (size == 0) { 200 if (size == 0) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 return false; 272 return false;
246 } 273 }
247 // Issue a sync frame if difference in quality between TL0 and TL1 isn't too 274 // Issue a sync frame if difference in quality between TL0 and TL1 isn't too
248 // large. 275 // large.
249 if (layers_[0].last_qp - layers_[1].last_qp < kQpDeltaThresholdForSync) 276 if (layers_[0].last_qp - layers_[1].last_qp < kQpDeltaThresholdForSync)
250 return true; 277 return true;
251 return false; 278 return false;
252 } 279 }
253 280
254 bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) { 281 bool ScreenshareLayers::UpdateConfiguration(vpx_codec_enc_cfg_t* cfg) {
255 bool cfg_updated = false;
256 if (bitrate_updated_) {
257 uint32_t target_bitrate_kbps = layers_[0].target_rate_kbps_;
258
259 if (number_of_temporal_layers_ > 1) {
260 // Calculate a codec target bitrate. This may be higher than TL0, gaining
261 // quality at the expense of frame rate at TL0. Constraints:
262 // - TL0 frame rate no less than framerate / kMaxTL0FpsReduction.
263 // - Target rate * kAcceptableTargetOvershoot should not exceed TL1 rate.
264 target_bitrate_kbps =
265 std::min(layers_[0].target_rate_kbps_ * kMaxTL0FpsReduction,
266 layers_[1].target_rate_kbps_ / kAcceptableTargetOvershoot);
267
268 cfg->rc_target_bitrate =
269 std::max(layers_[0].target_rate_kbps_, target_bitrate_kbps);
270 }
271
272 // Don't reconfigure qp limits during quality boost frames.
273 if (active_layer_ == -1 ||
274 layers_[active_layer_].state != TemporalLayer::State::kQualityBoost) {
275 min_qp_ = cfg->rc_min_quantizer;
276 max_qp_ = cfg->rc_max_quantizer;
277 // After a dropped frame, a frame with max qp will be encoded and the
278 // quality will then ramp up from there. To boost the speed of recovery,
279 // encode the next frame with lower max qp. TL0 is the most important to
280 // improve since the errors in this layer will propagate to TL1.
281 // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
282 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
283 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
284 }
285
286 if (framerate_ > 0) {
287 int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate_);
288 max_debt_bytes_ = 4 * avg_frame_size;
289 }
290
291 bitrate_updated_ = false;
292 cfg_updated = true;
293 }
294
295 // Don't try to update boosts state if not active yet.
296 if (active_layer_ == -1)
297 return cfg_updated;
298
299 if (max_qp_ == -1 || number_of_temporal_layers_ <= 1) 282 if (max_qp_ == -1 || number_of_temporal_layers_ <= 1)
300 return cfg_updated; 283 return false;
284 RTC_DCHECK_NE(-1, active_layer_);
301 285
302 // If layer is in the quality boost state (following a dropped frame), update 286 // If layer is in the quality boost state (following a dropped frame), update
303 // the configuration with the adjusted (lower) qp and set the state back to 287 // the configuration with the adjusted (lower) qp and set the state back to
304 // normal. 288 // normal.
305 unsigned int adjusted_max_qp; 289 unsigned int adjusted_max_qp;
306 if (layers_[active_layer_].state == TemporalLayer::State::kQualityBoost && 290 if (layers_[active_layer_].state == TemporalLayer::State::kQualityBoost &&
307 layers_[active_layer_].enhanced_max_qp != -1) { 291 layers_[active_layer_].enhanced_max_qp != -1) {
308 adjusted_max_qp = layers_[active_layer_].enhanced_max_qp; 292 adjusted_max_qp = layers_[active_layer_].enhanced_max_qp;
309 layers_[active_layer_].state = TemporalLayer::State::kNormal; 293 layers_[active_layer_].state = TemporalLayer::State::kNormal;
310 } else { 294 } else {
311 if (max_qp_ == -1) 295 if (max_qp_ == -1)
312 return cfg_updated; 296 return false;
313 adjusted_max_qp = max_qp_; // Set the normal max qp. 297 adjusted_max_qp = max_qp_; // Set the normal max qp.
314 } 298 }
315 299
316 if (adjusted_max_qp == cfg->rc_max_quantizer) 300 if (adjusted_max_qp == cfg->rc_max_quantizer)
317 return cfg_updated; 301 return false;
318 302
319 cfg->rc_max_quantizer = adjusted_max_qp; 303 cfg->rc_max_quantizer = adjusted_max_qp;
320 cfg_updated = true; 304 return true;
321 return cfg_updated;
322 } 305 }
323 306
324 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) { 307 void ScreenshareLayers::TemporalLayer::UpdateDebt(int64_t delta_ms) {
325 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8; 308 uint32_t debt_reduction_bytes = target_rate_kbps_ * delta_ms / 8;
326 if (debt_reduction_bytes >= debt_bytes_) { 309 if (debt_reduction_bytes >= debt_bytes_) {
327 debt_bytes_ = 0; 310 debt_bytes_ = 0;
328 } else { 311 } else {
329 debt_bytes_ -= debt_reduction_bytes; 312 debt_bytes_ -= debt_reduction_bytes;
330 } 313 }
331 } 314 }
(...skipping 30 matching lines...) Expand all
362 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", 345 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp",
363 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); 346 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_);
364 RTC_HISTOGRAM_COUNTS_10000( 347 RTC_HISTOGRAM_COUNTS_10000(
365 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", 348 "WebRTC.Video.Screenshare.Layer1.TargetBitrate",
366 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); 349 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_);
367 } 350 }
368 } 351 }
369 } 352 }
370 353
371 } // namespace webrtc 354 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698