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

Unified Diff: remoting/protocol/webrtc_frame_scheduler_simple.cc

Issue 2381213002: Use high quantizer value for "big" frames after a sequence of "small" frames. (Closed)
Patch Set: Created 4 years, 2 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 | « remoting/protocol/webrtc_frame_scheduler_simple.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/protocol/webrtc_frame_scheduler_simple.cc
diff --git a/remoting/protocol/webrtc_frame_scheduler_simple.cc b/remoting/protocol/webrtc_frame_scheduler_simple.cc
index 6f6d94895cdd46ca8c16d4c97150423a4e3fc5e4..910018c88b632d0118b1f2c6b51ab8b146268b23 100644
--- a/remoting/protocol/webrtc_frame_scheduler_simple.cc
+++ b/remoting/protocol/webrtc_frame_scheduler_simple.cc
@@ -23,16 +23,40 @@ constexpr base::TimeDelta kTargetFrameInterval =
// Target quantizer at which stop the encoding top-off.
const int kTargetQuantizerForVp8TopOff = 30;
+const int64_t kPixelsPerMegapixel = 1000000;
+
// Minimum target bitrate per megapixel. The value is chosen experimentally such
// that when screen is not changing the codec converges to the target quantizer
// above in less than 10 frames.
const int kVp8MinimumTargetBitrateKbpsPerMegapixel = 2500;
+// Threshold in number of updated pixels used to detect "big" frames. These
+// frames update significant portion of the screen compared to the preceding
+// frames. For these frames min quantizer may need to be adjusted in order to
+// ensure that they get delivered to the client as soon as possible, in exchange
+// for lower-quality image.
+const int kBigFrameThresholdPixels = 300000;
+
+// Estimated size (in bytes per megapixel) of encoded frame at target quantizer
+// value (see kTargetQuantizerForVp8TopOff). Compression ratio varies depending
+// on the image, so this is just a rough estimate. It's used to predict when
+// encoded "big" frame may be too large to be delivered to the client quickly.
+const int kEstimatedBytesPerMegapixel = 100000;
+
+int64_t GetRegionArea(const webrtc::DesktopRegion& region) {
+ int64_t result = 0;
+ for (webrtc::DesktopRegion::Iterator r(region); !r.IsAtEnd(); r.Advance()) {
+ result += r.rect().width() * r.rect().height();
+ }
+ return result;
+}
+
} // namespace
WebrtcFrameSchedulerSimple::WebrtcFrameSchedulerSimple()
: pacing_bucket_(LeakyBucket::kUnlimitedDepth, 0),
- frame_processing_delay_us_(kStatsWindow) {}
+ frame_processing_delay_us_(kStatsWindow),
+ updated_region_area_(kStatsWindow) {}
WebrtcFrameSchedulerSimple::~WebrtcFrameSchedulerSimple() {}
void WebrtcFrameSchedulerSimple::Start(const base::Closure& capture_callback) {
@@ -72,19 +96,37 @@ bool WebrtcFrameSchedulerSimple::GetEncoderFrameParams(
// TODO(sergeyu): This logic is applicable only to VP8. Reconsider it for VP9.
int minimum_bitrate =
- static_cast<uint64_t>(kVp8MinimumTargetBitrateKbpsPerMegapixel) *
+ static_cast<int64_t>(kVp8MinimumTargetBitrateKbpsPerMegapixel) *
frame.size().width() * frame.size().height() / 1000000LL;
params_out->bitrate_kbps =
std::max(minimum_bitrate, pacing_bucket_.rate() * 8 / 1000);
- // TODO(sergeyu): Currently duration is always set to 1/15 of a second.
- // Experiment with different values, and try changing it dynamically.
- params_out->duration = base::TimeDelta::FromSeconds(1) / 15;
-
+ params_out->duration = kTargetFrameInterval;
params_out->key_frame = key_frame_request_;
key_frame_request_ = false;
params_out->vpx_min_quantizer = 10;
+
+ int64_t updated_area = params_out->key_frame
+ ? frame.size().width() * frame.size().height()
+ : GetRegionArea(frame.updated_region());
+
+ // If bandwidth is being underutilized then libvpx is likely to choose the
+ // minimum allowed quantizer value, which means that encoded frame size may be
+ // significantly bigger than the bandwidth allows. Detect this case and set
+ // vpx_min_quantizer to 60. The quality will be topped off later.
+ if (updated_area - updated_region_area_.Max() > kBigFrameThresholdPixels) {
+ int expected_frame_size = updated_area *
+ kEstimatedBytesPerMegapixel / kPixelsPerMegapixel;
+ base::TimeDelta expected_send_delay = base::TimeDelta::FromMicroseconds(
+ base::Time::kMicrosecondsPerSecond * expected_frame_size /
+ pacing_bucket_.rate());
+ if (expected_send_delay > kTargetFrameInterval)
+ params_out->vpx_min_quantizer = 60;
+ }
+
+ updated_region_area_.Record(updated_area);
+
params_out->vpx_max_quantizer = 63;
params_out->clear_active_map = !top_off_is_active_;
« no previous file with comments | « remoting/protocol/webrtc_frame_scheduler_simple.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698