Index: remoting/host/capture_scheduler.cc |
diff --git a/remoting/host/capture_scheduler.cc b/remoting/host/capture_scheduler.cc |
index 1aa8f58e06326857c4476075ff74648e1a3ebdaf..ca6f28d3462cdfc8fc63dba4dc373cc3791ce5d5 100644 |
--- a/remoting/host/capture_scheduler.cc |
+++ b/remoting/host/capture_scheduler.cc |
@@ -25,16 +25,25 @@ const int64 kDefaultMinimumIntervalMs = 33; |
// available while 1 means using 100% of all CPUs available. |
const double kRecordingCpuConsumption = 0.5; |
+// Maximum number of captured frames in the encoding queue. Currently capturer |
+// implementations do not allow to keep more than 2 DesktopFrame objects. |
+static const int kMaxFramesInEncodingQueue = 2; |
+ |
// Maximum number of frames that can be processed simultaneously. |
-static const int kMaxPendingFrames = 2; |
+static const int kMaxPendingFrames = 4; |
+static const int kMaxPendingFramesWithoutAcks = 2; |
} // namespace |
namespace remoting { |
// We assume that the number of available cores is constant. |
-CaptureScheduler::CaptureScheduler(const base::Closure& capture_closure) |
+CaptureScheduler::CaptureScheduler(const base::Closure& capture_closure, |
+ bool acks_supported) |
: capture_closure_(capture_closure), |
+ acks_supported_(acks_supported), |
+ max_pending_frames_(acks_supported ? kMaxPendingFrames |
+ : kMaxPendingFramesWithoutAcks), |
tick_clock_(new base::DefaultTickClock()), |
capture_timer_(new base::Timer(false, false)), |
minimum_interval_( |
@@ -42,7 +51,8 @@ CaptureScheduler::CaptureScheduler(const base::Closure& capture_closure) |
num_of_processors_(base::SysInfo::NumberOfProcessors()), |
capture_time_(kStatisticsWindow), |
encode_time_(kStatisticsWindow), |
- pending_frames_(0), |
+ num_encoding_frames_(0), |
+ num_sending_frames_(0), |
capture_pending_(false), |
is_paused_(false) { |
DCHECK(num_of_processors_); |
@@ -78,30 +88,54 @@ void CaptureScheduler::OnCaptureCompleted() { |
capture_time_.Record( |
(tick_clock_->NowTicks() - last_capture_started_time_).InMilliseconds()); |
+ ++num_encoding_frames_; |
+ |
ScheduleNextCapture(); |
} |
-void CaptureScheduler::OnFrameSent() { |
+void CaptureScheduler::OnFrameEncoded(base::TimeDelta encode_time) { |
DCHECK(CalledOnValidThread()); |
- // Decrement the pending capture count. |
- pending_frames_--; |
- DCHECK_GE(pending_frames_, 0); |
+ encode_time_.Record(encode_time.InMilliseconds()); |
+ |
+ --num_encoding_frames_; |
+ ++num_sending_frames_; |
ScheduleNextCapture(); |
} |
-void CaptureScheduler::OnFrameEncoded(base::TimeDelta encode_time) { |
+void CaptureScheduler::OnFrameSent() { |
DCHECK(CalledOnValidThread()); |
- encode_time_.Record(encode_time.InMilliseconds()); |
+ // If ACKs are supported then wait for the ACK before decrementing |
+ // |num_sending_frames_|. |
+ if (!acks_supported_) { |
+ --num_sending_frames_; |
+ DCHECK_GE(num_sending_frames_, 0); |
+ |
+ ScheduleNextCapture(); |
+ } |
+} |
+ |
+void CaptureScheduler::OnFrameAck() { |
+ DCHECK(CalledOnValidThread()); |
+ DCHECK(acks_supported_); |
+ |
+ --num_sending_frames_; |
+ DCHECK_GE(num_sending_frames_, 0); |
+ |
ScheduleNextCapture(); |
} |
void CaptureScheduler::ScheduleNextCapture() { |
DCHECK(CalledOnValidThread()); |
- if (is_paused_ || pending_frames_ >= kMaxPendingFrames || capture_pending_) |
+ if (is_paused_ || capture_pending_ || |
+ num_encoding_frames_ >= kMaxFramesInEncodingQueue) { |
+ return; |
+ } |
+ |
+ if (num_encoding_frames_ + num_sending_frames_ >= max_pending_frames_) |
return; |
// Delay by an amount chosen such that if capture and encode times |
@@ -127,9 +161,6 @@ void CaptureScheduler::CaptureNextFrame() { |
DCHECK(!is_paused_); |
DCHECK(!capture_pending_); |
- pending_frames_++; |
- DCHECK_LE(pending_frames_, kMaxPendingFrames); |
- |
capture_pending_ = true; |
last_capture_started_time_ = tick_clock_->NowTicks(); |
capture_closure_.Run(); |