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

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

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