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 26 matching lines...) Expand all Loading... |
37 | 37 |
38 // Time interval for logging frame counts. | 38 // Time interval for logging frame counts. |
39 const int64_t kFrameLogIntervalMs = 60000; | 39 const int64_t kFrameLogIntervalMs = 60000; |
40 | 40 |
41 // We will never ask for a resolution lower than this. | 41 // We will never ask for a resolution lower than this. |
42 // TODO(kthelgason): Lower this limit when better testing | 42 // TODO(kthelgason): Lower this limit when better testing |
43 // on MediaCodec and fallback implementations are in place. | 43 // on MediaCodec and fallback implementations are in place. |
44 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206 | 44 // See https://bugs.chromium.org/p/webrtc/issues/detail?id=7206 |
45 const int kMinPixelsPerFrame = 320 * 180; | 45 const int kMinPixelsPerFrame = 320 * 180; |
46 const int kMinFramerateFps = 2; | 46 const int kMinFramerateFps = 2; |
| 47 const int kMaxFramerateFps = 120; |
47 | 48 |
48 // The maximum number of frames to drop at beginning of stream | 49 // The maximum number of frames to drop at beginning of stream |
49 // to try and achieve desired bitrate. | 50 // to try and achieve desired bitrate. |
50 const int kMaxInitialFramedrop = 4; | 51 const int kMaxInitialFramedrop = 4; |
51 | 52 |
52 // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle | |
53 // pipelining encoders better (multiple input frames before something comes | |
54 // out). This should effectively turn off CPU adaptations for systems that | |
55 // remotely cope with the load right now. | |
56 CpuOveruseOptions GetCpuOveruseOptions(bool full_overuse_time) { | |
57 CpuOveruseOptions options; | |
58 if (full_overuse_time) { | |
59 options.low_encode_usage_threshold_percent = 150; | |
60 options.high_encode_usage_threshold_percent = 200; | |
61 } | |
62 return options; | |
63 } | |
64 | |
65 uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) { | 53 uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) { |
66 if (kbps > 0) { | 54 if (kbps > 0) { |
67 if (kbps < 300 /* qvga */) { | 55 if (kbps < 300 /* qvga */) { |
68 return 320 * 240; | 56 return 320 * 240; |
69 } else if (kbps < 500 /* vga */) { | 57 } else if (kbps < 500 /* vga */) { |
70 return 640 * 480; | 58 return 640 * 480; |
71 } | 59 } |
72 } | 60 } |
73 return std::numeric_limits<uint32_t>::max(); | 61 return std::numeric_limits<uint32_t>::max(); |
74 } | 62 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 const VideoSendStream::DegradationPreference& degradation_preference) { | 188 const VideoSendStream::DegradationPreference& degradation_preference) { |
201 // Called on libjingle's worker thread. | 189 // Called on libjingle's worker thread. |
202 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); | 190 RTC_DCHECK_CALLED_SEQUENTIALLY(&main_checker_); |
203 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; | 191 rtc::VideoSourceInterface<VideoFrame>* old_source = nullptr; |
204 rtc::VideoSinkWants wants; | 192 rtc::VideoSinkWants wants; |
205 { | 193 { |
206 rtc::CritScope lock(&crit_); | 194 rtc::CritScope lock(&crit_); |
207 degradation_preference_ = degradation_preference; | 195 degradation_preference_ = degradation_preference; |
208 old_source = source_; | 196 old_source = source_; |
209 source_ = source; | 197 source_ = source; |
210 wants = GetActiveSinkWants(); | 198 wants = GetActiveSinkWantsInternal(); |
211 } | 199 } |
212 | 200 |
213 if (old_source != source && old_source != nullptr) { | 201 if (old_source != source && old_source != nullptr) { |
214 old_source->RemoveSink(vie_encoder_); | 202 old_source->RemoveSink(vie_encoder_); |
215 } | 203 } |
216 | 204 |
217 if (!source) { | 205 if (!source) { |
218 return; | 206 return; |
219 } | 207 } |
220 | 208 |
221 source->AddOrUpdateSink(vie_encoder_, wants); | 209 source->AddOrUpdateSink(vie_encoder_, wants); |
222 } | 210 } |
223 | 211 |
224 void SetWantsRotationApplied(bool rotation_applied) { | 212 void SetWantsRotationApplied(bool rotation_applied) { |
225 rtc::CritScope lock(&crit_); | 213 rtc::CritScope lock(&crit_); |
226 sink_wants_.rotation_applied = rotation_applied; | 214 sink_wants_.rotation_applied = rotation_applied; |
227 if (source_) | 215 if (source_) |
228 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | 216 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
229 } | 217 } |
230 | 218 |
231 rtc::VideoSinkWants GetActiveSinkWants() EXCLUSIVE_LOCKS_REQUIRED(&crit_) { | 219 rtc::VideoSinkWants GetActiveSinkWants() { |
232 rtc::VideoSinkWants wants = sink_wants_; | 220 rtc::CritScope lock(&crit_); |
233 // Clear any constraints from the current sink wants that don't apply to | 221 return GetActiveSinkWantsInternal(); |
234 // the used degradation_preference. | |
235 switch (degradation_preference_) { | |
236 case VideoSendStream::DegradationPreference::kBalanced: | |
237 break; | |
238 case VideoSendStream::DegradationPreference::kMaintainFramerate: | |
239 wants.max_framerate_fps = std::numeric_limits<int>::max(); | |
240 break; | |
241 case VideoSendStream::DegradationPreference::kMaintainResolution: | |
242 wants.max_pixel_count = std::numeric_limits<int>::max(); | |
243 wants.target_pixel_count.reset(); | |
244 break; | |
245 case VideoSendStream::DegradationPreference::kDegradationDisabled: | |
246 wants.max_pixel_count = std::numeric_limits<int>::max(); | |
247 wants.target_pixel_count.reset(); | |
248 wants.max_framerate_fps = std::numeric_limits<int>::max(); | |
249 } | |
250 return wants; | |
251 } | 222 } |
252 | 223 |
253 void ResetPixelFpsCount() { | 224 void ResetPixelFpsCount() { |
254 rtc::CritScope lock(&crit_); | 225 rtc::CritScope lock(&crit_); |
255 sink_wants_.max_pixel_count = std::numeric_limits<int>::max(); | 226 sink_wants_.max_pixel_count = std::numeric_limits<int>::max(); |
256 sink_wants_.target_pixel_count.reset(); | 227 sink_wants_.target_pixel_count.reset(); |
257 sink_wants_.max_framerate_fps = std::numeric_limits<int>::max(); | 228 sink_wants_.max_framerate_fps = std::numeric_limits<int>::max(); |
258 if (source_) | 229 if (source_) |
259 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); | 230 source_->AddOrUpdateSink(vie_encoder_, sink_wants_); |
260 } | 231 } |
261 | 232 |
262 bool RequestResolutionLowerThan(int pixel_count) { | 233 bool RequestResolutionLowerThan(int pixel_count) { |
263 // Called on the encoder task queue. | 234 // Called on the encoder task queue. |
264 rtc::CritScope lock(&crit_); | 235 rtc::CritScope lock(&crit_); |
265 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { | 236 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
266 // This can happen since |degradation_preference_| is set on libjingle's | 237 // This can happen since |degradation_preference_| is set on libjingle's |
267 // worker thread but the adaptation is done on the encoder task queue. | 238 // worker thread but the adaptation is done on the encoder task queue. |
268 return false; | 239 return false; |
269 } | 240 } |
270 // The input video frame size will have a resolution less than or equal to | 241 // The input video frame size will have a resolution less than or equal to |
271 // |max_pixel_count| depending on how the source can scale the frame size. | 242 // |max_pixel_count| depending on how the source can scale the frame size. |
272 const int pixels_wanted = (pixel_count * 3) / 5; | 243 const int pixels_wanted = (pixel_count * 3) / 5; |
273 if (pixels_wanted < kMinPixelsPerFrame || | 244 if (pixels_wanted < kMinPixelsPerFrame || |
274 pixels_wanted >= sink_wants_.max_pixel_count) { | 245 pixels_wanted >= sink_wants_.max_pixel_count) { |
275 return false; | 246 return false; |
276 } | 247 } |
277 LOG(LS_INFO) << "Scaling down resolution, max pixels: " << pixels_wanted; | 248 LOG(LS_INFO) << "Scaling down resolution, max pixels: " << pixels_wanted; |
278 sink_wants_.max_pixel_count = pixels_wanted; | 249 sink_wants_.max_pixel_count = pixels_wanted; |
279 sink_wants_.target_pixel_count = rtc::Optional<int>(); | 250 sink_wants_.target_pixel_count = rtc::Optional<int>(); |
280 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 251 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWantsInternal()); |
281 return true; | 252 return true; |
282 } | 253 } |
283 | 254 |
284 bool RequestFramerateLowerThan(int fps) { | 255 int RequestFramerateLowerThan(int fps) { |
285 // Called on the encoder task queue. | 256 // Called on the encoder task queue. |
286 // The input video frame rate will be scaled down to 2/3, rounding down. | 257 // The input video frame rate will be scaled down to 2/3, rounding down. |
287 return RestrictFramerate((fps * 2) / 3); | 258 int framerate_wanted = (fps * 2) / 3; |
| 259 return RestrictFramerate(framerate_wanted) ? framerate_wanted : -1; |
288 } | 260 } |
289 | 261 |
290 bool RequestHigherResolutionThan(int pixel_count) { | 262 bool RequestHigherResolutionThan(int pixel_count) { |
291 // Called on the encoder task queue. | 263 // Called on the encoder task queue. |
292 rtc::CritScope lock(&crit_); | 264 rtc::CritScope lock(&crit_); |
293 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { | 265 if (!source_ || !IsResolutionScalingEnabled(degradation_preference_)) { |
294 // This can happen since |degradation_preference_| is set on libjingle's | 266 // This can happen since |degradation_preference_| is set on libjingle's |
295 // worker thread but the adaptation is done on the encoder task queue. | 267 // worker thread but the adaptation is done on the encoder task queue. |
296 return false; | 268 return false; |
297 } | 269 } |
(...skipping 12 matching lines...) Expand all Loading... |
310 // On step down we request at most 3/5 the pixel count of the previous | 282 // On step down we request at most 3/5 the pixel count of the previous |
311 // resolution, so in order to take "one step up" we request a resolution | 283 // resolution, so in order to take "one step up" we request a resolution |
312 // as close as possible to 5/3 of the current resolution. The actual pixel | 284 // as close as possible to 5/3 of the current resolution. The actual pixel |
313 // count selected depends on the capabilities of the source. In order to | 285 // count selected depends on the capabilities of the source. In order to |
314 // not take a too large step up, we cap the requested pixel count to be at | 286 // not take a too large step up, we cap the requested pixel count to be at |
315 // most four time the current number of pixels. | 287 // most four time the current number of pixels. |
316 sink_wants_.target_pixel_count = | 288 sink_wants_.target_pixel_count = |
317 rtc::Optional<int>((pixel_count * 5) / 3); | 289 rtc::Optional<int>((pixel_count * 5) / 3); |
318 } | 290 } |
319 LOG(LS_INFO) << "Scaling up resolution, max pixels: " << max_pixels_wanted; | 291 LOG(LS_INFO) << "Scaling up resolution, max pixels: " << max_pixels_wanted; |
320 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 292 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWantsInternal()); |
321 return true; | 293 return true; |
322 } | 294 } |
323 | 295 |
324 bool RequestHigherFramerateThan(int fps) { | 296 // Request upgrade in framerate. Returns the new requested frame, or -1 if |
| 297 // no change requested. Note that maxint may be returned if limits due to |
| 298 // adaptation requests are removed completely. In that case, consider |
| 299 // |max_framerate_| to be the current limit (assuming the capturer complies). |
| 300 int RequestHigherFramerateThan(int fps) { |
325 // Called on the encoder task queue. | 301 // Called on the encoder task queue. |
326 // The input frame rate will be scaled up to the last step, with rounding. | 302 // The input frame rate will be scaled up to the last step, with rounding. |
327 int framerate_wanted = fps; | 303 int framerate_wanted = fps; |
328 if (fps != std::numeric_limits<int>::max()) | 304 if (fps != std::numeric_limits<int>::max()) |
329 framerate_wanted = (fps * 3) / 2; | 305 framerate_wanted = (fps * 3) / 2; |
330 | 306 |
331 return IncreaseFramerate(framerate_wanted); | 307 return IncreaseFramerate(framerate_wanted) ? framerate_wanted : -1; |
332 } | 308 } |
333 | 309 |
334 bool RestrictFramerate(int fps) { | 310 bool RestrictFramerate(int fps) { |
335 // Called on the encoder task queue. | 311 // Called on the encoder task queue. |
336 rtc::CritScope lock(&crit_); | 312 rtc::CritScope lock(&crit_); |
337 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) | 313 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
338 return false; | 314 return false; |
339 | 315 |
340 const int fps_wanted = std::max(kMinFramerateFps, fps); | 316 const int fps_wanted = std::max(kMinFramerateFps, fps); |
341 if (fps_wanted >= sink_wants_.max_framerate_fps) | 317 if (fps_wanted >= sink_wants_.max_framerate_fps) |
342 return false; | 318 return false; |
343 | 319 |
344 LOG(LS_INFO) << "Scaling down framerate: " << fps_wanted; | 320 LOG(LS_INFO) << "Scaling down framerate: " << fps_wanted; |
345 sink_wants_.max_framerate_fps = fps_wanted; | 321 sink_wants_.max_framerate_fps = fps_wanted; |
346 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 322 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWantsInternal()); |
347 return true; | 323 return true; |
348 } | 324 } |
349 | 325 |
350 bool IncreaseFramerate(int fps) { | 326 bool IncreaseFramerate(int fps) { |
351 // Called on the encoder task queue. | 327 // Called on the encoder task queue. |
352 rtc::CritScope lock(&crit_); | 328 rtc::CritScope lock(&crit_); |
353 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) | 329 if (!source_ || !IsFramerateScalingEnabled(degradation_preference_)) |
354 return false; | 330 return false; |
355 | 331 |
356 const int fps_wanted = std::max(kMinFramerateFps, fps); | 332 const int fps_wanted = std::max(kMinFramerateFps, fps); |
357 if (fps_wanted <= sink_wants_.max_framerate_fps) | 333 if (fps_wanted <= sink_wants_.max_framerate_fps) |
358 return false; | 334 return false; |
359 | 335 |
360 LOG(LS_INFO) << "Scaling up framerate: " << fps_wanted; | 336 LOG(LS_INFO) << "Scaling up framerate: " << fps_wanted; |
361 sink_wants_.max_framerate_fps = fps_wanted; | 337 sink_wants_.max_framerate_fps = fps_wanted; |
362 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWants()); | 338 source_->AddOrUpdateSink(vie_encoder_, GetActiveSinkWantsInternal()); |
363 return true; | 339 return true; |
364 } | 340 } |
365 | 341 |
366 private: | 342 private: |
| 343 rtc::VideoSinkWants GetActiveSinkWantsInternal() |
| 344 EXCLUSIVE_LOCKS_REQUIRED(&crit_) { |
| 345 rtc::VideoSinkWants wants = sink_wants_; |
| 346 // Clear any constraints from the current sink wants that don't apply to |
| 347 // the used degradation_preference. |
| 348 switch (degradation_preference_) { |
| 349 case VideoSendStream::DegradationPreference::kBalanced: |
| 350 break; |
| 351 case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| 352 wants.max_framerate_fps = std::numeric_limits<int>::max(); |
| 353 break; |
| 354 case VideoSendStream::DegradationPreference::kMaintainResolution: |
| 355 wants.max_pixel_count = std::numeric_limits<int>::max(); |
| 356 wants.target_pixel_count.reset(); |
| 357 break; |
| 358 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| 359 wants.max_pixel_count = std::numeric_limits<int>::max(); |
| 360 wants.target_pixel_count.reset(); |
| 361 wants.max_framerate_fps = std::numeric_limits<int>::max(); |
| 362 } |
| 363 return wants; |
| 364 } |
| 365 |
367 rtc::CriticalSection crit_; | 366 rtc::CriticalSection crit_; |
368 rtc::SequencedTaskChecker main_checker_; | 367 rtc::SequencedTaskChecker main_checker_; |
369 ViEEncoder* const vie_encoder_; | 368 ViEEncoder* const vie_encoder_; |
370 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); | 369 rtc::VideoSinkWants sink_wants_ GUARDED_BY(&crit_); |
371 VideoSendStream::DegradationPreference degradation_preference_ | 370 VideoSendStream::DegradationPreference degradation_preference_ |
372 GUARDED_BY(&crit_); | 371 GUARDED_BY(&crit_); |
373 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); | 372 rtc::VideoSourceInterface<VideoFrame>* source_ GUARDED_BY(&crit_); |
374 | 373 |
375 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); | 374 RTC_DISALLOW_COPY_AND_ASSIGN(VideoSourceProxy); |
376 }; | 375 }; |
377 | 376 |
378 ViEEncoder::ViEEncoder(uint32_t number_of_cores, | 377 ViEEncoder::ViEEncoder(uint32_t number_of_cores, |
379 SendStatisticsProxy* stats_proxy, | 378 SendStatisticsProxy* stats_proxy, |
380 const VideoSendStream::Config::EncoderSettings& settings, | 379 const VideoSendStream::Config::EncoderSettings& settings, |
381 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, | 380 rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback, |
382 EncodedFrameObserver* encoder_timing) | 381 EncodedFrameObserver* encoder_timing, |
| 382 std::unique_ptr<OveruseFrameDetector> overuse_detector) |
383 : shutdown_event_(true /* manual_reset */, false), | 383 : shutdown_event_(true /* manual_reset */, false), |
384 number_of_cores_(number_of_cores), | 384 number_of_cores_(number_of_cores), |
385 initial_rampup_(0), | 385 initial_rampup_(0), |
386 source_proxy_(new VideoSourceProxy(this)), | 386 source_proxy_(new VideoSourceProxy(this)), |
387 sink_(nullptr), | 387 sink_(nullptr), |
388 settings_(settings), | 388 settings_(settings), |
389 codec_type_(PayloadNameToCodecType(settings.payload_name) | 389 codec_type_(PayloadNameToCodecType(settings.payload_name) |
390 .value_or(VideoCodecType::kVideoCodecUnknown)), | 390 .value_or(VideoCodecType::kVideoCodecUnknown)), |
391 video_sender_(Clock::GetRealTimeClock(), this, this), | 391 video_sender_(Clock::GetRealTimeClock(), this, this), |
392 overuse_detector_(GetCpuOveruseOptions(settings.full_overuse_time), | 392 overuse_detector_( |
393 this, | 393 overuse_detector.get() |
394 encoder_timing, | 394 ? overuse_detector.release() |
395 stats_proxy), | 395 : new OveruseFrameDetector( |
| 396 GetCpuOveruseOptions(settings.full_overuse_time), |
| 397 this, |
| 398 encoder_timing, |
| 399 stats_proxy)), |
396 stats_proxy_(stats_proxy), | 400 stats_proxy_(stats_proxy), |
397 pre_encode_callback_(pre_encode_callback), | 401 pre_encode_callback_(pre_encode_callback), |
398 module_process_thread_(nullptr), | 402 module_process_thread_(nullptr), |
| 403 max_framerate_(-1), |
399 pending_encoder_reconfiguration_(false), | 404 pending_encoder_reconfiguration_(false), |
400 encoder_start_bitrate_bps_(0), | 405 encoder_start_bitrate_bps_(0), |
401 max_data_payload_length_(0), | 406 max_data_payload_length_(0), |
402 nack_enabled_(false), | 407 nack_enabled_(false), |
403 last_observed_bitrate_bps_(0), | 408 last_observed_bitrate_bps_(0), |
404 encoder_paused_and_dropped_frame_(false), | 409 encoder_paused_and_dropped_frame_(false), |
405 clock_(Clock::GetRealTimeClock()), | 410 clock_(Clock::GetRealTimeClock()), |
406 degradation_preference_( | 411 degradation_preference_( |
407 VideoSendStream::DegradationPreference::kDegradationDisabled), | 412 VideoSendStream::DegradationPreference::kDegradationDisabled), |
408 last_captured_timestamp_(0), | 413 last_captured_timestamp_(0), |
409 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - | 414 delta_ntp_internal_ms_(clock_->CurrentNtpInMilliseconds() - |
410 clock_->TimeInMilliseconds()), | 415 clock_->TimeInMilliseconds()), |
411 last_frame_log_ms_(clock_->TimeInMilliseconds()), | 416 last_frame_log_ms_(clock_->TimeInMilliseconds()), |
412 captured_frame_count_(0), | 417 captured_frame_count_(0), |
413 dropped_frame_count_(0), | 418 dropped_frame_count_(0), |
414 bitrate_observer_(nullptr), | 419 bitrate_observer_(nullptr), |
415 encoder_queue_("EncoderQueue") { | 420 encoder_queue_("EncoderQueue") { |
416 RTC_DCHECK(stats_proxy); | 421 RTC_DCHECK(stats_proxy); |
417 encoder_queue_.PostTask([this] { | 422 encoder_queue_.PostTask([this] { |
418 RTC_DCHECK_RUN_ON(&encoder_queue_); | 423 RTC_DCHECK_RUN_ON(&encoder_queue_); |
419 overuse_detector_.StartCheckForOveruse(); | 424 overuse_detector_->StartCheckForOveruse(); |
420 video_sender_.RegisterExternalEncoder( | 425 video_sender_.RegisterExternalEncoder( |
421 settings_.encoder, settings_.payload_type, settings_.internal_source); | 426 settings_.encoder, settings_.payload_type, settings_.internal_source); |
422 }); | 427 }); |
423 } | 428 } |
424 | 429 |
425 ViEEncoder::~ViEEncoder() { | 430 ViEEncoder::~ViEEncoder() { |
426 RTC_DCHECK_RUN_ON(&thread_checker_); | 431 RTC_DCHECK_RUN_ON(&thread_checker_); |
427 RTC_DCHECK(shutdown_event_.Wait(0)) | 432 RTC_DCHECK(shutdown_event_.Wait(0)) |
428 << "Must call ::Stop() before destruction."; | 433 << "Must call ::Stop() before destruction."; |
429 } | 434 } |
430 | 435 |
| 436 // TODO(pbos): Lower these thresholds (to closer to 100%) when we handle |
| 437 // pipelining encoders better (multiple input frames before something comes |
| 438 // out). This should effectively turn off CPU adaptations for systems that |
| 439 // remotely cope with the load right now. |
| 440 CpuOveruseOptions ViEEncoder::GetCpuOveruseOptions(bool full_overuse_time) { |
| 441 CpuOveruseOptions options; |
| 442 if (full_overuse_time) { |
| 443 options.low_encode_usage_threshold_percent = 150; |
| 444 options.high_encode_usage_threshold_percent = 200; |
| 445 } |
| 446 return options; |
| 447 } |
| 448 |
431 void ViEEncoder::Stop() { | 449 void ViEEncoder::Stop() { |
432 RTC_DCHECK_RUN_ON(&thread_checker_); | 450 RTC_DCHECK_RUN_ON(&thread_checker_); |
433 source_proxy_->SetSource(nullptr, VideoSendStream::DegradationPreference()); | 451 source_proxy_->SetSource(nullptr, VideoSendStream::DegradationPreference()); |
434 encoder_queue_.PostTask([this] { | 452 encoder_queue_.PostTask([this] { |
435 RTC_DCHECK_RUN_ON(&encoder_queue_); | 453 RTC_DCHECK_RUN_ON(&encoder_queue_); |
436 overuse_detector_.StopCheckForOveruse(); | 454 overuse_detector_->StopCheckForOveruse(); |
437 rate_allocator_.reset(); | 455 rate_allocator_.reset(); |
438 bitrate_observer_ = nullptr; | 456 bitrate_observer_ = nullptr; |
439 video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, | 457 video_sender_.RegisterExternalEncoder(nullptr, settings_.payload_type, |
440 false); | 458 false); |
441 quality_scaler_ = nullptr; | 459 quality_scaler_ = nullptr; |
442 shutdown_event_.Set(); | 460 shutdown_event_.Set(); |
443 }); | 461 }); |
444 | 462 |
445 shutdown_event_.Wait(rtc::Event::kForever); | 463 shutdown_event_.Wait(rtc::Event::kForever); |
446 } | 464 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 // TODO(asapersson): Consider removing |adapt_counters_| map and use one | 504 // TODO(asapersson): Consider removing |adapt_counters_| map and use one |
487 // AdaptCounter for all modes. | 505 // AdaptCounter for all modes. |
488 source_proxy_->ResetPixelFpsCount(); | 506 source_proxy_->ResetPixelFpsCount(); |
489 adapt_counters_.clear(); | 507 adapt_counters_.clear(); |
490 } | 508 } |
491 } | 509 } |
492 degradation_preference_ = degradation_preference; | 510 degradation_preference_ = degradation_preference; |
493 bool allow_scaling = IsResolutionScalingEnabled(degradation_preference_); | 511 bool allow_scaling = IsResolutionScalingEnabled(degradation_preference_); |
494 initial_rampup_ = allow_scaling ? 0 : kMaxInitialFramedrop; | 512 initial_rampup_ = allow_scaling ? 0 : kMaxInitialFramedrop; |
495 ConfigureQualityScaler(); | 513 ConfigureQualityScaler(); |
| 514 if (!IsFramerateScalingEnabled(degradation_preference) && |
| 515 max_framerate_ != -1) { |
| 516 // If frame rate scaling is no longer allowed, remove any potential |
| 517 // allowance for longer frame intervals. |
| 518 overuse_detector_->OnTargetFramerateUpdated(max_framerate_); |
| 519 } |
496 }); | 520 }); |
497 } | 521 } |
498 | 522 |
499 void ViEEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { | 523 void ViEEncoder::SetSink(EncoderSink* sink, bool rotation_applied) { |
500 source_proxy_->SetWantsRotationApplied(rotation_applied); | 524 source_proxy_->SetWantsRotationApplied(rotation_applied); |
501 encoder_queue_.PostTask([this, sink] { | 525 encoder_queue_.PostTask([this, sink] { |
502 RTC_DCHECK_RUN_ON(&encoder_queue_); | 526 RTC_DCHECK_RUN_ON(&encoder_queue_); |
503 sink_ = sink; | 527 sink_ = sink; |
504 }); | 528 }); |
505 } | 529 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
555 if (!VideoCodecInitializer::SetupCodec(encoder_config_, settings_, streams, | 579 if (!VideoCodecInitializer::SetupCodec(encoder_config_, settings_, streams, |
556 nack_enabled_, &codec, | 580 nack_enabled_, &codec, |
557 &rate_allocator_)) { | 581 &rate_allocator_)) { |
558 LOG(LS_ERROR) << "Failed to create encoder configuration."; | 582 LOG(LS_ERROR) << "Failed to create encoder configuration."; |
559 } | 583 } |
560 | 584 |
561 codec.startBitrate = | 585 codec.startBitrate = |
562 std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate); | 586 std::max(encoder_start_bitrate_bps_ / 1000, codec.minBitrate); |
563 codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate); | 587 codec.startBitrate = std::min(codec.startBitrate, codec.maxBitrate); |
564 codec.expect_encode_from_texture = last_frame_info_->is_texture; | 588 codec.expect_encode_from_texture = last_frame_info_->is_texture; |
| 589 max_framerate_ = codec.maxFramerate; |
| 590 RTC_DCHECK_LE(max_framerate_, kMaxFramerateFps); |
565 | 591 |
566 bool success = video_sender_.RegisterSendCodec( | 592 bool success = video_sender_.RegisterSendCodec( |
567 &codec, number_of_cores_, | 593 &codec, number_of_cores_, |
568 static_cast<uint32_t>(max_data_payload_length_)) == VCM_OK; | 594 static_cast<uint32_t>(max_data_payload_length_)) == VCM_OK; |
569 if (!success) { | 595 if (!success) { |
570 LOG(LS_ERROR) << "Failed to configure encoder."; | 596 LOG(LS_ERROR) << "Failed to configure encoder."; |
571 rate_allocator_.reset(); | 597 rate_allocator_.reset(); |
572 } | 598 } |
573 | 599 |
574 video_sender_.UpdateChannelParemeters(rate_allocator_.get(), | 600 video_sender_.UpdateChannelParemeters(rate_allocator_.get(), |
575 bitrate_observer_); | 601 bitrate_observer_); |
576 | 602 |
577 int framerate = stats_proxy_->GetSendFrameRate(); | 603 // Get the current actual framerate, as measured by the stats proxy. This is |
578 if (framerate == 0) | 604 // used to get the correct bitrate layer allocation. |
579 framerate = codec.maxFramerate; | 605 int current_framerate = stats_proxy_->GetSendFrameRate(); |
| 606 if (current_framerate == 0) |
| 607 current_framerate = codec.maxFramerate; |
580 stats_proxy_->OnEncoderReconfigured( | 608 stats_proxy_->OnEncoderReconfigured( |
581 encoder_config_, rate_allocator_.get() | 609 encoder_config_, |
582 ? rate_allocator_->GetPreferredBitrateBps(framerate) | 610 rate_allocator_.get() |
583 : codec.maxBitrate); | 611 ? rate_allocator_->GetPreferredBitrateBps(current_framerate) |
| 612 : codec.maxBitrate); |
584 | 613 |
585 pending_encoder_reconfiguration_ = false; | 614 pending_encoder_reconfiguration_ = false; |
586 | 615 |
587 sink_->OnEncoderConfigurationChanged( | 616 sink_->OnEncoderConfigurationChanged( |
588 std::move(streams), encoder_config_.min_transmit_bitrate_bps); | 617 std::move(streams), encoder_config_.min_transmit_bitrate_bps); |
589 | 618 |
| 619 // Get the current target framerate, ie the maximum framerate as specified by |
| 620 // the current codec configuration, or any limit imposed by cpu adaption in |
| 621 // maintain-resolution or balanced mode. This is used to make sure overuse |
| 622 // detection doesn't needlessly trigger in low and/or variable framerate |
| 623 // scenarios. |
| 624 int target_framerate = std::min( |
| 625 max_framerate_, source_proxy_->GetActiveSinkWants().max_framerate_fps); |
| 626 overuse_detector_->OnTargetFramerateUpdated(target_framerate); |
| 627 |
590 ConfigureQualityScaler(); | 628 ConfigureQualityScaler(); |
591 } | 629 } |
592 | 630 |
593 void ViEEncoder::ConfigureQualityScaler() { | 631 void ViEEncoder::ConfigureQualityScaler() { |
594 RTC_DCHECK_RUN_ON(&encoder_queue_); | 632 RTC_DCHECK_RUN_ON(&encoder_queue_); |
595 const auto scaling_settings = settings_.encoder->GetScalingSettings(); | 633 const auto scaling_settings = settings_.encoder->GetScalingSettings(); |
596 const bool quality_scaling_allowed = | 634 const bool quality_scaling_allowed = |
597 IsResolutionScalingEnabled(degradation_preference_) && | 635 IsResolutionScalingEnabled(degradation_preference_) && |
598 scaling_settings.enabled; | 636 scaling_settings.enabled; |
599 | 637 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 766 |
729 if (EncoderPaused()) { | 767 if (EncoderPaused()) { |
730 TraceFrameDropStart(); | 768 TraceFrameDropStart(); |
731 return; | 769 return; |
732 } | 770 } |
733 TraceFrameDropEnd(); | 771 TraceFrameDropEnd(); |
734 | 772 |
735 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), | 773 TRACE_EVENT_ASYNC_STEP0("webrtc", "Video", video_frame.render_time_ms(), |
736 "Encode"); | 774 "Encode"); |
737 | 775 |
738 overuse_detector_.FrameCaptured(video_frame, time_when_posted_us); | 776 overuse_detector_->FrameCaptured(video_frame, time_when_posted_us); |
739 | 777 |
740 video_sender_.AddVideoFrame(video_frame, nullptr); | 778 video_sender_.AddVideoFrame(video_frame, nullptr); |
741 } | 779 } |
742 | 780 |
743 void ViEEncoder::SendKeyFrame() { | 781 void ViEEncoder::SendKeyFrame() { |
744 if (!encoder_queue_.IsCurrent()) { | 782 if (!encoder_queue_.IsCurrent()) { |
745 encoder_queue_.PostTask([this] { SendKeyFrame(); }); | 783 encoder_queue_.PostTask([this] { SendKeyFrame(); }); |
746 return; | 784 return; |
747 } | 785 } |
748 RTC_DCHECK_RUN_ON(&encoder_queue_); | 786 RTC_DCHECK_RUN_ON(&encoder_queue_); |
(...skipping 10 matching lines...) Expand all Loading... |
759 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); | 797 stats_proxy_->OnSendEncodedImage(encoded_image, codec_specific_info); |
760 | 798 |
761 EncodedImageCallback::Result result = | 799 EncodedImageCallback::Result result = |
762 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation); | 800 sink_->OnEncodedImage(encoded_image, codec_specific_info, fragmentation); |
763 | 801 |
764 int64_t time_sent_us = rtc::TimeMicros(); | 802 int64_t time_sent_us = rtc::TimeMicros(); |
765 uint32_t timestamp = encoded_image._timeStamp; | 803 uint32_t timestamp = encoded_image._timeStamp; |
766 const int qp = encoded_image.qp_; | 804 const int qp = encoded_image.qp_; |
767 encoder_queue_.PostTask([this, timestamp, time_sent_us, qp] { | 805 encoder_queue_.PostTask([this, timestamp, time_sent_us, qp] { |
768 RTC_DCHECK_RUN_ON(&encoder_queue_); | 806 RTC_DCHECK_RUN_ON(&encoder_queue_); |
769 overuse_detector_.FrameSent(timestamp, time_sent_us); | 807 overuse_detector_->FrameSent(timestamp, time_sent_us); |
770 if (quality_scaler_ && qp >= 0) | 808 if (quality_scaler_ && qp >= 0) |
771 quality_scaler_->ReportQP(qp); | 809 quality_scaler_->ReportQP(qp); |
772 }); | 810 }); |
773 | 811 |
774 return result; | 812 return result; |
775 } | 813 } |
776 | 814 |
777 void ViEEncoder::OnDroppedFrame() { | 815 void ViEEncoder::OnDroppedFrame() { |
778 encoder_queue_.PostTask([this] { | 816 encoder_queue_.PostTask([this] { |
779 RTC_DCHECK_RUN_ON(&encoder_queue_); | 817 RTC_DCHECK_RUN_ON(&encoder_queue_); |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 FALLTHROUGH(); | 932 FALLTHROUGH(); |
895 } | 933 } |
896 case VideoSendStream::DegradationPreference::kMaintainFramerate: | 934 case VideoSendStream::DegradationPreference::kMaintainFramerate: |
897 // Scale down resolution. | 935 // Scale down resolution. |
898 if (!source_proxy_->RequestResolutionLowerThan( | 936 if (!source_proxy_->RequestResolutionLowerThan( |
899 adaptation_request.input_pixel_count_)) { | 937 adaptation_request.input_pixel_count_)) { |
900 return; | 938 return; |
901 } | 939 } |
902 GetAdaptCounter().IncrementResolution(reason); | 940 GetAdaptCounter().IncrementResolution(reason); |
903 break; | 941 break; |
904 case VideoSendStream::DegradationPreference::kMaintainResolution: | 942 case VideoSendStream::DegradationPreference::kMaintainResolution: { |
905 // Scale down framerate. | 943 // Scale down framerate. |
906 if (!source_proxy_->RequestFramerateLowerThan( | 944 const int requested_framerate = source_proxy_->RequestFramerateLowerThan( |
907 adaptation_request.framerate_fps_)) { | 945 adaptation_request.framerate_fps_); |
| 946 if (requested_framerate == -1) |
908 return; | 947 return; |
909 } | 948 RTC_DCHECK_NE(max_framerate_, -1); |
| 949 overuse_detector_->OnTargetFramerateUpdated( |
| 950 std::min(max_framerate_, requested_framerate)); |
910 GetAdaptCounter().IncrementFramerate(reason); | 951 GetAdaptCounter().IncrementFramerate(reason); |
911 break; | 952 break; |
| 953 } |
912 case VideoSendStream::DegradationPreference::kDegradationDisabled: | 954 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
913 RTC_NOTREACHED(); | 955 RTC_NOTREACHED(); |
914 } | 956 } |
915 | 957 |
916 last_adaptation_request_.emplace(adaptation_request); | 958 last_adaptation_request_.emplace(adaptation_request); |
917 | 959 |
918 UpdateAdaptationStats(reason); | 960 UpdateAdaptationStats(reason); |
919 | 961 |
920 LOG(LS_INFO) << GetConstAdaptCounter().ToString(); | 962 LOG(LS_INFO) << GetConstAdaptCounter().ToString(); |
921 } | 963 } |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
978 GetAdaptCounter().DecrementResolution(reason); | 1020 GetAdaptCounter().DecrementResolution(reason); |
979 break; | 1021 break; |
980 } | 1022 } |
981 case VideoSendStream::DegradationPreference::kMaintainResolution: { | 1023 case VideoSendStream::DegradationPreference::kMaintainResolution: { |
982 // Scale up framerate. | 1024 // Scale up framerate. |
983 int fps = adaptation_request.framerate_fps_; | 1025 int fps = adaptation_request.framerate_fps_; |
984 if (adapt_counter.FramerateCount() == 1) { | 1026 if (adapt_counter.FramerateCount() == 1) { |
985 LOG(LS_INFO) << "Removing framerate down-scaling setting."; | 1027 LOG(LS_INFO) << "Removing framerate down-scaling setting."; |
986 fps = std::numeric_limits<int>::max(); | 1028 fps = std::numeric_limits<int>::max(); |
987 } | 1029 } |
988 if (!source_proxy_->RequestHigherFramerateThan(fps)) | 1030 |
| 1031 const int requested_framerate = |
| 1032 source_proxy_->RequestHigherFramerateThan(fps); |
| 1033 if (requested_framerate == -1) { |
| 1034 overuse_detector_->OnTargetFramerateUpdated(max_framerate_); |
989 return; | 1035 return; |
| 1036 } |
| 1037 overuse_detector_->OnTargetFramerateUpdated( |
| 1038 std::min(max_framerate_, requested_framerate)); |
990 GetAdaptCounter().DecrementFramerate(reason); | 1039 GetAdaptCounter().DecrementFramerate(reason); |
991 break; | 1040 break; |
992 } | 1041 } |
993 case VideoSendStream::DegradationPreference::kDegradationDisabled: | 1042 case VideoSendStream::DegradationPreference::kDegradationDisabled: |
994 return; | 1043 return; |
995 } | 1044 } |
996 | 1045 |
997 last_adaptation_request_.emplace(adaptation_request); | 1046 last_adaptation_request_.emplace(adaptation_request); |
998 | 1047 |
999 UpdateAdaptationStats(reason); | 1048 UpdateAdaptationStats(reason); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1146 std::string ViEEncoder::AdaptCounter::ToString( | 1195 std::string ViEEncoder::AdaptCounter::ToString( |
1147 const std::vector<int>& counters) const { | 1196 const std::vector<int>& counters) const { |
1148 std::stringstream ss; | 1197 std::stringstream ss; |
1149 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { | 1198 for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { |
1150 ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; | 1199 ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; |
1151 } | 1200 } |
1152 return ss.str(); | 1201 return ss.str(); |
1153 } | 1202 } |
1154 | 1203 |
1155 } // namespace webrtc | 1204 } // namespace webrtc |
OLD | NEW |