Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(151)

Unified Diff: webrtc/video/vie_encoder.cc

Issue 2871623002: Update video adaptation stats to support degradations in both resolution and framerate. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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

Powered by Google App Engine
This is Rietveld 408576698