summaryrefslogtreecommitdiffstats
path: root/remoting/base
diff options
context:
space:
mode:
authoralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-20 20:32:30 +0000
committeralexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-20 20:32:30 +0000
commit8c197e505cd05525768826f46aa1d0e0d6058435 (patch)
tree07af5cc4921732d8a0e901b3eade6358411e386e /remoting/base
parent6908083dd88547e95791f39c6b600c225934bda4 (diff)
downloadchromium_src-8c197e505cd05525768826f46aa1d0e0d6058435.zip
chromium_src-8c197e505cd05525768826f46aa1d0e0d6058435.tar.gz
chromium_src-8c197e505cd05525768826f46aa1d0e0d6058435.tar.bz2
Adding support of shared memory buffers to the video capturer (Windows only).
Changes in this CL: - The video capturer allocates frame buffers in shared memory and registers them with the provided delegate. The delegate is expected to pass information about the buffers to the process consuming the buffers. - A reference to a shared buffer is passed along with CaptureData. BUG=134694 Review URL: https://chromiumcodereview.appspot.com/11416021 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@168862 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/base')
-rw-r--r--remoting/base/capture_data.h26
-rw-r--r--remoting/base/shared_buffer.cc37
-rw-r--r--remoting/base/shared_buffer.h69
-rw-r--r--remoting/base/shared_buffer_factory.h28
-rw-r--r--remoting/base/shared_buffer_unittest.cc50
5 files changed, 203 insertions, 7 deletions
diff --git a/remoting/base/capture_data.h b/remoting/base/capture_data.h
index 7e65b37..adab19e 100644
--- a/remoting/base/capture_data.h
+++ b/remoting/base/capture_data.h
@@ -10,10 +10,13 @@
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "media/base/video_frame.h"
+#include "remoting/base/shared_buffer.h"
#include "third_party/skia/include/core/SkRegion.h"
namespace remoting {
+class SharedBuffer;
+
struct DataPlanes {
DataPlanes();
@@ -30,25 +33,24 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
const SkISize& size,
media::VideoFrame::Format format);
- // Get the data_planes data of the previous capture.
+ // Gets the data_planes data of the previous capture.
const DataPlanes& data_planes() const { return data_planes_; }
- // Get the dirty region from the previous capture.
+ // Gets the dirty region from the previous capture.
const SkRegion& dirty_region() const { return dirty_region_; }
- // Return the size of the image captured.
+ // Returns the size of the image captured.
SkISize size() const { return size_; }
- // Get the pixel format of the image captured.
+ // Gets the pixel format of the image captured.
media::VideoFrame::Format pixel_format() const { return pixel_format_; }
- // Mutating methods.
SkRegion& mutable_dirty_region() { return dirty_region_; }
- // Return the time spent on capturing.
+ // Returns the time spent on capturing.
int capture_time_ms() const { return capture_time_ms_; }
- // Set the time spent on capturing.
+ // Sets the time spent on capturing.
void set_capture_time_ms(int capture_time_ms) {
capture_time_ms_ = capture_time_ms;
}
@@ -63,6 +65,14 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
void set_dpi(const SkIPoint& dpi) { dpi_ = dpi; }
+ // Returns the shared memory buffer pointed to by |data_planes_.data[0]|.
+ scoped_refptr<SharedBuffer> shared_buffer() const { return shared_buffer_; }
+
+ // Sets the shared memory buffer pointed to by |data_planes_.data[0]|.
+ void set_shared_buffer(scoped_refptr<SharedBuffer> shared_buffer) {
+ shared_buffer_ = shared_buffer;
+ }
+
private:
friend class base::RefCountedThreadSafe<CaptureData>;
virtual ~CaptureData();
@@ -80,6 +90,8 @@ class CaptureData : public base::RefCountedThreadSafe<CaptureData> {
// DPI for this frame.
SkIPoint dpi_;
+
+ scoped_refptr<SharedBuffer> shared_buffer_;
};
} // namespace remoting
diff --git a/remoting/base/shared_buffer.cc b/remoting/base/shared_buffer.cc
new file mode 100644
index 0000000..646f343
--- /dev/null
+++ b/remoting/base/shared_buffer.cc
@@ -0,0 +1,37 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/base/shared_buffer.h"
+
+const bool kReadOnly = true;
+
+namespace remoting {
+
+SharedBuffer::SharedBuffer(uint32 size)
+ : id_(0),
+ size_(size) {
+ shared_memory_.CreateAndMapAnonymous(size);
+}
+
+SharedBuffer::SharedBuffer(
+ intptr_t id, base::SharedMemoryHandle handle, uint32 size)
+ : id_(id),
+ shared_memory_(handle, kReadOnly),
+ size_(size) {
+ shared_memory_.Map(size);
+}
+
+SharedBuffer::SharedBuffer(
+ intptr_t id, base::SharedMemoryHandle handle, base::ProcessHandle process,
+ uint32 size)
+ : id_(id),
+ shared_memory_(handle, kReadOnly, process),
+ size_(size) {
+ shared_memory_.Map(size);
+}
+
+SharedBuffer::~SharedBuffer() {
+}
+
+} // namespace remoting
diff --git a/remoting/base/shared_buffer.h b/remoting/base/shared_buffer.h
new file mode 100644
index 0000000..a25c862
--- /dev/null
+++ b/remoting/base/shared_buffer.h
@@ -0,0 +1,69 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_BASE_SHARED_BUFFER_H_
+#define REMOTING_BASE_SHARED_BUFFER_H_
+
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/process.h"
+#include "base/shared_memory.h"
+
+namespace remoting {
+
+// Represents a memory buffer that can be shared between multiple processes.
+// It is more or less a convenience wrapper around base::SharedMemory providing
+// ref-counted lifetime management and unique buffer identifiers.
+class SharedBuffer
+ : public base::RefCountedThreadSafe<SharedBuffer> {
+ public:
+ // Creates a new shared memory buffer of the given size and maps it to
+ // the memory of the calling process. If the operation fails for any reason,
+ // ptr() method will return NULL. This constructor set the identifier of this
+ // buffer to 0.
+ explicit SharedBuffer(uint32 size);
+
+ // Opens an existing shared memory buffer and maps it to the memory of
+ // the calling process (in read only mode). If the operation fails for any
+ // reason, ptr() method will return NULL.
+ SharedBuffer(intptr_t id, base::SharedMemoryHandle handle, uint32 size);
+
+ // Opens an existing shared memory buffer created by a different process and
+ // maps it to the memory of the calling process (in read only mode). If
+ // the operation fails for any reason, ptr() method will return NULL.
+ SharedBuffer(intptr_t id, base::SharedMemoryHandle handle,
+ base::ProcessHandle process, uint32 size);
+
+ // Returns pointer to the beginning of the allocated data buffer. Returns NULL
+ // if the object initialization failed for any reason.
+ void* ptr() const { return shared_memory_.memory(); }
+
+ // Returns handle of the shared memory section containing the allocated
+ // data buffer.
+ base::SharedMemoryHandle handle() const { return shared_memory_.handle(); }
+
+ intptr_t id() const { return id_; }
+ uint32 size() const { return size_; }
+
+ void set_id(intptr_t id) { id_ = id; }
+
+ private:
+ friend class base::RefCountedThreadSafe<SharedBuffer>;
+ virtual ~SharedBuffer();
+
+ // Unique identifier of the buffer or 0 if ID hasn't been set.
+ intptr_t id_;
+
+ // Shared memory section backing up the buffer.
+ base::SharedMemory shared_memory_;
+
+ // Size of the buffer in bytes.
+ uint32 size_;
+
+ DISALLOW_COPY_AND_ASSIGN(SharedBuffer);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_BASE_SHARED_BUFFER_H_
diff --git a/remoting/base/shared_buffer_factory.h b/remoting/base/shared_buffer_factory.h
new file mode 100644
index 0000000..bd10a4b
--- /dev/null
+++ b/remoting/base/shared_buffer_factory.h
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef REMOTING_BASE_SHARED_BUFFER_FACTORY_H_
+#define REMOTING_BASE_SHARED_BUFFER_FACTORY_H_
+
+namespace remoting {
+
+class SharedBuffer;
+
+// Provides a way to create shared buffers accessible by two or more processes.
+class SharedBufferFactory {
+ public:
+ virtual ~SharedBufferFactory() {}
+
+ // Creates a shared memory buffer of the given size.
+ virtual scoped_refptr<SharedBuffer> CreateSharedBuffer(uint32 size) = 0;
+
+ // Notifies the factory that the buffer is no longer used by the caller and
+ // can be released. The caller still has to drop all references to free
+ // the memory.
+ virtual void ReleaseSharedBuffer(scoped_refptr<SharedBuffer> buffer) = 0;
+};
+
+} // namespace remoting
+
+#endif // REMOTING_BASE_SHARED_BUFFER_FACTORY_H_
diff --git a/remoting/base/shared_buffer_unittest.cc b/remoting/base/shared_buffer_unittest.cc
new file mode 100644
index 0000000..d09de2c
--- /dev/null
+++ b/remoting/base/shared_buffer_unittest.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "remoting/base/shared_buffer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+const uint32 kBufferSize = 4096;
+const int kPattern = 0x12345678;
+
+const intptr_t kIdZero = 0;
+const intptr_t kIdOne = 1;
+
+namespace remoting {
+
+TEST(SharedBufferTest, Basic) {
+ scoped_refptr<SharedBuffer> source(new SharedBuffer(kBufferSize));
+
+ // Make sure that the buffer is allocated, the size is recorded correctly and
+ // its ID is reset.
+ EXPECT_TRUE(source->ptr() != NULL);
+ EXPECT_EQ(source->id(), kIdZero);
+ EXPECT_EQ(source->size(), kBufferSize);
+
+ // See if setting of the ID works.
+ source->set_id(kIdOne);
+ EXPECT_EQ(source->id(), kIdOne);
+
+ scoped_refptr<SharedBuffer> dest(
+ new SharedBuffer(kIdZero, source->handle(), kBufferSize));
+
+ // Make sure that the buffer is allocated, the size is recorded correctly and
+ // its ID is reset.
+ EXPECT_TRUE(dest->ptr() != NULL);
+ EXPECT_EQ(dest->id(), kIdZero);
+ EXPECT_EQ(dest->size(), kBufferSize);
+
+ // Verify that the memory contents are the same for the two buffers.
+ int* source_ptr = reinterpret_cast<int*>(source->ptr());
+ *source_ptr = kPattern;
+ int* dest_ptr = reinterpret_cast<int*>(dest->ptr());
+ EXPECT_EQ(*source_ptr, *dest_ptr);
+
+ // Check that the destination buffer is still mapped even when the source
+ // buffer is destroyed.
+ source = NULL;
+ EXPECT_EQ(0x12345678, *dest_ptr);
+}
+
+} // namespace remoting