Chromium Code Reviews| 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/desktop_session_agent.h" | 5 #include "remoting/host/desktop_session_agent.h" |
| 6 | 6 |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/shared_memory.h" | |
| 9 #include "ipc/ipc_channel_proxy.h" | 10 #include "ipc/ipc_channel_proxy.h" |
| 10 #include "ipc/ipc_message.h" | 11 #include "ipc/ipc_message.h" |
| 11 #include "ipc/ipc_message_macros.h" | 12 #include "ipc/ipc_message_macros.h" |
| 12 #include "media/video/capture/screen/screen_capture_data.h" | |
| 13 #include "remoting/base/auto_thread_task_runner.h" | 13 #include "remoting/base/auto_thread_task_runner.h" |
| 14 #include "remoting/base/constants.h" | 14 #include "remoting/base/constants.h" |
| 15 #include "remoting/host/audio_capturer.h" | 15 #include "remoting/host/audio_capturer.h" |
| 16 #include "remoting/host/chromoting_messages.h" | 16 #include "remoting/host/chromoting_messages.h" |
| 17 #include "remoting/host/desktop_environment.h" | 17 #include "remoting/host/desktop_environment.h" |
| 18 #include "remoting/host/input_injector.h" | 18 #include "remoting/host/input_injector.h" |
| 19 #include "remoting/host/remote_input_filter.h" | 19 #include "remoting/host/remote_input_filter.h" |
| 20 #include "remoting/host/screen_controls.h" | 20 #include "remoting/host/screen_controls.h" |
| 21 #include "remoting/host/screen_resolution.h" | 21 #include "remoting/host/screen_resolution.h" |
| 22 #include "remoting/proto/audio.pb.h" | 22 #include "remoting/proto/audio.pb.h" |
| 23 #include "remoting/proto/control.pb.h" | 23 #include "remoting/proto/control.pb.h" |
| 24 #include "remoting/proto/event.pb.h" | 24 #include "remoting/proto/event.pb.h" |
| 25 #include "remoting/protocol/clipboard_stub.h" | 25 #include "remoting/protocol/clipboard_stub.h" |
| 26 #include "remoting/protocol/input_event_tracker.h" | 26 #include "remoting/protocol/input_event_tracker.h" |
| 27 #include "third_party/skia/include/core/SkRegion.h" | 27 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 28 #include "third_party/webrtc/modules/desktop_capture/shared_memory.h" | |
| 28 | 29 |
| 29 namespace remoting { | 30 namespace remoting { |
| 30 | 31 |
| 31 namespace { | 32 namespace { |
| 32 | 33 |
| 33 // Routes local clipboard events though the IPC channel to the network process. | 34 // Routes local clipboard events though the IPC channel to the network process. |
| 34 class DesktopSesssionClipboardStub : public protocol::ClipboardStub { | 35 class DesktopSesssionClipboardStub : public protocol::ClipboardStub { |
| 35 public: | 36 public: |
| 36 explicit DesktopSesssionClipboardStub( | 37 explicit DesktopSesssionClipboardStub( |
| 37 scoped_refptr<DesktopSessionAgent> desktop_session_agent); | 38 scoped_refptr<DesktopSessionAgent> desktop_session_agent); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 55 DesktopSesssionClipboardStub::~DesktopSesssionClipboardStub() { | 56 DesktopSesssionClipboardStub::~DesktopSesssionClipboardStub() { |
| 56 } | 57 } |
| 57 | 58 |
| 58 void DesktopSesssionClipboardStub::InjectClipboardEvent( | 59 void DesktopSesssionClipboardStub::InjectClipboardEvent( |
| 59 const protocol::ClipboardEvent& event) { | 60 const protocol::ClipboardEvent& event) { |
| 60 desktop_session_agent_->InjectClipboardEvent(event); | 61 desktop_session_agent_->InjectClipboardEvent(event); |
| 61 } | 62 } |
| 62 | 63 |
| 63 } // namespace | 64 } // namespace |
| 64 | 65 |
| 66 class DesktopSessionAgent::SharedBuffer : public webrtc::SharedMemory { | |
| 67 public: | |
| 68 static scoped_ptr<SharedBuffer> Create(DesktopSessionAgent* agent, | |
| 69 size_t size, | |
| 70 int id) { | |
| 71 scoped_ptr<base::SharedMemory> memory(new base::SharedMemory()); | |
| 72 if (!memory->CreateAndMapAnonymous(size)) | |
| 73 return scoped_ptr<SharedBuffer>(); | |
| 74 return scoped_ptr<SharedBuffer>( | |
| 75 new SharedBuffer(agent, memory.Pass(), size, id)); | |
| 76 } | |
| 77 | |
| 78 virtual ~SharedBuffer() { | |
| 79 if (agent_) | |
| 80 agent_->OnSharedBufferDeleted(id()); | |
|
alexeypa (please no reviews)
2013/04/26 21:33:58
This class has the same confusing relationships wi
Sergey Ulanov
2013/05/07 22:25:50
Actually it's much simpler here - we just need Sha
alexeypa (please no reviews)
2013/05/08 22:24:59
Sounds good.
| |
| 81 } | |
| 82 | |
| 83 void DetachFromAgent() { agent_ = NULL; } | |
| 84 | |
| 85 private: | |
| 86 SharedBuffer(DesktopSessionAgent* agent, | |
| 87 scoped_ptr<base::SharedMemory> memory, | |
| 88 size_t size, | |
| 89 int id) | |
| 90 : SharedMemory(memory->memory(), size, | |
| 91 #if defined(OS_WIN) | |
| 92 memory->handle(), | |
| 93 #else | |
| 94 memory->handle().fd, | |
| 95 #endif | |
| 96 id), | |
| 97 agent_(agent), | |
| 98 shared_memory_(memory.Pass()) { | |
| 99 } | |
| 100 | |
| 101 DesktopSessionAgent* agent_; | |
| 102 scoped_ptr<base::SharedMemory> shared_memory_; | |
| 103 | |
| 104 DISALLOW_COPY_AND_ASSIGN(SharedBuffer); | |
| 105 }; | |
| 106 | |
| 65 DesktopSessionAgent::Delegate::~Delegate() { | 107 DesktopSessionAgent::Delegate::~Delegate() { |
| 66 } | 108 } |
| 67 | 109 |
| 68 DesktopSessionAgent::~DesktopSessionAgent() { | 110 DesktopSessionAgent::~DesktopSessionAgent() { |
| 69 DCHECK(!audio_capturer_); | 111 DCHECK(!audio_capturer_); |
| 70 DCHECK(!desktop_environment_); | 112 DCHECK(!desktop_environment_); |
| 71 DCHECK(!network_channel_); | 113 DCHECK(!network_channel_); |
| 72 DCHECK(!screen_controls_); | 114 DCHECK(!screen_controls_); |
| 73 DCHECK(!video_capturer_); | 115 DCHECK(!video_capturer_); |
| 74 | 116 |
| 117 for (SharedBuffers::iterator i = shared_buffers_.begin(); | |
| 118 i != shared_buffers_.end(); ++i) { | |
| 119 i->second->DetachFromAgent(); | |
| 120 } | |
| 121 shared_buffers_.clear(); | |
| 122 | |
| 75 CloseDesktopPipeHandle(); | 123 CloseDesktopPipeHandle(); |
| 76 } | 124 } |
| 77 | 125 |
| 78 bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { | 126 bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { |
| 79 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 127 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 80 | 128 |
| 81 bool handled = true; | 129 bool handled = true; |
| 82 if (started_) { | 130 if (started_) { |
| 83 IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) | 131 IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) |
| 84 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, | 132 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, |
| 85 OnCaptureFrame) | 133 OnCaptureFrame) |
| 86 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SharedBufferCreated, | |
| 87 OnSharedBufferCreated) | |
|
alexeypa (please no reviews)
2013/04/26 21:33:58
Removing this message will introduce a race betwee
Sergey Ulanov
2013/05/07 22:25:50
I added |last_frame_| to make sure we hold the sha
alexeypa (please no reviews)
2013/05/08 22:24:59
|last_frame_| will nit work either. First there ma
Sergey Ulanov
2013/05/09 18:49:02
There assumption here is that DesktopCapturer::Cap
| |
| 88 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, | 134 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, |
| 89 OnInjectClipboardEvent) | 135 OnInjectClipboardEvent) |
| 90 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, | 136 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, |
| 91 OnInjectKeyEvent) | 137 OnInjectKeyEvent) |
| 92 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, | 138 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectMouseEvent, |
| 93 OnInjectMouseEvent) | 139 OnInjectMouseEvent) |
| 94 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution, | 140 IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SetScreenResolution, |
| 95 SetScreenResolution) | 141 SetScreenResolution) |
| 96 IPC_MESSAGE_UNHANDLED(handled = false) | 142 IPC_MESSAGE_UNHANDLED(handled = false) |
| 97 IPC_END_MESSAGE_MAP() | 143 IPC_END_MESSAGE_MAP() |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 120 | 166 |
| 121 // Make sure the channel is closed. | 167 // Make sure the channel is closed. |
| 122 network_channel_.reset(); | 168 network_channel_.reset(); |
| 123 CloseDesktopPipeHandle(); | 169 CloseDesktopPipeHandle(); |
| 124 | 170 |
| 125 // Notify the caller that the channel has been disconnected. | 171 // Notify the caller that the channel has been disconnected. |
| 126 if (delegate_.get()) | 172 if (delegate_.get()) |
| 127 delegate_->OnNetworkProcessDisconnected(); | 173 delegate_->OnNetworkProcessDisconnected(); |
| 128 } | 174 } |
| 129 | 175 |
| 130 scoped_refptr<media::SharedBuffer> DesktopSessionAgent::CreateSharedBuffer( | 176 webrtc::SharedMemory* DesktopSessionAgent::CreateSharedMemory(size_t size) { |
| 131 uint32 size) { | |
| 132 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 177 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 133 | 178 |
| 134 scoped_refptr<media::SharedBuffer> buffer = new media::SharedBuffer(size); | 179 scoped_ptr<SharedBuffer> buffer = |
| 135 if (buffer->ptr() != NULL) { | 180 SharedBuffer::Create(this, size, next_shared_buffer_id_); |
| 136 buffer->set_id(next_shared_buffer_id_); | 181 if (buffer) { |
| 137 shared_buffers_.push_back(buffer); | 182 shared_buffers_[buffer->id()] = buffer.get(); |
| 138 | 183 |
| 139 // |next_shared_buffer_id_| starts from 1 and incrementing it by 2 makes | 184 // |next_shared_buffer_id_| starts from 1 and incrementing it by 2 makes |
| 140 // sure it is always odd and therefore zero is never used as a valid buffer | 185 // sure it is always odd and therefore zero is never used as a valid buffer |
| 141 // ID. | 186 // ID. |
| 142 // | 187 // |
| 143 // It is very unlikely (though theoretically possible) to allocate the same | 188 // It is very unlikely (though theoretically possible) to allocate the same |
| 144 // ID for two different buffers due to integer overflow. It should take | 189 // ID for two different buffers due to integer overflow. It should take |
| 145 // about a year of allocating 100 new buffers every second. Practically | 190 // about a year of allocating 100 new buffers every second. Practically |
| 146 // speaking it never happens. | 191 // speaking it never happens. |
| 147 next_shared_buffer_id_ += 2; | 192 next_shared_buffer_id_ += 2; |
| 148 | 193 |
| 194 IPC::PlatformFileForTransit handle; | |
| 195 #if defined(OS_WIN) | |
| 196 handle = buffer->handle(); | |
| 197 #else | |
| 198 handle = base::FileDescriptor(buffer->handle(), false); | |
| 199 #endif | |
| 149 SendToNetwork(new ChromotingDesktopNetworkMsg_CreateSharedBuffer( | 200 SendToNetwork(new ChromotingDesktopNetworkMsg_CreateSharedBuffer( |
| 150 buffer->id(), buffer->handle(), buffer->size())); | 201 buffer->id(), handle, buffer->size())); |
| 151 } | 202 } |
| 152 | 203 |
| 153 return buffer; | 204 return buffer.release(); |
| 154 } | |
| 155 | |
| 156 void DesktopSessionAgent::ReleaseSharedBuffer( | |
| 157 scoped_refptr<media::SharedBuffer> buffer) { | |
| 158 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | |
| 159 DCHECK(buffer->id() != 0); | |
| 160 | |
| 161 SendToNetwork( | |
| 162 new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(buffer->id())); | |
| 163 } | 205 } |
| 164 | 206 |
| 165 const std::string& DesktopSessionAgent::client_jid() const { | 207 const std::string& DesktopSessionAgent::client_jid() const { |
| 166 return client_jid_; | 208 return client_jid_; |
| 167 } | 209 } |
| 168 | 210 |
| 169 void DesktopSessionAgent::DisconnectSession() { | 211 void DesktopSessionAgent::DisconnectSession() { |
| 170 SendToNetwork(new ChromotingDesktopNetworkMsg_DisconnectSession()); | 212 SendToNetwork(new ChromotingDesktopNetworkMsg_DisconnectSession()); |
| 171 } | 213 } |
| 172 | 214 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 audio_capture_task_runner()->PostTask( | 271 audio_capture_task_runner()->PostTask( |
| 230 FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this)); | 272 FROM_HERE, base::Bind(&DesktopSessionAgent::StartAudioCapturer, this)); |
| 231 } | 273 } |
| 232 | 274 |
| 233 // Start the video capturer. | 275 // Start the video capturer. |
| 234 video_capturer_ = desktop_environment_->CreateVideoCapturer(); | 276 video_capturer_ = desktop_environment_->CreateVideoCapturer(); |
| 235 video_capture_task_runner()->PostTask( | 277 video_capture_task_runner()->PostTask( |
| 236 FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); | 278 FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); |
| 237 } | 279 } |
| 238 | 280 |
| 239 void DesktopSessionAgent::OnCaptureCompleted( | 281 void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { |
| 240 scoped_refptr<media::ScreenCaptureData> capture_data) { | |
| 241 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 282 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 242 | 283 |
| 243 current_size_ = capture_data->size(); | 284 last_frame_.reset(frame); |
| 244 | 285 |
| 245 // Serialize media::ScreenCaptureData | 286 current_size_ = frame->size(); |
| 246 SerializedCapturedData serialized_data; | 287 |
| 247 serialized_data.shared_buffer_id = capture_data->shared_buffer()->id(); | 288 // Serialize webrtc::DesktopFrame. |
| 248 serialized_data.bytes_per_row = capture_data->stride(); | 289 SerializedDesktopFrame serialized_frame; |
| 249 serialized_data.dimensions = capture_data->size(); | 290 serialized_frame.shared_buffer_id = frame->shared_memory()->id(); |
| 250 serialized_data.capture_time_ms = capture_data->capture_time_ms(); | 291 serialized_frame.bytes_per_row = frame->stride(); |
| 251 serialized_data.client_sequence_number = | 292 serialized_frame.dimensions = frame->size(); |
| 252 capture_data->client_sequence_number(); | 293 serialized_frame.capture_time_ms = frame->capture_time_ms(); |
| 253 serialized_data.dpi = capture_data->dpi(); | 294 serialized_frame.dpi = frame->dpi(); |
| 254 for (SkRegion::Iterator i(capture_data->dirty_region()); !i.done(); i.next()) | 295 for (webrtc::DesktopRegion::Iterator i(frame->updated_region()); |
| 255 serialized_data.dirty_region.push_back(i.rect()); | 296 !i.IsAtEnd(); i.Advance()) { |
| 297 serialized_frame.dirty_region.push_back(i.rect()); | |
| 298 } | |
| 256 | 299 |
| 257 SendToNetwork( | 300 SendToNetwork( |
| 258 new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_data)); | 301 new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_frame)); |
| 259 } | 302 } |
| 260 | 303 |
| 261 void DesktopSessionAgent::OnCursorShapeChanged( | 304 void DesktopSessionAgent::OnCursorShapeChanged( |
| 262 scoped_ptr<media::MouseCursorShape> cursor_shape) { | 305 scoped_ptr<media::MouseCursorShape> cursor_shape) { |
| 263 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 306 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 264 | 307 |
| 265 SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( | 308 SendToNetwork(new ChromotingDesktopNetworkMsg_CursorShapeChanged( |
| 266 *cursor_shape)); | 309 *cursor_shape)); |
| 267 } | 310 } |
| 268 | 311 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 347 FROM_HERE, | 390 FROM_HERE, |
| 348 base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); | 391 base::Bind(&DesktopSessionAgent::OnCaptureFrame, this)); |
| 349 return; | 392 return; |
| 350 } | 393 } |
| 351 | 394 |
| 352 // media::ScreenCapturer supports a very few (currently 2) outstanding capture | 395 // media::ScreenCapturer supports a very few (currently 2) outstanding capture |
| 353 // requests. The requests are serialized on |video_capture_task_runner()| task | 396 // requests. The requests are serialized on |video_capture_task_runner()| task |
| 354 // runner. If the client issues more requests, pixel data in captured frames | 397 // runner. If the client issues more requests, pixel data in captured frames |
| 355 // will likely be corrupted but stability of media::ScreenCapturer will not be | 398 // will likely be corrupted but stability of media::ScreenCapturer will not be |
| 356 // affected. | 399 // affected. |
| 357 video_capturer_->CaptureFrame(); | 400 video_capturer_->Capture(webrtc::DesktopRegion()); |
| 358 } | |
| 359 | |
| 360 void DesktopSessionAgent::OnSharedBufferCreated(int id) { | |
| 361 if (!video_capture_task_runner()->BelongsToCurrentThread()) { | |
| 362 video_capture_task_runner()->PostTask( | |
| 363 FROM_HERE, | |
| 364 base::Bind(&DesktopSessionAgent::OnSharedBufferCreated, this, id)); | |
| 365 return; | |
| 366 } | |
| 367 | |
| 368 // Drop the cached reference to the buffer. | |
| 369 SharedBuffers::iterator i = shared_buffers_.begin(); | |
| 370 for (; i != shared_buffers_.end(); ++i) { | |
| 371 if ((*i)->id() == id) { | |
| 372 shared_buffers_.erase(i); | |
| 373 break; | |
| 374 } | |
| 375 } | |
| 376 } | 401 } |
| 377 | 402 |
| 378 void DesktopSessionAgent::OnInjectClipboardEvent( | 403 void DesktopSessionAgent::OnInjectClipboardEvent( |
| 379 const std::string& serialized_event) { | 404 const std::string& serialized_event) { |
| 380 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 405 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 381 | 406 |
| 382 protocol::ClipboardEvent event; | 407 protocol::ClipboardEvent event; |
| 383 if (!event.ParseFromString(serialized_event)) { | 408 if (!event.ParseFromString(serialized_event)) { |
| 384 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; | 409 LOG(ERROR) << "Failed to parse protocol::ClipboardEvent."; |
| 385 return; | 410 return; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 422 | 447 |
| 423 // InputStub implementations must verify events themselves, so we don't need | 448 // InputStub implementations must verify events themselves, so we don't need |
| 424 // verification here. This matches HostEventDispatcher. | 449 // verification here. This matches HostEventDispatcher. |
| 425 remote_input_filter_->InjectMouseEvent(event); | 450 remote_input_filter_->InjectMouseEvent(event); |
| 426 } | 451 } |
| 427 | 452 |
| 428 void DesktopSessionAgent::SetScreenResolution( | 453 void DesktopSessionAgent::SetScreenResolution( |
| 429 const ScreenResolution& resolution) { | 454 const ScreenResolution& resolution) { |
| 430 DCHECK(caller_task_runner()->BelongsToCurrentThread()); | 455 DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
| 431 | 456 |
| 432 if (screen_controls_ && resolution.IsValid()) | 457 if (screen_controls_ && resolution.IsEmpty()) |
| 433 screen_controls_->SetScreenResolution(resolution); | 458 screen_controls_->SetScreenResolution(resolution); |
| 434 } | 459 } |
| 435 | 460 |
| 436 void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { | 461 void DesktopSessionAgent::SendToNetwork(IPC::Message* message) { |
| 437 if (!caller_task_runner()->BelongsToCurrentThread()) { | 462 if (!caller_task_runner()->BelongsToCurrentThread()) { |
| 438 caller_task_runner()->PostTask( | 463 caller_task_runner()->PostTask( |
| 439 FROM_HERE, | 464 FROM_HERE, |
| 440 base::Bind(&DesktopSessionAgent::SendToNetwork, this, message)); | 465 base::Bind(&DesktopSessionAgent::SendToNetwork, this, message)); |
| 441 return; | 466 return; |
| 442 } | 467 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 459 | 484 |
| 460 void DesktopSessionAgent::StopAudioCapturer() { | 485 void DesktopSessionAgent::StopAudioCapturer() { |
| 461 DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); | 486 DCHECK(audio_capture_task_runner()->BelongsToCurrentThread()); |
| 462 | 487 |
| 463 audio_capturer_.reset(); | 488 audio_capturer_.reset(); |
| 464 } | 489 } |
| 465 | 490 |
| 466 void DesktopSessionAgent::StartVideoCapturer() { | 491 void DesktopSessionAgent::StartVideoCapturer() { |
| 467 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 492 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 468 | 493 |
| 469 if (video_capturer_) | 494 if (video_capturer_) { |
| 495 video_capturer_->SetMouseShapeObserver(this); | |
| 470 video_capturer_->Start(this); | 496 video_capturer_->Start(this); |
| 497 } | |
| 471 } | 498 } |
| 472 | 499 |
| 473 void DesktopSessionAgent::StopVideoCapturer() { | 500 void DesktopSessionAgent::StopVideoCapturer() { |
| 474 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | 501 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
| 475 | 502 |
| 476 video_capturer_.reset(); | 503 video_capturer_.reset(); |
| 504 last_frame_.reset(); | |
| 477 | 505 |
| 478 // Free any shared buffers left. | 506 // Video capturer must delete all buffers. |
| 479 shared_buffers_.clear(); | 507 DCHECK(shared_buffers_.empty()); |
| 480 } | 508 } |
| 481 | 509 |
| 482 DesktopSessionAgent::DesktopSessionAgent( | 510 DesktopSessionAgent::DesktopSessionAgent( |
| 483 scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, | 511 scoped_refptr<AutoThreadTaskRunner> audio_capture_task_runner, |
| 484 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, | 512 scoped_refptr<AutoThreadTaskRunner> caller_task_runner, |
| 485 scoped_refptr<AutoThreadTaskRunner> input_task_runner, | 513 scoped_refptr<AutoThreadTaskRunner> input_task_runner, |
| 486 scoped_refptr<AutoThreadTaskRunner> io_task_runner, | 514 scoped_refptr<AutoThreadTaskRunner> io_task_runner, |
| 487 scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner) | 515 scoped_refptr<AutoThreadTaskRunner> video_capture_task_runner) |
| 488 : audio_capture_task_runner_(audio_capture_task_runner), | 516 : audio_capture_task_runner_(audio_capture_task_runner), |
| 489 caller_task_runner_(caller_task_runner), | 517 caller_task_runner_(caller_task_runner), |
| 490 input_task_runner_(input_task_runner), | 518 input_task_runner_(input_task_runner), |
| 491 io_task_runner_(io_task_runner), | 519 io_task_runner_(io_task_runner), |
| 492 video_capture_task_runner_(video_capture_task_runner), | 520 video_capture_task_runner_(video_capture_task_runner), |
| 493 control_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 521 control_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 494 desktop_pipe_(IPC::InvalidPlatformFileForTransit()), | 522 desktop_pipe_(IPC::InvalidPlatformFileForTransit()), |
| 495 current_size_(SkISize::Make(0, 0)), | |
| 496 next_shared_buffer_id_(1), | 523 next_shared_buffer_id_(1), |
| 497 started_(false) { | 524 started_(false) { |
| 498 DCHECK(caller_task_runner_->BelongsToCurrentThread()); | 525 DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
| 499 } | 526 } |
| 500 | 527 |
| 528 void DesktopSessionAgent::OnSharedBufferDeleted(int id) { | |
| 529 DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); | |
| 530 DCHECK(id != 0); | |
| 531 | |
| 532 shared_buffers_.erase(id); | |
| 533 SendToNetwork(new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(id)); | |
| 534 } | |
| 535 | |
| 501 void DesktopSessionAgent::CloseDesktopPipeHandle() { | 536 void DesktopSessionAgent::CloseDesktopPipeHandle() { |
| 502 if (!(desktop_pipe_ == IPC::InvalidPlatformFileForTransit())) { | 537 if (!(desktop_pipe_ == IPC::InvalidPlatformFileForTransit())) { |
| 503 #if defined(OS_WIN) | 538 #if defined(OS_WIN) |
| 504 base::ClosePlatformFile(desktop_pipe_); | 539 base::ClosePlatformFile(desktop_pipe_); |
| 505 #elif defined(OS_POSIX) | 540 #elif defined(OS_POSIX) |
| 506 base::ClosePlatformFile(desktop_pipe_.fd); | 541 base::ClosePlatformFile(desktop_pipe_.fd); |
| 507 #else // !defined(OS_POSIX) | 542 #else // !defined(OS_POSIX) |
| 508 #error Unsupported platform. | 543 #error Unsupported platform. |
| 509 #endif // !defined(OS_POSIX) | 544 #endif // !defined(OS_POSIX) |
| 510 | 545 |
| 511 desktop_pipe_ = IPC::InvalidPlatformFileForTransit(); | 546 desktop_pipe_ = IPC::InvalidPlatformFileForTransit(); |
| 512 } | 547 } |
| 513 } | 548 } |
| 514 | 549 |
| 515 } // namespace remoting | 550 } // namespace remoting |
| OLD | NEW |