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 |