Chromium Code Reviews| Index: webrtc/video/vie_encoder.cc |
| diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc |
| index 2287a7e3bb911b74d1889a3113b5c193a03d79b7..e65e6cf991eb9d4eb1721c1d11f3906e282f259e 100644 |
| --- a/webrtc/video/vie_encoder.cc |
| +++ b/webrtc/video/vie_encoder.cc |
| @@ -72,6 +72,22 @@ uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) { |
| return std::numeric_limits<uint32_t>::max(); |
| } |
| +bool IsResolutionScalingEnabled( |
| + VideoSendStream::DegradationPreference degradation_preference) { |
| + return degradation_preference == |
| + VideoSendStream::DegradationPreference::kMaintainFramerate || |
| + degradation_preference == |
| + VideoSendStream::DegradationPreference::kBalanced; |
| +} |
| + |
| +bool IsFramerateScalingEnabled( |
| + VideoSendStream::DegradationPreference degradation_preference) { |
| + return degradation_preference == |
| + VideoSendStream::DegradationPreference::kMaintainResolution || |
| + degradation_preference == |
| + VideoSendStream::DegradationPreference::kBalanced; |
| +} |
| + |
| } // namespace |
| class ViEEncoder::ConfigureEncoderTask : public rtc::QueuedTask { |
| @@ -419,8 +435,7 @@ void ViEEncoder::SetBitrateObserver( |
| void ViEEncoder::SetSource( |
| rtc::VideoSourceInterface<VideoFrame>* source, |
| - const VideoSendStream::VideoSendStream::DegradationPreference& |
| - degradation_preference) { |
| + const VideoSendStream::DegradationPreference& degradation_preference) { |
| RTC_DCHECK_RUN_ON(&thread_checker_); |
| source_proxy_->SetSource(source, degradation_preference); |
| encoder_queue_.PostTask([this, degradation_preference] { |
| @@ -546,27 +561,24 @@ void ViEEncoder::ConfigureQualityScaler() { |
| const bool quality_scaling_allowed = |
| degradation_preference_allows_scaling && scaling_settings.enabled; |
| - const std::vector<int>& scale_counters = GetScaleCounters(); |
| - stats_proxy_->SetCpuScalingStats( |
| - degradation_preference_allows_scaling ? scale_counters[kCpu] : -1); |
| - stats_proxy_->SetQualityScalingStats( |
| - quality_scaling_allowed ? scale_counters[kQuality] : -1); |
| - |
| if (quality_scaling_allowed) { |
| - // Abort if quality scaler has already been configured. |
| - if (quality_scaler_.get() != nullptr) |
| - return; |
| - // Drop frames and scale down until desired quality is achieved. |
| - if (scaling_settings.thresholds) { |
| - quality_scaler_.reset( |
| - new QualityScaler(this, *(scaling_settings.thresholds))); |
| - } else { |
| - quality_scaler_.reset(new QualityScaler(this, codec_type_)); |
| + if (quality_scaler_.get() == nullptr) { |
| + // Quality scaler has not already been configured. |
| + // Drop frames and scale down until desired quality is achieved. |
| + if (scaling_settings.thresholds) { |
| + quality_scaler_.reset( |
| + new QualityScaler(this, *(scaling_settings.thresholds))); |
| + } else { |
| + quality_scaler_.reset(new QualityScaler(this, codec_type_)); |
| + } |
| } |
| } else { |
| quality_scaler_.reset(nullptr); |
| initial_rampup_ = kMaxInitialFramedrop; |
| } |
| + |
| + stats_proxy_->SetAdaptationStats(GetActiveCounts(kCpu), |
| + GetActiveCounts(kQuality)); |
| } |
| void ViEEncoder::OnFrame(const VideoFrame& video_frame) { |
| @@ -799,6 +811,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| last_frame_info_->pixel_count(), |
| stats_proxy_->GetStats().input_frame_rate, |
| AdaptationRequest::Mode::kAdaptDown}; |
| + |
| bool downgrade_requested = |
| last_adaptation_request_ && |
| last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown; |
| @@ -836,8 +849,7 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| } |
| if (reason == kCpu) { |
| - const int cpu_scale_counter = GetScaleCounters()[reason]; |
| - if (cpu_scale_counter >= max_downgrades) |
| + if (GetAdaptCounter().TotalCount(kCpu) >= max_downgrades) |
| return; |
| } |
| @@ -850,11 +862,13 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| return; |
| } |
| LOG(LS_INFO) << "Scaling down resolution."; |
| + IncrementResolutionCounter(reason, 1); |
| break; |
| case VideoSendStream::DegradationPreference::kMaintainResolution: |
| source_proxy_->RequestFramerateLowerThan( |
| adaptation_request.framerate_fps_); |
| LOG(LS_INFO) << "Scaling down framerate."; |
| + IncrementFramerateCounter(reason, 1); |
| break; |
| case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| RTC_NOTREACHED(); |
| @@ -862,32 +876,20 @@ void ViEEncoder::AdaptDown(AdaptReason reason) { |
| last_adaptation_request_.emplace(adaptation_request); |
| - IncrementScaleCounter(reason, 1); |
| + UpdateAdaptationStats(reason); |
| - // Update stats. |
| - const std::vector<int>& scale_counters = GetScaleCounters(); |
| - switch (reason) { |
| - case kQuality: |
| - stats_proxy_->OnQualityRestrictedResolutionChanged( |
| - scale_counters[reason]); |
| - break; |
| - case kCpu: |
| - stats_proxy_->OnCpuRestrictedResolutionChanged(true); |
| - break; |
| - } |
| - |
| - for (size_t i = 0; i < kScaleReasonSize; ++i) { |
| - LOG(LS_INFO) << "Scaled " << scale_counters[i] |
| - << " times for reason: " << (i ? "cpu" : "quality"); |
| - } |
| + LOG(LS_INFO) << GetAdaptCounter().ToString(); |
| } |
| void ViEEncoder::AdaptUp(AdaptReason reason) { |
| RTC_DCHECK_RUN_ON(&encoder_queue_); |
| - int scale_counter = GetScaleCounters()[reason]; |
| - if (scale_counter == 0) |
| + |
| + const AdaptCounter& adapt_counter = GetAdaptCounter(); |
| + int num_downgrades = adapt_counter.TotalCount(reason); |
| + if (num_downgrades == 0) |
| return; |
| - RTC_DCHECK_GT(scale_counter, 0); |
| + RTC_DCHECK_GT(num_downgrades, 0); |
| + |
| AdaptationRequest adaptation_request = { |
| last_frame_info_->pixel_count(), |
| stats_proxy_->GetStats().input_frame_rate, |
| @@ -896,6 +898,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| bool adapt_up_requested = |
| last_adaptation_request_ && |
| last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp; |
| + |
| switch (degradation_preference_) { |
| case VideoSendStream::DegradationPreference::kBalanced: |
| FALLTHROUGH(); |
| @@ -916,20 +919,11 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| return; |
| } |
| - // Decrease counter of how many times we have scaled down, for this |
| - // degradation preference mode and reason. |
| - IncrementScaleCounter(reason, -1); |
| - |
| - // Get a sum of how many times have scaled down, in total, for this |
| - // degradation preference mode. If it is 0, remove any restraints. |
| - const std::vector<int>& scale_counters = GetScaleCounters(); |
| - const int scale_sum = |
| - std::accumulate(scale_counters.begin(), scale_counters.end(), 0); |
| switch (degradation_preference_) { |
| case VideoSendStream::DegradationPreference::kBalanced: |
| FALLTHROUGH(); |
| case VideoSendStream::DegradationPreference::kMaintainFramerate: |
| - if (scale_sum == 0) { |
| + if (adapt_counter.TotalCount() == 1) { |
| LOG(LS_INFO) << "Removing resolution down-scaling setting."; |
| source_proxy_->RequestHigherResolutionThan( |
| std::numeric_limits<int>::max()); |
| @@ -938,9 +932,10 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| adaptation_request.input_pixel_count_); |
| LOG(LS_INFO) << "Scaling up resolution."; |
| } |
| + IncrementResolutionCounter(reason, -1); |
| break; |
| case VideoSendStream::DegradationPreference::kMaintainResolution: |
| - if (scale_sum == 0) { |
| + if (adapt_counter.TotalCount() == 1) { |
| LOG(LS_INFO) << "Removing framerate down-scaling setting."; |
| source_proxy_->RequestHigherFramerateThan( |
| std::numeric_limits<int>::max()); |
| @@ -949,6 +944,7 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| adaptation_request.framerate_fps_); |
| LOG(LS_INFO) << "Scaling up framerate."; |
| } |
| + IncrementFramerateCounter(reason, -1); |
| break; |
| case VideoSendStream::DegradationPreference::kDegradationDisabled: |
| RTC_NOTREACHED(); |
| @@ -956,40 +952,127 @@ void ViEEncoder::AdaptUp(AdaptReason reason) { |
| last_adaptation_request_.emplace(adaptation_request); |
| - // Update stats. |
| + UpdateAdaptationStats(reason); |
| + |
| + LOG(LS_INFO) << adapt_counter.ToString(); |
| +} |
| + |
| +void ViEEncoder::UpdateAdaptationStats(AdaptReason reason) { |
| switch (reason) { |
| + case kCpu: |
| + stats_proxy_->OnCpuAdaptationChanged(GetActiveCounts(kCpu), |
| + GetActiveCounts(kQuality)); |
| + break; |
| case kQuality: |
| - stats_proxy_->OnQualityRestrictedResolutionChanged( |
| - scale_counters[reason]); |
| + stats_proxy_->OnQualityAdaptationChanged(GetActiveCounts(kCpu), |
| + GetActiveCounts(kQuality)); |
| break; |
| + } |
| +} |
| + |
| +ViEEncoder::AdaptCounts ViEEncoder::GetActiveCounts(AdaptReason reason) { |
| + ViEEncoder::AdaptCounts counts = GetAdaptCounter().Counts(reason); |
| + switch (reason) { |
| case kCpu: |
| - stats_proxy_->OnCpuRestrictedResolutionChanged(scale_counters[reason] > |
| - 0); |
| + if (!IsFramerateScalingEnabled(degradation_preference_)) |
| + counts.fps = -1; |
| + if (!IsResolutionScalingEnabled(degradation_preference_)) |
| + counts.resolution = -1; |
| + break; |
| + case kQuality: |
| + if (!IsFramerateScalingEnabled(degradation_preference_) || |
| + !quality_scaler_) { |
| + counts.fps = -1; |
| + } |
| + if (!IsResolutionScalingEnabled(degradation_preference_) || |
| + !quality_scaler_) { |
| + counts.resolution = -1; |
| + } |
| break; |
| } |
| + return counts; |
| +} |
| - for (size_t i = 0; i < kScaleReasonSize; ++i) { |
| - LOG(LS_INFO) << "Scaled " << scale_counters[i] |
| - << " times for reason: " << (i ? "cpu" : "quality"); |
| - } |
| +const ViEEncoder::AdaptCounter& ViEEncoder::GetAdaptCounter() { |
| + return adapt_counters_[degradation_preference_]; |
| } |
| -const std::vector<int>& ViEEncoder::GetScaleCounters() { |
| - auto it = scale_counters_.find(degradation_preference_); |
| - if (it == scale_counters_.end()) { |
| - scale_counters_[degradation_preference_].resize(kScaleReasonSize); |
| - return scale_counters_[degradation_preference_]; |
| - } |
| - return it->second; |
| +void ViEEncoder::IncrementFramerateCounter(AdaptReason reason, int delta) { |
| + adapt_counters_[degradation_preference_].IncrementFramerate(reason, delta); |
| +} |
| + |
| +void ViEEncoder::IncrementResolutionCounter(AdaptReason reason, int delta) { |
| + adapt_counters_[degradation_preference_].IncrementResolution(reason, delta); |
| +} |
|
kthelgason
2017/05/09 11:50:15
are these two methods necessary? We have the Adapt
åsapersson
2017/05/10 08:24:45
Removed these methods and added a non const GetAda
|
| + |
| +// Class holding adaptation information. |
| +ViEEncoder::AdaptCounter::AdaptCounter() { |
| + fps_counters_.resize(kScaleReasonSize); |
| + resolution_counters_.resize(kScaleReasonSize); |
| +} |
| + |
| +ViEEncoder::AdaptCounter::~AdaptCounter() {} |
| + |
| +std::string ViEEncoder::AdaptCounter::ToString() const { |
| + std::stringstream ss; |
| + ss << "Downgrade counts: fps: {" << ToString(fps_counters_); |
| + ss << "}, resolution: {" << ToString(resolution_counters_) << "}"; |
| + return ss.str(); |
| +} |
| + |
| +ViEEncoder::AdaptCounts ViEEncoder::AdaptCounter::Counts(int reason) const { |
| + AdaptCounts counts; |
| + counts.fps = fps_counters_[reason]; |
| + counts.resolution = resolution_counters_[reason]; |
| + return counts; |
| +} |
| + |
| +void ViEEncoder::AdaptCounter::IncrementFramerate(int reason, int delta) { |
| + fps_counters_[reason] += delta; |
| +} |
| + |
| +void ViEEncoder::AdaptCounter::IncrementResolution(int reason, int delta) { |
| + resolution_counters_[reason] += delta; |
| +} |
| + |
| +int ViEEncoder::AdaptCounter::FramerateCount() const { |
| + return Count(fps_counters_); |
| +} |
| + |
| +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]; |
| +} |
| + |
| +int ViEEncoder::AdaptCounter::ResolutionCount(int reason) const { |
| + return resolution_counters_[reason]; |
| +} |
| + |
| +int ViEEncoder::AdaptCounter::TotalCount(int reason) const { |
| + return FramerateCount(reason) + ResolutionCount(reason); |
| +} |
| + |
| +int ViEEncoder::AdaptCounter::Count(const std::vector<int>& counters) const { |
| + int sum = 0; |
| + for (size_t reason = 0; reason < kScaleReasonSize; ++reason) |
| + sum += counters[reason]; |
| + return sum; |
|
kthelgason
2017/05/09 11:50:15
I'd prefer `return std::accumulate(counters.begin(
åsapersson
2017/05/10 08:24:45
Done.
|
| } |
| -void ViEEncoder::IncrementScaleCounter(int reason, int delta) { |
| - // Get the counters and validate. This may also lazily initialize the state. |
| - const std::vector<int>& counter = GetScaleCounters(); |
| - if (delta < 0) { |
| - RTC_DCHECK_GE(counter[reason], delta); |
| +std::string ViEEncoder::AdaptCounter::ToString( |
| + const std::vector<int>& counters) const { |
| + std::stringstream ss; |
|
kthelgason
2017/05/09 11:50:15
There has been some discussion about not adding ne
|
| + for (size_t reason = 0; reason < kScaleReasonSize; ++reason) { |
| + ss << (reason ? " cpu" : "quality") << ":" << counters[reason]; |
| } |
| - scale_counters_[degradation_preference_][reason] += delta; |
| + return ss.str(); |
| } |
| } // namespace webrtc |