| 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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 DCHECK(capturer_); | 53 DCHECK(capturer_); |
| 54 DCHECK(cursor_stub_); | 54 DCHECK(cursor_stub_); |
| 55 DCHECK(video_stub_); | 55 DCHECK(video_stub_); |
| 56 | 56 |
| 57 capture_task_runner_->PostTask( | 57 capture_task_runner_->PostTask( |
| 58 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this)); | 58 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this)); |
| 59 } | 59 } |
| 60 | 60 |
| 61 // Public methods -------------------------------------------------------------- | 61 // Public methods -------------------------------------------------------------- |
| 62 | 62 |
| 63 void VideoScheduler::OnCaptureCompleted( |
| 64 scoped_refptr<CaptureData> capture_data) { |
| 65 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 66 |
| 67 if (capture_data) { |
| 68 base::TimeDelta capture_time = base::Time::Now() - capture_start_time_; |
| 69 int capture_time_ms = |
| 70 static_cast<int>(capture_time.InMilliseconds()); |
| 71 capture_data->set_capture_time_ms(capture_time_ms); |
| 72 scheduler_.RecordCaptureTime(capture_time); |
| 73 |
| 74 // The best way to get this value is by binding the sequence number to |
| 75 // the callback when calling CaptureInvalidRects(). However the callback |
| 76 // system doesn't allow this. Reading from the member variable is |
| 77 // accurate as long as capture is synchronous as the following statement |
| 78 // will obtain the most recent sequence number received. |
| 79 capture_data->set_client_sequence_number(sequence_number_); |
| 80 } |
| 81 |
| 82 encode_task_runner_->PostTask( |
| 83 FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this, capture_data)); |
| 84 } |
| 85 |
| 86 void VideoScheduler::OnCursorShapeChanged( |
| 87 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { |
| 88 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 89 |
| 90 network_task_runner_->PostTask( |
| 91 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, |
| 92 base::Passed(&cursor_shape))); |
| 93 } |
| 94 |
| 63 void VideoScheduler::Stop(const base::Closure& done_task) { | 95 void VideoScheduler::Stop(const base::Closure& done_task) { |
| 64 DCHECK(network_task_runner_->BelongsToCurrentThread()); | 96 DCHECK(network_task_runner_->BelongsToCurrentThread()); |
| 65 DCHECK(!done_task.is_null()); | 97 DCHECK(!done_task.is_null()); |
| 66 | 98 |
| 67 // Clear stubs to prevent further updates reaching the client. | 99 // Clear stubs to prevent further updates reaching the client. |
| 68 cursor_stub_ = NULL; | 100 cursor_stub_ = NULL; |
| 69 video_stub_ = NULL; | 101 video_stub_ = NULL; |
| 70 | 102 |
| 71 capture_task_runner_->PostTask(FROM_HERE, | 103 capture_task_runner_->PostTask(FROM_HERE, |
| 72 base::Bind(&VideoScheduler::StopOnCaptureThread, this, done_task)); | 104 base::Bind(&VideoScheduler::StopOnCaptureThread, this, done_task)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 | 137 |
| 106 VideoScheduler::~VideoScheduler() { | 138 VideoScheduler::~VideoScheduler() { |
| 107 } | 139 } |
| 108 | 140 |
| 109 // Capturer thread ------------------------------------------------------------- | 141 // Capturer thread ------------------------------------------------------------- |
| 110 | 142 |
| 111 void VideoScheduler::StartOnCaptureThread() { | 143 void VideoScheduler::StartOnCaptureThread() { |
| 112 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | 144 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 113 | 145 |
| 114 // Start the capturer and let it notify us of cursor shape changes. | 146 // Start the capturer and let it notify us of cursor shape changes. |
| 115 capturer_->Start( | 147 capturer_->Start(this); |
| 116 base::Bind(&VideoScheduler::CursorShapeChangedCallback, this)); | |
| 117 | 148 |
| 118 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); | 149 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); |
| 119 | 150 |
| 120 // Capture first frame immedately. | 151 // Capture first frame immedately. |
| 121 CaptureNextFrame(); | 152 CaptureNextFrame(); |
| 122 } | 153 } |
| 123 | 154 |
| 124 void VideoScheduler::StopOnCaptureThread(const base::Closure& done_task) { | 155 void VideoScheduler::StopOnCaptureThread(const base::Closure& done_task) { |
| 125 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | 156 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 126 | 157 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 | 195 |
| 165 // At this point we are going to perform one capture so save the current time. | 196 // At this point we are going to perform one capture so save the current time. |
| 166 pending_captures_++; | 197 pending_captures_++; |
| 167 DCHECK_LE(pending_captures_, kMaxPendingCaptures); | 198 DCHECK_LE(pending_captures_, kMaxPendingCaptures); |
| 168 | 199 |
| 169 // Before doing a capture schedule for the next one. | 200 // Before doing a capture schedule for the next one. |
| 170 ScheduleNextCapture(); | 201 ScheduleNextCapture(); |
| 171 | 202 |
| 172 // And finally perform one capture. | 203 // And finally perform one capture. |
| 173 capture_start_time_ = base::Time::Now(); | 204 capture_start_time_ = base::Time::Now(); |
| 174 capturer_->CaptureInvalidRegion( | 205 capturer_->CaptureInvalidRegion(); |
| 175 base::Bind(&VideoScheduler::CaptureDoneCallback, this)); | |
| 176 } | |
| 177 | |
| 178 void VideoScheduler::CaptureDoneCallback( | |
| 179 scoped_refptr<CaptureData> capture_data) { | |
| 180 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | |
| 181 | |
| 182 if (capture_data) { | |
| 183 base::TimeDelta capture_time = base::Time::Now() - capture_start_time_; | |
| 184 int capture_time_ms = | |
| 185 static_cast<int>(capture_time.InMilliseconds()); | |
| 186 capture_data->set_capture_time_ms(capture_time_ms); | |
| 187 scheduler_.RecordCaptureTime(capture_time); | |
| 188 | |
| 189 // The best way to get this value is by binding the sequence number to | |
| 190 // the callback when calling CaptureInvalidRects(). However the callback | |
| 191 // system doesn't allow this. Reading from the member variable is | |
| 192 // accurate as long as capture is synchronous as the following statement | |
| 193 // will obtain the most recent sequence number received. | |
| 194 capture_data->set_client_sequence_number(sequence_number_); | |
| 195 } | |
| 196 | |
| 197 encode_task_runner_->PostTask( | |
| 198 FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this, capture_data)); | |
| 199 } | |
| 200 | |
| 201 void VideoScheduler::CursorShapeChangedCallback( | |
| 202 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { | |
| 203 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | |
| 204 | |
| 205 network_task_runner_->PostTask( | |
| 206 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, | |
| 207 base::Passed(&cursor_shape))); | |
| 208 } | 206 } |
| 209 | 207 |
| 210 void VideoScheduler::FrameCaptureCompleted() { | 208 void VideoScheduler::FrameCaptureCompleted() { |
| 211 DCHECK(capture_task_runner_->BelongsToCurrentThread()); | 209 DCHECK(capture_task_runner_->BelongsToCurrentThread()); |
| 212 | 210 |
| 213 // Decrement the pending capture count. | 211 // Decrement the pending capture count. |
| 214 pending_captures_--; | 212 pending_captures_--; |
| 215 DCHECK_GE(pending_captures_, 0); | 213 DCHECK_GE(pending_captures_, 0); |
| 216 | 214 |
| 217 // If we've skipped a frame capture because too we had too many captures | 215 // If we've skipped a frame capture because too we had too many captures |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 packet->set_encode_time_ms(encode_time_ms); | 287 packet->set_encode_time_ms(encode_time_ms); |
| 290 scheduler_.RecordEncodeTime(encode_time); | 288 scheduler_.RecordEncodeTime(encode_time); |
| 291 } | 289 } |
| 292 | 290 |
| 293 network_task_runner_->PostTask( | 291 network_task_runner_->PostTask( |
| 294 FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this, | 292 FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this, |
| 295 base::Passed(&packet))); | 293 base::Passed(&packet))); |
| 296 } | 294 } |
| 297 | 295 |
| 298 } // namespace remoting | 296 } // namespace remoting |
| OLD | NEW |