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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |