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

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

Issue 2887303003: Implement kBalanced degradation preference. (Closed)
Patch Set: address comments Created 3 years, 7 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
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 if (kbps > 0) { 66 if (kbps > 0) {
67 if (kbps < 300 /* qvga */) { 67 if (kbps < 300 /* qvga */) {
68 return 320 * 240; 68 return 320 * 240;
69 } else if (kbps < 500 /* vga */) { 69 } else if (kbps < 500 /* vga */) {
70 return 640 * 480; 70 return 640 * 480;
71 } 71 }
72 } 72 }
73 return std::numeric_limits<uint32_t>::max(); 73 return std::numeric_limits<uint32_t>::max();
74 } 74 }
75 75
76 // Limits for kBalanced degradation preference.
77 // >640x480: | max |
78 // <=640x480: | 15fps | max |
79 // <=480x270: | 10fps | 15fps |
80 // <=320x240: | 7fps | 10fps |
81 // ----------------------------------------------------------
82 // kbps: 0 60 130 500 |
83
84 int MinFps(int pixels) {
85 if (pixels <= 320 * 240)
86 return 7;
87 else if (pixels <= 480 * 270)
88 return 10;
89 else if (pixels <= 640 * 480)
90 return 15;
91 else
92 return std::numeric_limits<int>::max();
93 }
94
95 int MaxFps(int pixels) {
96 if (pixels <= 320 * 240)
97 return 10;
98 else if (pixels <= 480 * 270)
99 return 15;
100 else
101 return std::numeric_limits<int>::max();
102 }
103
104 uint32_t BitrateLimit(int pixels) {
105 if (pixels <= 320 * 240)
106 return 60000;
107 else if (pixels <= 480 * 270)
108 return 130000;
109 else if (pixels <= 640 * 480)
110 return 500000;
111 else
112 return std::numeric_limits<uint32_t>::max();
113 }
114
115 int MaxFpsForBitrateAndResolution(uint32_t bps, int pixels) {
116 return (bps <= BitrateLimit(pixels)) ? MinFps(pixels) : MaxFps(pixels);
117 }
118
76 bool IsResolutionScalingEnabled( 119 bool IsResolutionScalingEnabled(
77 VideoSendStream::DegradationPreference degradation_preference) { 120 VideoSendStream::DegradationPreference degradation_preference) {
78 return degradation_preference == 121 return degradation_preference ==
79 VideoSendStream::DegradationPreference::kMaintainFramerate || 122 VideoSendStream::DegradationPreference::kMaintainFramerate ||
80 degradation_preference == 123 degradation_preference ==
81 VideoSendStream::DegradationPreference::kBalanced; 124 VideoSendStream::DegradationPreference::kBalanced;
82 } 125 }
83 126
84 bool IsFramerateScalingEnabled( 127 bool IsFramerateScalingEnabled(
85 VideoSendStream::DegradationPreference degradation_preference) { 128 VideoSendStream::DegradationPreference degradation_preference) {
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 if (source_) 247 if (source_)
205 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); 248 source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
206 } 249 }
207 250
208 rtc::VideoSinkWants GetActiveSinkWants() EXCLUSIVE_LOCKS_REQUIRED(&crit_) { 251 rtc::VideoSinkWants GetActiveSinkWants() EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
209 rtc::VideoSinkWants wants = sink_wants_; 252 rtc::VideoSinkWants wants = sink_wants_;
210 // Clear any constraints from the current sink wants that don't apply to 253 // Clear any constraints from the current sink wants that don't apply to
211 // the used degradation_preference. 254 // the used degradation_preference.
212 switch (degradation_preference_) { 255 switch (degradation_preference_) {
213 case VideoSendStream::DegradationPreference::kBalanced: 256 case VideoSendStream::DegradationPreference::kBalanced:
214 FALLTHROUGH(); 257 break;
215 case VideoSendStream::DegradationPreference::kMaintainFramerate: 258 case VideoSendStream::DegradationPreference::kMaintainFramerate:
216 wants.max_framerate_fps = std::numeric_limits<int>::max(); 259 wants.max_framerate_fps = std::numeric_limits<int>::max();
217 break; 260 break;
218 case VideoSendStream::DegradationPreference::kMaintainResolution: 261 case VideoSendStream::DegradationPreference::kMaintainResolution:
219 wants.max_pixel_count = std::numeric_limits<int>::max(); 262 wants.max_pixel_count = std::numeric_limits<int>::max();
220 wants.target_pixel_count.reset(); 263 wants.target_pixel_count.reset();
221 break; 264 break;
222 case VideoSendStream::DegradationPreference::kDegradationDisabled: 265 case VideoSendStream::DegradationPreference::kDegradationDisabled:
223 wants.max_pixel_count = std::numeric_limits<int>::max(); 266 wants.max_pixel_count = std::numeric_limits<int>::max();
224 wants.target_pixel_count.reset(); 267 wants.target_pixel_count.reset();
225 wants.max_framerate_fps = std::numeric_limits<int>::max(); 268 wants.max_framerate_fps = std::numeric_limits<int>::max();
226 } 269 }
227 return wants; 270 return wants;
228 } 271 }
229 272
230 bool RequestResolutionLowerThan(int pixel_count) { 273 bool RequestResolutionLowerThan(int pixel_count) {
231 // Called on the encoder task queue. 274 // Called on the encoder task queue.
232 rtc::CritScope lock(&crit_); 275 rtc::CritScope lock(&crit_);
233 if (!IsResolutionScalingEnabledLocked()) { 276 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) {
234 // This can happen since |degradation_preference_| is set on libjingle's 277 // This can happen since |degradation_preference_| is set on libjingle's
235 // worker thread but the adaptation is done on the encoder task queue. 278 // worker thread but the adaptation is done on the encoder task queue.
236 return false; 279 return false;
237 } 280 }
238 // The input video frame size will have a resolution with less than or 281 // The input video frame size will have a resolution less than or equal to
239 // equal to |max_pixel_count| depending on how the source can scale the 282 // |max_pixel_count| depending on how the source can scale the frame size.
240 // input frame size.
241 const int pixels_wanted = (pixel_count * 3) / 5; 283 const int pixels_wanted = (pixel_count * 3) / 5;
242 if (pixels_wanted < kMinPixelsPerFrame) 284 if (pixels_wanted < kMinPixelsPerFrame ||
285 pixels_wanted >= sink_wants_.max_pixel_count) {
243 return false; 286 return false;
244 287 }
288 LOG(LS_INFO) << "Scaling down resolution";
245 sink_wants_.max_pixel_count = pixels_wanted; 289 sink_wants_.max_pixel_count = pixels_wanted;
246 sink_wants_.target_pixel_count = rtc::Optional<int>(); 290 sink_wants_.target_pixel_count = rtc::Optional<int>();
247 if (source_) 291 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
248 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
249 return true; 292 return true;
250 } 293 }
251 294
252 void RequestFramerateLowerThan(int framerate_fps) { 295 bool RequestFramerateLowerThan(int fps) {
296 // Called on the encoder task queue.
297 // The input video frame rate will be scaled down to 2/3, rounding down.
298 return RestrictFramerate((fps * 2) / 3);
299 }
300
301 bool RequestHigherResolutionThan(int pixel_count) {
253 // Called on the encoder task queue. 302 // Called on the encoder task queue.
254 rtc::CritScope lock(&crit_); 303 rtc::CritScope lock(&crit_);
255 if (!IsFramerateScalingEnabledLocked()) { 304 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) {
256 // This can happen since |degradation_preference_| is set on libjingle's 305 // This can happen since |degradation_preference_| is set on libjingle's
257 // worker thread but the adaptation is done on the encoder task queue. 306 // worker thread but the adaptation is done on the encoder task queue.
258 return; 307 return false;
259 } 308 }
260 // The input video frame rate will be scaled down to 2/3 of input fps, 309 int max_pixels_wanted = pixel_count;
261 // rounding down. 310 if (max_pixels_wanted != std::numeric_limits<int>::max())
262 const int framerate_wanted = 311 max_pixels_wanted = pixel_count * 4;
263 std::max(kMinFramerateFps, (framerate_fps * 2) / 3);
264 sink_wants_.max_framerate_fps = framerate_wanted;
265 if (source_)
266 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
267 }
268 312
269 void RequestHigherResolutionThan(int pixel_count) { 313 if (max_pixels_wanted <= sink_wants_.max_pixel_count)
270 rtc::CritScope lock(&crit_); 314 return false;
271 if (!IsResolutionScalingEnabledLocked()) {
272 // This can happen since |degradation_preference_| is set on libjingle's
273 // worker thread but the adaptation is done on the encoder task queue.
274 return;
275 }
276 315
277 if (pixel_count == std::numeric_limits<int>::max()) { 316 sink_wants_.max_pixel_count = max_pixels_wanted;
317 if (max_pixels_wanted == std::numeric_limits<int>::max()) {
278 // Remove any constraints. 318 // Remove any constraints.
279 sink_wants_.target_pixel_count.reset(); 319 sink_wants_.target_pixel_count.reset();
280 sink_wants_.max_pixel_count = std::numeric_limits<int>::max();
281 } else { 320 } else {
282 // On step down we request at most 3/5 the pixel count of the previous 321 // On step down we request at most 3/5 the pixel count of the previous
283 // resolution, so in order to take "one step up" we request a resolution 322 // resolution, so in order to take "one step up" we request a resolution
284 // as close as possible to 5/3 of the current resolution. The actual pixel 323 // as close as possible to 5/3 of the current resolution. The actual pixel
285 // count selected depends on the capabilities of the source. In order to 324 // count selected depends on the capabilities of the source. In order to
286 // not take a too large step up, we cap the requested pixel count to be at 325 // not take a too large step up, we cap the requested pixel count to be at
287 // most four time the current number of pixels. 326 // most four time the current number of pixels.
288 sink_wants_.target_pixel_count = 327 sink_wants_.target_pixel_count =
289 rtc::Optional<int>((pixel_count * 5) / 3); 328 rtc::Optional<int>((pixel_count * 5) / 3);
290 sink_wants_.max_pixel_count = pixel_count * 4;
291 } 329 }
292 if (source_) 330 LOG(LS_INFO) << "Scaling up resolution";
293 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); 331 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
332 return true;
294 } 333 }
295 334
296 void RequestHigherFramerateThan(int framerate_fps) { 335 bool RequestHigherFramerateThan(int fps) {
336 // Called on the encoder task queue.
337 // The input frame rate will be scaled up to the last step, with rounding.
338 int framerate_wanted = fps;
339 if (fps != std::numeric_limits<int>::max())
340 framerate_wanted = (fps * 3) / 2;
341
342 return IncreaseFramerate(framerate_wanted);
343 }
344
345 bool RestrictFramerate(int fps) {
297 // Called on the encoder task queue. 346 // Called on the encoder task queue.
298 rtc::CritScope lock(&crit_); 347 rtc::CritScope lock(&crit_);
299 if (!IsFramerateScalingEnabledLocked()) { 348 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_))
300 // This can happen since |degradation_preference_| is set on libjingle's 349 return false;
301 // worker thread but the adaptation is done on the encoder task queue. 350
302 return; 351 const int fps_wanted = std::max(kMinFramerateFps, fps);
303 } 352 if (fps_wanted >= sink_wants_.max_framerate_fps)
304 if (framerate_fps == std::numeric_limits<int>::max()) { 353 return false;
305 // Remove any restrains. 354
306 sink_wants_.max_framerate_fps = std::numeric_limits<int>::max(); 355 LOG(LS_INFO) << "Scaling down framerate: " << fps_wanted;
307 } else { 356 sink_wants_.max_framerate_fps = fps_wanted;
308 // The input video frame rate will be scaled up to the last step, with 357 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
309 // rounding. 358 return true;
310 const int framerate_wanted = (framerate_fps * 3) / 2; 359 }
311 sink_wants_.max_framerate_fps = framerate_wanted; 360
312 } 361 bool IncreaseFramerate(int fps) {
313 if (source_) 362 // Called on the encoder task queue.
314 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); 363 rtc::CritScope lock(&crit_);
364 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_))
365 return false;
366
367 const int fps_wanted = std::max(kMinFramerateFps, fps);
368 if (fps_wanted <= sink_wants_.max_framerate_fps)
369 return false;
370
371 LOG(LS_INFO) << "Scaling up framerate: " << fps_wanted;
372 sink_wants_.max_framerate_fps = fps_wanted;
373 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants());
374 return true;
315 } 375 }
316 376
317 private: 377 private:
318 bool IsResolutionScalingEnabledLocked() const
319 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
320 return degradation_preference_ ==
321 VideoSendStream::DegradationPreference::kMaintainFramerate ||
322 degradation_preference_ ==
323 VideoSendStream::DegradationPreference::kBalanced;
324 }
325
326 bool IsFramerateScalingEnabledLocked() const
327 EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
328 // TODO(sprang): Also accept kBalanced here?
329 return degradation_preference_ ==
330 VideoSendStream::DegradationPreference::kMaintainResolution;
331 }
332
333 rtc::CriticalSection crit_; 378 rtc::CriticalSection crit_;
334 rtc::SequencedTaskChecker main_checker_; 379 rtc::SequencedTaskChecker main_checker_;
335 ViEEncoder* const vie_encoder_; 380 ViEEncoder* const vie_encoder_;
336 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); 381 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_);
337 VideoSendStream::DegradationPreference degradation_preference_ 382 VideoSendStream::DegradationPreference degradation_preference_
338 GUARDED_BY(&crit_); 383 GUARDED_BY(&crit_);
339 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); 384 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_);
340 385
341 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); 386 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy);
342 }; 387 };
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
638 return last_observed_bitrate_bps_ == 0; 683 return last_observed_bitrate_bps_ == 0;
639 } 684 }
640 685
641 void ViEEncoder::TraceFrameDropStart() { 686 void ViEEncoder::TraceFrameDropStart() {
642 RTC_DCHECK_RUN_ON(&encoder_queue_); 687 RTC_DCHECK_RUN_ON(&encoder_queue_);
643 // Start trace event only on the first frame after encoder is paused. 688 // Start trace event only on the first frame after encoder is paused.
644 if (!encoder_paused_and_dropped_frame_) { 689 if (!encoder_paused_and_dropped_frame_) {
645 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this); 690 TRACE_EVENT_ASYNC_BEGIN0("webrtc", "EncoderPaused", this);
646 } 691 }
647 encoder_paused_and_dropped_frame_ = true; 692 encoder_paused_and_dropped_frame_ = true;
648 return;
649 } 693 }
650 694
651 void ViEEncoder::TraceFrameDropEnd() { 695 void ViEEncoder::TraceFrameDropEnd() {
652 RTC_DCHECK_RUN_ON(&encoder_queue_); 696 RTC_DCHECK_RUN_ON(&encoder_queue_);
653 // End trace event on first frame after encoder resumes, if frame was dropped. 697 // End trace event on first frame after encoder resumes, if frame was dropped.
654 if (encoder_paused_and_dropped_frame_) { 698 if (encoder_paused_and_dropped_frame_) {
655 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this); 699 TRACE_EVENT_ASYNC_END0("webrtc", "EncoderPaused", this);
656 } 700 }
657 encoder_paused_and_dropped_frame_ = false; 701 encoder_paused_and_dropped_frame_ = false;
658 } 702 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 stats_proxy_->GetStats().input_frame_rate, 854 stats_proxy_->GetStats().input_frame_rate,
811 AdaptationRequest::Mode::kAdaptDown}; 855 AdaptationRequest::Mode::kAdaptDown};
812 856
813 bool downgrade_requested = 857 bool downgrade_requested =
814 last_adaptation_request_ && 858 last_adaptation_request_ &&
815 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown; 859 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown;
816 860
817 int max_downgrades = 0; 861 int max_downgrades = 0;
818 switch (degradation_preference_) { 862 switch (degradation_preference_) {
819 case VideoSendStream::DegradationPreference::kBalanced: 863 case VideoSendStream::DegradationPreference::kBalanced:
820 FALLTHROUGH(); 864 max_downgrades = kMaxCpuResolutionDowngrades;
865 break;
821 case VideoSendStream::DegradationPreference::kMaintainFramerate: 866 case VideoSendStream::DegradationPreference::kMaintainFramerate:
822 max_downgrades = kMaxCpuResolutionDowngrades; 867 max_downgrades = kMaxCpuResolutionDowngrades;
823 if (downgrade_requested && 868 if (downgrade_requested &&
824 adaptation_request.input_pixel_count_ >= 869 adaptation_request.input_pixel_count_ >=
825 last_adaptation_request_->input_pixel_count_) { 870 last_adaptation_request_->input_pixel_count_) {
826 // Don't request lower resolution if the current resolution is not 871 // Don't request lower resolution if the current resolution is not
827 // lower than the last time we asked for the resolution to be lowered. 872 // lower than the last time we asked for the resolution to be lowered.
828 return; 873 return;
829 } 874 }
830 break; 875 break;
(...skipping 14 matching lines...) Expand all
845 case VideoSendStream::DegradationPreference::kDegradationDisabled: 890 case VideoSendStream::DegradationPreference::kDegradationDisabled:
846 return; 891 return;
847 } 892 }
848 893
849 if (reason == kCpu) { 894 if (reason == kCpu) {
850 if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades) 895 if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades)
851 return; 896 return;
852 } 897 }
853 898
854 switch (degradation_preference_) { 899 switch (degradation_preference_) {
855 case VideoSendStream::DegradationPreference::kBalanced: 900 case VideoSendStream::DegradationPreference::kBalanced: {
901 // Try scale down framerate, if lower.
902 int max_fps = MaxFpsForBitrateAndResolution(
903 last_observed_bitrate_bps_, last_frame_info_->pixel_count());
904 if (source_proxy_->RestrictFramerate(max_fps)) {
905 GetAdaptCounter().IncrementFramerate(reason);
906 break;
907 }
908 // Scale down resolution.
856 FALLTHROUGH(); 909 FALLTHROUGH();
910 }
857 case VideoSendStream::DegradationPreference::kMaintainFramerate: 911 case VideoSendStream::DegradationPreference::kMaintainFramerate:
912 // Scale down resolution.
858 if (!source_proxy_->RequestResolutionLowerThan( 913 if (!source_proxy_->RequestResolutionLowerThan(
859 adaptation_request.input_pixel_count_)) { 914 adaptation_request.input_pixel_count_)) {
860 return; 915 return;
861 } 916 }
862 LOG(LS_INFO) << "Scaling down resolution."; 917 GetAdaptCounter().IncrementResolution(reason);
863 GetAdaptCounter().IncrementResolution(reason, 1);
864 break; 918 break;
865 case VideoSendStream::DegradationPreference::kMaintainResolution: 919 case VideoSendStream::DegradationPreference::kMaintainResolution:
866 source_proxy_->RequestFramerateLowerThan( 920 // Scale down framerate.
867 adaptation_request.framerate_fps_); 921 if (!source_proxy_->RequestFramerateLowerThan(
868 LOG(LS_INFO) << "Scaling down framerate."; 922 adaptation_request.framerate_fps_)) {
869 GetAdaptCounter().IncrementFramerate(reason, 1); 923 return;
924 }
925 GetAdaptCounter().IncrementFramerate(reason);
870 break; 926 break;
871 case VideoSendStream::DegradationPreference::kDegradationDisabled: 927 case VideoSendStream::DegradationPreference::kDegradationDisabled:
872 RTC_NOTREACHED(); 928 RTC_NOTREACHED();
873 } 929 }
874 930
875 last_adaptation_request_.emplace(adaptation_request); 931 last_adaptation_request_.emplace(adaptation_request);
876 932
877 UpdateAdaptationStats(reason); 933 UpdateAdaptationStats(reason);
878 934
879 LOG(LS_INFO) << GetConstAdaptCounter().ToString(); 935 LOG(LS_INFO) << GetConstAdaptCounter().ToString();
(...skipping 10 matching lines...) Expand all
890 946
891 AdaptationRequest adaptation_request = { 947 AdaptationRequest adaptation_request = {
892 last_frame_info_->pixel_count(), 948 last_frame_info_->pixel_count(),
893 stats_proxy_->GetStats().input_frame_rate, 949 stats_proxy_->GetStats().input_frame_rate,
894 AdaptationRequest::Mode::kAdaptUp}; 950 AdaptationRequest::Mode::kAdaptUp};
895 951
896 bool adapt_up_requested = 952 bool adapt_up_requested =
897 last_adaptation_request_ && 953 last_adaptation_request_ &&
898 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp; 954 last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp;
899 955
956 if (degradation_preference_ ==
957 VideoSendStream::DegradationPreference::kMaintainFramerate) {
958 if (adapt_up_requested &&
959 adaptation_request.input_pixel_count_ <=
960 last_adaptation_request_->input_pixel_count_) {
961 // Don't request higher resolution if the current resolution is not
962 // higher than the last time we asked for the resolution to be higher.
963 return;
964 }
965 }
966
900 switch (degradation_preference_) { 967 switch (degradation_preference_) {
901 case VideoSendStream::DegradationPreference::kBalanced: 968 case VideoSendStream::DegradationPreference::kBalanced: {
969 // Try scale up framerate, if higher.
970 int fps = MaxFps(last_frame_info_->pixel_count());
971 if (source_proxy_->IncreaseFramerate(fps)) {
972 GetAdaptCounter().DecrementFramerate(reason);
973 break;
974 }
975 // Scale up resolution.
902 FALLTHROUGH(); 976 FALLTHROUGH();
903 case VideoSendStream::DegradationPreference::kMaintainFramerate: 977 }
904 if (adapt_up_requested && 978 case VideoSendStream::DegradationPreference::kMaintainFramerate: {
905 adaptation_request.input_pixel_count_ <= 979 // Scale up resolution.
906 last_adaptation_request_->input_pixel_count_) { 980 int pixel_count = adaptation_request.input_pixel_count_;
907 // Don't request higher resolution if the current resolution is not 981 if (adapt_counter.ResolutionCount() == 1) {
908 // higher than the last time we asked for the resolution to be higher. 982 LOG(LS_INFO) << "Removing resolution down-scaling setting.";
983 pixel_count = std::numeric_limits<int>::max();
984 }
985 if (!source_proxy_->RequestHigherResolutionThan(pixel_count))
909 return; 986 return;
987 GetAdaptCounter().DecrementResolution(reason);
988 break;
989 }
990 case VideoSendStream::DegradationPreference::kMaintainResolution: {
991 // Scale up framerate.
992 int fps = adaptation_request.framerate_fps_;
993 if (adapt_counter.FramerateCount() == 1) {
994 LOG(LS_INFO) << "Removing framerate down-scaling setting.";
995 fps = std::numeric_limits<int>::max();
910 } 996 }
997 if (!source_proxy_->RequestHigherFramerateThan(fps))
998 return;
999 GetAdaptCounter().DecrementFramerate(reason);
911 break; 1000 break;
912 case VideoSendStream::DegradationPreference::kMaintainResolution: 1001 }
913 // TODO(sprang): Don't request higher framerate if we are already at
914 // max requested fps?
915 break;
916 case VideoSendStream::DegradationPreference::kDegradationDisabled: 1002 case VideoSendStream::DegradationPreference::kDegradationDisabled:
917 return; 1003 return;
918 } 1004 }
919 1005
920 switch (degradation_preference_) {
921 case VideoSendStream::DegradationPreference::kBalanced:
922 FALLTHROUGH();
923 case VideoSendStream::DegradationPreference::kMaintainFramerate:
924 if (adapt_counter.TotalCount() == 1) {
925 LOG(LS_INFO) << "Removing resolution down-scaling setting.";
926 source_proxy_->RequestHigherResolutionThan(
927 std::numeric_limits<int>::max());
928 } else {
929 source_proxy_->RequestHigherResolutionThan(
930 adaptation_request.input_pixel_count_);
931 LOG(LS_INFO) << "Scaling up resolution.";
932 }
933 GetAdaptCounter().IncrementResolution(reason, -1);
934 break;
935 case VideoSendStream::DegradationPreference::kMaintainResolution:
936 if (adapt_counter.TotalCount() == 1) {
937 LOG(LS_INFO) << "Removing framerate down-scaling setting.";
938 source_proxy_->RequestHigherFramerateThan(
939 std::numeric_limits<int>::max());
940 } else {
941 source_proxy_->RequestHigherFramerateThan(
942 adaptation_request.framerate_fps_);
943 LOG(LS_INFO) << "Scaling up framerate.";
944 }
945 GetAdaptCounter().IncrementFramerate(reason, -1);
946 break;
947 case VideoSendStream::DegradationPreference::kDegradationDisabled:
948 RTC_NOTREACHED();
949 }
950
951 last_adaptation_request_.emplace(adaptation_request); 1006 last_adaptation_request_.emplace(adaptation_request);
952 1007
953 UpdateAdaptationStats(reason); 1008 UpdateAdaptationStats(reason);
954 1009
955 LOG(LS_INFO) << adapt_counter.ToString(); 1010 LOG(LS_INFO) << adapt_counter.ToString();
956 } 1011 }
957 1012
958 void ViEEncoder::UpdateAdaptationStats(AdaptReason reason) { 1013 void ViEEncoder::UpdateAdaptationStats(AdaptReason reason) {
959 switch (reason) { 1014 switch (reason) {
960 case kCpu: 1015 case kCpu:
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 } 1051 }
997 1052
998 const ViEEncoder::AdaptCounter& ViEEncoder::GetConstAdaptCounter() { 1053 const ViEEncoder::AdaptCounter& ViEEncoder::GetConstAdaptCounter() {
999 return adapt_counters_[degradation_preference_]; 1054 return adapt_counters_[degradation_preference_];
1000 } 1055 }
1001 1056
1002 // Class holding adaptation information. 1057 // Class holding adaptation information.
1003 ViEEncoder::AdaptCounter::AdaptCounter() { 1058 ViEEncoder::AdaptCounter::AdaptCounter() {
1004 fps_counters_.resize(kScaleReasonSize); 1059 fps_counters_.resize(kScaleReasonSize);
1005 resolution_counters_.resize(kScaleReasonSize); 1060 resolution_counters_.resize(kScaleReasonSize);
1061 RTC_DCHECK_EQ(fps_counters_.size(), 2) << "Update MoveCount()";
kthelgason 2017/05/30 11:17:06 Perhaps it would be better to add a `static_assert
åsapersson 2017/06/08 13:55:33 Done.
1062 RTC_DCHECK_EQ(resolution_counters_.size(), 2) << "Update MoveCount()";
1006 } 1063 }
1007 1064
1008 ViEEncoder::AdaptCounter::~AdaptCounter() {} 1065 ViEEncoder::AdaptCounter::~AdaptCounter() {}
1009 1066
1010 std::string ViEEncoder::AdaptCounter::ToString() const { 1067 std::string ViEEncoder::AdaptCounter::ToString() const {
1011 std::stringstream ss; 1068 std::stringstream ss;
1012 ss << "Downgrade counts: fps: {" << ToString(fps_counters_); 1069 ss << "Downgrade counts: fps: {" << ToString(fps_counters_);
1013 ss << "}, resolution: {" << ToString(resolution_counters_) << "}"; 1070 ss << "}, resolution: {" << ToString(resolution_counters_) << "}";
1014 return ss.str(); 1071 return ss.str();
1015 } 1072 }
1016 1073
1017 ViEEncoder::AdaptCounts ViEEncoder::AdaptCounter::Counts(int reason) const { 1074 ViEEncoder::AdaptCounts ViEEncoder::AdaptCounter::Counts(int reason) const {
1018 AdaptCounts counts; 1075 AdaptCounts counts;
1019 counts.fps = fps_counters_[reason]; 1076 counts.fps = fps_counters_[reason];
1020 counts.resolution = resolution_counters_[reason]; 1077 counts.resolution = resolution_counters_[reason];
1021 return counts; 1078 return counts;
1022 } 1079 }
1023 1080
1024 void ViEEncoder::AdaptCounter::IncrementFramerate(int reason, int delta) { 1081 void ViEEncoder::AdaptCounter::IncrementFramerate(int reason) {
1025 fps_counters_[reason] += delta; 1082 ++(fps_counters_[reason]);
1026 } 1083 }
1027 1084
1028 void ViEEncoder::AdaptCounter::IncrementResolution(int reason, int delta) { 1085 void ViEEncoder::AdaptCounter::IncrementResolution(int reason) {
1029 resolution_counters_[reason] += delta; 1086 ++(resolution_counters_[reason]);
1087 }
1088
1089 void ViEEncoder::AdaptCounter::DecrementFramerate(int reason) {
1090 if (fps_counters_[reason] == 0) {
1091 // Adapt up is in a different order, switch reason.
1092 // E.g. framerate adapt down: quality (2), framerate adapt up: cpu (3).
1093 // 1. Down resolution (cpu): res={quality:0,cpu:1}, fps={quality:0,cpu:0}
1094 // 2. Down fps (quality): res={quality:0,cpu:1}, fps={quality:1,cpu:0}
1095 // 3. Up fps (cpu): res={quality:1,cpu:0}, fps={quality:0,cpu:0}
1096 // 4. Up resolution (quality): res={quality:0,cpu:0}, fps={quality:0,cpu:0}
1097 MoveCount(&resolution_counters_, reason);
1098 MoveCount(&fps_counters_, (reason + 1) % kScaleReasonSize);
1099 }
1100 --(fps_counters_[reason]);
1101 RTC_DCHECK_GE(fps_counters_[reason], 0);
1102 }
1103
1104 void ViEEncoder::AdaptCounter::DecrementResolution(int reason) {
1105 if (resolution_counters_[reason] == 0) {
1106 // Adapt up is in a different order, switch reason.
1107 // E.g. resolution adapt down: quality, resolution adapt up: cpu.
1108 MoveCount(&fps_counters_, reason);
1109 MoveCount(&resolution_counters_, (reason + 1) % kScaleReasonSize);
1110 }
1111 --(resolution_counters_[reason]);
1112 RTC_DCHECK_GE(resolution_counters_[reason], 0);
1030 } 1113 }
1031 1114
1032 int ViEEncoder::AdaptCounter::FramerateCount() const { 1115 int ViEEncoder::AdaptCounter::FramerateCount() const {
1033 return Count(fps_counters_); 1116 return Count(fps_counters_);
1034 } 1117 }
1035 1118
1036 int ViEEncoder::AdaptCounter::ResolutionCount() const { 1119 int ViEEncoder::AdaptCounter::ResolutionCount() const {
1037 return Count(resolution_counters_); 1120 return Count(resolution_counters_);
1038 } 1121 }
1039 1122
(...skipping 10 matching lines...) Expand all
1050 } 1133 }
1051 1134
1052 int ViEEncoder::AdaptCounter::TotalCount(int reason) const { 1135 int ViEEncoder::AdaptCounter::TotalCount(int reason) const {
1053 return FramerateCount(reason) + ResolutionCount(reason); 1136 return FramerateCount(reason) + ResolutionCount(reason);
1054 } 1137 }
1055 1138
1056 int ViEEncoder::AdaptCounter::Count(const std::vector<int>& counters) const { 1139 int ViEEncoder::AdaptCounter::Count(const std::vector<int>& counters) const {
1057 return std::accumulate(counters.begin(), counters.end(), 0); 1140 return std::accumulate(counters.begin(), counters.end(), 0);
1058 } 1141 }
1059 1142
1143 void ViEEncoder::AdaptCounter::MoveCount(std::vector<int>* counters,
1144 int from_reason) {
1145 int to_reason = (from_reason + 1) % kScaleReasonSize;
1146 ++((*counters)[to_reason]);
1147 --((*counters)[from_reason]);
1148 RTC_DCHECK_GE((*counters)[from_reason], 0);
kthelgason 2017/05/30 11:17:06 This postcondition is not at all clear to me. If t
åsapersson 2017/06/08 13:55:33 Done.
1149 }
1150
1060 std::string ViEEncoder::AdaptCounter::ToString( 1151 std::string ViEEncoder::AdaptCounter::ToString(
1061 const std::vector<int>& counters) const { 1152 const std::vector<int>& counters) const {
1062 std::stringstream ss; 1153 std::stringstream ss;
1063 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { 1154 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) {
1064 ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; 1155 ss << (reason ? " cpu" : "quality") << ":" << counters[reason];
1065 } 1156 }
1066 return ss.str(); 1157 return ss.str();
1067 } 1158 }
1068 1159
1069 } // namespace webrtc 1160 } // 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