Chromium Code Reviews| Index: webrtc/video/vie_encoder.cc |
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
| index 6e48f97e66a369da9956bea64c10a1261bc7e0ee..df5086c43caf7b597982a9cfc1d66fe4772acc0d 100644 |
| --- a/webrtc/video/vie_encoder.cc |
| +++ b/webrtc/video/vie_encoder.cc |
| @@ -73,6 +73,49 @@ uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) { |
| return std::numeric_limits<uint32_t>::max(); |
| } |
| +// Limits for kBalanced degradation preference. |
| +// >640x480: | max | |
|
sprang_webrtc
2017/06/13 11:58:29
I think there could be a case for 24fps for 720p a
åsapersson
2017/06/13 12:40:04
Agree, these are initial limits.
|
| +// <=640x480: | 15fps | max | |
| +// <=480x270: | 10fps | 15fps | |
| +// <=320x240: | 7fps | 10fps | |
| +// ---------------------------------------------------------- |
| +// kbps: 0 60 130 500 | |
| + |
| +int MinFps(int pixels) { |
| + if (pixels <= 320 * 240) |
| + return 7; |
| + else if (pixels <= 480 * 270) |
| + return 10; |
| + else if (pixels <= 640 * 480) |
| + return 15; |
| + else |
| + return std::numeric_limits<int>::max(); |
|
sprang_webrtc
2017/06/13 11:58:29
nit: please use brackets for if/else statements
åsapersson
2017/06/13 12:40:05
Done.
|
| +} |
| + |
| +int MaxFps(int pixels) { |
| + if (pixels <= 320 * 240) |
| + return 10; |
| + else if (pixels <= 480 * 270) |
| + return 15; |
| + else |
| + return std::numeric_limits<int>::max(); |
| +} |
| + |
| +uint32_t BitrateLimit(int pixels) { |
| + if (pixels <= 320 * 240) |
| + return 60000; |
| + else if (pixels <= 480 * 270) |
| + return 130000; |
| + else if (pixels <= 640 * 480) |
| + return 500000; |
| + else |
| + return std::numeric_limits<uint32_t>::max(); |
| +} |
| + |
| +int MaxFpsForBitrateAndResolution(uint32_t bps, int pixels) { |
| + return (bps <= BitrateLimit(pixels)) ? MinFps(pixels) : MaxFps(pixels); |
| +} |
| + |
| bool IsResolutionScalingEnabled( |
| VideoSendStream::DegradationPreference degradation_preference) { |
| return degradation_preference == |
| @@ -211,6 +254,7 @@ class ViEEncoder::VideoSourceProxy { |
| // the used degradation_preference. |
| switch (degradation_preference_) { |
| case VideoSendStream::DegradationPreference::kBalanced: |
| + break; |
| case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| wants.max_framerate_fps = std::numeric_limits<int>::max(); |
| break; |
| @@ -806,6 +850,8 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| int max_downgrades = 0; |
| switch (degradation_preference_) { |
| case VideoSendStream::DegradationPreference::kBalanced: |
| + max_downgrades = kMaxCpuResolutionDowngrades; |
| + break; |
| case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| max_downgrades = kMaxCpuResolutionDowngrades; |
| if (downgrade_requested && |
| @@ -840,14 +886,24 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| } |
| switch (degradation_preference_) { |
| - case VideoSendStream::DegradationPreference::kBalanced: |
| + case VideoSendStream::DegradationPreference::kBalanced: { |
| + // Try scale down framerate, if lower. |
| + int max_fps = MaxFpsForBitrateAndResolution( |
| + last_observed_bitrate_bps_, last_frame_info_->pixel_count()); |
| + if (source_proxy_->RestrictFramerate(max_fps)) { |
| + GetAdaptCounter().IncrementFramerate(reason); |
| + break; |
| + } |
| + // Scale down resolution. |
| + FALLTHROUGH(); |
| + } |
| case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| // Scale down resolution. |
| if (!source_proxy_->RequestResolutionLowerThan( |
| adaptation_request.input_pixel_count_)) { |
| return; |
| } |
| - GetAdaptCounter().IncrementResolution(reason, 1); |
| + GetAdaptCounter().IncrementResolution(reason); |
| break; |
| case VideoSendStream::DegradationPreference::kMaintainResolution: |
| // Scale down framerate. |
| @@ -855,7 +911,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| adaptation_request.framerate_fps_)) { |
| return; |
| } |
| - GetAdaptCounter().IncrementFramerate(reason, 1); |
| + GetAdaptCounter().IncrementFramerate(reason); |
| break; |
| case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| RTC_NOTREACHED(); |
| @@ -886,27 +942,28 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| last_adaptation_request_ && |
| last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp; |
| - switch (degradation_preference_) { |
| - case VideoSendStream::DegradationPreference::kBalanced: |
| - case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| - if (adapt_up_requested && |
| - adaptation_request.input_pixel_count_ <= |
| - last_adaptation_request_->input_pixel_count_) { |
| - // Don't request higher resolution if the current resolution is not |
| - // higher than the last time we asked for the resolution to be higher. |
| - return; |
| - } |
| - break; |
| - case VideoSendStream::DegradationPreference::kMaintainResolution: |
| - // TODO(sprang): Don't request higher framerate if we are already at |
| - // max requested fps? |
| - break; |
| - case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| + if (degradation_preference_ == |
| + VideoSendStream::DegradationPreference::kMaintainFramerate) { |
| + if (adapt_up_requested && |
| + adaptation_request.input_pixel_count_ <= |
| + last_adaptation_request_->input_pixel_count_) { |
| + // Don't request higher resolution if the current resolution is not |
| + // higher than the last time we asked for the resolution to be higher. |
| return; |
| + } |
| } |
| switch (degradation_preference_) { |
| - case VideoSendStream::DegradationPreference::kBalanced: |
| + case VideoSendStream::DegradationPreference::kBalanced: { |
| + // Try scale up framerate, if higher. |
| + int fps = MaxFps(last_frame_info_->pixel_count()); |
| + if (source_proxy_->IncreaseFramerate(fps)) { |
| + GetAdaptCounter().DecrementFramerate(reason); |
| + break; |
| + } |
| + // Scale up resolution. |
| + FALLTHROUGH(); |
| + } |
| case VideoSendStream::DegradationPreference::kMaintainFramerate: { |
| // Scale up resolution. |
| int pixel_count = adaptation_request.input_pixel_count_; |
| @@ -916,7 +973,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| } |
| if (!source_proxy_->RequestHigherResolutionThan(pixel_count)) |
| return; |
| - GetAdaptCounter().IncrementResolution(reason, -1); |
| + GetAdaptCounter().DecrementResolution(reason); |
| break; |
| } |
| case VideoSendStream::DegradationPreference::kMaintainResolution: { |
| @@ -928,11 +985,11 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| } |
| if (!source_proxy_->RequestHigherFramerateThan(fps)) |
| return; |
| - GetAdaptCounter().IncrementFramerate(reason, -1); |
| + GetAdaptCounter().DecrementFramerate(reason); |
| break; |
| } |
| case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| - RTC_NOTREACHED(); |
| + return; |
| } |
| last_adaptation_request_.emplace(adaptation_request); |
| @@ -990,6 +1047,7 @@ const ViEEncoder::AdaptCounter& ViEEncoder::GetConstAdaptCounter() { |
| ViEEncoder::AdaptCounter::AdaptCounter() { |
| fps_counters_.resize(kScaleReasonSize); |
| resolution_counters_.resize(kScaleReasonSize); |
| + static_assert(kScaleReasonSize == 2, "Update MoveCount."); |
| } |
| ViEEncoder::AdaptCounter::~AdaptCounter() {} |
| @@ -1008,12 +1066,41 @@ ViEEncoder::AdaptCounts ViEEncoder::AdaptCounter::Counts(int reason) const { |
| return counts; |
| } |
| -void ViEEncoder::AdaptCounter::IncrementFramerate(int reason, int delta) { |
| - fps_counters_[reason] += delta; |
| +void ViEEncoder::AdaptCounter::IncrementFramerate(int reason) { |
| + ++(fps_counters_[reason]); |
| +} |
| + |
| +void ViEEncoder::AdaptCounter::IncrementResolution(int reason) { |
| + ++(resolution_counters_[reason]); |
| } |
| -void ViEEncoder::AdaptCounter::IncrementResolution(int reason, int delta) { |
| - resolution_counters_[reason] += delta; |
| +void ViEEncoder::AdaptCounter::DecrementFramerate(int reason) { |
| + if (fps_counters_[reason] == 0) { |
| + // Balanced mode: Adapt up is in a different order, switch reason. |
| + // E.g. framerate adapt down: quality (2), framerate adapt up: cpu (3). |
| + // 1. Down resolution (cpu): res={quality:0,cpu:1}, fps={quality:0,cpu:0} |
| + // 2. Down fps (quality): res={quality:0,cpu:1}, fps={quality:1,cpu:0} |
| + // 3. Up fps (cpu): res={quality:1,cpu:0}, fps={quality:0,cpu:0} |
| + // 4. Up resolution (quality): res={quality:0,cpu:0}, fps={quality:0,cpu:0} |
| + RTC_DCHECK_GT(TotalCount(reason), 0) << "No downgrade for reason."; |
| + RTC_DCHECK_GT(FramerateCount(), 0) << "Framerate not downgraded."; |
| + MoveCount(&resolution_counters_, reason); |
| + MoveCount(&fps_counters_, (reason + 1) % kScaleReasonSize); |
| + } |
| + --(fps_counters_[reason]); |
| + RTC_DCHECK_GE(fps_counters_[reason], 0); |
| +} |
| + |
| +void ViEEncoder::AdaptCounter::DecrementResolution(int reason) { |
| + if (resolution_counters_[reason] == 0) { |
| + // Balanced mode: Adapt up is in a different order, switch reason. |
| + RTC_DCHECK_GT(TotalCount(reason), 0) << "No downgrade for reason."; |
| + RTC_DCHECK_GT(ResolutionCount(), 0) << "Resolution not downgraded."; |
| + MoveCount(&fps_counters_, reason); |
| + MoveCount(&resolution_counters_, (reason + 1) % kScaleReasonSize); |
| + } |
| + --(resolution_counters_[reason]); |
| + RTC_DCHECK_GE(resolution_counters_[reason], 0); |
| } |
| int ViEEncoder::AdaptCounter::FramerateCount() const { |
| @@ -1024,10 +1111,6 @@ int ViEEncoder::AdaptCounter::ResolutionCount() const { |
| return Count(resolution_counters_); |
| } |
| -int ViEEncoder::AdaptCounter::TotalCount() const { |
| - return FramerateCount() + ResolutionCount(); |
| -} |
| - |
| int ViEEncoder::AdaptCounter::FramerateCount(int reason) const { |
| return fps_counters_[reason]; |
| } |
| @@ -1044,6 +1127,13 @@ int ViEEncoder::AdaptCounter::Count(const std::vector<int>& counters) const { |
| return std::accumulate(counters.begin(), counters.end(), 0); |
| } |
| +void ViEEncoder::AdaptCounter::MoveCount(std::vector<int>* counters, |
| + int from_reason) { |
| + int to_reason = (from_reason + 1) % kScaleReasonSize; |
| + ++((*counters)[to_reason]); |
| + --((*counters)[from_reason]); |
| +} |
| + |
| std::string ViEEncoder::AdaptCounter::ToString( |
| const std::vector<int>& counters) const { |
| std::stringstream ss; |