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 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 wants.max_pixel_count = std::numeric_limits<int>::max(); | 223 wants.max_pixel_count = std::numeric_limits<int>::max(); |
224 wants.target_pixel_count.reset(); | 224 wants.target_pixel_count.reset(); |
225 wants.max_framerate_fps = std::numeric_limits<int>::max(); | 225 wants.max_framerate_fps = std::numeric_limits<int>::max(); |
226 } | 226 } |
227 return wants; | 227 return wants; |
228 } | 228 } |
229 | 229 |
230 bool RequestResolutionLowerThan(int pixel_count) { | 230 bool RequestResolutionLowerThan(int pixel_count) { |
231 // Called on the encoder task queue. | 231 // Called on the encoder task queue. |
232 rtc::CritScope lock(&crit_); | 232 rtc::CritScope lock(&crit_); |
233 if (!IsResolutionScalingEnabled(degradation_preference_)) { | 233 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
234 // This can happen since |degradation_preference_| is set on libjingle's | 234 // This can happen since |degradation_preference_| is set on libjingle's |
235 // worker thread but the adaptation is done on the encoder task queue. | 235 // worker thread but the adaptation is done on the encoder task queue. |
236 return false; | 236 return false; |
237 } | 237 } |
238 // The input video frame size will have a resolution with less than or | 238 // 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 | 239 // |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; | 240 const int pixels_wanted = (pixel_count * 3) / 5; |
242 if (pixels_wanted < kMinPixelsPerFrame) | 241 if (pixels_wanted < kMinPixelsPerFrame || |
| 242 pixels_wanted >= sink_wants_.max_pixel_count) { |
243 return false; | 243 return false; |
244 | 244 } |
| 245 LOG(LS_INFO) << "Scaling down resolution, max pixels: " << pixels_wanted; |
245 sink_wants_.max_pixel_count = pixels_wanted; | 246 sink_wants_.max_pixel_count = pixels_wanted; |
246 sink_wants_.target_pixel_count = rtc::Optional<int>(); | 247 sink_wants_.target_pixel_count = rtc::Optional<int>(); |
247 if (source_) | 248 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
248 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | |
249 return true; | 249 return true; |
250 } | 250 } |
251 | 251 |
252 void RequestFramerateLowerThan(int framerate_fps) { | 252 bool RequestFramerateLowerThan(int fps) { |
| 253 // Called on the encoder task queue. |
| 254 // The input video frame rate will be scaled down to 2/3, rounding down. |
| 255 return RestrictFramerate((fps * 2) / 3); |
| 256 } |
| 257 |
| 258 bool RequestHigherResolutionThan(int pixel_count) { |
253 // Called on the encoder task queue. | 259 // Called on the encoder task queue. |
254 rtc::CritScope lock(&crit_); | 260 rtc::CritScope lock(&crit_); |
255 if (!IsFramerateScalingEnabled(degradation_preference_)) { | 261 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
256 // This can happen since |degradation_preference_| is set on libjingle's | 262 // This can happen since |degradation_preference_| is set on libjingle's |
257 // worker thread but the adaptation is done on the encoder task queue. | 263 // worker thread but the adaptation is done on the encoder task queue. |
258 return; | 264 return false; |
259 } | 265 } |
260 // The input video frame rate will be scaled down to 2/3 of input fps, | 266 int max_pixels_wanted = pixel_count; |
261 // rounding down. | 267 if (max_pixels_wanted != std::numeric_limits<int>::max()) |
262 const int framerate_wanted = | 268 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 | 269 |
269 void RequestHigherResolutionThan(int pixel_count) { | 270 if (max_pixels_wanted <= sink_wants_.max_pixel_count) |
270 rtc::CritScope lock(&crit_); | 271 return false; |
271 if (!IsResolutionScalingEnabled(degradation_preference_)) { | |
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 | 272 |
277 if (pixel_count == std::numeric_limits<int>::max()) { | 273 sink_wants_.max_pixel_count = max_pixels_wanted; |
| 274 if (max_pixels_wanted == std::numeric_limits<int>::max()) { |
278 // Remove any constraints. | 275 // Remove any constraints. |
279 sink_wants_.target_pixel_count.reset(); | 276 sink_wants_.target_pixel_count.reset(); |
280 sink_wants_.max_pixel_count = std::numeric_limits<int>::max(); | |
281 } else { | 277 } else { |
282 // On step down we request at most 3/5 the pixel count of the previous | 278 // 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 | 279 // 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 | 280 // 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 | 281 // 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 | 282 // 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. | 283 // most four time the current number of pixels. |
288 sink_wants_.target_pixel_count = | 284 sink_wants_.target_pixel_count = |
289 rtc::Optional<int>((pixel_count * 5) / 3); | 285 rtc::Optional<int>((pixel_count * 5) / 3); |
290 sink_wants_.max_pixel_count = pixel_count * 4; | |
291 } | 286 } |
292 if (source_) | 287 LOG(LS_INFO) << "Scaling up resolution, max pixels: " << max_pixels_wanted; |
293 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 288 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
| 289 return true; |
294 } | 290 } |
295 | 291 |
296 void RequestHigherFramerateThan(int framerate_fps) { | 292 bool RequestHigherFramerateThan(int fps) { |
| 293 // Called on the encoder task queue. |
| 294 // The input frame rate will be scaled up to the last step, with rounding. |
| 295 int framerate_wanted = fps; |
| 296 if (fps != std::numeric_limits<int>::max()) |
| 297 framerate_wanted = (fps * 3) / 2; |
| 298 |
| 299 return IncreaseFramerate(framerate_wanted); |
| 300 } |
| 301 |
| 302 bool RestrictFramerate(int fps) { |
297 // Called on the encoder task queue. | 303 // Called on the encoder task queue. |
298 rtc::CritScope lock(&crit_); | 304 rtc::CritScope lock(&crit_); |
299 if (!IsFramerateScalingEnabled(degradation_preference_)) { | 305 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
300 // This can happen since |degradation_preference_| is set on libjingle's | 306 return false; |
301 // worker thread but the adaptation is done on the encoder task queue. | 307 |
302 return; | 308 const int fps_wanted = std::max(kMinFramerateFps, fps); |
303 } | 309 if (fps_wanted >= sink_wants_.max_framerate_fps) |
304 if (framerate_fps == std::numeric_limits<int>::max()) { | 310 return false; |
305 // Remove any restrains. | 311 |
306 sink_wants_.max_framerate_fps = std::numeric_limits<int>::max(); | 312 LOG(LS_INFO) << "Scaling down framerate: " << fps_wanted; |
307 } else { | 313 sink_wants_.max_framerate_fps = fps_wanted; |
308 // The input video frame rate will be scaled up to the last step, with | 314 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
309 // rounding. | 315 return true; |
310 const int framerate_wanted = (framerate_fps * 3) / 2; | 316 } |
311 sink_wants_.max_framerate_fps = framerate_wanted; | 317 |
312 } | 318 bool IncreaseFramerate(int fps) { |
313 if (source_) | 319 // Called on the encoder task queue. |
314 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 320 rtc::CritScope lock(&crit_); |
| 321 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
| 322 return false; |
| 323 |
| 324 const int fps_wanted = std::max(kMinFramerateFps, fps); |
| 325 if (fps_wanted <= sink_wants_.max_framerate_fps) |
| 326 return false; |
| 327 |
| 328 LOG(LS_INFO) << "Scaling up framerate: " << fps_wanted; |
| 329 sink_wants_.max_framerate_fps = fps_wanted; |
| 330 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); |
| 331 return true; |
315 } | 332 } |
316 | 333 |
317 private: | 334 private: |
318 rtc::CriticalSection crit_; | 335 rtc::CriticalSection crit_; |
319 rtc::SequencedTaskChecker main_checker_; | 336 rtc::SequencedTaskChecker main_checker_; |
320 ViEEncoder* const vie_encoder_; | 337 ViEEncoder* const vie_encoder_; |
321 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); | 338 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); |
322 VideoSendStream::DegradationPreference degradation_preference_ | 339 VideoSendStream::DegradationPreference degradation_preference_ |
323 GUARDED_BY(&crit_); | 340 GUARDED_BY(&crit_); |
324 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); | 341 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 | 837 |
821 if (reason == kCpu) { | 838 if (reason == kCpu) { |
822 if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades) | 839 if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades) |
823 return; | 840 return; |
824 } | 841 } |
825 | 842 |
826 switch (degradation_preference_) { | 843 switch (degradation_preference_) { |
827 case VideoSendStream::DegradationPreference::kBalanced: | 844 case VideoSendStream::DegradationPreference::kBalanced: |
828 FALLTHROUGH(); | 845 FALLTHROUGH(); |
829 case VideoSendStream::DegradationPreference::kMaintainFramerate: | 846 case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| 847 // Scale down resolution. |
830 if (!source_proxy_->RequestResolutionLowerThan( | 848 if (!source_proxy_->RequestResolutionLowerThan( |
831 adaptation_request.input_pixel_count_)) { | 849 adaptation_request.input_pixel_count_)) { |
832 return; | 850 return; |
833 } | 851 } |
834 LOG(LS_INFO) << "Scaling down resolution."; | |
835 GetAdaptCounter().IncrementResolution(reason, 1); | 852 GetAdaptCounter().IncrementResolution(reason, 1); |
836 break; | 853 break; |
837 case VideoSendStream::DegradationPreference::kMaintainResolution: | 854 case VideoSendStream::DegradationPreference::kMaintainResolution: |
838 source_proxy_->RequestFramerateLowerThan( | 855 // Scale down framerate. |
839 adaptation_request.framerate_fps_); | 856 if (!source_proxy_->RequestFramerateLowerThan( |
840 LOG(LS_INFO) << "Scaling down framerate."; | 857 adaptation_request.framerate_fps_)) { |
| 858 return; |
| 859 } |
841 GetAdaptCounter().IncrementFramerate(reason, 1); | 860 GetAdaptCounter().IncrementFramerate(reason, 1); |
842 break; | 861 break; |
843 case VideoSendStream::DegradationPreference::kDegradationDisabled: | 862 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
844 RTC_NOTREACHED(); | 863 RTC_NOTREACHED(); |
845 } | 864 } |
846 | 865 |
847 last_adaptation_request_.emplace(adaptation_request); | 866 last_adaptation_request_.emplace(adaptation_request); |
848 | 867 |
849 UpdateAdaptationStats(reason); | 868 UpdateAdaptationStats(reason); |
850 | 869 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
885 // TODO(sprang): Don't request higher framerate if we are already at | 904 // TODO(sprang): Don't request higher framerate if we are already at |
886 // max requested fps? | 905 // max requested fps? |
887 break; | 906 break; |
888 case VideoSendStream::DegradationPreference::kDegradationDisabled: | 907 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
889 return; | 908 return; |
890 } | 909 } |
891 | 910 |
892 switch (degradation_preference_) { | 911 switch (degradation_preference_) { |
893 case VideoSendStream::DegradationPreference::kBalanced: | 912 case VideoSendStream::DegradationPreference::kBalanced: |
894 FALLTHROUGH(); | 913 FALLTHROUGH(); |
895 case VideoSendStream::DegradationPreference::kMaintainFramerate: | 914 case VideoSendStream::DegradationPreference::kMaintainFramerate: { |
896 if (adapt_counter.TotalCount() == 1) { | 915 // Scale up resolution. |
| 916 int pixel_count = adaptation_request.input_pixel_count_; |
| 917 if (adapt_counter.ResolutionCount() == 1) { |
897 LOG(LS_INFO) << "Removing resolution down-scaling setting."; | 918 LOG(LS_INFO) << "Removing resolution down-scaling setting."; |
898 source_proxy_->RequestHigherResolutionThan( | 919 pixel_count = std::numeric_limits<int>::max(); |
899 std::numeric_limits<int>::max()); | |
900 } else { | |
901 source_proxy_->RequestHigherResolutionThan( | |
902 adaptation_request.input_pixel_count_); | |
903 LOG(LS_INFO) << "Scaling up resolution."; | |
904 } | 920 } |
| 921 if (!source_proxy_->RequestHigherResolutionThan(pixel_count)) |
| 922 return; |
905 GetAdaptCounter().IncrementResolution(reason, -1); | 923 GetAdaptCounter().IncrementResolution(reason, -1); |
906 break; | 924 break; |
907 case VideoSendStream::DegradationPreference::kMaintainResolution: | 925 } |
908 if (adapt_counter.TotalCount() == 1) { | 926 case VideoSendStream::DegradationPreference::kMaintainResolution: { |
| 927 // Scale up framerate. |
| 928 int fps = adaptation_request.framerate_fps_; |
| 929 if (adapt_counter.FramerateCount() == 1) { |
909 LOG(LS_INFO) << "Removing framerate down-scaling setting."; | 930 LOG(LS_INFO) << "Removing framerate down-scaling setting."; |
910 source_proxy_->RequestHigherFramerateThan( | 931 fps = std::numeric_limits<int>::max(); |
911 std::numeric_limits<int>::max()); | |
912 } else { | |
913 source_proxy_->RequestHigherFramerateThan( | |
914 adaptation_request.framerate_fps_); | |
915 LOG(LS_INFO) << "Scaling up framerate."; | |
916 } | 932 } |
| 933 if (!source_proxy_->RequestHigherFramerateThan(fps)) |
| 934 return; |
917 GetAdaptCounter().IncrementFramerate(reason, -1); | 935 GetAdaptCounter().IncrementFramerate(reason, -1); |
918 break; | 936 break; |
| 937 } |
919 case VideoSendStream::DegradationPreference::kDegradationDisabled: | 938 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
920 RTC_NOTREACHED(); | 939 RTC_NOTREACHED(); |
921 } | 940 } |
922 | 941 |
923 last_adaptation_request_.emplace(adaptation_request); | 942 last_adaptation_request_.emplace(adaptation_request); |
924 | 943 |
925 UpdateAdaptationStats(reason); | 944 UpdateAdaptationStats(reason); |
926 | 945 |
927 LOG(LS_INFO) << adapt_counter.ToString(); | 946 LOG(LS_INFO) << adapt_counter.ToString(); |
928 } | 947 } |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1032 std::string ViEEncoder::AdaptCounter::ToString( | 1051 std::string ViEEncoder::AdaptCounter::ToString( |
1033 const std::vector<int>& counters) const { | 1052 const std::vector<int>& counters) const { |
1034 std::stringstream ss; | 1053 std::stringstream ss; |
1035 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { | 1054 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { |
1036 ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; | 1055 ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; |
1037 } | 1056 } |
1038 return ss.str(); | 1057 return ss.str(); |
1039 } | 1058 } |
1040 | 1059 |
1041 } // namespace webrtc | 1060 } // namespace webrtc |
OLD | NEW |