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 |