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

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

Issue 2578993002: Add frame rate throttling to vp8 screenshare_layers. (Closed)
Patch Set: Don't throttle if target framerate is 0 Created 4 years 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 number_of_temporal_layers_(num_temporal_layers), 69 number_of_temporal_layers_(num_temporal_layers),
70 last_base_layer_sync_(false), 70 last_base_layer_sync_(false),
71 tl0_pic_idx_(initial_tl0_pic_idx), 71 tl0_pic_idx_(initial_tl0_pic_idx),
72 active_layer_(-1), 72 active_layer_(-1),
73 last_timestamp_(-1), 73 last_timestamp_(-1),
74 last_sync_timestamp_(-1), 74 last_sync_timestamp_(-1),
75 last_emitted_tl0_timestamp_(-1), 75 last_emitted_tl0_timestamp_(-1),
76 min_qp_(-1), 76 min_qp_(-1),
77 max_qp_(-1), 77 max_qp_(-1),
78 max_debt_bytes_(0), 78 max_debt_bytes_(0),
79 framerate_(-1), 79 encode_framerate_(1000.0f, 1000.0f), // 1 second window, second scale.
80 bitrate_updated_(false) { 80 bitrate_updated_(false) {
81 RTC_CHECK_GT(num_temporal_layers, 0); 81 RTC_CHECK_GT(num_temporal_layers, 0);
82 RTC_CHECK_LE(num_temporal_layers, 2); 82 RTC_CHECK_LE(num_temporal_layers, 2);
83 } 83 }
84 84
85 ScreenshareLayers::~ScreenshareLayers() { 85 ScreenshareLayers::~ScreenshareLayers() {
86 UpdateHistograms(); 86 UpdateHistograms();
87 } 87 }
88 88
89 int ScreenshareLayers::CurrentLayerId() const { 89 int ScreenshareLayers::CurrentLayerId() const {
90 // Codec does not use temporal layers for screenshare. 90 // Codec does not use temporal layers for screenshare.
91 return 0; 91 return 0;
92 } 92 }
93 93
94 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) { 94 int ScreenshareLayers::EncodeFlags(uint32_t timestamp) {
95 if (number_of_temporal_layers_ <= 1) { 95 if (number_of_temporal_layers_ <= 1) {
96 // No flags needed for 1 layer screenshare. 96 // No flags needed for 1 layer screenshare.
97 return 0; 97 return 0;
98 } 98 }
99 99
100 const int64_t now_ms = clock_->TimeInMilliseconds();
101 if (target_framerate_.value_or(0) > 0 &&
102 encode_framerate_.Rate(now_ms).value_or(0) > *target_framerate_) {
103 // Max framerate exceeded, drop frame.
104 return -1;
105 }
106
100 if (stats_.first_frame_time_ms_ == -1) 107 if (stats_.first_frame_time_ms_ == -1)
101 stats_.first_frame_time_ms_ = clock_->TimeInMilliseconds(); 108 stats_.first_frame_time_ms_ = now_ms;
102 109
103 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp); 110 int64_t unwrapped_timestamp = time_wrap_handler_.Unwrap(timestamp);
104 int flags = 0; 111 int flags = 0;
105 if (active_layer_ == -1 || 112 if (active_layer_ == -1 ||
106 layers_[active_layer_].state != TemporalLayer::State::kDropped) { 113 layers_[active_layer_].state != TemporalLayer::State::kDropped) {
107 if (last_emitted_tl0_timestamp_ != -1 && 114 if (last_emitted_tl0_timestamp_ != -1 &&
108 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 > 115 (unwrapped_timestamp - last_emitted_tl0_timestamp_) / 90 >
109 kMaxFrameIntervalMs) { 116 kMaxFrameIntervalMs) {
110 // Too long time has passed since the last frame was emitted, cancel 117 // Too long time has passed since the last frame was emitted, cancel
111 // enough debt to allow a single frame. 118 // enough debt to allow a single frame.
(...skipping 29 matching lines...) Expand all
141 flags = -1; 148 flags = -1;
142 ++stats_.num_dropped_frames_; 149 ++stats_.num_dropped_frames_;
143 break; 150 break;
144 default: 151 default:
145 flags = -1; 152 flags = -1;
146 RTC_NOTREACHED(); 153 RTC_NOTREACHED();
147 } 154 }
148 155
149 int64_t ts_diff; 156 int64_t ts_diff;
150 if (last_timestamp_ == -1) { 157 if (last_timestamp_ == -1) {
151 ts_diff = kOneSecond90Khz / (framerate_ <= 0 ? 5 : framerate_); 158 ts_diff =
159 kOneSecond90Khz / incoming_framerate_.value_or(*target_framerate_);
stefan-webrtc 2016/12/19 10:58:29 Looks like incoming_framerate_ can be zero. I'm pr
sprang_webrtc 2016/12/19 16:46:34 This "shouldn't happen" since we treat 0 fps as in
stefan-webrtc 2016/12/22 09:39:34 Yes, sounds like the check is pretty far away from
sprang_webrtc 2016/12/28 13:00:35 Sure, added dcheck to OnRatesUpdated.
152 } else { 160 } else {
153 ts_diff = unwrapped_timestamp - last_timestamp_; 161 ts_diff = unwrapped_timestamp - last_timestamp_;
154 } 162 }
155 // Make sure both frame droppers leak out bits. 163 // Make sure both frame droppers leak out bits.
156 layers_[0].UpdateDebt(ts_diff / 90); 164 layers_[0].UpdateDebt(ts_diff / 90);
157 layers_[1].UpdateDebt(ts_diff / 90); 165 layers_[1].UpdateDebt(ts_diff / 90);
158 last_timestamp_ = timestamp; 166 last_timestamp_ = timestamp;
159 return flags; 167 return flags;
160 } 168 }
161 169
162 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps, 170 std::vector<uint32_t> ScreenshareLayers::OnRatesUpdated(int bitrate_kbps,
163 int max_bitrate_kbps, 171 int max_bitrate_kbps,
164 int framerate) { 172 int framerate) {
165 bitrate_updated_ = 173 if (!target_framerate_) {
166 bitrate_kbps != static_cast<int>(layers_[0].target_rate_kbps_) || 174 // First OnRatesUpdated() is called during construction, with the configured
167 max_bitrate_kbps != static_cast<int>(layers_[1].target_rate_kbps_) || 175 // targets as parameters.
168 framerate != framerate_; 176 target_framerate_.emplace(framerate);
177 incoming_framerate_ = target_framerate_;
178 bitrate_updated_ = true;
179 } else {
180 bitrate_updated_ =
181 bitrate_kbps != static_cast<int>(layers_[0].target_rate_kbps_) ||
182 max_bitrate_kbps != static_cast<int>(layers_[1].target_rate_kbps_) ||
183 (incoming_framerate_ &&
184 framerate != static_cast<int>(*incoming_framerate_));
185 if (framerate < 0) {
186 incoming_framerate_.reset();
187 } else {
188 incoming_framerate_.emplace(framerate);
189 }
190 }
191
169 layers_[0].target_rate_kbps_ = bitrate_kbps; 192 layers_[0].target_rate_kbps_ = bitrate_kbps;
170 layers_[1].target_rate_kbps_ = max_bitrate_kbps; 193 layers_[1].target_rate_kbps_ = max_bitrate_kbps;
171 framerate_ = framerate;
172 194
173 std::vector<uint32_t> allocation; 195 std::vector<uint32_t> allocation;
174 allocation.push_back(bitrate_kbps); 196 allocation.push_back(bitrate_kbps);
175 if (max_bitrate_kbps > bitrate_kbps) 197 if (max_bitrate_kbps > bitrate_kbps)
176 allocation.push_back(max_bitrate_kbps - bitrate_kbps); 198 allocation.push_back(max_bitrate_kbps - bitrate_kbps);
177 return allocation; 199 return allocation;
178 } 200 }
179 201
180 void ScreenshareLayers::FrameEncoded(unsigned int size, 202 void ScreenshareLayers::FrameEncoded(unsigned int size,
181 uint32_t timestamp, 203 uint32_t timestamp,
182 int qp) { 204 int qp) {
205 if (size > 0)
206 encode_framerate_.Update(1, clock_->TimeInMilliseconds());
207
183 if (number_of_temporal_layers_ == 1) 208 if (number_of_temporal_layers_ == 1)
184 return; 209 return;
185 210
186 RTC_DCHECK_NE(-1, active_layer_); 211 RTC_DCHECK_NE(-1, active_layer_);
187 if (size == 0) { 212 if (size == 0) {
188 layers_[active_layer_].state = TemporalLayer::State::kDropped; 213 layers_[active_layer_].state = TemporalLayer::State::kDropped;
189 ++stats_.num_overshoots_; 214 ++stats_.num_overshoots_;
190 return; 215 return;
191 } 216 }
192 217
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 max_qp_ = cfg->rc_max_quantizer; 319 max_qp_ = cfg->rc_max_quantizer;
295 // After a dropped frame, a frame with max qp will be encoded and the 320 // After a dropped frame, a frame with max qp will be encoded and the
296 // quality will then ramp up from there. To boost the speed of recovery, 321 // quality will then ramp up from there. To boost the speed of recovery,
297 // encode the next frame with lower max qp. TL0 is the most important to 322 // encode the next frame with lower max qp. TL0 is the most important to
298 // improve since the errors in this layer will propagate to TL1. 323 // improve since the errors in this layer will propagate to TL1.
299 // Currently, reduce max qp by 20% for TL0 and 15% for TL1. 324 // Currently, reduce max qp by 20% for TL0 and 15% for TL1.
300 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100); 325 layers_[0].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 80) / 100);
301 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100); 326 layers_[1].enhanced_max_qp = min_qp_ + (((max_qp_ - min_qp_) * 85) / 100);
302 } 327 }
303 328
304 if (framerate_ > 0) { 329 if (incoming_framerate_) {
305 int avg_frame_size = (target_bitrate_kbps * 1000) / (8 * framerate_); 330 int avg_frame_size =
331 (target_bitrate_kbps * 1000) / (8 * *incoming_framerate_);
306 max_debt_bytes_ = 4 * avg_frame_size; 332 max_debt_bytes_ = 4 * avg_frame_size;
307 } 333 }
308 334
309 bitrate_updated_ = false; 335 bitrate_updated_ = false;
310 cfg_updated = true; 336 cfg_updated = true;
311 } 337 }
312 338
313 // Don't try to update boosts state if not active yet. 339 // Don't try to update boosts state if not active yet.
314 if (active_layer_ == -1) 340 if (active_layer_ == -1)
315 return cfg_updated; 341 return cfg_updated;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp", 407 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.Screenshare.Layer1.Qp",
382 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_); 408 stats_.tl1_qp_sum_ / stats_.num_tl1_frames_);
383 RTC_HISTOGRAM_COUNTS_10000( 409 RTC_HISTOGRAM_COUNTS_10000(
384 "WebRTC.Video.Screenshare.Layer1.TargetBitrate", 410 "WebRTC.Video.Screenshare.Layer1.TargetBitrate",
385 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_); 411 stats_.tl1_target_bitrate_sum_ / stats_.num_tl1_frames_);
386 } 412 }
387 } 413 }
388 } 414 }
389 415
390 } // namespace webrtc 416 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698