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 |