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

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

Issue 92473002: Use webrtc::MouseCursorMonitor for cursor shapes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix linux build Created 6 years, 4 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
« no previous file with comments | « remoting/host/video_scheduler.h ('k') | remoting/host/video_scheduler_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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"
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/message_loop_proxy.h" 13 #include "base/message_loop/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/time.h" 16 #include "base/time/time.h"
17 #include "remoting/proto/control.pb.h" 17 #include "remoting/proto/control.pb.h"
18 #include "remoting/proto/internal.pb.h" 18 #include "remoting/proto/internal.pb.h"
19 #include "remoting/proto/video.pb.h" 19 #include "remoting/proto/video.pb.h"
20 #include "remoting/protocol/cursor_shape_stub.h" 20 #include "remoting/protocol/cursor_shape_stub.h"
21 #include "remoting/protocol/message_decoder.h" 21 #include "remoting/protocol/message_decoder.h"
22 #include "remoting/protocol/video_stub.h" 22 #include "remoting/protocol/video_stub.h"
23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 23 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
24 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor.h"
24 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_shape.h" 25 #include "third_party/webrtc/modules/desktop_capture/mouse_cursor_shape.h"
25 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" 26 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
26 27
27 namespace remoting { 28 namespace remoting {
28 29
29 // Maximum number of frames that can be processed simultaneously. 30 // Maximum number of frames that can be processed simultaneously.
30 // TODO(hclam): Move this value to CaptureScheduler. 31 // TODO(hclam): Move this value to CaptureScheduler.
31 static const int kMaxPendingFrames = 2; 32 static const int kMaxPendingFrames = 2;
32 33
33 // Interval between empty keep-alive frames. These frames are sent only 34 // Interval between empty keep-alive frames. These frames are sent only
34 // when there are no real video frames being sent. To prevent PseudoTCP from 35 // when there are no real video frames being sent. To prevent PseudoTCP from
35 // resetting congestion window this value must be smaller than the minimum 36 // resetting congestion window this value must be smaller than the minimum
36 // RTO used in PseudoTCP, which is 250ms. 37 // RTO used in PseudoTCP, which is 250ms.
37 static const int kKeepAlivePacketIntervalMs = 200; 38 static const int kKeepAlivePacketIntervalMs = 200;
38 39
39 static bool g_enable_timestamps = false; 40 static bool g_enable_timestamps = false;
40 41
41 // static 42 // static
42 void VideoScheduler::EnableTimestampsForTests() { 43 void VideoScheduler::EnableTimestampsForTests() {
43 g_enable_timestamps = true; 44 g_enable_timestamps = true;
44 } 45 }
45 46
46 VideoScheduler::VideoScheduler( 47 VideoScheduler::VideoScheduler(
47 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner, 48 scoped_refptr<base::SingleThreadTaskRunner> capture_task_runner,
48 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner, 49 scoped_refptr<base::SingleThreadTaskRunner> encode_task_runner,
49 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner, 50 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner,
50 scoped_ptr<webrtc::ScreenCapturer> capturer, 51 scoped_ptr<webrtc::ScreenCapturer> capturer,
52 scoped_ptr<webrtc::MouseCursorMonitor> mouse_cursor_monitor,
51 scoped_ptr<VideoEncoder> encoder, 53 scoped_ptr<VideoEncoder> encoder,
52 protocol::CursorShapeStub* cursor_stub, 54 protocol::CursorShapeStub* cursor_stub,
53 protocol::VideoStub* video_stub) 55 protocol::VideoStub* video_stub)
54 : capture_task_runner_(capture_task_runner), 56 : capture_task_runner_(capture_task_runner),
55 encode_task_runner_(encode_task_runner), 57 encode_task_runner_(encode_task_runner),
56 network_task_runner_(network_task_runner), 58 network_task_runner_(network_task_runner),
57 capturer_(capturer.Pass()), 59 capturer_(capturer.Pass()),
60 mouse_cursor_monitor_(mouse_cursor_monitor.Pass()),
58 encoder_(encoder.Pass()), 61 encoder_(encoder.Pass()),
59 cursor_stub_(cursor_stub), 62 cursor_stub_(cursor_stub),
60 video_stub_(video_stub), 63 video_stub_(video_stub),
61 pending_frames_(0), 64 pending_frames_(0),
62 capture_pending_(false), 65 capture_pending_(false),
63 did_skip_frame_(false), 66 did_skip_frame_(false),
64 is_paused_(false), 67 is_paused_(false),
65 sequence_number_(0) { 68 sequence_number_(0) {
66 DCHECK(network_task_runner_->BelongsToCurrentThread()); 69 DCHECK(network_task_runner_->BelongsToCurrentThread());
67 DCHECK(capturer_); 70 DCHECK(capturer_);
71 DCHECK(mouse_cursor_monitor_);
68 DCHECK(encoder_); 72 DCHECK(encoder_);
69 DCHECK(cursor_stub_); 73 DCHECK(cursor_stub_);
70 DCHECK(video_stub_); 74 DCHECK(video_stub_);
71 } 75 }
72 76
73 // Public methods -------------------------------------------------------------- 77 // Public methods --------------------------------------------------------------
74 78
75 webrtc::SharedMemory* VideoScheduler::CreateSharedMemory(size_t size) { 79 webrtc::SharedMemory* VideoScheduler::CreateSharedMemory(size_t size) {
76 return NULL; 80 return NULL;
77 } 81 }
(...skipping 18 matching lines...) Expand all
96 base::Passed(&owned_frame), sequence_number_, 100 base::Passed(&owned_frame), sequence_number_,
97 base::TimeTicks::Now())); 101 base::TimeTicks::Now()));
98 102
99 // If a frame was skipped, try to capture it again. 103 // If a frame was skipped, try to capture it again.
100 if (did_skip_frame_) { 104 if (did_skip_frame_) {
101 capture_task_runner_->PostTask( 105 capture_task_runner_->PostTask(
102 FROM_HERE, base::Bind(&VideoScheduler::CaptureNextFrame, this)); 106 FROM_HERE, base::Bind(&VideoScheduler::CaptureNextFrame, this));
103 } 107 }
104 } 108 }
105 109
106 void VideoScheduler::OnCursorShapeChanged( 110 void VideoScheduler::OnMouseCursor(webrtc::MouseCursor* cursor) {
107 webrtc::MouseCursorShape* cursor_shape) {
108 DCHECK(capture_task_runner_->BelongsToCurrentThread()); 111 DCHECK(capture_task_runner_->BelongsToCurrentThread());
109 112
110 scoped_ptr<webrtc::MouseCursorShape> owned_cursor(cursor_shape); 113 scoped_ptr<webrtc::MouseCursor> owned_cursor(cursor);
111 114
112 // Do nothing if the scheduler is being stopped. 115 // Do nothing if the scheduler is being stopped.
113 if (!capturer_) 116 if (!capturer_)
114 return; 117 return;
115 118
116 scoped_ptr<protocol::CursorShapeInfo> cursor_proto( 119 scoped_ptr<protocol::CursorShapeInfo> cursor_proto(
117 new protocol::CursorShapeInfo()); 120 new protocol::CursorShapeInfo());
118 cursor_proto->set_width(cursor_shape->size.width()); 121 cursor_proto->set_width(cursor->image()->size().width());
119 cursor_proto->set_height(cursor_shape->size.height()); 122 cursor_proto->set_height(cursor->image()->size().height());
120 cursor_proto->set_hotspot_x(cursor_shape->hotspot.x()); 123 cursor_proto->set_hotspot_x(cursor->hotspot().x());
121 cursor_proto->set_hotspot_y(cursor_shape->hotspot.y()); 124 cursor_proto->set_hotspot_y(cursor->hotspot().y());
122 cursor_proto->set_data(cursor_shape->data); 125
126 std::string data;
127 uint8_t* current_row = cursor->image()->data();
128 for (int y = 0; y < cursor->image()->size().height(); ++y) {
129 cursor_proto->mutable_data()->append(
130 current_row,
131 current_row + cursor->image()->size().width() *
132 webrtc::DesktopFrame::kBytesPerPixel);
133 current_row += cursor->image()->stride();
134 }
123 135
124 network_task_runner_->PostTask( 136 network_task_runner_->PostTask(
125 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this, 137 FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this,
126 base::Passed(&cursor_proto))); 138 base::Passed(&cursor_proto)));
127 } 139 }
128 140
141 void VideoScheduler::OnMouseCursorPosition(
142 webrtc::MouseCursorMonitor::CursorState state,
143 const webrtc::DesktopVector& position) {
144 // We're not subscribing to mouse position changes.
145 NOTREACHED();
146 }
147
129 void VideoScheduler::Start() { 148 void VideoScheduler::Start() {
130 DCHECK(network_task_runner_->BelongsToCurrentThread()); 149 DCHECK(network_task_runner_->BelongsToCurrentThread());
131 150
132 capture_task_runner_->PostTask( 151 capture_task_runner_->PostTask(
133 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this)); 152 FROM_HERE, base::Bind(&VideoScheduler::StartOnCaptureThread, this));
134 } 153 }
135 154
136 void VideoScheduler::Stop() { 155 void VideoScheduler::Stop() {
137 DCHECK(network_task_runner_->BelongsToCurrentThread()); 156 DCHECK(network_task_runner_->BelongsToCurrentThread());
138 157
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 } 216 }
198 217
199 encoder_->SetLosslessColor(want_lossless); 218 encoder_->SetLosslessColor(want_lossless);
200 } 219 }
201 220
202 // Private methods ----------------------------------------------------------- 221 // Private methods -----------------------------------------------------------
203 222
204 VideoScheduler::~VideoScheduler() { 223 VideoScheduler::~VideoScheduler() {
205 // Destroy the capturer and encoder on their respective threads. 224 // Destroy the capturer and encoder on their respective threads.
206 capture_task_runner_->DeleteSoon(FROM_HERE, capturer_.release()); 225 capture_task_runner_->DeleteSoon(FROM_HERE, capturer_.release());
226 capture_task_runner_->DeleteSoon(FROM_HERE, mouse_cursor_monitor_.release());
207 encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release()); 227 encode_task_runner_->DeleteSoon(FROM_HERE, encoder_.release());
208 } 228 }
209 229
210 // Capturer thread ------------------------------------------------------------- 230 // Capturer thread -------------------------------------------------------------
211 231
212 void VideoScheduler::StartOnCaptureThread() { 232 void VideoScheduler::StartOnCaptureThread() {
213 DCHECK(capture_task_runner_->BelongsToCurrentThread()); 233 DCHECK(capture_task_runner_->BelongsToCurrentThread());
214 DCHECK(!capture_timer_); 234 DCHECK(!capture_timer_);
215 235
216 // Start the capturer and let it notify us if cursor shape changes. 236 // Start mouse cursor monitor.
217 capturer_->SetMouseShapeObserver(this); 237 mouse_cursor_monitor_->Init(this, webrtc::MouseCursorMonitor::SHAPE_ONLY);
238
239 // Start the capturer.
218 capturer_->Start(this); 240 capturer_->Start(this);
219 241
220 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>()); 242 capture_timer_.reset(new base::OneShotTimer<VideoScheduler>());
221 keep_alive_timer_.reset(new base::DelayTimer<VideoScheduler>( 243 keep_alive_timer_.reset(new base::DelayTimer<VideoScheduler>(
222 FROM_HERE, base::TimeDelta::FromMilliseconds(kKeepAlivePacketIntervalMs), 244 FROM_HERE, base::TimeDelta::FromMilliseconds(kKeepAlivePacketIntervalMs),
223 this, &VideoScheduler::SendKeepAlivePacket)); 245 this, &VideoScheduler::SendKeepAlivePacket));
224 246
225 // Capture first frame immedately. 247 // Capture first frame immediately.
226 CaptureNextFrame(); 248 CaptureNextFrame();
227 } 249 }
228 250
229 void VideoScheduler::StopOnCaptureThread() { 251 void VideoScheduler::StopOnCaptureThread() {
230 DCHECK(capture_task_runner_->BelongsToCurrentThread()); 252 DCHECK(capture_task_runner_->BelongsToCurrentThread());
231 253
232 // This doesn't deleted already captured frames, so encoder can keep using the 254 // This doesn't deleted already captured frames, so encoder can keep using the
233 // frames that were captured previously. 255 // frames that were captured previously.
234 capturer_.reset(); 256 capturer_.reset();
235 257
(...skipping 29 matching lines...) Expand all
265 287
266 // At this point we are going to perform one capture so save the current time. 288 // At this point we are going to perform one capture so save the current time.
267 pending_frames_++; 289 pending_frames_++;
268 DCHECK_LE(pending_frames_, kMaxPendingFrames); 290 DCHECK_LE(pending_frames_, kMaxPendingFrames);
269 291
270 // Before doing a capture schedule for the next one. 292 // Before doing a capture schedule for the next one.
271 ScheduleNextCapture(); 293 ScheduleNextCapture();
272 294
273 capture_pending_ = true; 295 capture_pending_ = true;
274 296
297 // Capture the mouse shape.
298 mouse_cursor_monitor_->Capture();
299
275 // And finally perform one capture. 300 // And finally perform one capture.
276 capturer_->Capture(webrtc::DesktopRegion()); 301 capturer_->Capture(webrtc::DesktopRegion());
277 } 302 }
278 303
279 void VideoScheduler::FrameCaptureCompleted() { 304 void VideoScheduler::FrameCaptureCompleted() {
280 DCHECK(capture_task_runner_->BelongsToCurrentThread()); 305 DCHECK(capture_task_runner_->BelongsToCurrentThread());
281 306
282 // Decrement the pending capture count. 307 // Decrement the pending capture count.
283 pending_frames_--; 308 pending_frames_--;
284 DCHECK_GE(pending_frames_, 0); 309 DCHECK_GE(pending_frames_, 0);
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 frame.reset(); 395 frame.reset();
371 396
372 scheduler_.RecordEncodeTime( 397 scheduler_.RecordEncodeTime(
373 base::TimeDelta::FromMilliseconds(packet->encode_time_ms())); 398 base::TimeDelta::FromMilliseconds(packet->encode_time_ms()));
374 network_task_runner_->PostTask( 399 network_task_runner_->PostTask(
375 FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this, 400 FROM_HERE, base::Bind(&VideoScheduler::SendVideoPacket, this,
376 base::Passed(&packet))); 401 base::Passed(&packet)));
377 } 402 }
378 403
379 } // namespace remoting 404 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/video_scheduler.h ('k') | remoting/host/video_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698