| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "remoting/host/video_scheduler.h" | 5 #include "remoting/host/video_scheduler.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | 10 #include "base/callback.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "remoting/protocol/message_decoder.h" | 24 #include "remoting/protocol/message_decoder.h" |
| 25 #include "remoting/protocol/video_stub.h" | 25 #include "remoting/protocol/video_stub.h" |
| 26 #include "remoting/protocol/util.h" | 26 #include "remoting/protocol/util.h" |
| 27 | 27 |
| 28 namespace remoting { | 28 namespace remoting { |
| 29 | 29 |
| 30 // Maximum number of frames that can be processed simultaneously. | 30 // Maximum number of frames that can be processed simultaneously. |
| 31 // TODO(hclam): Move this value to CaptureScheduler. | 31 // TODO(hclam): Move this value to CaptureScheduler. |
| 32 static const int kMaxPendingCaptures = 2; | 32 static const int kMaxPendingCaptures = 2; |
| 33 | 33 |
| 34 // static | 34 VideoScheduler::VideoScheduler( |
| 35 scoped_refptr<VideoScheduler> VideoScheduler::Create( | |
| 36 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, | 35 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, |
| 37 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, | 36 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, |
| 38 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, | 37 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, |
| 39 scoped_ptr<media::ScreenCapturer> capturer, | 38 scoped_ptr<media::ScreenCapturer> capturer, |
| 40 scoped_ptr<VideoEncoder> encoder, | 39 scoped_ptr<VideoEncoder> encoder, |
| 41 protocol::CursorShapeStub* cursor_stub, | 40 protocol::CursorShapeStub* cursor_stub, |
| 42 protocol::VideoStub* video_stub) { | 41 protocol::VideoStub* video_stub) |
| 43 DCHECK(network_task_runner->BelongsToCurrentThread()); | 42 : capture_task_runner_(capture_task_runner), |
| 44 DCHECK(capturer); | 43 encode_task_runner_(encode_task_runner), |
| 45 DCHECK(encoder); | 44 network_task_runner_(network_task_runner), |
| 46 DCHECK(cursor_stub); | 45 capturer_(capturer.Pass()), |
| 47 DCHECK(video_stub); | 46 encoder_(encoder.Pass()), |
| 48 | 47 cursor_stub_(cursor_stub), |
| 49 scoped_refptr<VideoScheduler> scheduler = new VideoScheduler( | 48 video_stub_(video_stub), |
| 50 capture_task_runner, encode_task_runner, network_task_runner, | 49 pending_captures_(0), |
| 51 capturer.Pass(), encoder.Pass(), cursor_stub, video_stub); | 50 did_skip_frame_(false), |
| 52 capture_task_runner->PostTask( | 51 is_paused_(false), |
| 53 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, scheduler)); | 52 sequence_number_(0) { |
| 54 | 53 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 55 return scheduler; | 54 DCHECK(capturer_); |
| 55 DCHECK(encoder_); |
| 56 DCHECK(cursor_stub_); |
| 57 DCHECK(video_stub_); |
| 56 } | 58 } |
| 57 | 59 |
| 58 // Public methods -------------------------------------------------------------- | 60 // Public methods -------------------------------------------------------------- |
| 59 | 61 |
| 60 void VideoScheduler::OnCaptureCompleted( | 62 void VideoScheduler::OnCaptureCompleted( |
| 61 scoped_refptr<media::ScreenCaptureData> capture_data) { | 63 scoped_refptr<media::ScreenCaptureData> capture_data) { |
| 62 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | 64 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 63 | 65 |
| 64 // Do nothing if the scheduler is being stopped. | 66 // Do nothing if the scheduler is being stopped. |
| 65 if (!capturer_) | 67 if (!capturer_) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 95 cursor_proto->set_height(cursor_shape->size.height()); | 97 cursor_proto->set_height(cursor_shape->size.height()); |
| 96 cursor_proto->set_hotspot_x(cursor_shape->hotspot.x()); | 98 cursor_proto->set_hotspot_x(cursor_shape->hotspot.x()); |
| 97 cursor_proto->set_hotspot_y(cursor_shape->hotspot.y()); | 99 cursor_proto->set_hotspot_y(cursor_shape->hotspot.y()); |
| 98 cursor_proto->set_data(cursor_shape->data); | 100 cursor_proto->set_data(cursor_shape->data); |
| 99 | 101 |
| 100 network_task_runner_->PostTask( | 102 network_task_runner_->PostTask( |
| 101 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, | 103 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, |
| 102 base::Passed(&cursor_proto))); | 104 base::Passed(&cursor_proto))); |
| 103 } | 105 } |
| 104 | 106 |
| 107 void VideoScheduler::Start() { |
| 108 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 109 |
| 110 capture_task_runner_->PostTask( |
| 111 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this)); |
| 112 } |
| 113 |
| 105 void VideoScheduler::Stop() { | 114 void VideoScheduler::Stop() { |
| 106 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 115 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 107 | 116 |
| 108 // Clear stubs to prevent further updates reaching the client. | 117 // Clear stubs to prevent further updates reaching the client. |
| 109 cursor_stub_ = NULL; | 118 cursor_stub_ = NULL; |
| 110 video_stub_ = NULL; | 119 video_stub_ = NULL; |
| 111 | 120 |
| 112 capture_task_runner_->PostTask(FROM_HERE, | 121 capture_task_runner_->PostTask(FROM_HERE, |
| 113 base::Bind(&VideoScheduler::StopOnCaptureThread, this)); | 122 base::Bind(&VideoScheduler::StopOnCaptureThread, this)); |
| 114 } | 123 } |
| 115 | 124 |
| 116 void VideoScheduler::Pause(bool pause) { | 125 void VideoScheduler::Pause(bool pause) { |
| 117 if (!capture_task_runner_->BelongsToCurrentThread()) { | 126 if (!capture_task_runner_->BelongsToCurrentThread()) { |
| 118 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 127 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 119 capture_task_runner_->PostTask( | 128 capture_task_runner_->PostTask( |
| 120 FROM_HERE, base::Bind(&VideoScheduler::Pause, this, pause)); | 129 FROM_HERE, base::Bind(&VideoScheduler::Pause, this, pause)); |
| 121 return; | 130 return; |
| 122 } | 131 } |
| 123 | 132 |
| 124 if (is_paused_ != pause) { | 133 if (is_paused_ != pause) { |
| 125 is_paused_ = pause; | 134 is_paused_ = pause; |
| 126 | 135 |
| 127 // Restart captures if we're resuming and there are none scheduled. | 136 // Restart captures if we're resuming and there are none scheduled. |
| 128 if (!is_paused_ && !capture_timer_->IsRunning()) | 137 if (!is_paused_ && capture_timer_ && !capture_timer_->IsRunning()) |
| 129 CaptureNextFrame(); | 138 CaptureNextFrame(); |
| 130 } | 139 } |
| 131 } | 140 } |
| 132 | 141 |
| 133 void VideoScheduler::UpdateSequenceNumber(int64 sequence_number) { | 142 void VideoScheduler::UpdateSequenceNumber(int64 sequence_number) { |
| 134 if (!capture_task_runner_->BelongsToCurrentThread()) { | 143 if (!capture_task_runner_->BelongsToCurrentThread()) { |
| 135 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 144 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 136 capture_task_runner_->PostTask( | 145 capture_task_runner_->PostTask( |
| 137 FROM_HERE, base::Bind(&VideoScheduler::UpdateSequenceNumber, | 146 FROM_HERE, base::Bind(&VideoScheduler::UpdateSequenceNumber, |
| 138 this, sequence_number)); | 147 this, sequence_number)); |
| 139 return; | 148 return; |
| 140 } | 149 } |
| 141 | 150 |
| 142 sequence_number_ = sequence_number; | 151 sequence_number_ = sequence_number; |
| 143 } | 152 } |
| 144 | 153 |
| 145 // Private methods ----------------------------------------------------------- | 154 // Private methods ----------------------------------------------------------- |
| 146 | 155 |
| 147 VideoScheduler::VideoScheduler( | |
| 148 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, | |
| 149 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, | |
| 150 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, | |
| 151 scoped_ptr<media::ScreenCapturer> capturer, | |
| 152 scoped_ptr<VideoEncoder> encoder, | |
| 153 protocol::CursorShapeStub* cursor_stub, | |
| 154 protocol::VideoStub* video_stub) | |
| 155 : capture_task_runner_(capture_task_runner), | |
| 156 encode_task_runner_(encode_task_runner), | |
| 157 network_task_runner_(network_task_runner), | |
| 158 capturer_(capturer.Pass()), | |
| 159 encoder_(encoder.Pass()), | |
| 160 cursor_stub_(cursor_stub), | |
| 161 video_stub_(video_stub), | |
| 162 pending_captures_(0), | |
| 163 did_skip_frame_(false), | |
| 164 is_paused_(false), | |
| 165 sequence_number_(0) { | |
| 166 } | |
| 167 | |
| 168 VideoScheduler::~VideoScheduler() { | 156 VideoScheduler::~VideoScheduler() { |
| 169 } | 157 } |
| 170 | 158 |
| 171 // Capturer thread ------------------------------------------------------------- | 159 // Capturer thread ------------------------------------------------------------- |
| 172 | 160 |
| 173 void VideoScheduler::StartOnCaptureThread() { | 161 void VideoScheduler::StartOnCaptureThread() { |
| 174 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | 162 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 163 DCHECK(!capture_timer_); |
| 175 | 164 |
| 176 // Start the capturer and let it notify us if cursor shape changes. | 165 // Start the capturer and let it notify us if cursor shape changes. |
| 177 capturer_->Start(this); | 166 capturer_->Start(this); |
| 178 | 167 |
| 179 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); | 168 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); |
| 180 | 169 |
| 181 // Capture first frame immedately. | 170 // Capture first frame immedately. |
| 182 CaptureNextFrame(); | 171 CaptureNextFrame(); |
| 183 } | 172 } |
| 184 | 173 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 scoped_ptr<media::ScreenCapturer> capturer) { | 312 scoped_ptr<media::ScreenCapturer> capturer) { |
| 324 DCHECK(encode_task_runner_->BelongsToCurrentThread()); | 313 DCHECK(encode_task_runner_->BelongsToCurrentThread()); |
| 325 | 314 |
| 326 // This is posted by StopOnCaptureThread, so we know that by the time we | 315 // This is posted by StopOnCaptureThread, so we know that by the time we |
| 327 // process it there are no more encode tasks queued. Pass |capturer| for | 316 // process it there are no more encode tasks queued. Pass |capturer| for |
| 328 // deletion on the capture thread. | 317 // deletion on the capture thread. |
| 329 capture_task_runner_->DeleteSoon(FROM_HERE, capturer.release()); | 318 capture_task_runner_->DeleteSoon(FROM_HERE, capturer.release()); |
| 330 } | 319 } |
| 331 | 320 |
| 332 } // namespace remoting | 321 } // namespace remoting |
| OLD | NEW |