Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 // Time interval for logging frame counts. | 36 // Time interval for logging frame counts. |
| 37 const int64_t kFrameLogIntervalMs = 60000; | 37 const int64_t kFrameLogIntervalMs = 60000; |
| 38 // We will never ask for a resolution lower than this. | 38 // We will never ask for a resolution lower than this. |
| 39 #if defined(WEBRTC_ANDROID) | 39 #if defined(WEBRTC_ANDROID) |
| 40 // TODO(kthelgason): Lower this limit when better testing | 40 // TODO(kthelgason): Lower this limit when better testing |
| 41 // on MediaCodec and fallback implementations are in place. | 41 // on MediaCodec and fallback implementations are in place. |
| 42 const int kMinPixelsPerFrame = 320 * 180; | 42 const int kMinPixelsPerFrame = 320 * 180; |
| 43 #else | 43 #else |
| 44 const int kMinPixelsPerFrame = 120 * 90; | 44 const int kMinPixelsPerFrame = 120 * 90; |
| 45 #endif | 45 #endif |
| 46 const int kMinFramerateFps = 2; | |
| 46 | 47 |
| 47 // The maximum number of frames to drop at beginning of stream | 48 // The maximum number of frames to drop at beginning of stream |
| 48 // to try and achieve desired bitrate. | 49 // to try and achieve desired bitrate. |
| 49 const int kMaxInitialFramedrop = 4; | 50 const int kMaxInitialFramedrop = 4; |
| 50 | 51 |
| 51 // 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 |
| 52 // pipelining encoders better (multiple input frames before something comes | 53 // pipelining encoders better (multiple input frames before something comes |
| 53 // out). This should effectively turn off CPU adaptations for systems that | 54 // out). This should effectively turn off CPU adaptations for systems that |
| 54 // remotely cope with the load right now. | 55 // remotely cope with the load right now. |
| 55 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { | 56 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 source_(nullptr) {} | 156 source_(nullptr) {} |
| 156 | 157 |
| 157 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source, | 158 void SetSource(rtc::VideoSourceInterface<VideoFrame>* source, |
| 158 const DegradationPreference& degradation_preference) { | 159 const DegradationPreference& degradation_preference) { |
| 159 // Called on libjingle's worker thread. | 160 // Called on libjingle's worker thread. |
| 160 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); | 161 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); |
| 161 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; | 162 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; |
| 162 rtc::VideoSinkWants wants; | 163 rtc::VideoSinkWants wants; |
| 163 { | 164 { |
| 164 rtc::CritScope lock(&crit_); | 165 rtc::CritScope lock(&crit_); |
| 166 wants = sink_wants_; | |
| 167 // If changing degradation preference, clear any constraints from the | |
| 168 // current sink wants that will no longer apply. | |
| 169 if (degradation_preference_ != degradation_preference) { | |
| 170 switch (degradation_preference) { | |
| 171 case DegradationPreference::kBalanced: | |
| 172 wants.max_framerate_fps_.reset(); | |
| 173 break; | |
| 174 case DegradationPreference::kMaintainResolution: | |
| 175 wants.max_pixel_count.reset(); | |
| 176 wants.target_pixel_count.reset(); | |
| 177 break; | |
| 178 } | |
| 179 } | |
| 180 degradation_preference_ = degradation_preference; | |
| 165 old_source = source_; | 181 old_source = source_; |
| 166 source_ = source; | 182 source_ = source; |
| 167 degradation_preference_ = degradation_preference; | |
| 168 wants = current_wants(); | |
| 169 } | 183 } |
| 170 | 184 |
| 171 if (old_source != source && old_source != nullptr) { | 185 if (old_source != source && old_source != nullptr) { |
| 172 old_source->RemoveSink(vie_encoder_); | 186 old_source->RemoveSink(vie_encoder_); |
| 173 } | 187 } |
| 174 | 188 |
| 175 if (!source) { | 189 if (!source) { |
| 176 return; | 190 return; |
| 177 } | 191 } |
| 178 | 192 |
| 179 source->AddOrUpdateSink(vie_encoder_, wants); | 193 source->AddOrUpdateSink(vie_encoder_, wants); |
| 180 } | 194 } |
| 181 | 195 |
| 182 void SetWantsRotationApplied(bool rotation_applied) { | 196 void SetWantsRotationApplied(bool rotation_applied) { |
| 183 rtc::CritScope lock(&crit_); | 197 rtc::CritScope lock(&crit_); |
| 184 sink_wants_.rotation_applied = rotation_applied; | 198 sink_wants_.rotation_applied = rotation_applied; |
| 185 disabled_scaling_sink_wants_.rotation_applied = rotation_applied; | 199 if (source_) |
| 186 if (source_) { | 200 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
| 187 source_->AddOrUpdateSink(vie_encoder_, current_wants()); | |
| 188 } | |
| 189 } | 201 } |
| 190 | 202 |
| 191 void RequestResolutionLowerThan(int pixel_count) { | 203 void RequestResolutionLowerThan(int pixel_count) { |
| 192 // Called on the encoder task queue. | 204 // Called on the encoder task queue. |
| 193 rtc::CritScope lock(&crit_); | 205 rtc::CritScope lock(&crit_); |
| 194 if (!IsResolutionScalingEnabledLocked()) { | 206 if (!IsResolutionScalingEnabledLocked()) { |
| 195 // This can happen since |degradation_preference_| is set on | 207 // This can happen since |degradation_preference_| is set on |
| 196 // libjingle's worker thread but the adaptation is done on the encoder | 208 // libjingle's worker thread but the adaptation is done on the encoder |
| 197 // task queue. | 209 // task queue. |
| 198 return; | 210 return; |
| 199 } | 211 } |
| 200 // The input video frame size will have a resolution with less than or | 212 // The input video frame size will have a resolution with less than or |
| 201 // equal to |max_pixel_count| depending on how the source can scale the | 213 // equal to |max_pixel_count| depending on how the source can scale the |
| 202 // input frame size. | 214 // input frame size. |
| 203 const int pixels_wanted = (pixel_count * 3) / 5; | 215 const int pixels_wanted = (pixel_count * 3) / 5; |
| 204 if (pixels_wanted < kMinPixelsPerFrame) | 216 if (pixels_wanted < kMinPixelsPerFrame) |
| 205 return; | 217 return; |
| 206 sink_wants_.max_pixel_count = rtc::Optional<int>(pixels_wanted); | 218 sink_wants_.max_pixel_count = rtc::Optional<int>(pixels_wanted); |
| 207 sink_wants_.target_pixel_count = rtc::Optional<int>(); | 219 sink_wants_.target_pixel_count = rtc::Optional<int>(); |
| 208 if (source_) | 220 if (source_) |
| 209 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | 221 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
| 210 } | 222 } |
| 211 | 223 |
| 224 void RequestFramerateLowerThan(int framerate_fps) { | |
| 225 // Called on the encoder task queue. | |
| 226 rtc::CritScope lock(&crit_); | |
| 227 if (!IsFramerateScalingEnabledLocked()) { | |
| 228 // This can happen since |degradation_preference_| is set on | |
| 229 // libjingle's worker thread but the adaptation is done on the encoder | |
| 230 // task queue. | |
| 231 return; | |
| 232 } | |
| 233 // The input video frame rate will be scaled down to | |
| 234 const int framerate_wanted = (framerate_fps * 2) / 3; | |
| 235 if (framerate_fps < kMinFramerateFps) | |
|
magjed_webrtc
2017/02/27 09:30:35
Shouldn't it be 'framerate_wanted < kMinFramerateF
sprang_webrtc
2017/02/27 12:51:49
I think I intended it to be framerate_fps, but pla
magjed_webrtc
2017/02/28 14:21:55
Hmm, maybe just do:
framerate_wanted = max(kMinFra
sprang_webrtc
2017/02/28 15:15:30
Done.
| |
| 236 return; | |
| 237 sink_wants_.max_framerate_fps_.emplace(framerate_wanted); | |
| 238 if (source_) | |
| 239 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | |
| 240 } | |
| 241 | |
| 212 void RequestHigherResolutionThan(int pixel_count) { | 242 void RequestHigherResolutionThan(int pixel_count) { |
| 213 rtc::CritScope lock(&crit_); | 243 rtc::CritScope lock(&crit_); |
| 214 if (!IsResolutionScalingEnabledLocked()) { | 244 if (!IsResolutionScalingEnabledLocked()) { |
| 215 // This can happen since |degradation_preference_| is set on | 245 // This can happen since |degradation_preference_| is set on |
| 216 // libjingle's worker thread but the adaptation is done on the encoder | 246 // libjingle's worker thread but the adaptation is done on the encoder |
| 217 // task queue. | 247 // task queue. |
| 218 return; | 248 return; |
| 219 } | 249 } |
| 220 // On step down we request at most 3/5 the pixel count of the previous | 250 // On step down we request at most 3/5 the pixel count of the previous |
| 221 // resolution, so in order to take "one step up" we request a resolution as | 251 // resolution, so in order to take "one step up" we request a resolution as |
| 222 // close as possible to 5/3 of the current resolution. The actual pixel | 252 // close as possible to 5/3 of the current resolution. The actual pixel |
| 223 // count selected depends on the capabilities of the source. In order to not | 253 // count selected depends on the capabilities of the source. In order to not |
| 224 // take a too large step up, we cap the requested pixel count to be at most | 254 // take a too large step up, we cap the requested pixel count to be at most |
| 225 // four time the current number of pixels. | 255 // four time the current number of pixels. |
| 226 sink_wants_.target_pixel_count = rtc::Optional<int>((pixel_count * 5) / 3); | 256 sink_wants_.target_pixel_count = rtc::Optional<int>((pixel_count * 5) / 3); |
| 227 sink_wants_.max_pixel_count = rtc::Optional<int>(pixel_count * 4); | 257 sink_wants_.max_pixel_count = rtc::Optional<int>(pixel_count * 4); |
| 228 if (source_) | 258 if (source_) |
| 229 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | 259 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
| 230 } | 260 } |
| 231 | 261 |
| 262 void RequestHigherFramerateThan(int framerate_fps) { | |
| 263 // Called on the encoder task queue. | |
| 264 rtc::CritScope lock(&crit_); | |
| 265 if (!IsFramerateScalingEnabledLocked()) { | |
| 266 // This can happen since |degradation_preference_| is set on | |
| 267 // libjingle's worker thread but the adaptation is done on the encoder | |
| 268 // task queue. | |
| 269 return; | |
| 270 } | |
| 271 // The input video frame rate will be scaled up to | |
| 272 const int framerate_wanted = (framerate_fps * 3) / 2; | |
| 273 sink_wants_.max_framerate_fps_.emplace(framerate_wanted); | |
| 274 if (source_) | |
| 275 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | |
| 276 } | |
| 277 | |
| 232 private: | 278 private: |
| 233 bool IsResolutionScalingEnabledLocked() const | 279 bool IsResolutionScalingEnabledLocked() const |
| 234 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { | 280 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { |
| 235 return degradation_preference_ != | 281 return degradation_preference_ != |
| 236 DegradationPreference::kMaintainResolution; | 282 DegradationPreference::kMaintainResolution; |
| 237 } | 283 } |
| 238 | 284 |
| 239 const rtc::VideoSinkWants& current_wants() const | 285 bool IsFramerateScalingEnabledLocked() const |
| 240 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { | 286 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { |
| 241 return IsResolutionScalingEnabledLocked() ? sink_wants_ | 287 return degradation_preference_ == |
| 242 : disabled_scaling_sink_wants_; | 288 DegradationPreference::kMaintainResolution; |
| 243 } | 289 } |
| 244 | 290 |
| 245 rtc::CriticalSection crit_; | 291 rtc::CriticalSection crit_; |
| 246 rtc::SequencedTaskChecker main_checker_; | 292 rtc::SequencedTaskChecker main_checker_; |
| 247 ViEEncoder* const vie_encoder_; | 293 ViEEncoder* const vie_encoder_; |
| 248 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); | 294 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); |
| 249 rtc::VideoSinkWants disabled_scaling_sink_wants_ GUARDED_BY(&crit_); | |
| 250 DegradationPreference degradation_preference_ GUARDED_BY(&crit_); | 295 DegradationPreference degradation_preference_ GUARDED_BY(&crit_); |
| 251 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); | 296 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); |
| 252 | 297 |
| 253 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); | 298 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); |
| 254 }; | 299 }; |
| 255 | 300 |
| 256 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 301 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
| 257 SendStatisticsProxy* stats_proxy, | 302 SendStatisticsProxy* stats_proxy, |
| 258 const VideoSendStream::Config::EncoderSettings& settings, | 303 const VideoSendStream::Config::EncoderSettings& settings, |
| 259 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, | 304 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 278 encoder_start_bitrate_bps_(0), | 323 encoder_start_bitrate_bps_(0), |
| 279 max_data_payload_length_(0), | 324 max_data_payload_length_(0), |
| 280 nack_enabled_(false), | 325 nack_enabled_(false), |
| 281 last_observed_bitrate_bps_(0), | 326 last_observed_bitrate_bps_(0), |
| 282 encoder_paused_and_dropped_frame_(false), | 327 encoder_paused_and_dropped_frame_(false), |
| 283 has_received_sli_(false), | 328 has_received_sli_(false), |
| 284 picture_id_sli_(0), | 329 picture_id_sli_(0), |
| 285 has_received_rpsi_(false), | 330 has_received_rpsi_(false), |
| 286 picture_id_rpsi_(0), | 331 picture_id_rpsi_(0), |
| 287 clock_(Clock::GetRealTimeClock()), | 332 clock_(Clock::GetRealTimeClock()), |
| 288 scale_counter_(kScaleReasonSize, 0), | |
| 289 degradation_preference_(DegradationPreference::kMaintainResolution), | 333 degradation_preference_(DegradationPreference::kMaintainResolution), |
| 290 last_captured_timestamp_(0), | 334 last_captured_timestamp_(0), |
| 291 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - | 335 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - |
| 292 clock_->TimeInMilliseconds()), | 336 clock_->TimeInMilliseconds()), |
| 293 last_frame_log_ms_(clock_->TimeInMilliseconds()), | 337 last_frame_log_ms_(clock_->TimeInMilliseconds()), |
| 294 captured_frame_count_(0), | 338 captured_frame_count_(0), |
| 295 dropped_frame_count_(0), | 339 dropped_frame_count_(0), |
| 296 bitrate_observer_(nullptr), | 340 bitrate_observer_(nullptr), |
| 297 encoder_queue_("EncoderQueue") { | 341 encoder_queue_("EncoderQueue") { |
| 298 RTC_DCHECK(stats_proxy); | 342 RTC_DCHECK(stats_proxy); |
| 299 encoder_queue_.PostTask([this] { | 343 encoder_queue_.PostTask([this] { |
| 300 RTC_DCHECK_RUN_ON(&encoder_queue_); | 344 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 301 overuse_detector_.StartCheckForOveruse(); | 345 overuse_detector_.StartCheckForOveruse(); |
| 302 video_sender_.RegisterExternalEncoder( | 346 video_sender_.RegisterExternalEncoder( |
| 303 settings_.encoder, settings_.payload_type, settings_.internal_source); | 347 settings_.encoder, settings_.payload_type, settings_.internal_source); |
| 304 }); | 348 }); |
| 349 | |
| 350 for (size_t i = 0; i < VideoSendStream::kNumDegradationPreferences; ++i) | |
| 351 scale_counter_[i].resize(kScaleReasonSize); | |
| 305 } | 352 } |
| 306 | 353 |
| 307 ViEEncoder::~ViEEncoder() { | 354 ViEEncoder::~ViEEncoder() { |
| 308 RTC_DCHECK_RUN_ON(&thread_checker_); | 355 RTC_DCHECK_RUN_ON(&thread_checker_); |
| 309 RTC_DCHECK(shutdown_event_.Wait(0)) | 356 RTC_DCHECK(shutdown_event_.Wait(0)) |
| 310 << "Must call ::Stop() before destruction."; | 357 << "Must call ::Stop() before destruction."; |
| 311 } | 358 } |
| 312 | 359 |
| 313 void ViEEncoder::Stop() { | 360 void ViEEncoder::Stop() { |
| 314 RTC_DCHECK_RUN_ON(&thread_checker_); | 361 RTC_DCHECK_RUN_ON(&thread_checker_); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 469 if (scaling_settings.thresholds) { | 516 if (scaling_settings.thresholds) { |
| 470 quality_scaler_.reset( | 517 quality_scaler_.reset( |
| 471 new QualityScaler(this, *(scaling_settings.thresholds))); | 518 new QualityScaler(this, *(scaling_settings.thresholds))); |
| 472 } else { | 519 } else { |
| 473 quality_scaler_.reset(new QualityScaler(this, codec_type_)); | 520 quality_scaler_.reset(new QualityScaler(this, codec_type_)); |
| 474 } | 521 } |
| 475 } else { | 522 } else { |
| 476 quality_scaler_.reset(nullptr); | 523 quality_scaler_.reset(nullptr); |
| 477 initial_rampup_ = kMaxInitialFramedrop; | 524 initial_rampup_ = kMaxInitialFramedrop; |
| 478 } | 525 } |
| 526 const std::vector<int>& scale_counter = | |
| 527 scale_counter_[static_cast<size_t>(degradation_preference_)]; | |
| 479 stats_proxy_->SetResolutionRestrictionStats( | 528 stats_proxy_->SetResolutionRestrictionStats( |
| 480 degradation_preference_allows_scaling, scale_counter_[kCpu] > 0, | 529 degradation_preference_allows_scaling, scale_counter[kCpu] > 0, |
| 481 scale_counter_[kQuality]); | 530 scale_counter[kQuality]); |
| 482 } | 531 } |
| 483 | 532 |
| 484 void ViEEncoder::OnFrame(const VideoFrame& video_frame) { | 533 void ViEEncoder::OnFrame(const VideoFrame& video_frame) { |
| 485 RTC_DCHECK_RUNS_SERIALIZED(&incoming_frame_race_checker_); | 534 RTC_DCHECK_RUNS_SERIALIZED(&incoming_frame_race_checker_); |
| 486 VideoFrame incoming_frame = video_frame; | 535 VideoFrame incoming_frame = video_frame; |
| 487 | 536 |
| 488 // Local time in webrtc time base. | 537 // Local time in webrtc time base. |
| 489 int64_t current_time_us = clock_->TimeInMicroseconds(); | 538 int64_t current_time_us = clock_->TimeInMicroseconds(); |
| 490 int64_t current_time_ms = current_time_us / rtc::kNumMicrosecsPerMillisec; | 539 int64_t current_time_ms = current_time_us / rtc::kNumMicrosecsPerMillisec; |
| 491 // TODO(nisse): This always overrides the incoming timestamp. Don't | 540 // TODO(nisse): This always overrides the incoming timestamp. Don't |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 | 783 |
| 735 if (video_suspension_changed) { | 784 if (video_suspension_changed) { |
| 736 LOG(LS_INFO) << "Video suspend state changed to: " | 785 LOG(LS_INFO) << "Video suspend state changed to: " |
| 737 << (video_is_suspended ? "suspended" : "not suspended"); | 786 << (video_is_suspended ? "suspended" : "not suspended"); |
| 738 stats_proxy_->OnSuspendChange(video_is_suspended); | 787 stats_proxy_->OnSuspendChange(video_is_suspended); |
| 739 } | 788 } |
| 740 } | 789 } |
| 741 | 790 |
| 742 void ViEEncoder::AdaptDown(AdaptReason reason) { | 791 void ViEEncoder::AdaptDown(AdaptReason reason) { |
| 743 RTC_DCHECK_RUN_ON(&encoder_queue_); | 792 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 744 if (degradation_preference_ != DegradationPreference::kBalanced) | 793 AdaptationRequest adaptation_request = { |
| 745 return; | 794 last_frame_info_->pixel_count(), |
| 746 RTC_DCHECK(static_cast<bool>(last_frame_info_)); | 795 stats_proxy_->GetStats().input_frame_rate, |
| 747 int current_pixel_count = last_frame_info_->pixel_count(); | 796 AdaptationRequest::Mode::kAdaptDown}; |
| 797 | |
| 748 if (last_adaptation_request_ && | 798 if (last_adaptation_request_ && |
| 749 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown && | 799 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown) { |
| 750 current_pixel_count >= last_adaptation_request_->input_pixel_count_) { | 800 switch (degradation_preference_) { |
| 751 // Don't request lower resolution if the current resolution is not lower | 801 case DegradationPreference::kBalanced: |
| 752 // than the last time we asked for the resolution to be lowered. | 802 if (adaptation_request.input_pixel_count_ >= |
| 753 return; | 803 last_adaptation_request_->input_pixel_count_) { |
| 804 // Don't request lower resolution if the current resolution is not | |
|
magjed_webrtc
2017/02/27 09:30:35
Reflow comment.
sprang_webrtc
2017/02/27 12:51:49
Done.
| |
| 805 // lower | |
| 806 // than the last time we asked for the resolution to be lowered. | |
| 807 return; | |
| 808 } | |
| 809 break; | |
| 810 case DegradationPreference::kMaintainResolution: | |
| 811 if (adaptation_request.framerate_fps_ <= 1) { | |
| 812 // Don't request lower framerate if we don't have a valid frame rate. | |
| 813 // Since framerate, unlike resolution, is a measure we have to | |
| 814 // estimate, and can fluctuate naturally over time, don't make the | |
| 815 // same kind of limitations as for resolution, but trust the overuse | |
| 816 // detector to not trigger too often. | |
| 817 return; | |
| 818 } | |
| 819 break; | |
| 820 } | |
| 754 } | 821 } |
| 755 last_adaptation_request_.emplace(AdaptationRequest{ | 822 |
| 756 current_pixel_count, AdaptationRequest::Mode::kAdaptDown}); | 823 last_adaptation_request_.emplace(adaptation_request); |
| 824 std::vector<int>* scale_counter = | |
| 825 &scale_counter_[static_cast<size_t>(degradation_preference_)]; | |
| 757 | 826 |
| 758 switch (reason) { | 827 switch (reason) { |
| 759 case kQuality: | 828 case kQuality: |
| 760 stats_proxy_->OnQualityRestrictedResolutionChanged( | 829 stats_proxy_->OnQualityRestrictedResolutionChanged( |
| 761 scale_counter_[reason] + 1); | 830 (*scale_counter)[reason] + 1); |
| 762 break; | 831 break; |
| 763 case kCpu: | 832 case kCpu: |
| 764 if (scale_counter_[reason] >= kMaxCpuDowngrades) | 833 if ((*scale_counter)[reason] >= kMaxCpuDowngrades) |
| 765 return; | 834 return; |
| 766 // Update stats accordingly. | 835 // Update stats accordingly. |
| 767 stats_proxy_->OnCpuRestrictedResolutionChanged(true); | 836 stats_proxy_->OnCpuRestrictedResolutionChanged(true); |
| 768 break; | 837 break; |
| 769 } | 838 } |
| 770 ++scale_counter_[reason]; | 839 ++(*scale_counter)[reason]; |
| 771 source_proxy_->RequestResolutionLowerThan(current_pixel_count); | 840 |
| 841 switch (degradation_preference_) { | |
| 842 case DegradationPreference::kBalanced: | |
| 843 source_proxy_->RequestResolutionLowerThan( | |
| 844 adaptation_request.input_pixel_count_); | |
| 845 LOG(LS_INFO) << "Scaling down resolution."; | |
| 846 break; | |
| 847 case DegradationPreference::kMaintainResolution: | |
| 848 source_proxy_->RequestFramerateLowerThan( | |
| 849 adaptation_request.framerate_fps_); | |
| 850 LOG(LS_INFO) << "Scaling down framerate."; | |
| 851 break; | |
| 852 } | |
| 853 | |
| 772 LOG(LS_INFO) << "Scaling down resolution."; | 854 LOG(LS_INFO) << "Scaling down resolution."; |
| 773 for (size_t i = 0; i < kScaleReasonSize; ++i) { | 855 for (size_t i = 0; i < kScaleReasonSize; ++i) { |
| 774 LOG(LS_INFO) << "Scaled " << scale_counter_[i] | 856 LOG(LS_INFO) << "Scaled " << (*scale_counter)[i] |
| 775 << " times for reason: " << (i ? "cpu" : "quality"); | 857 << " times for reason: " << (i ? "cpu" : "quality"); |
| 776 } | 858 } |
| 777 } | 859 } |
| 778 | 860 |
| 779 void ViEEncoder::AdaptUp(AdaptReason reason) { | 861 void ViEEncoder::AdaptUp(AdaptReason reason) { |
| 780 RTC_DCHECK_RUN_ON(&encoder_queue_); | 862 RTC_DCHECK_RUN_ON(&encoder_queue_); |
| 781 if (scale_counter_[reason] == 0 || | 863 std::vector<int>* scale_counter = |
| 782 degradation_preference_ != DegradationPreference::kBalanced) { | 864 &scale_counter_[static_cast<size_t>(degradation_preference_)]; |
| 865 if ((*scale_counter)[reason] == 0) | |
| 783 return; | 866 return; |
| 867 AdaptationRequest adaptation_request = { | |
| 868 last_frame_info_->pixel_count(), | |
| 869 stats_proxy_->GetStats().input_frame_rate, | |
| 870 AdaptationRequest::Mode::kAdaptUp}; | |
| 871 | |
| 872 if (last_adaptation_request_ && | |
| 873 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp) { | |
| 874 switch (degradation_preference_) { | |
| 875 case DegradationPreference::kBalanced: | |
| 876 if (adaptation_request.input_pixel_count_ <= | |
| 877 last_adaptation_request_->input_pixel_count_) { | |
| 878 // Don't request higher resolution if the current resolution is not | |
| 879 // higher than the last time we asked for the resolution to be higher. | |
| 880 return; | |
| 881 } | |
| 882 break; | |
| 883 case DegradationPreference::kMaintainResolution: | |
| 884 // TODO(sprang): Don't request higher framerate if we are already at | |
| 885 // max requested fps? | |
| 886 break; | |
| 887 } | |
| 784 } | 888 } |
| 785 // Only scale if resolution is higher than last time we requested higher | |
| 786 // resolution. | |
| 787 RTC_DCHECK(static_cast<bool>(last_frame_info_)); | |
| 788 int current_pixel_count = last_frame_info_->pixel_count(); | |
| 789 if (last_adaptation_request_ && | |
| 790 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp && | |
| 791 current_pixel_count <= last_adaptation_request_->input_pixel_count_) { | |
| 792 // Don't request higher resolution if the current resolution is not higher | |
| 793 // than the last time we asked for the resolution to be higher. | |
| 794 return; | |
| 795 } | |
| 796 last_adaptation_request_.emplace(AdaptationRequest{ | |
| 797 current_pixel_count, AdaptationRequest::Mode::kAdaptUp}); | |
| 798 | 889 |
| 799 switch (reason) { | 890 switch (reason) { |
| 800 case kQuality: | 891 case kQuality: |
| 801 stats_proxy_->OnQualityRestrictedResolutionChanged( | 892 stats_proxy_->OnQualityRestrictedResolutionChanged( |
| 802 scale_counter_[reason] - 1); | 893 (*scale_counter)[reason] - 1); |
| 803 break; | 894 break; |
| 804 case kCpu: | 895 case kCpu: |
| 805 // Update stats accordingly. | 896 // Update stats accordingly. |
| 806 stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counter_[reason] > | 897 stats_proxy_->OnCpuRestrictedResolutionChanged((*scale_counter)[reason] > |
| 807 1); | 898 1); |
| 808 break; | 899 break; |
| 809 } | 900 } |
| 810 --scale_counter_[reason]; | 901 --(*scale_counter)[reason]; |
| 811 source_proxy_->RequestHigherResolutionThan(current_pixel_count); | 902 |
| 903 switch (degradation_preference_) { | |
| 904 case DegradationPreference::kBalanced: | |
| 905 source_proxy_->RequestHigherResolutionThan( | |
| 906 adaptation_request.input_pixel_count_); | |
| 907 LOG(LS_INFO) << "Scaling up resolution."; | |
| 908 break; | |
| 909 case DegradationPreference::kMaintainResolution: | |
| 910 source_proxy_->RequestHigherFramerateThan( | |
| 911 adaptation_request.framerate_fps_); | |
| 912 LOG(LS_INFO) << "Scaling up framerate."; | |
| 913 break; | |
| 914 } | |
| 915 | |
| 812 LOG(LS_INFO) << "Scaling up resolution."; | 916 LOG(LS_INFO) << "Scaling up resolution."; |
| 813 for (size_t i = 0; i < kScaleReasonSize; ++i) { | 917 for (size_t i = 0; i < kScaleReasonSize; ++i) { |
| 814 LOG(LS_INFO) << "Scaled " << scale_counter_[i] | 918 LOG(LS_INFO) << "Scaled " << (*scale_counter)[i] |
| 815 << " times for reason: " << (i ? "cpu" : "quality"); | 919 << " times for reason: " << (i ? "cpu" : "quality"); |
| 816 } | 920 } |
| 817 } | 921 } |
| 818 | 922 |
| 819 } // namespace webrtc | 923 } // namespace webrtc |
| OLD | NEW |