Index: remoting/host/screen_recorder.cc |
diff --git a/remoting/host/screen_recorder.cc b/remoting/host/screen_recorder.cc |
index 98266e3cf02bf768fe5cd5ec1f5eca3e2fc39a76..9353381dedab19cdef9cc1b688c374872cdd52b3 100644 |
--- a/remoting/host/screen_recorder.cc |
+++ b/remoting/host/screen_recorder.cc |
@@ -11,6 +11,7 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/message_loop_proxy.h" |
#include "base/stl_util.h" |
+#include "base/sys_info.h" |
#include "base/task.h" |
#include "base/time.h" |
#include "remoting/base/capture_data.h" |
@@ -25,14 +26,7 @@ using remoting::protocol::ConnectionToClient; |
namespace remoting { |
-// By default we capture 20 times a second. This number is obtained by |
-// experiment to provide good latency. |
-static const double kDefaultCaptureRate = 20.0; |
- |
// Maximum number of frames that can be processed similtaneously. |
-// TODO(sergeyu): Should this be set to 1? Or should we change |
-// dynamically depending on how fast network and CPU are? Experement |
-// with it. |
static const int kMaxRecordings = 2; |
ScreenRecorder::ScreenRecorder( |
@@ -49,9 +43,9 @@ ScreenRecorder::ScreenRecorder( |
is_recording_(false), |
network_stopped_(false), |
encoder_stopped_(false), |
+ max_recordings_(kMaxRecordings), |
recordings_(0), |
frame_skipped_(false), |
- max_rate_(kDefaultCaptureRate), |
sequence_number_(0) { |
DCHECK(capture_loop_); |
DCHECK(encode_loop_); |
@@ -84,11 +78,6 @@ void ScreenRecorder::Stop(const base::Closure& done_task) { |
&ScreenRecorder::DoStopOnNetworkThread, this, done_task)); |
} |
-void ScreenRecorder::SetMaxRate(double rate) { |
- capture_loop_->PostTask( |
- FROM_HERE, NewRunnableMethod(this, &ScreenRecorder::DoSetMaxRate, rate)); |
-} |
- |
void ScreenRecorder::AddConnection( |
scoped_refptr<ConnectionToClient> connection) { |
capture_loop_->PostTask( |
@@ -152,33 +141,18 @@ void ScreenRecorder::DoStart() { |
} |
is_recording_ = true; |
- StartCaptureTimer(); |
// Capture first frame immedately. |
DoCapture(); |
} |
-void ScreenRecorder::DoSetMaxRate(double max_rate) { |
- DCHECK_EQ(capture_loop_, MessageLoop::current()); |
- |
- // TODO(hclam): Should also check for small epsilon. |
- DCHECK_GT(max_rate, 0.0) << "Rate is too small."; |
- |
- max_rate_ = max_rate; |
- |
- // Restart the timer with the new rate. |
- if (is_recording_) { |
- capture_timer_.Stop(); |
- StartCaptureTimer(); |
- } |
-} |
- |
void ScreenRecorder::StartCaptureTimer() { |
DCHECK_EQ(capture_loop_, MessageLoop::current()); |
- base::TimeDelta interval = base::TimeDelta::FromMilliseconds( |
- static_cast<int>(base::Time::kMillisecondsPerSecond / max_rate_)); |
- capture_timer_.Start(FROM_HERE, interval, this, &ScreenRecorder::DoCapture); |
+ capture_timer_.Start(FROM_HERE, |
+ scheduler_.NextCaptureDelay(), |
+ this, |
+ &ScreenRecorder::DoCapture); |
} |
void ScreenRecorder::DoCapture() { |
@@ -186,19 +160,24 @@ void ScreenRecorder::DoCapture() { |
// Make sure we have at most two oustanding recordings. We can simply return |
// if we can't make a capture now, the next capture will be started by the |
// end of an encode operation. |
- if (recordings_ >= kMaxRecordings || !is_recording_) { |
+ if (recordings_ >= max_recordings_ || !is_recording_) { |
frame_skipped_ = true; |
return; |
} |
- if (frame_skipped_) { |
+ if (frame_skipped_) |
frame_skipped_ = false; |
- capture_timer_.Reset(); |
- } |
// At this point we are going to perform one capture so save the current time. |
++recordings_; |
- DCHECK_LE(recordings_, kMaxRecordings); |
+ DCHECK_LE(recordings_, max_recordings_); |
+ |
+ // Before doing a capture schedule for the next one. |
+ capture_timer_.Stop(); |
+ capture_timer_.Start(FROM_HERE, |
+ scheduler_.NextCaptureDelay(), |
+ this, |
+ &ScreenRecorder::DoCapture); |
// And finally perform one capture. |
capture_start_time_ = base::Time::Now(); |
@@ -214,9 +193,11 @@ void ScreenRecorder::CaptureDoneCallback( |
return; |
if (capture_data) { |
- int capture_time = static_cast<int>( |
- (base::Time::Now() - capture_start_time_).InMilliseconds()); |
- capture_data->set_capture_time_ms(capture_time); |
+ base::TimeDelta capture_time = base::Time::Now() - capture_start_time_; |
+ int capture_time_ms = |
+ static_cast<int>(capture_time.InMilliseconds()); |
+ capture_data->set_capture_time_ms(capture_time_ms); |
+ scheduler_.RecordCaptureTime(capture_time); |
// The best way to get this value is by binding the sequence number to |
// the callback when calling CaptureInvalidRects(). However the callback |
@@ -381,9 +362,11 @@ void ScreenRecorder::EncodedDataAvailableCallback(VideoPacket* packet) { |
bool last = (packet->flags() & VideoPacket::LAST_PACKET) != 0; |
if (last) { |
- int encode_time = static_cast<int>( |
- (base::Time::Now() - encode_start_time_).InMilliseconds()); |
- packet->set_encode_time_ms(encode_time); |
+ base::TimeDelta encode_time = base::Time::Now() - encode_start_time_; |
+ int encode_time_ms = |
+ static_cast<int>(encode_time.InMilliseconds()); |
+ packet->set_encode_time_ms(encode_time_ms); |
+ scheduler_.RecordEncodeTime(encode_time); |
} |
network_loop_->PostTask( |