Index: remoting/host/desktop_session_agent.cc |
diff --git a/remoting/host/desktop_session_agent.cc b/remoting/host/desktop_session_agent.cc |
index 6dd811c5814f3369784cf23dfade48af0a2f6308..025f6e975593c503d85ee178233ae323b38e2ce7 100644 |
--- a/remoting/host/desktop_session_agent.cc |
+++ b/remoting/host/desktop_session_agent.cc |
@@ -6,10 +6,10 @@ |
#include "base/file_util.h" |
#include "base/logging.h" |
+#include "base/memory/shared_memory.h" |
#include "ipc/ipc_channel_proxy.h" |
#include "ipc/ipc_message.h" |
#include "ipc/ipc_message_macros.h" |
-#include "media/video/capture/screen/screen_capture_data.h" |
#include "remoting/base/auto_thread_task_runner.h" |
#include "remoting/base/constants.h" |
#include "remoting/host/audio_capturer.h" |
@@ -24,7 +24,8 @@ |
#include "remoting/proto/event.pb.h" |
#include "remoting/protocol/clipboard_stub.h" |
#include "remoting/protocol/input_event_tracker.h" |
-#include "third_party/skia/include/core/SkRegion.h" |
+#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
+#include "third_party/webrtc/modules/desktop_capture/shared_memory.h" |
namespace remoting { |
@@ -62,6 +63,46 @@ void DesktopSesssionClipboardStub::InjectClipboardEvent( |
} // namespace |
+// webrtc::SharedMemory implementation that notifies creating |
+// DesktopSessionAgent when it's deleted. |
+class DesktopSessionAgent::SharedBuffer : public webrtc::SharedMemory { |
+ public: |
+ static scoped_ptr<SharedBuffer> Create(DesktopSessionAgent* agent, |
+ size_t size, |
+ int id) { |
+ scoped_ptr<base::SharedMemory> memory(new base::SharedMemory()); |
+ if (!memory->CreateAndMapAnonymous(size)) |
+ return scoped_ptr<SharedBuffer>(); |
+ return scoped_ptr<SharedBuffer>( |
+ new SharedBuffer(agent, memory.Pass(), size, id)); |
+ } |
+ |
+ virtual ~SharedBuffer() { |
+ agent_->OnSharedBufferDeleted(id()); |
+ } |
+ |
+ private: |
+ SharedBuffer(DesktopSessionAgent* agent, |
+ scoped_ptr<base::SharedMemory> memory, |
+ size_t size, |
+ int id) |
+ : SharedMemory(memory->memory(), size, |
+#if defined(OS_WIN) |
+ memory->handle(), |
+#else |
+ memory->handle().fd, |
+#endif |
+ id), |
+ agent_(agent), |
+ shared_memory_(memory.Pass()) { |
+ } |
+ |
+ DesktopSessionAgent* agent_; |
+ scoped_ptr<base::SharedMemory> shared_memory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SharedBuffer); |
+}; |
+ |
DesktopSessionAgent::Delegate::~Delegate() { |
} |
@@ -83,8 +124,6 @@ bool DesktopSessionAgent::OnMessageReceived(const IPC::Message& message) { |
IPC_BEGIN_MESSAGE_MAP(DesktopSessionAgent, message) |
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_CaptureFrame, |
OnCaptureFrame) |
- IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_SharedBufferCreated, |
- OnSharedBufferCreated) |
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectClipboardEvent, |
OnInjectClipboardEvent) |
IPC_MESSAGE_HANDLER(ChromotingNetworkDesktopMsg_InjectKeyEvent, |
@@ -127,14 +166,13 @@ void DesktopSessionAgent::OnChannelError() { |
delegate_->OnNetworkProcessDisconnected(); |
} |
-scoped_refptr<media::SharedBuffer> DesktopSessionAgent::CreateSharedBuffer( |
- uint32 size) { |
+webrtc::SharedMemory* DesktopSessionAgent::CreateSharedMemory(size_t size) { |
DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
- scoped_refptr<media::SharedBuffer> buffer = new media::SharedBuffer(size); |
- if (buffer->ptr() != NULL) { |
- buffer->set_id(next_shared_buffer_id_); |
- shared_buffers_.push_back(buffer); |
+ scoped_ptr<SharedBuffer> buffer = |
+ SharedBuffer::Create(this, size, next_shared_buffer_id_); |
+ if (buffer) { |
+ shared_buffers_++; |
// |next_shared_buffer_id_| starts from 1 and incrementing it by 2 makes |
// sure it is always odd and therefore zero is never used as a valid buffer |
@@ -146,20 +184,17 @@ scoped_refptr<media::SharedBuffer> DesktopSessionAgent::CreateSharedBuffer( |
// speaking it never happens. |
next_shared_buffer_id_ += 2; |
+ IPC::PlatformFileForTransit handle; |
+#if defined(OS_WIN) |
+ handle = buffer->handle(); |
+#else |
+ handle = base::FileDescriptor(buffer->handle(), false); |
+#endif |
SendToNetwork(new ChromotingDesktopNetworkMsg_CreateSharedBuffer( |
- buffer->id(), buffer->handle(), buffer->size())); |
+ buffer->id(), handle, buffer->size())); |
} |
- return buffer; |
-} |
- |
-void DesktopSessionAgent::ReleaseSharedBuffer( |
- scoped_refptr<media::SharedBuffer> buffer) { |
- DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
- DCHECK(buffer->id() != 0); |
- |
- SendToNetwork( |
- new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(buffer->id())); |
+ return buffer.release(); |
} |
const std::string& DesktopSessionAgent::client_jid() const { |
@@ -241,26 +276,27 @@ void DesktopSessionAgent::OnStartSessionAgent( |
FROM_HERE, base::Bind(&DesktopSessionAgent::StartVideoCapturer, this)); |
} |
-void DesktopSessionAgent::OnCaptureCompleted( |
- scoped_refptr<media::ScreenCaptureData> capture_data) { |
+void DesktopSessionAgent::OnCaptureCompleted(webrtc::DesktopFrame* frame) { |
DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
- current_size_ = capture_data->size(); |
+ last_frame_.reset(frame); |
+ |
+ current_size_ = frame->size(); |
- // Serialize media::ScreenCaptureData |
- SerializedCapturedData serialized_data; |
- serialized_data.shared_buffer_id = capture_data->shared_buffer()->id(); |
- serialized_data.bytes_per_row = capture_data->stride(); |
- serialized_data.dimensions = capture_data->size(); |
- serialized_data.capture_time_ms = capture_data->capture_time_ms(); |
- serialized_data.client_sequence_number = |
- capture_data->client_sequence_number(); |
- serialized_data.dpi = capture_data->dpi(); |
- for (SkRegion::Iterator i(capture_data->dirty_region()); !i.done(); i.next()) |
- serialized_data.dirty_region.push_back(i.rect()); |
+ // Serialize webrtc::DesktopFrame. |
+ SerializedDesktopFrame serialized_frame; |
+ serialized_frame.shared_buffer_id = frame->shared_memory()->id(); |
+ serialized_frame.bytes_per_row = frame->stride(); |
+ serialized_frame.dimensions = frame->size(); |
+ serialized_frame.capture_time_ms = frame->capture_time_ms(); |
+ serialized_frame.dpi = frame->dpi(); |
+ for (webrtc::DesktopRegion::Iterator i(frame->updated_region()); |
+ !i.IsAtEnd(); i.Advance()) { |
+ serialized_frame.dirty_region.push_back(i.rect()); |
+ } |
SendToNetwork( |
- new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_data)); |
+ new ChromotingDesktopNetworkMsg_CaptureCompleted(serialized_frame)); |
} |
void DesktopSessionAgent::OnCursorShapeChanged( |
@@ -359,25 +395,7 @@ void DesktopSessionAgent::OnCaptureFrame() { |
// runner. If the client issues more requests, pixel data in captured frames |
// will likely be corrupted but stability of media::ScreenCapturer will not be |
// affected. |
- video_capturer_->CaptureFrame(); |
-} |
- |
-void DesktopSessionAgent::OnSharedBufferCreated(int id) { |
- if (!video_capture_task_runner()->BelongsToCurrentThread()) { |
- video_capture_task_runner()->PostTask( |
- FROM_HERE, |
- base::Bind(&DesktopSessionAgent::OnSharedBufferCreated, this, id)); |
- return; |
- } |
- |
- // Drop the cached reference to the buffer. |
- SharedBuffers::iterator i = shared_buffers_.begin(); |
- for (; i != shared_buffers_.end(); ++i) { |
- if ((*i)->id() == id) { |
- shared_buffers_.erase(i); |
- break; |
- } |
- } |
+ video_capturer_->Capture(webrtc::DesktopRegion()); |
} |
void DesktopSessionAgent::OnInjectClipboardEvent( |
@@ -434,7 +452,7 @@ void DesktopSessionAgent::SetScreenResolution( |
const ScreenResolution& resolution) { |
DCHECK(caller_task_runner()->BelongsToCurrentThread()); |
- if (screen_controls_ && resolution.IsValid()) |
+ if (screen_controls_ && resolution.IsEmpty()) |
screen_controls_->SetScreenResolution(resolution); |
} |
@@ -471,17 +489,20 @@ void DesktopSessionAgent::StopAudioCapturer() { |
void DesktopSessionAgent::StartVideoCapturer() { |
DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
- if (video_capturer_) |
+ if (video_capturer_) { |
+ video_capturer_->SetMouseShapeObserver(this); |
video_capturer_->Start(this); |
+ } |
} |
void DesktopSessionAgent::StopVideoCapturer() { |
DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
video_capturer_.reset(); |
+ last_frame_.reset(); |
- // Free any shared buffers left. |
- shared_buffers_.clear(); |
+ // Video capturer must delete all buffers. |
+ DCHECK_EQ(shared_buffers_, 0); |
} |
DesktopSessionAgent::DesktopSessionAgent( |
@@ -497,12 +518,21 @@ DesktopSessionAgent::DesktopSessionAgent( |
video_capture_task_runner_(video_capture_task_runner), |
control_factory_(this), |
desktop_pipe_(IPC::InvalidPlatformFileForTransit()), |
- current_size_(SkISize::Make(0, 0)), |
next_shared_buffer_id_(1), |
+ shared_buffers_(0), |
started_(false) { |
DCHECK(caller_task_runner_->BelongsToCurrentThread()); |
} |
+void DesktopSessionAgent::OnSharedBufferDeleted(int id) { |
+ DCHECK(video_capture_task_runner()->BelongsToCurrentThread()); |
+ DCHECK(id != 0); |
+ |
+ shared_buffers_--; |
+ DCHECK_GE(shared_buffers_, 0); |
+ SendToNetwork(new ChromotingDesktopNetworkMsg_ReleaseSharedBuffer(id)); |
+} |
+ |
void DesktopSessionAgent::CloseDesktopPipeHandle() { |
if (!(desktop_pipe_ == IPC::InvalidPlatformFileForTransit())) { |
#if defined(OS_WIN) |