| 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(
|
|
|