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

Side by Side Diff: webrtc/video/vie_encoder.cc

Issue 2789823002: Reland of Add framerate to VideoSinkWants and ability to signal on overuse (Closed)
Patch Set: Rebase fix Created 3 years, 8 months 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
« no previous file with comments | « webrtc/video/vie_encoder.h ('k') | webrtc/video/vie_encoder_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/video/vie_encoder.h" 11 #include "webrtc/video/vie_encoder.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <limits> 14 #include <limits>
15 #include <numeric>
15 #include <utility> 16 #include <utility>
16 17
17 #include "webrtc/base/arraysize.h" 18 #include "webrtc/base/arraysize.h"
18 #include "webrtc/base/checks.h" 19 #include "webrtc/base/checks.h"
19 #include "webrtc/base/location.h" 20 #include "webrtc/base/location.h"
20 #include "webrtc/base/logging.h" 21 #include "webrtc/base/logging.h"
21 #include "webrtc/base/timeutils.h" 22 #include "webrtc/base/timeutils.h"
22 #include "webrtc/base/trace_event.h" 23 #include "webrtc/base/trace_event.h"
23 #include "webrtc/common_video/include/video_bitrate_allocator.h" 24 #include "webrtc/common_video/include/video_bitrate_allocator.h"
24 #include "webrtc/modules/pacing/paced_sender.h" 25 #include "webrtc/modules/pacing/paced_sender.h"
(...skipping 10 matching lines...) Expand all
35 using DegradationPreference = VideoSendStream::DegradationPreference; 36 using DegradationPreference = VideoSendStream::DegradationPreference;
36 37
37 // Time interval for logging frame counts. 38 // Time interval for logging frame counts.
38 const int64_t kFrameLogIntervalMs = 60000; 39 const int64_t kFrameLogIntervalMs = 60000;
39 40
40 // We will never ask for a resolution lower than this. 41 // We will never ask for a resolution lower than this.
41 // TODO(kthelgason): Lower this limit when better testing 42 // TODO(kthelgason): Lower this limit when better testing
42 // on MediaCodec and fallback implementations are in place. 43 // on MediaCodec and fallback implementations are in place.
43 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206 44 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206
44 const int kMinPixelsPerFrame = 320 * 180; 45 const int kMinPixelsPerFrame = 320 * 180;
46 const int kMinFramerateFps = 2;
45 47
46 // The maximum number of frames to drop at beginning of stream 48 // The maximum number of frames to drop at beginning of stream
47 // to try and achieve desired bitrate. 49 // to try and achieve desired bitrate.
48 const int kMaxInitialFramedrop = 4; 50 const int kMaxInitialFramedrop = 4;
49 51
50 // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle 52 // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle
51 // pipelining encoders better (multiple input frames before something comes 53 // pipelining encoders better (multiple input frames before something comes
52 // out). This should effectively turn off CPU adaptations for systems that 54 // out). This should effectively turn off CPU adaptations for systems that
53 // remotely cope with the load right now. 55 // remotely cope with the load right now.
54 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { 56 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 }; 145 };
144 146
145 // VideoSourceProxy is responsible ensuring thread safety between calls to 147 // VideoSourceProxy is responsible ensuring thread safety between calls to
146 // ViEEncoder::SetSource that will happen on libjingle's worker thread when a 148 // ViEEncoder::SetSource that will happen on libjingle's worker thread when a
147 // video capturer is connected to the encoder and the encoder task queue 149 // video capturer is connected to the encoder and the encoder task queue
148 // (encoder_queue_) where the encoder reports its VideoSinkWants. 150 // (encoder_queue_) where the encoder reports its VideoSinkWants.
149 class ViEEncoder::VideoSourceProxy { 151 class ViEEncoder::VideoSourceProxy {
150 public: 152 public:
151 explicit VideoSourceProxy(ViEEncoder* vie_encoder) 153 explicit VideoSourceProxy(ViEEncoder* vie_encoder)
152 : vie_encoder_(vie_encoder), 154 : vie_encoder_(vie_encoder),
153 degradation_preference_(DegradationPreference::kMaintainResolution), 155 degradation_preference_(DegradationPreference::kDegradationDisabled),
154 source_(nullptr) {} 156 source_(nullptr) {}
155 157
156 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source, 158 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source,
157 const DegradationPreference& degradation_preference) { 159 const DegradationPreference& degradation_preference) {
158 // Called on libjingle's worker thread. 160 // Called on libjingle's worker thread.
159 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); 161 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_);
160 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; 162 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr;
161 rtc::VideoSinkWants wants; 163 rtc::VideoSinkWants wants;
162 { 164 {
163 rtc::CritScope lock(&crit_); 165 rtc::CritScope lock(&crit_);
166 degradation_preference_ = degradation_preference;
164 old_source = source_; 167 old_source = source_;
165 source_ = source; 168 source_ = source;
166 degradation_preference_ = degradation_preference; 169 wants = GetActiveSinkWants();
167 wants = current_wants();
168 } 170 }
169 171
170 if (old_source != source && old_source != nullptr) { 172 if (old_source != source && old_source != nullptr) {
171 old_source->RemoveSink(vie_encoder_); 173 old_source->RemoveSink(vie_encoder_);
172 } 174 }
173 175
174 if (!source) { 176 if (!source) {
175 return; 177 return;
176 } 178 }
177 179
178 source->AddOrUpdateSink(vie_encoder_, wants); 180 source->AddOrUpdateSink(vie_encoder_, wants);
179 } 181 }
180 182
181 void SetWantsRotationApplied(bool rotation_applied) { 183 void SetWantsRotationApplied(bool rotation_applied) {
182 rtc::CritScope lock(&crit_); 184 rtc::CritScope lock(&crit_);
183 sink_wants_.rotation_applied = rotation_applied; 185 sink_wants_.rotation_applied = rotation_applied;
184 disabled_scaling_sink_wants_.rotation_applied = rotation_applied; 186 if (source_)
185 if (source_) { 187 source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
186 source_->AddOrUpdateSink(vie_encoder_, current_wants()); 188 }
189
190 rtc::VideoSinkWants GetActiveSinkWants() EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
191 rtc::VideoSinkWants wants = sink_wants_;
192 // Clear any constraints from the current sink wants that don't apply to
193 // the used degradation_preference.
194 switch (degradation_preference_) {
195 case DegradationPreference::kBalanced:
196 FALLTHROUGH();
197 case DegradationPreference::kMaintainFramerate:
198 wants.max_framerate_fps = std::numeric_limits<int>::max();
199 break;
200 case DegradationPreference::kMaintainResolution:
201 wants.max_pixel_count = std::numeric_limits<int>::max();
202 wants.target_pixel_count.reset();
203 break;
204 case DegradationPreference::kDegradationDisabled:
205 wants.max_pixel_count = std::numeric_limits<int>::max();
206 wants.target_pixel_count.reset();
207 wants.max_framerate_fps = std::numeric_limits<int>::max();
187 } 208 }
209 return wants;
188 } 210 }
189 211
190 void RequestResolutionLowerThan(int pixel_count) { 212 void RequestResolutionLowerThan(int pixel_count) {
191 // Called on the encoder task queue. 213 // Called on the encoder task queue.
192 rtc::CritScope lock(&crit_); 214 rtc::CritScope lock(&crit_);
193 if (!IsResolutionScalingEnabledLocked()) { 215 if (!IsResolutionScalingEnabledLocked()) {
194 // This can happen since |degradation_preference_| is set on 216 // This can happen since |degradation_preference_| is set on
195 // libjingle's worker thread but the adaptation is done on the encoder 217 // libjingle's worker thread but the adaptation is done on the encoder
196 // task queue. 218 // task queue.
197 return; 219 return;
198 } 220 }
199 // The input video frame size will have a resolution with less than or 221 // The input video frame size will have a resolution with less than or
200 // equal to |max_pixel_count| depending on how the source can scale the 222 // equal to |max_pixel_count| depending on how the source can scale the
201 // input frame size. 223 // input frame size.
202 const int pixels_wanted = (pixel_count * 3) / 5; 224 const int pixels_wanted = (pixel_count * 3) / 5;
203 if (pixels_wanted < kMinPixelsPerFrame) 225 if (pixels_wanted < kMinPixelsPerFrame)
204 return; 226 return;
205 sink_wants_.max_pixel_count = rtc::Optional<int>(pixels_wanted); 227 sink_wants_.max_pixel_count = pixels_wanted;
206 sink_wants_.target_pixel_count = rtc::Optional<int>(); 228 sink_wants_.target_pixel_count = rtc::Optional<int>();
207 if (source_) 229 if (source_)
208 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); 230 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
231 }
232
233 void RequestFramerateLowerThan(int framerate_fps) {
234 // Called on the encoder task queue.
235 rtc::CritScope lock(&crit_);
236 if (!IsFramerateScalingEnabledLocked()) {
237 // This can happen since |degradation_preference_| is set on
238 // libjingle's worker thread but the adaptation is done on the encoder
239 // task queue.
240 return;
241 }
242 // The input video frame rate will be scaled down to 2/3 of input fps,
243 // rounding down.
244 const int framerate_wanted =
245 std::max(kMinFramerateFps, (framerate_fps * 2) / 3);
246 sink_wants_.max_framerate_fps = framerate_wanted;
247 if (source_)
248 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
209 } 249 }
210 250
211 void RequestHigherResolutionThan(int pixel_count) { 251 void RequestHigherResolutionThan(int pixel_count) {
212 rtc::CritScope lock(&crit_); 252 rtc::CritScope lock(&crit_);
213 if (!IsResolutionScalingEnabledLocked()) { 253 if (!IsResolutionScalingEnabledLocked()) {
214 // This can happen since |degradation_preference_| is set on 254 // This can happen since |degradation_preference_| is set on
215 // libjingle's worker thread but the adaptation is done on the encoder 255 // libjingle's worker thread but the adaptation is done on the encoder
216 // task queue. 256 // task queue.
217 return; 257 return;
218 } 258 }
219 // On step down we request at most 3/5 the pixel count of the previous 259
220 // resolution, so in order to take "one step up" we request a resolution as 260 if (pixel_count == std::numeric_limits<int>::max()) {
221 // close as possible to 5/3 of the current resolution. The actual pixel 261 // Remove any constraints.
222 // count selected depends on the capabilities of the source. In order to not 262 sink_wants_.target_pixel_count.reset();
223 // take a too large step up, we cap the requested pixel count to be at most 263 sink_wants_.max_pixel_count = std::numeric_limits<int>::max();
224 // four time the current number of pixels. 264 } else {
225 sink_wants_.target_pixel_count = rtc::Optional<int>((pixel_count * 5) / 3); 265 // On step down we request at most 3/5 the pixel count of the previous
226 sink_wants_.max_pixel_count = rtc::Optional<int>(pixel_count * 4); 266 // resolution, so in order to take "one step up" we request a resolution
267 // as close as possible to 5/3 of the current resolution. The actual pixel
268 // count selected depends on the capabilities of the source. In order to
269 // not take a too large step up, we cap the requested pixel count to be at
270 // most four time the current number of pixels.
271 sink_wants_.target_pixel_count =
272 rtc::Optional<int>((pixel_count * 5) / 3);
273 sink_wants_.max_pixel_count = pixel_count * 4;
274 }
227 if (source_) 275 if (source_)
228 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); 276 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
277 }
278
279 void RequestHigherFramerateThan(int framerate_fps) {
280 // Called on the encoder task queue.
281 rtc::CritScope lock(&crit_);
282 if (!IsFramerateScalingEnabledLocked()) {
283 // This can happen since |degradation_preference_| is set on
284 // libjingle's worker thread but the adaptation is done on the encoder
285 // task queue.
286 return;
287 }
288 if (framerate_fps == std::numeric_limits<int>::max()) {
289 // Remove any restrains.
290 sink_wants_.max_framerate_fps = std::numeric_limits<int>::max();
291 } else {
292 // The input video frame rate will be scaled up to the last step, with
293 // rounding.
294 const int framerate_wanted = (framerate_fps * 3) / 2;
295 sink_wants_.max_framerate_fps = framerate_wanted;
296 }
297 if (source_)
298 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
229 } 299 }
230 300
231 private: 301 private:
232 bool IsResolutionScalingEnabledLocked() const 302 bool IsResolutionScalingEnabledLocked() const
233 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { 303 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
234 return degradation_preference_ != 304 return degradation_preference_ ==
235 DegradationPreference::kMaintainResolution; 305 DegradationPreference::kMaintainFramerate ||
306 degradation_preference_ == DegradationPreference::kBalanced;
236 } 307 }
237 308
238 const rtc::VideoSinkWants& current_wants() const 309 bool IsFramerateScalingEnabledLocked() const
239 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { 310 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
240 return IsResolutionScalingEnabledLocked() ? sink_wants_ 311 // TODO(sprang): Also accept kBalanced here?
241 : disabled_scaling_sink_wants_; 312 return degradation_preference_ ==
313 DegradationPreference::kMaintainResolution;
242 } 314 }
243 315
244 rtc::CriticalSection crit_; 316 rtc::CriticalSection crit_;
245 rtc::SequencedTaskChecker main_checker_; 317 rtc::SequencedTaskChecker main_checker_;
246 ViEEncoder* const vie_encoder_; 318 ViEEncoder* const vie_encoder_;
247 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); 319 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_);
248 rtc::VideoSinkWants disabled_scaling_sink_wants_ GUARDED_BY(&crit_);
249 DegradationPreference degradation_preference_ GUARDED_BY(&crit_); 320 DegradationPreference degradation_preference_ GUARDED_BY(&crit_);
250 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); 321 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_);
251 322
252 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); 323 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy);
253 }; 324 };
254 325
255 ViEEncoder::ViEEncoder(uint32_t number_of_cores, 326 ViEEncoder::ViEEncoder(uint32_t number_of_cores,
256 SendStatisticsProxy* stats_proxy, 327 SendStatisticsProxy* stats_proxy,
257 const VideoSendStream::Config::EncoderSettings& settings, 328 const VideoSendStream::Config::EncoderSettings& settings,
258 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, 329 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback,
(...skipping 14 matching lines...) Expand all
273 stats_proxy_(stats_proxy), 344 stats_proxy_(stats_proxy),
274 pre_encode_callback_(pre_encode_callback), 345 pre_encode_callback_(pre_encode_callback),
275 module_process_thread_(nullptr), 346 module_process_thread_(nullptr),
276 pending_encoder_reconfiguration_(false), 347 pending_encoder_reconfiguration_(false),
277 encoder_start_bitrate_bps_(0), 348 encoder_start_bitrate_bps_(0),
278 max_data_payload_length_(0), 349 max_data_payload_length_(0),
279 nack_enabled_(false), 350 nack_enabled_(false),
280 last_observed_bitrate_bps_(0), 351 last_observed_bitrate_bps_(0),
281 encoder_paused_and_dropped_frame_(false), 352 encoder_paused_and_dropped_frame_(false),
282 clock_(Clock::GetRealTimeClock()), 353 clock_(Clock::GetRealTimeClock()),
283 scale_counter_(kScaleReasonSize, 0), 354 degradation_preference_(DegradationPreference::kDegradationDisabled),
284 degradation_preference_(DegradationPreference::kMaintainResolution),
285 last_captured_timestamp_(0), 355 last_captured_timestamp_(0),
286 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - 356 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() -
287 clock_->TimeInMilliseconds()), 357 clock_->TimeInMilliseconds()),
288 last_frame_log_ms_(clock_->TimeInMilliseconds()), 358 last_frame_log_ms_(clock_->TimeInMilliseconds()),
289 captured_frame_count_(0), 359 captured_frame_count_(0),
290 dropped_frame_count_(0), 360 dropped_frame_count_(0),
291 bitrate_observer_(nullptr), 361 bitrate_observer_(nullptr),
292 encoder_queue_("EncoderQueue") { 362 encoder_queue_("EncoderQueue") {
293 RTC_DCHECK(stats_proxy); 363 RTC_DCHECK(stats_proxy);
294 encoder_queue_.PostTask([this] { 364 encoder_queue_.PostTask([this] {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 }); 415 });
346 } 416 }
347 417
348 void ViEEncoder::SetSource( 418 void ViEEncoder::SetSource(
349 rtc::VideoSourceInterface<VideoFrame>* source, 419 rtc::VideoSourceInterface<VideoFrame>* source,
350 const VideoSendStream::DegradationPreference& degradation_preference) { 420 const VideoSendStream::DegradationPreference& degradation_preference) {
351 RTC_DCHECK_RUN_ON(&thread_checker_); 421 RTC_DCHECK_RUN_ON(&thread_checker_);
352 source_proxy_->SetSource(source, degradation_preference); 422 source_proxy_->SetSource(source, degradation_preference);
353 encoder_queue_.PostTask([this, degradation_preference] { 423 encoder_queue_.PostTask([this, degradation_preference] {
354 RTC_DCHECK_RUN_ON(&encoder_queue_); 424 RTC_DCHECK_RUN_ON(&encoder_queue_);
355 425 if (degradation_preference_ != degradation_preference) {
426 // Reset adaptation state, so that we're not tricked into thinking there's
427 // an already pending request of the same type.
428 last_adaptation_request_.reset();
429 }
356 degradation_preference_ = degradation_preference; 430 degradation_preference_ = degradation_preference;
357 initial_rampup_ = 431 bool allow_scaling =
358 degradation_preference_ != DegradationPreference::kMaintainResolution 432 degradation_preference_ == DegradationPreference::kMaintainFramerate ||
359 ? 0 433 degradation_preference_ == DegradationPreference::kBalanced;
360 : kMaxInitialFramedrop; 434 initial_rampup_ = allow_scaling ? 0 : kMaxInitialFramedrop;
361 ConfigureQualityScaler(); 435 ConfigureQualityScaler();
362 }); 436 });
363 } 437 }
364 438
365 void ViEEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { 439 void ViEEncoder::SetSink(EncoderSink* sink, bool rotation_applied) {
366 source_proxy_->SetWantsRotationApplied(rotation_applied); 440 source_proxy_->SetWantsRotationApplied(rotation_applied);
367 encoder_queue_.PostTask([this, sink] { 441 encoder_queue_.PostTask([this, sink] {
368 RTC_DCHECK_RUN_ON(&encoder_queue_); 442 RTC_DCHECK_RUN_ON(&encoder_queue_);
369 sink_ = sink; 443 sink_ = sink;
370 }); 444 });
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
453 sink_->OnEncoderConfigurationChanged( 527 sink_->OnEncoderConfigurationChanged(
454 std::move(streams), encoder_config_.min_transmit_bitrate_bps); 528 std::move(streams), encoder_config_.min_transmit_bitrate_bps);
455 529
456 ConfigureQualityScaler(); 530 ConfigureQualityScaler();
457 } 531 }
458 532
459 void ViEEncoder::ConfigureQualityScaler() { 533 void ViEEncoder::ConfigureQualityScaler() {
460 RTC_DCHECK_RUN_ON(&encoder_queue_); 534 RTC_DCHECK_RUN_ON(&encoder_queue_);
461 const auto scaling_settings = settings_.encoder->GetScalingSettings(); 535 const auto scaling_settings = settings_.encoder->GetScalingSettings();
462 const bool degradation_preference_allows_scaling = 536 const bool degradation_preference_allows_scaling =
463 degradation_preference_ != DegradationPreference::kMaintainResolution; 537 degradation_preference_ == DegradationPreference::kMaintainFramerate ||
538 degradation_preference_ == DegradationPreference::kBalanced;
464 const bool quality_scaling_allowed = 539 const bool quality_scaling_allowed =
465 degradation_preference_allows_scaling && scaling_settings.enabled; 540 degradation_preference_allows_scaling && scaling_settings.enabled;
466 541
542 const std::vector<int>& scale_counters = GetScaleCounters();
467 stats_proxy_->SetCpuScalingStats( 543 stats_proxy_->SetCpuScalingStats(
468 degradation_preference_allows_scaling ? scale_counter_[kCpu] > 0 : false); 544 degradation_preference_allows_scaling ? scale_counters[kCpu] > 0 : false);
469 stats_proxy_->SetQualityScalingStats( 545 stats_proxy_->SetQualityScalingStats(
470 quality_scaling_allowed ? scale_counter_[kQuality] : -1); 546 quality_scaling_allowed ? scale_counters[kQuality] : -1);
471 547
472 if (quality_scaling_allowed) { 548 if (quality_scaling_allowed) {
473 // Abort if quality scaler has already been configured. 549 // Abort if quality scaler has already been configured.
474 if (quality_scaler_.get() != nullptr) 550 if (quality_scaler_.get() != nullptr)
475 return; 551 return;
476 // Drop frames and scale down until desired quality is achieved. 552 // Drop frames and scale down until desired quality is achieved.
477 if (scaling_settings.thresholds) { 553 if (scaling_settings.thresholds) {
478 quality_scaler_.reset( 554 quality_scaler_.reset(
479 new QualityScaler(this, *(scaling_settings.thresholds))); 555 new QualityScaler(this, *(scaling_settings.thresholds)));
480 } else { 556 } else {
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 781
706 if (video_suspension_changed) { 782 if (video_suspension_changed) {
707 LOG(LS_INFO) << "Video suspend state changed to: " 783 LOG(LS_INFO) << "Video suspend state changed to: "
708 << (video_is_suspended ? "suspended" : "not suspended"); 784 << (video_is_suspended ? "suspended" : "not suspended");
709 stats_proxy_->OnSuspendChange(video_is_suspended); 785 stats_proxy_->OnSuspendChange(video_is_suspended);
710 } 786 }
711 } 787 }
712 788
713 void ViEEncoder::AdaptDown(AdaptReason reason) { 789 void ViEEncoder::AdaptDown(AdaptReason reason) {
714 RTC_DCHECK_RUN_ON(&encoder_queue_); 790 RTC_DCHECK_RUN_ON(&encoder_queue_);
715 if (degradation_preference_ != DegradationPreference::kBalanced) 791 AdaptationRequest adaptation_request = {
716 return; 792 last_frame_info_->pixel_count(),
717 RTC_DCHECK(static_cast<bool>(last_frame_info_)); 793 stats_proxy_->GetStats().input_frame_rate,
718 int current_pixel_count = last_frame_info_->pixel_count(); 794 AdaptationRequest::Mode::kAdaptDown};
719 if (last_adaptation_request_ && 795 bool downgrade_requested =
720 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown && 796 last_adaptation_request_ &&
721 current_pixel_count >= last_adaptation_request_->input_pixel_count_) { 797 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown;
722 // Don't request lower resolution if the current resolution is not lower 798
723 // than the last time we asked for the resolution to be lowered. 799 int max_downgrades = 0;
724 return; 800 switch (degradation_preference_) {
801 case DegradationPreference::kBalanced:
802 FALLTHROUGH();
803 case DegradationPreference::kMaintainFramerate:
804 max_downgrades = kMaxCpuResolutionDowngrades;
805 if (downgrade_requested &&
806 adaptation_request.input_pixel_count_ >=
807 last_adaptation_request_->input_pixel_count_) {
808 // Don't request lower resolution if the current resolution is not
809 // lower than the last time we asked for the resolution to be lowered.
810 return;
811 }
812 break;
813 case DegradationPreference::kMaintainResolution:
814 max_downgrades = kMaxCpuFramerateDowngrades;
815 if (adaptation_request.framerate_fps_ <= 0 ||
816 (downgrade_requested &&
817 adaptation_request.framerate_fps_ < kMinFramerateFps)) {
818 // If no input fps estimate available, can't determine how to scale down
819 // framerate. Otherwise, don't request lower framerate if we don't have
820 // a valid frame rate. Since framerate, unlike resolution, is a measure
821 // we have to estimate, and can fluctuate naturally over time, don't
822 // make the same kind of limitations as for resolution, but trust the
823 // overuse detector to not trigger too often.
824 return;
825 }
826 break;
827 case DegradationPreference::kDegradationDisabled:
828 return;
725 } 829 }
726 last_adaptation_request_.emplace(AdaptationRequest{ 830
727 current_pixel_count, AdaptationRequest::Mode::kAdaptDown}); 831 last_adaptation_request_.emplace(adaptation_request);
832 const std::vector<int>& scale_counter = GetScaleCounters();
728 833
729 switch (reason) { 834 switch (reason) {
730 case kQuality: 835 case kQuality:
731 stats_proxy_->OnQualityRestrictedResolutionChanged( 836 stats_proxy_->OnQualityRestrictedResolutionChanged(scale_counter[reason] +
732 scale_counter_[reason] + 1); 837 1);
733 break; 838 break;
734 case kCpu: 839 case kCpu:
735 if (scale_counter_[reason] >= kMaxCpuDowngrades) 840 if (scale_counter[reason] >= max_downgrades)
736 return; 841 return;
737 // Update stats accordingly. 842 // Update stats accordingly.
738 stats_proxy_->OnCpuRestrictedResolutionChanged(true); 843 stats_proxy_->OnCpuRestrictedResolutionChanged(true);
739 break; 844 break;
740 } 845 }
741 ++scale_counter_[reason]; 846
742 source_proxy_->RequestResolutionLowerThan(current_pixel_count); 847 IncrementScaleCounter(reason, 1);
743 LOG(LS_INFO) << "Scaling down resolution."; 848
849 switch (degradation_preference_) {
850 case DegradationPreference::kBalanced:
851 FALLTHROUGH();
852 case DegradationPreference::kMaintainFramerate:
853 source_proxy_->RequestResolutionLowerThan(
854 adaptation_request.input_pixel_count_);
855 LOG(LS_INFO) << "Scaling down resolution.";
856 break;
857 case DegradationPreference::kMaintainResolution:
858 source_proxy_->RequestFramerateLowerThan(
859 adaptation_request.framerate_fps_);
860 LOG(LS_INFO) << "Scaling down framerate.";
861 break;
862 case DegradationPreference::kDegradationDisabled:
863 RTC_NOTREACHED();
864 }
865
744 for (size_t i = 0; i < kScaleReasonSize; ++i) { 866 for (size_t i = 0; i < kScaleReasonSize; ++i) {
745 LOG(LS_INFO) << "Scaled " << scale_counter_[i] 867 LOG(LS_INFO) << "Scaled " << GetScaleCounters()[i]
746 << " times for reason: " << (i ? "cpu" : "quality"); 868 << " times for reason: " << (i ? "cpu" : "quality");
747 } 869 }
748 } 870 }
749 871
750 void ViEEncoder::AdaptUp(AdaptReason reason) { 872 void ViEEncoder::AdaptUp(AdaptReason reason) {
751 RTC_DCHECK_RUN_ON(&encoder_queue_); 873 RTC_DCHECK_RUN_ON(&encoder_queue_);
752 if (scale_counter_[reason] == 0 || 874 int scale_counter = GetScaleCounters()[reason];
753 degradation_preference_ != DegradationPreference::kBalanced) { 875 if (scale_counter == 0)
754 return; 876 return;
877 RTC_DCHECK_GT(scale_counter, 0);
878 AdaptationRequest adaptation_request = {
879 last_frame_info_->pixel_count(),
880 stats_proxy_->GetStats().input_frame_rate,
881 AdaptationRequest::Mode::kAdaptUp};
882
883 bool adapt_up_requested =
884 last_adaptation_request_ &&
885 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp;
886 switch (degradation_preference_) {
887 case DegradationPreference::kBalanced:
888 FALLTHROUGH();
889 case DegradationPreference::kMaintainFramerate:
890 if (adapt_up_requested &&
891 adaptation_request.input_pixel_count_ <=
892 last_adaptation_request_->input_pixel_count_) {
893 // Don't request higher resolution if the current resolution is not
894 // higher than the last time we asked for the resolution to be higher.
895 return;
896 }
897 break;
898 case DegradationPreference::kMaintainResolution:
899 // TODO(sprang): Don't request higher framerate if we are already at
900 // max requested fps?
901 break;
902 case DegradationPreference::kDegradationDisabled:
903 return;
755 } 904 }
756 // Only scale if resolution is higher than last time we requested higher 905
757 // resolution. 906 last_adaptation_request_.emplace(adaptation_request);
758 RTC_DCHECK(static_cast<bool>(last_frame_info_));
759 int current_pixel_count = last_frame_info_->pixel_count();
760 if (last_adaptation_request_ &&
761 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp &&
762 current_pixel_count <= last_adaptation_request_->input_pixel_count_) {
763 // Don't request higher resolution if the current resolution is not higher
764 // than the last time we asked for the resolution to be higher.
765 return;
766 }
767 last_adaptation_request_.emplace(AdaptationRequest{
768 current_pixel_count, AdaptationRequest::Mode::kAdaptUp});
769 907
770 switch (reason) { 908 switch (reason) {
771 case kQuality: 909 case kQuality:
772 stats_proxy_->OnQualityRestrictedResolutionChanged( 910 stats_proxy_->OnQualityRestrictedResolutionChanged(scale_counter - 1);
773 scale_counter_[reason] - 1);
774 break; 911 break;
775 case kCpu: 912 case kCpu:
776 // Update stats accordingly. 913 // Update stats accordingly.
777 stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter_[reason] > 914 stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter > 1);
778 1);
779 break; 915 break;
780 } 916 }
781 --scale_counter_[reason]; 917
782 source_proxy_->RequestHigherResolutionThan(current_pixel_count); 918 // Decrease counter of how many times we have scaled down, for this
783 LOG(LS_INFO) << "Scaling up resolution."; 919 // degradation preference mode and reason.
920 IncrementScaleCounter(reason, -1);
921
922 // Get a sum of how many times have scaled down, in total, for this
923 // degradation preference mode. If it is 0, remove any restraints.
924 const std::vector<int>& current_scale_counters = GetScaleCounters();
925 const int scale_sum = std::accumulate(current_scale_counters.begin(),
926 current_scale_counters.end(), 0);
927 switch (degradation_preference_) {
928 case DegradationPreference::kBalanced:
929 FALLTHROUGH();
930 case DegradationPreference::kMaintainFramerate:
931 if (scale_sum == 0) {
932 LOG(LS_INFO) << "Removing resolution down-scaling setting.";
933 source_proxy_->RequestHigherResolutionThan(
934 std::numeric_limits<int>::max());
935 } else {
936 source_proxy_->RequestHigherResolutionThan(
937 adaptation_request.input_pixel_count_);
938 LOG(LS_INFO) << "Scaling up resolution.";
939 }
940 break;
941 case DegradationPreference::kMaintainResolution:
942 if (scale_sum == 0) {
943 LOG(LS_INFO) << "Removing framerate down-scaling setting.";
944 source_proxy_->RequestHigherFramerateThan(
945 std::numeric_limits<int>::max());
946 } else {
947 source_proxy_->RequestHigherFramerateThan(
948 adaptation_request.framerate_fps_);
949 LOG(LS_INFO) << "Scaling up framerate.";
950 }
951 break;
952 case DegradationPreference::kDegradationDisabled:
953 RTC_NOTREACHED();
954 }
955
784 for (size_t i = 0; i < kScaleReasonSize; ++i) { 956 for (size_t i = 0; i < kScaleReasonSize; ++i) {
785 LOG(LS_INFO) << "Scaled " << scale_counter_[i] 957 LOG(LS_INFO) << "Scaled " << current_scale_counters[i]
786 << " times for reason: " << (i ? "cpu" : "quality"); 958 << " times for reason: " << (i ? "cpu" : "quality");
787 } 959 }
788 } 960 }
789 961
962 const std::vector<int>& ViEEncoder::GetScaleCounters() {
963 auto it = scale_counters_.find(degradation_preference_);
964 if (it == scale_counters_.end()) {
965 scale_counters_[degradation_preference_].resize(kScaleReasonSize);
966 return scale_counters_[degradation_preference_];
967 }
968 return it->second;
969 }
970
971 void ViEEncoder::IncrementScaleCounter(int reason, int delta) {
972 // Get the counters and validate. This may also lazily initialize the state.
973 const std::vector<int>& counter = GetScaleCounters();
974 if (delta < 0) {
975 RTC_DCHECK_GE(counter[reason], delta);
976 }
977 scale_counters_[degradation_preference_][reason] += delta;
978 }
979
790 } // namespace webrtc 980 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/video/vie_encoder.h ('k') | webrtc/video/vie_encoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698