Index: remoting/host/screen_recorder.cc |
diff --git a/remoting/host/screen_recorder.cc b/remoting/host/screen_recorder.cc |
index ab96a53708cf35a6c6db14f1e7d1fea6ef8635ff..40e42dbb1a7efea6ff947a55c8f8d3ca6846eaf6 100644 |
--- a/remoting/host/screen_recorder.cc |
+++ b/remoting/host/screen_recorder.cc |
@@ -15,9 +15,12 @@ |
#include "base/sys_info.h" |
#include "base/time.h" |
#include "remoting/base/capture_data.h" |
+#include "remoting/base/cursor_shape_data.h" |
#include "remoting/proto/control.pb.h" |
+#include "remoting/proto/internal.pb.h" |
#include "remoting/proto/video.pb.h" |
#include "remoting/protocol/client_stub.h" |
+#include "remoting/protocol/cursor_shape_stub.h" |
#include "remoting/protocol/connection_to_client.h" |
#include "remoting/protocol/message_decoder.h" |
#include "remoting/protocol/util.h" |
@@ -142,6 +145,9 @@ void ScreenRecorder::DoStart() { |
return; |
} |
+ capturer()->SetCursorShapeChangedCallback( |
+ base::Bind(&ScreenRecorder::CursorShapeChangedCallback, this)); |
+ |
capturer()->Start(); |
capture_timer_.reset(new base::OneShotTimer<ScreenRecorder>()); |
@@ -214,6 +220,19 @@ void ScreenRecorder::CaptureDoneCallback( |
FROM_HERE, base::Bind(&ScreenRecorder::DoEncode, this, capture_data)); |
} |
+void ScreenRecorder::CursorShapeChangedCallback( |
+ scoped_refptr<CursorShapeData> cursor_data) { |
+ DCHECK_EQ(capture_loop_, MessageLoop::current()); |
+ |
+ if (!is_recording()) |
+ return; |
+ |
+ LOG(INFO) << "posting encode task"; |
+ encode_loop_->PostTask( |
+ FROM_HERE, base::Bind(&ScreenRecorder::DoEncodeCursorShape, |
+ this, cursor_data)); |
+} |
+ |
void ScreenRecorder::DoFinishOneRecording() { |
DCHECK_EQ(capture_loop_, MessageLoop::current()); |
@@ -281,6 +300,18 @@ void ScreenRecorder::DoStopOnNetworkThread(const base::Closure& done_task) { |
this, done_task)); |
} |
+void ScreenRecorder::DoSendCursorShape( |
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) { |
+ DCHECK(network_loop_->BelongsToCurrentThread()); |
+ |
+ if (network_stopped_ || connections_.empty()) |
+ return; |
+ |
+ // TODO(sergeyu): Currently we send the data only to the first |
+ // connection. Send it to all connections if necessary. |
+ connections_.front()->cursor_shape_stub()->SetCursorShape(*cursor_shape); |
+} |
+ |
// Encoder thread -------------------------------------------------------------- |
void ScreenRecorder::DoEncode( |
@@ -307,6 +338,41 @@ void ScreenRecorder::DoEncode( |
base::Bind(&ScreenRecorder::EncodedDataAvailableCallback, this)); |
} |
+void ScreenRecorder::DoEncodeCursorShape( |
+ scoped_refptr<CursorShapeData> cursor) { |
+ DCHECK_EQ(encode_loop_, MessageLoop::current()); |
+ |
+ SkISize size = cursor->size(); |
+ SkISize hotspot = cursor->hotspot(); |
+ int bpp = cursor->bytes_per_pixel(); |
+ uint8* data = cursor->data(); |
+ |
+ int width = size.width(); |
+ int height = size.height(); |
+ |
+ scoped_ptr<protocol::CursorShapeInfo> cursor_proto( |
+ new protocol::CursorShapeInfo()); |
+ cursor_proto->set_width(width); |
+ cursor_proto->set_height(height); |
+ cursor_proto->set_hotspot_x(hotspot.width()); |
+ cursor_proto->set_hotspot_y(hotspot.height()); |
+ |
+ cursor_proto->mutable_data()->resize(width * height * bpp); |
+ uint8* proto_data = const_cast<uint8*>(reinterpret_cast<const uint8*>( |
+ cursor_proto->mutable_data()->data())); |
+ for (int y = 0; y < height; y++) { |
+ for (int x = 0; x < width; x++) { |
+ for (int b = 0; b < bpp; b++) { |
+ *proto_data++ = *data++; |
Wez
2012/05/23 00:01:57
This block is a memcpy(), surely?
garykac
2012/05/26 01:58:01
Done.
|
+ } |
+ } |
+ } |
+ |
+ network_loop_->PostTask( |
+ FROM_HERE, base::Bind(&ScreenRecorder::DoSendCursorShape, this, |
+ base::Passed(cursor_proto.Pass()))); |
+} |
+ |
void ScreenRecorder::DoStopOnEncodeThread(const base::Closure& done_task) { |
DCHECK_EQ(encode_loop_, MessageLoop::current()); |