diff options
author | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-20 20:32:30 +0000 |
---|---|---|
committer | alexeypa@chromium.org <alexeypa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-20 20:32:30 +0000 |
commit | 8c197e505cd05525768826f46aa1d0e0d6058435 (patch) | |
tree | 07af5cc4921732d8a0e901b3eade6358411e386e /remoting/base | |
parent | 6908083dd88547e95791f39c6b600c225934bda4 (diff) | |
download | chromium_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.h | 26 | ||||
-rw-r--r-- | remoting/base/shared_buffer.cc | 37 | ||||
-rw-r--r-- | remoting/base/shared_buffer.h | 69 | ||||
-rw-r--r-- | remoting/base/shared_buffer_factory.h | 28 | ||||
-rw-r--r-- | remoting/base/shared_buffer_unittest.cc | 50 |
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 |