Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: remoting/host/screen_recorder.cc

Issue 10382184: [Chromoting] Initial plumbing for cursor shape. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove extra LOGs Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/screen_recorder.h" 5 #include "remoting/host/screen_recorder.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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop_proxy.h" 13 #include "base/message_loop_proxy.h"
14 #include "base/stl_util.h" 14 #include "base/stl_util.h"
15 #include "base/sys_info.h" 15 #include "base/sys_info.h"
16 #include "base/time.h" 16 #include "base/time.h"
17 #include "remoting/base/capture_data.h" 17 #include "remoting/base/capture_data.h"
18 #include "remoting/base/cursor_shape_data.h"
18 #include "remoting/proto/control.pb.h" 19 #include "remoting/proto/control.pb.h"
20 #include "remoting/proto/internal.pb.h"
19 #include "remoting/proto/video.pb.h" 21 #include "remoting/proto/video.pb.h"
20 #include "remoting/protocol/client_stub.h" 22 #include "remoting/protocol/client_stub.h"
23 #include "remoting/protocol/cursor_shape_stub.h"
21 #include "remoting/protocol/connection_to_client.h" 24 #include "remoting/protocol/connection_to_client.h"
22 #include "remoting/protocol/message_decoder.h" 25 #include "remoting/protocol/message_decoder.h"
23 #include "remoting/protocol/util.h" 26 #include "remoting/protocol/util.h"
24 27
25 using remoting::protocol::ConnectionToClient; 28 using remoting::protocol::ConnectionToClient;
26 29
27 namespace remoting { 30 namespace remoting {
28 31
29 // Maximum number of frames that can be processed similtaneously. 32 // Maximum number of frames that can be processed similtaneously.
30 // TODO(hclam): Move this value to CaptureScheduler. 33 // TODO(hclam): Move this value to CaptureScheduler.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 // Capturer thread ------------------------------------------------------------- 138 // Capturer thread -------------------------------------------------------------
136 139
137 void ScreenRecorder::DoStart() { 140 void ScreenRecorder::DoStart() {
138 DCHECK_EQ(capture_loop_, MessageLoop::current()); 141 DCHECK_EQ(capture_loop_, MessageLoop::current());
139 142
140 if (is_recording()) { 143 if (is_recording()) {
141 NOTREACHED() << "Record session already started."; 144 NOTREACHED() << "Record session already started.";
142 return; 145 return;
143 } 146 }
144 147
148 capturer()->SetCursorShapeChangedCallback(
149 base::Bind(&ScreenRecorder::CursorShapeChangedCallback, this));
150
145 capturer()->Start(); 151 capturer()->Start();
146 capture_timer_.reset(new base::OneShotTimer<ScreenRecorder>()); 152 capture_timer_.reset(new base::OneShotTimer<ScreenRecorder>());
147 153
148 // Capture first frame immedately. 154 // Capture first frame immedately.
149 DoCapture(); 155 DoCapture();
150 } 156 }
151 157
152 void ScreenRecorder::StartCaptureTimer() { 158 void ScreenRecorder::StartCaptureTimer() {
153 DCHECK_EQ(capture_loop_, MessageLoop::current()); 159 DCHECK_EQ(capture_loop_, MessageLoop::current());
154 160
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 // system doesn't allow this. Reading from the member variable is 213 // system doesn't allow this. Reading from the member variable is
208 // accurate as long as capture is synchronous as the following statement 214 // accurate as long as capture is synchronous as the following statement
209 // will obtain the most recent sequence number received. 215 // will obtain the most recent sequence number received.
210 capture_data->set_client_sequence_number(sequence_number_); 216 capture_data->set_client_sequence_number(sequence_number_);
211 } 217 }
212 218
213 encode_loop_->PostTask( 219 encode_loop_->PostTask(
214 FROM_HERE, base::Bind(&ScreenRecorder::DoEncode, this, capture_data)); 220 FROM_HERE, base::Bind(&ScreenRecorder::DoEncode, this, capture_data));
215 } 221 }
216 222
223 void ScreenRecorder::CursorShapeChangedCallback(
224 scoped_refptr<CursorShapeData> cursor_data) {
225 DCHECK_EQ(capture_loop_, MessageLoop::current());
226
227 if (!is_recording())
228 return;
229
230 LOG(INFO) << "posting encode task";
231 encode_loop_->PostTask(
232 FROM_HERE, base::Bind(&ScreenRecorder::DoEncodeCursorShape,
233 this, cursor_data));
234 }
235
217 void ScreenRecorder::DoFinishOneRecording() { 236 void ScreenRecorder::DoFinishOneRecording() {
218 DCHECK_EQ(capture_loop_, MessageLoop::current()); 237 DCHECK_EQ(capture_loop_, MessageLoop::current());
219 238
220 if (!is_recording()) 239 if (!is_recording())
221 return; 240 return;
222 241
223 // Decrement the number of recording in process since we have completed 242 // Decrement the number of recording in process since we have completed
224 // one cycle. 243 // one cycle.
225 --recordings_; 244 --recordings_;
226 DCHECK_GE(recordings_, 0); 245 DCHECK_GE(recordings_, 0);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 // 293 //
275 // After that a task is posted on encode thread to continue the stop 294 // After that a task is posted on encode thread to continue the stop
276 // sequence. 295 // sequence.
277 network_stopped_ = true; 296 network_stopped_ = true;
278 297
279 encode_loop_->PostTask( 298 encode_loop_->PostTask(
280 FROM_HERE, base::Bind(&ScreenRecorder::DoStopOnEncodeThread, 299 FROM_HERE, base::Bind(&ScreenRecorder::DoStopOnEncodeThread,
281 this, done_task)); 300 this, done_task));
282 } 301 }
283 302
303 void ScreenRecorder::DoSendCursorShape(
304 scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
305 DCHECK(network_loop_->BelongsToCurrentThread());
306
307 if (network_stopped_ || connections_.empty())
308 return;
309
310 // TODO(sergeyu): Currently we send the data only to the first
311 // connection. Send it to all connections if necessary.
312 connections_.front()->cursor_shape_stub()->SetCursorShape(*cursor_shape);
313 }
314
284 // Encoder thread -------------------------------------------------------------- 315 // Encoder thread --------------------------------------------------------------
285 316
286 void ScreenRecorder::DoEncode( 317 void ScreenRecorder::DoEncode(
287 scoped_refptr<CaptureData> capture_data) { 318 scoped_refptr<CaptureData> capture_data) {
288 DCHECK_EQ(encode_loop_, MessageLoop::current()); 319 DCHECK_EQ(encode_loop_, MessageLoop::current());
289 320
290 if (encoder_stopped_) 321 if (encoder_stopped_)
291 return; 322 return;
292 323
293 // Early out if there's nothing to encode. 324 // Early out if there's nothing to encode.
294 if (!capture_data || capture_data->dirty_region().isEmpty()) { 325 if (!capture_data || capture_data->dirty_region().isEmpty()) {
295 // Send an empty video packet to keep network active. 326 // Send an empty video packet to keep network active.
296 scoped_ptr<VideoPacket> packet(new VideoPacket()); 327 scoped_ptr<VideoPacket> packet(new VideoPacket());
297 packet->set_flags(VideoPacket::LAST_PARTITION); 328 packet->set_flags(VideoPacket::LAST_PARTITION);
298 network_loop_->PostTask( 329 network_loop_->PostTask(
299 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, 330 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket,
300 this, base::Passed(packet.Pass()))); 331 this, base::Passed(packet.Pass())));
301 return; 332 return;
302 } 333 }
303 334
304 encode_start_time_ = base::Time::Now(); 335 encode_start_time_ = base::Time::Now();
305 encoder()->Encode( 336 encoder()->Encode(
306 capture_data, false, 337 capture_data, false,
307 base::Bind(&ScreenRecorder::EncodedDataAvailableCallback, this)); 338 base::Bind(&ScreenRecorder::EncodedDataAvailableCallback, this));
308 } 339 }
309 340
341 void ScreenRecorder::DoEncodeCursorShape(
342 scoped_refptr<CursorShapeData> cursor) {
343 DCHECK_EQ(encode_loop_, MessageLoop::current());
344
345 SkISize size = cursor->size();
346 SkISize hotspot = cursor->hotspot();
347 int bpp = cursor->bytes_per_pixel();
348 uint8* data = cursor->data();
349
350 int width = size.width();
351 int height = size.height();
352
353 scoped_ptr<protocol::CursorShapeInfo> cursor_proto(
354 new protocol::CursorShapeInfo());
355 cursor_proto->set_width(width);
356 cursor_proto->set_height(height);
357 cursor_proto->set_hotspot_x(hotspot.width());
358 cursor_proto->set_hotspot_y(hotspot.height());
359
360 cursor_proto->mutable_data()->resize(width * height * bpp);
361 uint8* proto_data = const_cast<uint8*>(reinterpret_cast<const uint8*>(
362 cursor_proto->mutable_data()->data()));
363 for (int y = 0; y < height; y++) {
364 for (int x = 0; x < width; x++) {
365 for (int b = 0; b < bpp; b++) {
366 *proto_data++ = *data++;
Wez 2012/05/23 00:01:57 This block is a memcpy(), surely?
garykac 2012/05/26 01:58:01 Done.
367 }
368 }
369 }
370
371 network_loop_->PostTask(
372 FROM_HERE, base::Bind(&ScreenRecorder::DoSendCursorShape, this,
373 base::Passed(cursor_proto.Pass())));
374 }
375
310 void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) { 376 void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) {
311 DCHECK_EQ(encode_loop_, MessageLoop::current()); 377 DCHECK_EQ(encode_loop_, MessageLoop::current());
312 378
313 encoder_stopped_ = true; 379 encoder_stopped_ = true;
314 380
315 // When this method is being executed there are no more tasks on encode thread 381 // When this method is being executed there are no more tasks on encode thread
316 // for this object. We can then post a task to capture thread to finish the 382 // for this object. We can then post a task to capture thread to finish the
317 // stop sequence. 383 // stop sequence.
318 capture_loop_->PostTask(FROM_HERE, done_task); 384 capture_loop_->PostTask(FROM_HERE, done_task);
319 } 385 }
(...skipping 13 matching lines...) Expand all
333 packet->set_encode_time_ms(encode_time_ms); 399 packet->set_encode_time_ms(encode_time_ms);
334 scheduler_.RecordEncodeTime(encode_time); 400 scheduler_.RecordEncodeTime(encode_time);
335 } 401 }
336 402
337 network_loop_->PostTask( 403 network_loop_->PostTask(
338 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, this, 404 FROM_HERE, base::Bind(&ScreenRecorder::DoSendVideoPacket, this,
339 base::Passed(packet.Pass()))); 405 base::Passed(packet.Pass())));
340 } 406 }
341 407
342 } // namespace remoting 408 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698