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

Unified Diff: webrtc/video/vie_encoder.cc

Issue 2887303003: Implement kBalanced degradation preference. (Closed)
Patch Set: rebase Created 3 years, 6 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
« no previous file with comments | « webrtc/video/vie_encoder.h ('k') | webrtc/video/vie_encoder_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webrtc/video/vie_encoder.cc
diff --git a/webrtc/video/vie_encoder.cc b/webrtc/video/vie_encoder.cc
index 203d1c405a8813d05b627cd464803bb9df39f645..63b1c80fefbe9b0f0f8afaf95a83dd0f140a3540 100644
--- a/webrtc/video/vie_encoder.cc
+++ b/webrtc/video/vie_encoder.cc
@@ -73,6 +73,29 @@ uint32_t MaximumFrameSizeForBitrate(uint32_t kbps) {
return std::numeric_limits<uint32_t>::max();
}
+// Initial limits for kBalanced degradation preference.
+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();
+ }
+}
+
+int MaxFps(int pixels) {
+ if (pixels <= 320 * 240) {
+ return 10;
+ } else if (pixels <= 480 * 270) {
+ return 15;
+ } else {
+ return std::numeric_limits<int>::max();
+ }
+}
+
bool IsResolutionScalingEnabled(
VideoSendStream::DegradationPreference degradation_preference) {
return degradation_preference ==
@@ -211,7 +234,7 @@ class ViEEncoder::VideoSourceProxy {
// the used degradation_preference.
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
- FALLTHROUGH();
+ break;
case VideoSendStream::DegradationPreference::kMaintainFramerate:
wants.max_framerate_fps = std::numeric_limits<int>::max();
break;
@@ -227,6 +250,15 @@ class ViEEncoder::VideoSourceProxy {
return wants;
}
+ void ResetPixelFpsCount() {
+ rtc::CritScope lock(&crit_);
+ sink_wants_.max_pixel_count = std::numeric_limits<int>::max();
+ sink_wants_.target_pixel_count.reset();
+ sink_wants_.max_framerate_fps = std::numeric_limits<int>::max();
+ if (source_)
+ source_->AddOrUpdateSink(vie_encoder_, sink_wants_);
+ }
+
bool RequestResolutionLowerThan(int pixel_count) {
// Called on the encoder task queue.
rtc::CritScope lock(&crit_);
@@ -447,6 +479,15 @@ void ViEEncoder::SetSource(
// Reset adaptation state, so that we're not tricked into thinking there's
// an already pending request of the same type.
last_adaptation_request_.reset();
+ if (degradation_preference ==
+ VideoSendStream::DegradationPreference::kBalanced ||
+ degradation_preference_ ==
+ VideoSendStream::DegradationPreference::kBalanced) {
+ // TODO(asapersson): Consider removing |adapt_counters_| map and use one
+ // AdaptCounter for all modes.
+ source_proxy_->ResetPixelFpsCount();
+ adapt_counters_.clear();
+ }
}
degradation_preference_ = degradation_preference;
bool allow_scaling = IsResolutionScalingEnabled(degradation_preference_);
@@ -803,12 +844,10 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
last_adaptation_request_ &&
last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptDown;
- int max_downgrades = 0;
switch (degradation_preference_) {
case VideoSendStream::DegradationPreference::kBalanced:
- FALLTHROUGH();
+ break;
case VideoSendStream::DegradationPreference::kMaintainFramerate:
- max_downgrades = kMaxCpuResolutionDowngrades;
if (downgrade_requested &&
adaptation_request.input_pixel_count_ >=
last_adaptation_request_->input_pixel_count_) {
@@ -818,7 +857,6 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
}
break;
case VideoSendStream::DegradationPreference::kMaintainResolution:
- max_downgrades = kMaxCpuFramerateDowngrades;
if (adaptation_request.framerate_fps_ <= 0 ||
(downgrade_requested &&
adaptation_request.framerate_fps_ < kMinFramerateFps)) {
@@ -836,20 +874,32 @@ void ViEEncoder::AdaptDown(AdaptReason reason) {
}
if (reason == kCpu) {
- if (GetConstAdaptCounter().TotalCount(kCpu) >= max_downgrades)
+ if (GetConstAdaptCounter().ResolutionCount(kCpu) >=
+ kMaxCpuResolutionDowngrades ||
+ GetConstAdaptCounter().FramerateCount(kCpu) >=
+ kMaxCpuFramerateDowngrades) {
return;
+ }
}
switch (degradation_preference_) {
- case VideoSendStream::DegradationPreference::kBalanced:
+ case VideoSendStream::DegradationPreference::kBalanced: {
+ // Try scale down framerate, if lower.
+ int fps = MinFps(last_frame_info_->pixel_count());
+ if (source_proxy_->RestrictFramerate(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.
@@ -857,7 +907,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();
@@ -888,29 +938,34 @@ void ViEEncoder::AdaptUp(AdaptReason reason) {
last_adaptation_request_ &&
last_adaptation_request_->mode_ == AdaptationRequest::Mode::kAdaptUp;
- switch (degradation_preference_) {
- case VideoSendStream::DegradationPreference::kBalanced:
- FALLTHROUGH();
- 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, fps);
+ // Reset framerate in case of fewer fps steps down than up.
+ if (adapt_counter.FramerateCount() == 0 &&
+ fps != std::numeric_limits<int>::max()) {
+ LOG(LS_INFO) << "Removing framerate down-scaling setting.";
+ source_proxy_->IncreaseFramerate(std::numeric_limits<int>::max());
+ }
+ break;
+ }
+ // Scale up resolution.
FALLTHROUGH();
+ }
case VideoSendStream::DegradationPreference::kMaintainFramerate: {
// Scale up resolution.
int pixel_count = adaptation_request.input_pixel_count_;
@@ -920,7 +975,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: {
@@ -932,11 +987,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);
@@ -994,6 +1049,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() {}
@@ -1012,12 +1068,48 @@ 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);
+}
+
+void ViEEncoder::AdaptCounter::DecrementFramerate(int reason, int cur_fps) {
+ DecrementFramerate(reason);
+ // Reset if at max fps (i.e. in case of fewer steps up than down).
+ if (cur_fps == std::numeric_limits<int>::max())
+ std::fill(fps_counters_.begin(), fps_counters_.end(), 0);
}
int ViEEncoder::AdaptCounter::FramerateCount() const {
@@ -1028,10 +1120,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];
}
@@ -1048,6 +1136,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;
« no previous file with comments | « webrtc/video/vie_encoder.h ('k') | webrtc/video/vie_encoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698