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 | |
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
-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 | ||||
-rw-r--r-- | remoting/host/video_frame.h | 11 | ||||
-rw-r--r-- | remoting/host/video_frame_capturer.h | 6 | ||||
-rw-r--r-- | remoting/host/video_frame_capturer_linux.cc | 7 | ||||
-rw-r--r-- | remoting/host/video_frame_capturer_mac.mm | 7 | ||||
-rw-r--r-- | remoting/host/video_frame_capturer_unittest.cc | 51 | ||||
-rw-r--r-- | remoting/host/video_frame_capturer_win.cc | 86 | ||||
-rw-r--r-- | remoting/host/video_scheduler.h | 2 | ||||
-rw-r--r-- | remoting/remoting.gyp | 4 |
13 files changed, 360 insertions, 24 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 diff --git a/remoting/host/video_frame.h b/remoting/host/video_frame.h index cd7c093..86204f9 100644 --- a/remoting/host/video_frame.h +++ b/remoting/host/video_frame.h @@ -7,6 +7,8 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "remoting/base/shared_buffer.h" #include "third_party/skia/include/core/SkTypes.h" #include "third_party/skia/include/core/SkSize.h" @@ -20,6 +22,9 @@ class VideoFrame { int bytes_per_row() const { return bytes_per_row_; } const SkISize& dimensions() const { return dimensions_; } uint8* pixels() const { return pixels_; } + const scoped_refptr<SharedBuffer>& shared_buffer() const { + return shared_buffer_; + } protected: // Initializes an empty video frame. Derived classes are expected to allocate @@ -33,6 +38,9 @@ class VideoFrame { void set_dimensions(const SkISize& dimensions) { dimensions_ = dimensions; } void set_pixels(uint8* ptr) { pixels_ = ptr; } + void set_shared_buffer(scoped_refptr<SharedBuffer> shared_buffer) { + shared_buffer_ = shared_buffer; + } private: // Bytes per row of pixels including necessary padding. @@ -44,6 +52,9 @@ class VideoFrame { // Points to the pixel buffer. uint8* pixels_; + // Points to an optional shared memory buffer that backs up |pixels_| buffer. + scoped_refptr<SharedBuffer> shared_buffer_; + DISALLOW_COPY_AND_ASSIGN(VideoFrame); }; diff --git a/remoting/host/video_frame_capturer.h b/remoting/host/video_frame_capturer.h index 8fdb4ce..acf8152 100644 --- a/remoting/host/video_frame_capturer.h +++ b/remoting/host/video_frame_capturer.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/callback.h" +#include "base/shared_memory.h" #include "media/base/video_frame.h" #include "third_party/skia/include/core/SkRegion.h" @@ -17,6 +18,7 @@ class CursorShapeInfo; } class CaptureData; +class SharedBufferFactory; // Class used to capture video frames asynchronously. // @@ -71,6 +73,10 @@ class VideoFrameCapturer { // Create platform-specific capturer. static scoped_ptr<VideoFrameCapturer> Create(); + // Create platform-specific capturer that uses shared memory buffers. + static scoped_ptr<VideoFrameCapturer> CreateWithFactory( + SharedBufferFactory* shared_buffer_factory); + #if defined(OS_LINUX) // Set whether the VideoFrameCapturer should try to use X DAMAGE support if it // is available. This needs to be called before the VideoFrameCapturer is diff --git a/remoting/host/video_frame_capturer_linux.cc b/remoting/host/video_frame_capturer_linux.cc index 39f5026..2e20365 100644 --- a/remoting/host/video_frame_capturer_linux.cc +++ b/remoting/host/video_frame_capturer_linux.cc @@ -623,6 +623,13 @@ scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::Create() { } // static +scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( + SharedBufferFactory* shared_buffer_factory) { + NOTIMPLEMENTED(); + return scoped_ptr<VideoFrameCapturer>(); +} + +// static void VideoFrameCapturer::EnableXDamage(bool enable) { g_should_use_x_damage = enable; } diff --git a/remoting/host/video_frame_capturer_mac.mm b/remoting/host/video_frame_capturer_mac.mm index 786cd78..b02e8da 100644 --- a/remoting/host/video_frame_capturer_mac.mm +++ b/remoting/host/video_frame_capturer_mac.mm @@ -820,4 +820,11 @@ scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::Create() { return capturer.PassAs<VideoFrameCapturer>(); } +// static +scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( + SharedBufferFactory* shared_buffer_factory) { + NOTIMPLEMENTED(); + return scoped_ptr<VideoFrameCapturer>(); +} + } // namespace remoting diff --git a/remoting/host/video_frame_capturer_unittest.cc b/remoting/host/video_frame_capturer_unittest.cc index ccc4fdd..0749720 100644 --- a/remoting/host/video_frame_capturer_unittest.cc +++ b/remoting/host/video_frame_capturer_unittest.cc @@ -9,6 +9,7 @@ #include "base/mac/mac_util.h" #endif // defined(OS_MACOSX) #include "remoting/base/capture_data.h" +#include "remoting/base/shared_buffer_factory.h" #include "remoting/host/host_mock_objects.h" #include "remoting/protocol/protocol_mock_objects.h" #include "testing/gmock/include/gmock/gmock.h" @@ -19,6 +20,18 @@ using ::testing::AnyNumber; namespace remoting { +class MockSharedBufferFactory : public SharedBufferFactory { + public: + MockSharedBufferFactory() {} + virtual ~MockSharedBufferFactory() {} + + MOCK_METHOD1(CreateSharedBuffer, scoped_refptr<SharedBuffer>(uint32)); + MOCK_METHOD1(ReleaseSharedBuffer, void(scoped_refptr<SharedBuffer>)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockSharedBufferFactory); +}; + MATCHER(DirtyRegionIsNonEmptyRect, "") { const SkRegion& dirty_region = arg->dirty_region(); const SkIRect& dirty_region_bounds = dirty_region.getBounds(); @@ -29,16 +42,22 @@ MATCHER(DirtyRegionIsNonEmptyRect, "") { } class VideoFrameCapturerTest : public testing::Test { - protected: - virtual void SetUp() OVERRIDE { - capturer_ = VideoFrameCapturer::Create(); - } + public: + scoped_refptr<SharedBuffer> CreateSharedBuffer(uint32 size); + protected: scoped_ptr<VideoFrameCapturer> capturer_; + MockSharedBufferFactory shared_buffer_factory_; MockVideoFrameCapturerDelegate delegate_; }; +scoped_refptr<SharedBuffer> VideoFrameCapturerTest::CreateSharedBuffer( + uint32 size) { + return scoped_refptr<SharedBuffer>(new SharedBuffer(size)); +} + TEST_F(VideoFrameCapturerTest, StartCapturer) { + capturer_ = VideoFrameCapturer::Create(); capturer_->Start(&delegate_); capturer_->Stop(); } @@ -50,9 +69,33 @@ TEST_F(VideoFrameCapturerTest, Capture) { EXPECT_CALL(delegate_, OnCursorShapeChangedPtr(_)) .Times(AnyNumber()); + capturer_ = VideoFrameCapturer::Create(); + capturer_->Start(&delegate_); + capturer_->CaptureInvalidRegion(); + capturer_->Stop(); +} + +#if defined(OS_WIN) + +TEST_F(VideoFrameCapturerTest, UseSharedBuffers) { + EXPECT_CALL(delegate_, + OnCaptureCompleted(DirtyRegionIsNonEmptyRect())); + EXPECT_CALL(delegate_, OnCursorShapeChangedPtr(_)) + .Times(AnyNumber()); + + EXPECT_CALL(shared_buffer_factory_, CreateSharedBuffer(_)) + .Times(1) + .WillOnce(Invoke(this, &VideoFrameCapturerTest::CreateSharedBuffer)); + EXPECT_CALL(shared_buffer_factory_, ReleaseSharedBuffer(_)) + .Times(1); + + capturer_ = VideoFrameCapturer::CreateWithFactory(&shared_buffer_factory_); capturer_->Start(&delegate_); capturer_->CaptureInvalidRegion(); capturer_->Stop(); + capturer_.reset(); } +#endif // defined(OS_WIN) + } // namespace remoting diff --git a/remoting/host/video_frame_capturer_win.cc b/remoting/host/video_frame_capturer_win.cc index ad1a3a7..5a1b324 100644 --- a/remoting/host/video_frame_capturer_win.cc +++ b/remoting/host/video_frame_capturer_win.cc @@ -6,6 +6,8 @@ #include <windows.h> +#include "base/bind.h" +#include "base/bind_helpers.h" #include "base/file_path.h" #include "base/logging.h" #include "base/memory/scoped_ptr.h" @@ -14,6 +16,7 @@ #include "base/win/scoped_gdi_object.h" #include "base/win/scoped_hdc.h" #include "remoting/base/capture_data.h" +#include "remoting/base/shared_buffer_factory.h" #include "remoting/host/differ.h" #include "remoting/host/video_frame.h" #include "remoting/host/video_frame_capturer_helper.h" @@ -43,7 +46,8 @@ const uint32 kPixelBgraTransparent = 0x00000000; // A class representing a full-frame pixel buffer. class VideoFrameWin : public VideoFrame { public: - VideoFrameWin(HDC desktop_dc, const SkISize& size); + VideoFrameWin(HDC desktop_dc, const SkISize& size, + SharedBufferFactory* shared_buffer_factory); virtual ~VideoFrameWin(); // Returns handle of the device independent bitmap representing this frame @@ -51,8 +55,17 @@ class VideoFrameWin : public VideoFrame { HBITMAP GetBitmap(); private: + // Allocates a device independent bitmap representing this frame buffer to + // GDI. + void AllocateBitmap(HDC desktop_dc, const SkISize& size); + + // Handle of the device independent bitmap representing this frame buffer to + // GDI. base::win::ScopedBitmap bitmap_; + // Used to allocate shared memory buffers if set. + SharedBufferFactory* shared_buffer_factory_; + DISALLOW_COPY_AND_ASSIGN(VideoFrameWin); }; @@ -63,6 +76,7 @@ class VideoFrameWin : public VideoFrame { class VideoFrameCapturerWin : public VideoFrameCapturer { public: VideoFrameCapturerWin(); + explicit VideoFrameCapturerWin(SharedBufferFactory* shared_buffer_factory); virtual ~VideoFrameCapturerWin(); // Overridden from VideoFrameCapturer: @@ -91,6 +105,9 @@ class VideoFrameCapturerWin : public VideoFrameCapturer { // Capture the current cursor shape. void CaptureCursor(); + // Used to allocate shared memory buffers if set. + SharedBufferFactory* shared_buffer_factory_; + Delegate* delegate_; // A thread-safe list of invalid rectangles, and the size of the most @@ -132,7 +149,35 @@ static const int kPixelsPerMeter = 3780; // 32 bit RGBA is 4 bytes per pixel. static const int kBytesPerPixel = 4; -VideoFrameWin::VideoFrameWin(HDC desktop_dc, const SkISize& size) { +VideoFrameWin::VideoFrameWin( + HDC desktop_dc, + const SkISize& size, + SharedBufferFactory* shared_buffer_factory) + : shared_buffer_factory_(shared_buffer_factory) { + // Allocate a shared memory buffer. + uint32 buffer_size = size.width() * size.height() * kBytesPerPixel; + if (shared_buffer_factory_) { + scoped_refptr<SharedBuffer> shared_buffer = + shared_buffer_factory_->CreateSharedBuffer(buffer_size); + CHECK(shared_buffer->ptr() != NULL); + set_shared_buffer(shared_buffer); + } + + AllocateBitmap(desktop_dc, size); +} + +VideoFrameWin::~VideoFrameWin() { + if (shared_buffer()) + shared_buffer_factory_->ReleaseSharedBuffer(shared_buffer()); +} + +HBITMAP VideoFrameWin::GetBitmap() { + return bitmap_; +} + +void VideoFrameWin::AllocateBitmap(HDC desktop_dc, const SkISize& size) { + int bytes_per_row = size.width() * kBytesPerPixel; + // Describe a device independent bitmap (DIB) that is the size of the desktop. BITMAPINFO bmi; memset(&bmi, 0, sizeof(bmi)); @@ -141,14 +186,17 @@ VideoFrameWin::VideoFrameWin(HDC desktop_dc, const SkISize& size) { bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biBitCount = kBytesPerPixel * 8; bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader); - int bytes_per_row = size.width() * kBytesPerPixel; bmi.bmiHeader.biSizeImage = bytes_per_row * size.height(); bmi.bmiHeader.biXPelsPerMeter = kPixelsPerMeter; bmi.bmiHeader.biYPelsPerMeter = kPixelsPerMeter; // Create the DIB, and store a pointer to its pixel buffer. + HANDLE section_handle = NULL; + if (shared_buffer()) + section_handle = shared_buffer()->handle(); void* data = NULL; - bitmap_ = CreateDIBSection(desktop_dc, &bmi, DIB_RGB_COLORS, &data, NULL, 0); + bitmap_ = CreateDIBSection(desktop_dc, &bmi, DIB_RGB_COLORS, &data, + section_handle, 0); // TODO(wez): Cope gracefully with failure (crbug.com/157170). CHECK(bitmap_ != NULL); @@ -161,15 +209,19 @@ VideoFrameWin::VideoFrameWin(HDC desktop_dc, const SkISize& size) { bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight)); } -VideoFrameWin::~VideoFrameWin() { -} - -HBITMAP VideoFrameWin::GetBitmap() { - return bitmap_; +VideoFrameCapturerWin::VideoFrameCapturerWin() + : shared_buffer_factory_(NULL), + delegate_(NULL), + last_cursor_size_(SkISize::Make(0, 0)), + desktop_dc_rect_(SkIRect::MakeEmpty()), + pixel_format_(media::VideoFrame::RGB32), + composition_func_(NULL) { } -VideoFrameCapturerWin::VideoFrameCapturerWin() - : delegate_(NULL), +VideoFrameCapturerWin::VideoFrameCapturerWin( + SharedBufferFactory* shared_buffer_factory) + : shared_buffer_factory_(shared_buffer_factory), + delegate_(NULL), last_cursor_size_(SkISize::Make(0, 0)), desktop_dc_rect_(SkIRect::MakeEmpty()), pixel_format_(media::VideoFrame::RGB32), @@ -322,6 +374,7 @@ void VideoFrameCapturerWin::CaptureRegion(const SkRegion& region) { current_buffer->dimensions(), pixel_format_)); data->mutable_dirty_region() = region; + data->set_shared_buffer(current_buffer->shared_buffer()); helper_.set_size_most_recent(data->size()); @@ -342,7 +395,8 @@ void VideoFrameCapturerWin::CaptureImage() { SkISize size = SkISize::Make(desktop_dc_rect_.width(), desktop_dc_rect_.height()); - scoped_ptr<VideoFrameWin> buffer(new VideoFrameWin(*desktop_dc_, size)); + scoped_ptr<VideoFrameWin> buffer( + new VideoFrameWin(*desktop_dc_, size, shared_buffer_factory_)); queue_.ReplaceCurrentFrame(buffer.PassAs<VideoFrame>()); } @@ -553,4 +607,12 @@ scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::Create() { return scoped_ptr<VideoFrameCapturer>(new VideoFrameCapturerWin()); } +// static +scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( + SharedBufferFactory* shared_buffer_factory) { + scoped_ptr<VideoFrameCapturerWin> capturer( + new VideoFrameCapturerWin(shared_buffer_factory)); + return capturer.PassAs<VideoFrameCapturer>(); +} + } // namespace remoting diff --git a/remoting/host/video_scheduler.h b/remoting/host/video_scheduler.h index 98c4d41..597a0f7 100644 --- a/remoting/host/video_scheduler.h +++ b/remoting/host/video_scheduler.h @@ -86,7 +86,7 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>, protocol::ClientStub* client_stub, protocol::VideoStub* video_stub); - // VideoFrameCapturer::Delegate implementation + // VideoFrameCapturer::Delegate implementation. virtual void OnCaptureCompleted( scoped_refptr<CaptureData> capture_data) OVERRIDE; virtual void OnCursorShapeChanged( diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp index 8fde1dc..5673800 100644 --- a/remoting/remoting.gyp +++ b/remoting/remoting.gyp @@ -1456,6 +1456,9 @@ 'base/resources.h', 'base/running_average.cc', 'base/running_average.h', + 'base/shared_buffer.cc', + 'base/shared_buffer.h', + 'base/shared_buffer_factory.h', 'base/socket_reader.cc', 'base/socket_reader.h', 'base/stoppable.cc', @@ -2103,6 +2106,7 @@ 'base/breakpad_win_unittest.cc', 'base/compound_buffer_unittest.cc', 'base/resources_unittest.cc', + 'base/shared_buffer_unittest.cc', 'base/util_unittest.cc', 'client/audio_player_unittest.cc', 'client/key_event_mapper_unittest.cc', |