summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
authorsimonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 14:40:20 +0000
committersimonmorris@chromium.org <simonmorris@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 14:40:20 +0000
commitbab76b9b1c041f73ef5d973eaa27385f629c4d3b (patch)
tree8c2dbcbdbfec1bcfc1da8ae0b4403325fad26bb9 /remoting
parent82e4080d97b52798c3605fa73979c0bdf0fdc597 (diff)
downloadchromium_src-bab76b9b1c041f73ef5d973eaa27385f629c4d3b.zip
chromium_src-bab76b9b1c041f73ef5d973eaa27385f629c4d3b.tar.gz
chromium_src-bab76b9b1c041f73ef5d973eaa27385f629c4d3b.tar.bz2
Capturer is now pure virtual. The implementation it used to
contain is now in CapturerHelper. BUG=none TEST=none Review URL: http://codereview.chromium.org/6717020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79679 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/capturer.cc91
-rw-r--r--remoting/host/capturer.h83
-rw-r--r--remoting/host/capturer_fake.cc54
-rw-r--r--remoting/host/capturer_fake.h28
-rw-r--r--remoting/host/capturer_fake_ascii.cc48
-rw-r--r--remoting/host/capturer_fake_ascii.h26
-rw-r--r--remoting/host/capturer_gdi.cc54
-rw-r--r--remoting/host/capturer_gdi.h34
-rw-r--r--remoting/host/capturer_helper.cc65
-rw-r--r--remoting/host/capturer_helper.h70
-rw-r--r--remoting/host/capturer_linux.cc146
-rw-r--r--remoting/host/capturer_linux.h13
-rw-r--r--remoting/host/capturer_mac.cc55
-rw-r--r--remoting/host/capturer_mac.h27
-rw-r--r--remoting/host/capturer_mac_unittest.cc2
-rw-r--r--remoting/host/chromoting_host.cc2
-rw-r--r--remoting/host/chromoting_host_unittest.cc2
-rw-r--r--remoting/host/host_mock_objects.cc2
-rw-r--r--remoting/host/host_mock_objects.h9
-rw-r--r--remoting/host/screen_recorder_unittest.cc17
-rw-r--r--remoting/host/simple_host_process.cc2
-rw-r--r--remoting/remoting.gyp3
22 files changed, 541 insertions, 292 deletions
diff --git a/remoting/host/capturer.cc b/remoting/host/capturer.cc
deleted file mode 100644
index a138c05..0000000
--- a/remoting/host/capturer.cc
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (c) 2010 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/host/capturer.h"
-
-#include <algorithm>
-
-#include "remoting/base/tracer.h"
-
-namespace remoting {
-
-Capturer::Capturer(MessageLoop* message_loop)
- : pixel_format_(media::VideoFrame::INVALID),
- current_buffer_(0),
- message_loop_(message_loop),
- size_most_recent_(0, 0) {
-}
-
-Capturer::~Capturer() {
-}
-
-// Return the pixel format of the screen.
-media::VideoFrame::Format Capturer::pixel_format() const {
- return pixel_format_;
-}
-
-void Capturer::ClearInvalidRects() {
- base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
- inval_rects_.clear();
-}
-
-void Capturer::InvalidateRects(const InvalidRects& inval_rects) {
- InvalidRects temp_rects;
- std::set_union(inval_rects_.begin(), inval_rects_.end(),
- inval_rects.begin(), inval_rects.end(),
- std::inserter(temp_rects, temp_rects.begin()));
- {
- base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
- inval_rects_.swap(temp_rects);
- }
-}
-
-void Capturer::InvalidateScreen(const gfx::Size& size) {
- base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
- inval_rects_.clear();
- inval_rects_.insert(gfx::Rect(0, 0, size.width(), size.height()));
-}
-
-void Capturer::InvalidateFullScreen() {
- if (size_most_recent_ != gfx::Size(0, 0))
- InvalidateScreen(size_most_recent_);
-}
-
-void Capturer::CaptureInvalidRects(CaptureCompletedCallback* callback) {
- // Calculate which rects need to be captured.
- TraceContext::tracer()->PrintString("Started CalculateInvalidRects");
- CalculateInvalidRects();
- TraceContext::tracer()->PrintString("Done CalculateInvalidRects");
-
- // Braced to scope the lock.
- InvalidRects local_rects;
- {
- base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
- local_rects.swap(inval_rects_);
- }
-
- TraceContext::tracer()->PrintString("Start CaptureRects");
- CaptureRects(local_rects, callback);
-}
-
-void Capturer::FinishCapture(scoped_refptr<CaptureData> data,
- CaptureCompletedCallback* callback) {
- // Select the next buffer to be the current buffer.
- current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
-
- size_most_recent_ = data->size();
-
- callback->Run(data);
- delete callback;
-}
-
-bool Capturer::IsCaptureFullScreen(int width, int height) {
- base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
- return inval_rects_.size() == 1u &&
- inval_rects_.begin()->x() == 0 && inval_rects_.begin()->y() == 0 &&
- inval_rects_.begin()->width() == width &&
- inval_rects_.begin()->height() == height;
-}
-
-} // namespace remoting
diff --git a/remoting/host/capturer.h b/remoting/host/capturer.h
index 3444bcc..0adf45b 100644
--- a/remoting/host/capturer.h
+++ b/remoting/host/capturer.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -7,13 +7,9 @@
#include "base/basictypes.h"
#include "base/callback.h"
-#include "base/synchronization/lock.h"
-#include "base/task.h"
#include "remoting/base/capture_data.h"
#include "remoting/base/types.h"
-class MessageLoop;
-
namespace remoting {
// A class to perform the task of capturing the image of a window.
@@ -44,29 +40,29 @@ class Capturer {
// CaptureCompletedCallback is called when the capturer has completed.
typedef Callback1<scoped_refptr<CaptureData> >::Type CaptureCompletedCallback;
- virtual ~Capturer();
+ virtual ~Capturer() {};
- // Create platform-specific cpaturer.
- static Capturer* Create(MessageLoop* message_loop);
+ // Create platform-specific capturer.
+ static Capturer* Create();
// Called when the screen configuration is changed.
virtual void ScreenConfigurationChanged() = 0;
// Return the pixel format of the screen.
- virtual media::VideoFrame::Format pixel_format() const;
+ virtual media::VideoFrame::Format pixel_format() const = 0;
// Clear out the list of invalid rects.
- void ClearInvalidRects();
+ virtual void ClearInvalidRects() = 0;
// Invalidate the specified screen rects.
- void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateRects(const InvalidRects& inval_rects) = 0;
// Invalidate the entire screen, of a given size.
- void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateScreen(const gfx::Size& size) = 0;
// Invalidate the entire screen, using the size of the most recently
// captured screen.
- virtual void InvalidateFullScreen();
+ virtual void InvalidateFullScreen() = 0;
// Capture the screen data associated with each of the accumulated
// rects in |inval_rects|.
@@ -81,67 +77,10 @@ class Capturer {
// data of the last capture.
// There can be at most one concurrent read going on when this
// method is called.
- virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) = 0;
// Get the size of the most recently captured screen.
- const gfx::Size& size_most_recent() const { return size_most_recent_; }
-
- protected:
- explicit Capturer(MessageLoop* message_loop);
-
- // Update the list of |invalid_rects| to prepare for capturing the
- // screen data.
- // Depending on the platform implementation, this routine might:
- // (a) Analyze screen and calculate the list of rects that have changed
- // since the last capture.
- // (b) Merge already-acculumated rects into a more optimal list (for
- // example, by combining or removing rects).
- virtual void CalculateInvalidRects() = 0;
-
- // Capture the specified screen rects and call |callback| when complete.
- // Dirty or invalid regions are ignored and only the given |rects| areas are
- // captured.
- // This routine is used internally by CaptureInvalidRects().
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback) = 0;
-
- // Finish/cleanup capture task.
- // This should be called by CaptureRects() when it finishes.
- // This routine should (at least):
- // (1) Call the |callback| routine.
- // (2) Select the next screen buffer.
- // Note that capturers are required to be double-buffered so that we can
- // read from one which capturing into another.
- void FinishCapture(scoped_refptr<CaptureData> data,
- CaptureCompletedCallback* callback);
-
- // Called by subclasses' CalculateInvalidRects() method to check if
- // InvalidateFullScreen() was called by user.
- bool IsCaptureFullScreen(int width, int height);
-
- // Number of screen buffers.
- static const int kNumBuffers = 2;
-
- // Format of pixels returned in buffer.
- media::VideoFrame::Format pixel_format_;
-
- // The current buffer with valid data for reading.
- int current_buffer_;
-
- // Message loop that operations should run on.
- MessageLoop* message_loop_;
-
- private:
- // Rects that have been manually invalidated (through InvalidateRect).
- // These will be returned as dirty_rects in the capture data during the next
- // capture.
- InvalidRects inval_rects_;
-
- // A lock protecting |inval_rects_| across threads.
- base::Lock inval_rects_lock_;
-
- // The size of the most recently captured screen.
- gfx::Size size_most_recent_;
+ virtual const gfx::Size& size_most_recent() const = 0;
};
} // namespace remoting
diff --git a/remoting/host/capturer_fake.cc b/remoting/host/capturer_fake.cc
index 4db598e..9cf34d5 100644
--- a/remoting/host/capturer_fake.cc
+++ b/remoting/host/capturer_fake.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -24,13 +24,14 @@ COMPILE_ASSERT((kBoxWidth % kSpeed == 0) && (kWidth % kSpeed == 0) &&
static const int kBytesPerPixel = 4; // 32 bit RGB is 4 bytes per pixel.
-CapturerFake::CapturerFake(MessageLoop* message_loop)
- : Capturer(message_loop),
- bytes_per_row_(0),
+CapturerFake::CapturerFake()
+ : bytes_per_row_(0),
box_pos_x_(0),
box_pos_y_(0),
box_speed_x_(kSpeed),
- box_speed_y_(kSpeed) {
+ box_speed_y_(kSpeed),
+ current_buffer_(0),
+ pixel_format_(media::VideoFrame::RGB32) {
ScreenConfigurationChanged();
}
@@ -49,22 +50,53 @@ void CapturerFake::ScreenConfigurationChanged() {
}
}
-void CapturerFake::CalculateInvalidRects() {
+media::VideoFrame::Format CapturerFake::pixel_format() const {
+ return pixel_format_;
+}
+
+void CapturerFake::ClearInvalidRects() {
+ helper.ClearInvalidRects();
+}
+
+void CapturerFake::InvalidateRects(const InvalidRects& inval_rects) {
+ helper.InvalidateRects(inval_rects);
+}
+
+void CapturerFake::InvalidateScreen(const gfx::Size& size) {
+ helper.InvalidateScreen(size);
+}
+
+void CapturerFake::InvalidateFullScreen() {
+ helper.InvalidateFullScreen();
+
GenerateImage();
- InvalidateScreen(size_);
}
-void CapturerFake::CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback) {
+void CapturerFake::CaptureInvalidRects(CaptureCompletedCallback* callback) {
+ scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
+
+ InvalidateScreen(size_);
+
+ InvalidRects inval_rects;
+ helper.SwapInvalidRects(inval_rects);
+
DataPlanes planes;
planes.data[0] = buffers_[current_buffer_].get();
+ current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
planes.strides[0] = bytes_per_row_;
scoped_refptr<CaptureData> capture_data(new CaptureData(planes,
size_,
pixel_format_));
- capture_data->mutable_dirty_rects() = rects;
- FinishCapture(capture_data, callback);
+ capture_data->mutable_dirty_rects() = inval_rects;
+
+ helper.set_size_most_recent(capture_data->size());
+
+ callback->Run(capture_data);
+}
+
+const gfx::Size& CapturerFake::size_most_recent() const {
+ return helper.size_most_recent();
}
void CapturerFake::GenerateImage() {
diff --git a/remoting/host/capturer_fake.h b/remoting/host/capturer_fake.h
index 9eacc21..60b4fec 100644
--- a/remoting/host/capturer_fake.h
+++ b/remoting/host/capturer_fake.h
@@ -7,25 +7,30 @@
#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer.h"
+#include "remoting/host/capturer_helper.h"
namespace remoting {
// A CapturerFake generates artificial image for testing purpose.
//
-// CapturerFake is doubled buffered as required by Capturer. See
+// CapturerFake is double-buffered as required by Capturer. See
// remoting/host/capturer.h.
class CapturerFake : public Capturer {
public:
- explicit CapturerFake(MessageLoop* message_loop);
- virtual ~CapturerFake();
+ CapturerFake();
+ ~CapturerFake();
+ // Capturer interface.
virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
private:
- virtual void CalculateInvalidRects();
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback);
-
// Generates an image in the front buffer.
void GenerateImage();
@@ -36,9 +41,18 @@ class CapturerFake : public Capturer {
int box_speed_x_;
int box_speed_y_;
+ CapturerHelper helper;
+
// We have two buffers for the screen images as required by Capturer.
+ static const int kNumBuffers = 2;
scoped_array<uint8> buffers_[kNumBuffers];
+ // The current buffer with valid data for reading.
+ int current_buffer_;
+
+ // Format of pixels returned in buffer.
+ media::VideoFrame::Format pixel_format_;
+
DISALLOW_COPY_AND_ASSIGN(CapturerFake);
};
diff --git a/remoting/host/capturer_fake_ascii.cc b/remoting/host/capturer_fake_ascii.cc
index 60656c0..40f4509 100644
--- a/remoting/host/capturer_fake_ascii.cc
+++ b/remoting/host/capturer_fake_ascii.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -12,8 +12,9 @@ static const int kWidth = 32;
static const int kHeight = 20;
static const int kBytesPerPixel = 1;
-CapturerFakeAscii::CapturerFakeAscii(MessageLoop* message_loop)
- : Capturer(message_loop) {
+CapturerFakeAscii::CapturerFakeAscii()
+ : current_buffer_(0),
+ pixel_format_(media::VideoFrame::ASCII) {
}
CapturerFakeAscii::~CapturerFakeAscii() {
@@ -32,22 +33,45 @@ void CapturerFakeAscii::ScreenConfigurationChanged() {
}
}
-void CapturerFakeAscii::CalculateInvalidRects() {
- // Capture and invalidate the entire screen.
- // Performing the capture here is modelled on the Windows
- // GDI capturer.
- GenerateImage();
- InvalidateFullScreen();
+media::VideoFrame::Format CapturerFakeAscii::pixel_format() const {
+ return pixel_format_;
+}
+
+void CapturerFakeAscii::ClearInvalidRects() {
+ helper.ClearInvalidRects();
+}
+
+void CapturerFakeAscii::InvalidateRects(const InvalidRects& inval_rects) {
+ helper.InvalidateRects(inval_rects);
+}
+
+void CapturerFakeAscii::InvalidateScreen(const gfx::Size& size) {
+ helper.InvalidateScreen(size);
}
-void CapturerFakeAscii::CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback) {
+void CapturerFakeAscii::InvalidateFullScreen() {
+ helper.InvalidateFullScreen();
+}
+
+void CapturerFakeAscii::CaptureInvalidRects(
+ CaptureCompletedCallback* callback) {
+ scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
+
+ GenerateImage();
DataPlanes planes;
planes.data[0] = buffers_[current_buffer_].get();
+ current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
planes.strides[0] = bytes_per_row_;
scoped_refptr<CaptureData> capture_data(new CaptureData(
planes, gfx::Size(width_, height_), pixel_format_));
- FinishCapture(capture_data, callback);
+
+ helper.set_size_most_recent(capture_data->size());
+
+ callback->Run(capture_data);
+}
+
+const gfx::Size& CapturerFakeAscii::size_most_recent() const {
+ return helper.size_most_recent();
}
void CapturerFakeAscii::GenerateImage() {
diff --git a/remoting/host/capturer_fake_ascii.h b/remoting/host/capturer_fake_ascii.h
index a07fb06..fe008f7 100644
--- a/remoting/host/capturer_fake_ascii.h
+++ b/remoting/host/capturer_fake_ascii.h
@@ -7,6 +7,7 @@
#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer.h"
+#include "remoting/host/capturer_helper.h"
namespace remoting {
@@ -17,16 +18,20 @@ namespace remoting {
// remoting/host/capturer.h.
class CapturerFakeAscii : public Capturer {
public:
- explicit CapturerFakeAscii(MessageLoop* message_loop);
- virtual ~CapturerFakeAscii();
+ CapturerFakeAscii();
+ ~CapturerFakeAscii();
+ // Capturer interface.
virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
private:
- virtual void CalculateInvalidRects();
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback);
-
// Generates an image in the front buffer.
void GenerateImage();
@@ -35,9 +40,18 @@ class CapturerFakeAscii : public Capturer {
int height_;
int bytes_per_row_;
+ CapturerHelper helper;
+
// We have two buffers for the screen images as required by Capturer.
+ static const int kNumBuffers = 2;
scoped_array<uint8> buffers_[kNumBuffers];
+ // The current buffer with valid data for reading.
+ int current_buffer_;
+
+ // Format of pixels returned in buffer.
+ media::VideoFrame::Format pixel_format_;
+
DISALLOW_COPY_AND_ASSIGN(CapturerFakeAscii);
};
diff --git a/remoting/host/capturer_gdi.cc b/remoting/host/capturer_gdi.cc
index a45aef4..8e50bde 100644
--- a/remoting/host/capturer_gdi.cc
+++ b/remoting/host/capturer_gdi.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,11 +14,12 @@ static const int kPixelsPerMeter = 3780;
// 32 bit RGBA is 4 bytes per pixel.
static const int kBytesPerPixel = 4;
-CapturerGdi::CapturerGdi(MessageLoop* message_loop)
- : Capturer(message_loop),
- desktop_dc_(NULL),
+CapturerGdi::CapturerGdi()
+ : desktop_dc_(NULL),
memory_dc_(NULL),
dc_size_(0, 0),
+ current_buffer_(0),
+ pixel_format_(media::VideoFrame::RGB32),
capture_fullscreen_(true) {
memset(target_bitmap_, 0, sizeof(target_bitmap_));
memset(buffers_, 0, sizeof(buffers_));
@@ -29,6 +30,37 @@ CapturerGdi::~CapturerGdi() {
ReleaseBuffers();
}
+media::VideoFrame::Format CapturerGdi::pixel_format() const {
+ return pixel_format_;
+}
+
+void CapturerGdi::ClearInvalidRects() {
+ helper.ClearInvalidRects();
+}
+
+void CapturerGdi::InvalidateRects(const InvalidRects& inval_rects) {
+ helper.InvalidateRects(inval_rects);
+}
+
+void CapturerGdi::InvalidateScreen(const gfx::Size& size) {
+ helper.InvalidateScreen(size);
+}
+
+void CapturerGdi::InvalidateFullScreen() {
+ helper.InvalidateFullScreen();
+}
+
+void CapturerGdi::CaptureInvalidRects(CaptureCompletedCallback* callback) {
+ CalculateInvalidRects();
+ InvalidRects inval_rects;
+ helper.SwapInvalidRects(inval_rects);
+ CaptureRects(inval_rects, callback);
+}
+
+const gfx::Size& CapturerGdi::size_most_recent() const {
+ return helper.size_most_recent();
+}
+
void CapturerGdi::ReleaseBuffers() {
for (int i = kNumBuffers - 1; i >= 0; i--) {
if (target_bitmap_[i]) {
@@ -117,7 +149,7 @@ void CapturerGdi::CalculateInvalidRects() {
CaptureImage();
const VideoFrameBuffer& current = buffers_[current_buffer_];
- if (IsCaptureFullScreen(current.size.width(), current.size.height()))
+ if (helper.IsCaptureFullScreen(current.size))
capture_fullscreen_ = true;
if (capture_fullscreen_) {
@@ -160,7 +192,11 @@ void CapturerGdi::CalculateInvalidRects() {
void CapturerGdi::CaptureRects(const InvalidRects& rects,
CaptureCompletedCallback* callback) {
+ scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
+
const VideoFrameBuffer& buffer = buffers_[current_buffer_];
+ current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
+
DataPlanes planes;
planes.data[0] = static_cast<uint8*>(buffer.data);
planes.strides[0] = buffer.bytes_per_row;
@@ -170,7 +206,9 @@ void CapturerGdi::CaptureRects(const InvalidRects& rects,
pixel_format_));
data->mutable_dirty_rects() = rects;
- FinishCapture(data, callback);
+ helper.set_size_most_recent(data->size());
+
+ callback->Run(data);
}
void CapturerGdi::CaptureImage() {
@@ -192,8 +230,8 @@ gfx::Size CapturerGdi::GetScreenSize() {
}
// static
-Capturer* Capturer::Create(MessageLoop* message_loop) {
- return new CapturerGdi(message_loop);
+Capturer* Capturer::Create() {
+ return new CapturerGdi();
}
} // namespace remoting
diff --git a/remoting/host/capturer_gdi.h b/remoting/host/capturer_gdi.h
index 28f964b..fb8f157 100644
--- a/remoting/host/capturer_gdi.h
+++ b/remoting/host/capturer_gdi.h
@@ -9,6 +9,7 @@
typedef HBITMAP BitmapRef;
#include "base/memory/scoped_ptr.h"
#include "remoting/host/capturer.h"
+#include "remoting/host/capturer_helper.h"
namespace remoting {
@@ -16,14 +17,22 @@ class Differ;
// CapturerGdi captures 32bit RGB using GDI.
//
-// CapturerGdi is doubled buffered as required by Capturer. See
+// CapturerGdi is double-buffered as required by Capturer. See
// remoting/host/capturer.h.
class CapturerGdi : public Capturer {
public:
- explicit CapturerGdi(MessageLoop* message_loop);
+ CapturerGdi();
virtual ~CapturerGdi();
+ // Capturer interface.
virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
private:
struct VideoFrameBuffer {
@@ -51,9 +60,9 @@ class CapturerGdi : public Capturer {
// allocated for that buffer.
void ReallocateBuffer(int buffer_index, const gfx::Size& size);
- virtual void CalculateInvalidRects();
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback);
+ void CalculateInvalidRects();
+ void CaptureRects(const InvalidRects& rects,
+ CaptureCompletedCallback* callback);
void ReleaseBuffers();
// Generates an image in the current buffer.
@@ -66,6 +75,14 @@ class CapturerGdi : public Capturer {
// Gets the screen size.
gfx::Size GetScreenSize();
+ // A thread-safe list of invalid rectangles, and the size of the most
+ // recently captured screen.
+ CapturerHelper helper;
+
+ // There are two buffers for the screen images, as required by Capturer.
+ static const int kNumBuffers = 2;
+ VideoFrameBuffer buffers_[kNumBuffers];
+
// Gdi specific information about screen.
HDC desktop_dc_;
HDC memory_dc_;
@@ -75,8 +92,11 @@ class CapturerGdi : public Capturer {
// is captured.
gfx::Size dc_size_;
- // We have two buffers for the screen images as required by Capturer.
- VideoFrameBuffer buffers_[kNumBuffers];
+ // The current buffer with valid data for reading.
+ int current_buffer_;
+
+ // Format of pixels returned in buffer.
+ media::VideoFrame::Format pixel_format_;
// Class to calculate the difference between two screen bitmaps.
scoped_ptr<Differ> differ_;
diff --git a/remoting/host/capturer_helper.cc b/remoting/host/capturer_helper.cc
new file mode 100644
index 0000000..00b0d538
--- /dev/null
+++ b/remoting/host/capturer_helper.cc
@@ -0,0 +1,65 @@
+// Copyright (c) 2011 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/host/capturer_helper.h"
+
+#include <algorithm>
+
+namespace remoting {
+
+CapturerHelper::CapturerHelper() : size_most_recent_(0, 0) {
+}
+
+CapturerHelper::~CapturerHelper() {
+}
+
+void CapturerHelper::ClearInvalidRects() {
+ base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
+ inval_rects_.clear();
+}
+
+void CapturerHelper::InvalidateRects(const InvalidRects& inval_rects) {
+ InvalidRects temp_rects;
+ std::set_union(inval_rects_.begin(), inval_rects_.end(),
+ inval_rects.begin(), inval_rects.end(),
+ std::inserter(temp_rects, temp_rects.begin()));
+ {
+ base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
+ inval_rects_.swap(temp_rects);
+ }
+}
+
+void CapturerHelper::InvalidateScreen(const gfx::Size& size) {
+ base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
+ inval_rects_.clear();
+ inval_rects_.insert(gfx::Rect(0, 0, size.width(), size.height()));
+}
+
+void CapturerHelper::InvalidateFullScreen() {
+ if (size_most_recent_ != gfx::Size(0, 0))
+ InvalidateScreen(size_most_recent_);
+}
+
+bool CapturerHelper::IsCaptureFullScreen(const gfx::Size& size) {
+ base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
+ return inval_rects_.size() == 1u &&
+ inval_rects_.begin()->x() == 0 && inval_rects_.begin()->y() == 0 &&
+ inval_rects_.begin()->width() == size.width() &&
+ inval_rects_.begin()->height() == size.height();
+}
+
+void CapturerHelper::SwapInvalidRects(InvalidRects& inval_rects) {
+ base::AutoLock auto_inval_rects_lock(inval_rects_lock_);
+ inval_rects.swap(inval_rects_);
+}
+
+const gfx::Size& CapturerHelper::size_most_recent() const {
+ return size_most_recent_;
+}
+
+void CapturerHelper::set_size_most_recent(const gfx::Size& size) {
+ size_most_recent_ = size;
+}
+
+} // namespace remoting
diff --git a/remoting/host/capturer_helper.h b/remoting/host/capturer_helper.h
new file mode 100644
index 0000000..b7650c0
--- /dev/null
+++ b/remoting/host/capturer_helper.h
@@ -0,0 +1,70 @@
+// Copyright (c) 2011 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_HOST_CAPTURER_HELPER_H_
+#define REMOTING_HOST_CAPTURER_HELPER_H_
+
+#include "base/synchronization/lock.h"
+#include "remoting/base/types.h"
+
+namespace remoting {
+
+// CapturerHelper is intended to be used by an implementation of the Capturer
+// interface. It maintains a thread-safe list of invalid rectangles, and the
+// size of the most recently captured screen, on behalf of the Capturer that
+// owns it.
+class CapturerHelper {
+ public:
+ CapturerHelper();
+ ~CapturerHelper();
+
+ // Clear out the list of invalid rects.
+ void ClearInvalidRects();
+
+ // Invalidate the specified screen rects.
+ void InvalidateRects(const InvalidRects& inval_rects);
+
+ // Invalidate the entire screen, of a given size.
+ void InvalidateScreen(const gfx::Size& size);
+
+ // Invalidate the entire screen, using the size of the most recently
+ // captured screen.
+ void InvalidateFullScreen();
+
+ // Whether the invalid region is a full screen of a given size.
+ bool IsCaptureFullScreen(const gfx::Size& size);
+
+ // Swap the given set of rects with the stored invalid rects.
+ // This should be used like this:
+ //
+ // InvalidRects inval_rects;
+ // common.SwapInvalidRects(inval_rects);
+ //
+ // This passes the invalid rects to the caller, and removes them from this
+ // object. The caller should then pass the raster data in those rects to the
+ // client.
+ void SwapInvalidRects(InvalidRects& inval_rects);
+
+ // Access the size of the most recently captured screen.
+ const gfx::Size& size_most_recent() const;
+ void set_size_most_recent(const gfx::Size& size);
+
+ private:
+ // Rects that have been manually invalidated (through InvalidateRect).
+ // These will be returned as dirty_rects in the capture data during the next
+ // capture.
+ InvalidRects inval_rects_;
+
+ // A lock protecting |inval_rects_| across threads.
+ base::Lock inval_rects_lock_;
+
+ // The size of the most recently captured screen.
+ gfx::Size size_most_recent_;
+
+ DISALLOW_COPY_AND_ASSIGN(CapturerHelper);
+};
+
+} // namespace remoting
+
+#endif // REMOTING_HOST_CAPTURER_HELPER_H_
diff --git a/remoting/host/capturer_linux.cc b/remoting/host/capturer_linux.cc
index db0ffc4..71de8fd 100644
--- a/remoting/host/capturer_linux.cc
+++ b/remoting/host/capturer_linux.cc
@@ -10,24 +10,37 @@
#include <set>
+#include "base/logging.h"
#include "remoting/base/types.h"
+#include "remoting/host/capturer_helper.h"
#include "remoting/host/x_server_pixel_buffer.h"
namespace remoting {
// Private Implementation pattern to avoid leaking the X11 types into the header
// file.
-class CapturerLinuxPimpl {
+class CapturerLinuxPimpl : public Capturer {
public:
- explicit CapturerLinuxPimpl(CapturerLinux* capturer);
- ~CapturerLinuxPimpl();
+ CapturerLinuxPimpl();
+ virtual ~CapturerLinuxPimpl();
bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
+
+ // Capturer interface.
+ virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
+
+ private:
void CalculateInvalidRects();
void CaptureRects(const InvalidRects& rects,
Capturer::CaptureCompletedCallback* callback);
- private:
void DeinitXlib();
// We expose two forms of blitting to handle variations in the pixel format.
// In FastBlit, the operation is effectively a memcpy.
@@ -36,10 +49,6 @@ class CapturerLinuxPimpl {
static const int kBytesPerPixel = 4;
- // Reference to containing class so we can access friend functions.
- // Not owned.
- CapturerLinux* capturer_;
-
// X11 graphics context.
Display* display_;
GC gc_;
@@ -55,11 +64,20 @@ class CapturerLinuxPimpl {
// Access to the X Server's pixel buffer.
XServerPixelBuffer x_server_pixel_buffer_;
+ // A thread-safe list of invalid rectangles, and the size of the most
+ // recently captured screen.
+ CapturerHelper helper_;
+
// Capture state.
- uint8* buffers_[CapturerLinux::kNumBuffers];
+ static const int kNumBuffers = 2;
+ uint8* buffers_[kNumBuffers];
+ int current_buffer_;
int stride_;
bool capture_fullscreen_;
+ // Format of pixels returned in buffer.
+ media::VideoFrame::Format pixel_format_;
+
// Invalid rects in the last capture. This is used to synchronize current with
// the previous buffer used.
InvalidRects last_invalid_rects_;
@@ -68,9 +86,8 @@ class CapturerLinuxPimpl {
uint8* last_buffer_;
};
-CapturerLinux::CapturerLinux(MessageLoop* message_loop)
- : Capturer(message_loop),
- pimpl_(new CapturerLinuxPimpl(this)) {
+CapturerLinux::CapturerLinux()
+ : pimpl_(new CapturerLinuxPimpl()) {
// TODO(ajwong): This should be moved into an Init() method on Capturer
// itself. Then we can remove the CHECK.
CHECK(pimpl_->Init());
@@ -80,22 +97,39 @@ CapturerLinux::~CapturerLinux() {
}
void CapturerLinux::ScreenConfigurationChanged() {
- // TODO(ajwong): Support resolution changes.
- NOTIMPLEMENTED();
+ pimpl_->ScreenConfigurationChanged();
+}
+
+media::VideoFrame::Format CapturerLinux::pixel_format() const {
+ return pimpl_->pixel_format();
}
-void CapturerLinux::CalculateInvalidRects() {
- pimpl_->CalculateInvalidRects();
+void CapturerLinux::ClearInvalidRects() {
+ pimpl_->ClearInvalidRects();
}
-void CapturerLinux::CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback) {
- pimpl_->CaptureRects(rects, callback);
+void CapturerLinux::InvalidateRects(const InvalidRects& inval_rects) {
+ pimpl_->InvalidateRects(inval_rects);
}
-CapturerLinuxPimpl::CapturerLinuxPimpl(CapturerLinux* capturer)
- : capturer_(capturer),
- display_(NULL),
+void CapturerLinux::InvalidateScreen(const gfx::Size& size) {
+ pimpl_->InvalidateScreen(size);
+}
+
+void CapturerLinux::InvalidateFullScreen() {
+ pimpl_->InvalidateFullScreen();
+}
+
+void CapturerLinux::CaptureInvalidRects(CaptureCompletedCallback* callback) {
+ pimpl_->CaptureInvalidRects(callback);
+}
+
+const gfx::Size& CapturerLinux::size_most_recent() const {
+ return pimpl_->size_most_recent();
+}
+
+CapturerLinuxPimpl::CapturerLinuxPimpl()
+ : display_(NULL),
gc_(NULL),
root_window_(BadValue),
width_(0),
@@ -103,10 +137,12 @@ CapturerLinuxPimpl::CapturerLinuxPimpl(CapturerLinux* capturer)
damage_handle_(BadValue),
damage_event_base_(-1),
damage_error_base_(-1),
+ current_buffer_(0),
stride_(0),
capture_fullscreen_(true),
+ pixel_format_(media::VideoFrame::RGB32),
last_buffer_(NULL) {
- for (int i = 0; i < CapturerLinux::kNumBuffers; i++) {
+ for (int i = 0; i < kNumBuffers; i++) {
buffers_[i] = NULL;
}
}
@@ -114,7 +150,7 @@ CapturerLinuxPimpl::CapturerLinuxPimpl(CapturerLinux* capturer)
CapturerLinuxPimpl::~CapturerLinuxPimpl() {
DeinitXlib();
- for (int i = 0; i < CapturerLinux::kNumBuffers; i++) {
+ for (int i = 0; i < kNumBuffers; i++) {
delete [] buffers_[i];
buffers_[i] = NULL;
}
@@ -173,15 +209,50 @@ bool CapturerLinuxPimpl::Init() {
VLOG(1) << "Initialized with Geometry: " << width_ << "x" << height_;
// Allocate the screen buffers.
- for (int i = 0; i < CapturerLinux::kNumBuffers; i++) {
+ for (int i = 0; i < kNumBuffers; i++) {
buffers_[i] = new uint8[width_ * height_ * kBytesPerPixel];
}
return true;
}
+void CapturerLinuxPimpl::ScreenConfigurationChanged() {
+ // TODO(ajwong): Support resolution changes.
+ NOTIMPLEMENTED();
+}
+
+media::VideoFrame::Format CapturerLinuxPimpl::pixel_format() const {
+ return pixel_format_;
+}
+
+void CapturerLinuxPimpl::ClearInvalidRects() {
+ helper_.ClearInvalidRects();
+}
+
+void CapturerLinuxPimpl::InvalidateRects(const InvalidRects& inval_rects) {
+ helper_.InvalidateRects(inval_rects);
+}
+
+void CapturerLinuxPimpl::InvalidateScreen(const gfx::Size& size) {
+ helper_.InvalidateScreen(size);
+}
+
+void CapturerLinuxPimpl::InvalidateFullScreen() {
+ helper_.InvalidateFullScreen();
+}
+
+void CapturerLinuxPimpl::CaptureInvalidRects(
+ CaptureCompletedCallback* callback) {
+ CalculateInvalidRects();
+
+ InvalidRects rects;
+ helper_.SwapInvalidRects(rects);
+
+ CaptureRects(rects, callback);
+}
+
void CapturerLinuxPimpl::CalculateInvalidRects() {
- if (capturer_->IsCaptureFullScreen(width_, height_))
+ if (helper_.IsCaptureFullScreen(gfx::Size(width_, height_)))
capture_fullscreen_ = true;
// TODO(ajwong): The capture_fullscreen_ logic here is very ugly. Refactor.
@@ -216,17 +287,19 @@ void CapturerLinuxPimpl::CalculateInvalidRects() {
if (capture_fullscreen_) {
// TODO(hclam): Check the new dimension again.
- capturer_->InvalidateScreen(gfx::Size(width_, height_));
+ helper_.InvalidateScreen(gfx::Size(width_, height_));
capture_fullscreen_ = false;
} else {
- capturer_->InvalidateRects(invalid_rects);
+ helper_.InvalidateRects(invalid_rects);
}
}
void CapturerLinuxPimpl::CaptureRects(
const InvalidRects& rects,
Capturer::CaptureCompletedCallback* callback) {
- uint8* buffer = buffers_[capturer_->current_buffer_];
+ scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
+
+ uint8* buffer = buffers_[current_buffer_];
DataPlanes planes;
planes.data[0] = buffer;
planes.strides[0] = stride_;
@@ -275,9 +348,10 @@ void CapturerLinuxPimpl::CaptureRects(
last_invalid_rects_ = rects;
last_buffer_ = buffer;
- // TODO(ajwong): These completion signals back to the upper class are very
- // strange. Fix it.
- capturer_->FinishCapture(capture_data, callback);
+ current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
+ helper_.set_size_most_recent(capture_data->size());
+
+ callback->Run(capture_data);
}
void CapturerLinuxPimpl::DeinitXlib() {
@@ -365,9 +439,13 @@ void CapturerLinuxPimpl::SlowBlit(uint8* image, const gfx::Rect& rect,
}
}
+const gfx::Size& CapturerLinuxPimpl::size_most_recent() const {
+ return helper_.size_most_recent();
+}
+
// static
-Capturer* Capturer::Create(MessageLoop* message_loop) {
- return new CapturerLinux(message_loop);
+Capturer* Capturer::Create() {
+ return new CapturerLinux();
}
} // namespace remoting
diff --git a/remoting/host/capturer_linux.h b/remoting/host/capturer_linux.h
index 15aa438..f0ef413 100644
--- a/remoting/host/capturer_linux.h
+++ b/remoting/host/capturer_linux.h
@@ -16,16 +16,21 @@ class CapturerLinuxPimpl;
// A class to perform capturing for Linux.
class CapturerLinux : public Capturer {
public:
- explicit CapturerLinux(MessageLoop* message_loop);
+ CapturerLinux();
virtual ~CapturerLinux();
+ // Capturer interface.
virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
private:
friend class CapturerLinuxPimpl;
- virtual void CalculateInvalidRects();
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback);
scoped_ptr<CapturerLinuxPimpl> pimpl_;
DISALLOW_COPY_AND_ASSIGN(CapturerLinux);
diff --git a/remoting/host/capturer_mac.cc b/remoting/host/capturer_mac.cc
index cd7838d..d13a5f5 100644
--- a/remoting/host/capturer_mac.cc
+++ b/remoting/host/capturer_mac.cc
@@ -1,7 +1,8 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 "base/logging.h"
#include "remoting/host/capturer_mac.h"
#include <stddef.h>
@@ -10,12 +11,13 @@
namespace remoting {
-CapturerMac::CapturerMac(MessageLoop* message_loop)
- : Capturer(message_loop),
- cgl_context_(NULL),
+CapturerMac::CapturerMac()
+ : cgl_context_(NULL),
width_(0),
height_(0),
- bytes_per_row_(0) {
+ bytes_per_row_(0),
+ current_buffer_(0),
+ pixel_format_(media::VideoFrame::RGB32) {
// TODO(dmaclach): move this initialization out into session_manager,
// or at least have session_manager call into here to initialize it.
CGError err =
@@ -79,14 +81,30 @@ void CapturerMac::ScreenConfigurationChanged() {
CGLSetCurrentContext(cgl_context_);
}
-void CapturerMac::CalculateInvalidRects() {
- // Since the Mac gets its list of invalid rects via calls to InvalidateRect(),
- // this step only needs to perform post-processing optimizations on the rect
- // list (if needed).
+media::VideoFrame::Format CapturerMac::pixel_format() const {
+ return pixel_format_;
}
-void CapturerMac::CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback) {
+void CapturerMac::ClearInvalidRects() {
+ helper_.ClearInvalidRects();
+}
+
+void CapturerMac::InvalidateRects(const InvalidRects& inval_rects) {
+ helper_.InvalidateRects(inval_rects);
+}
+
+void CapturerMac::InvalidateScreen(const gfx::Size& size) {
+ helper_.InvalidateScreen(size);
+}
+
+void CapturerMac::InvalidateFullScreen() {
+ helper_.InvalidateFullScreen();
+}
+
+void CapturerMac::CaptureInvalidRects(CaptureCompletedCallback* callback) {
+ InvalidRects rects;
+ helper_.SwapInvalidRects(rects);
+
CGLContextObj CGL_MACRO_CONTEXT = cgl_context_;
glReadBuffer(GL_FRONT);
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
@@ -118,7 +136,16 @@ void CapturerMac::CaptureRects(const InvalidRects& rects,
scoped_refptr<CaptureData> data(
new CaptureData(planes, gfx::Size(width_, height_), pixel_format()));
data->mutable_dirty_rects() = rects;
- FinishCapture(data, callback);
+
+ current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
+ helper_.set_size_most_recent(data->size());
+
+ callback->Run(data);
+ delete callback;
+}
+
+const gfx::Size& CapturerMac::size_most_recent() const {
+ return helper_.size_most_recent();
}
void CapturerMac::ScreenRefresh(CGRectCount count, const CGRect *rect_array) {
@@ -169,8 +196,8 @@ void CapturerMac::DisplaysReconfiguredCallback(
}
// static
-Capturer* Capturer::Create(MessageLoop* message_loop) {
- return new CapturerMac(message_loop);
+Capturer* Capturer::Create() {
+ return new CapturerMac();
}
} // namespace remoting
diff --git a/remoting/host/capturer_mac.h b/remoting/host/capturer_mac.h
index 442098d..ee42882 100644
--- a/remoting/host/capturer_mac.h
+++ b/remoting/host/capturer_mac.h
@@ -6,6 +6,7 @@
#define REMOTING_HOST_CAPTURER_MAC_H_
#include "remoting/host/capturer.h"
+#include "remoting/host/capturer_helper.h"
#include <ApplicationServices/ApplicationServices.h>
#include <OpenGL/OpenGL.h>
#include "base/memory/scoped_ptr.h"
@@ -15,15 +16,22 @@ namespace remoting {
// A class to perform capturing for mac.
class CapturerMac : public Capturer {
public:
- explicit CapturerMac(MessageLoop* message_loop);
+ CapturerMac();
virtual ~CapturerMac();
+ // Capturer interface.
virtual void ScreenConfigurationChanged();
+ virtual media::VideoFrame::Format pixel_format() const;
+ virtual void ClearInvalidRects();
+ virtual void InvalidateRects(const InvalidRects& inval_rects);
+ virtual void InvalidateScreen(const gfx::Size& size);
+ virtual void InvalidateFullScreen();
+ virtual void CaptureInvalidRects(CaptureCompletedCallback* callback);
+ virtual const gfx::Size& size_most_recent() const;
private:
- virtual void CalculateInvalidRects();
- virtual void CaptureRects(const InvalidRects& rects,
- CaptureCompletedCallback* callback);
+ void CaptureRects(const InvalidRects& rects,
+ CaptureCompletedCallback* callback);
void ScreenRefresh(CGRectCount count, const CGRect *rect_array);
void ScreenUpdateMove(CGScreenUpdateMoveDelta delta,
@@ -42,15 +50,26 @@ class CapturerMac : public Capturer {
void ReleaseBuffers();
CGLContextObj cgl_context_;
+ static const int kNumBuffers = 2;
scoped_array<uint8> buffers_[kNumBuffers];
scoped_array<uint8> flip_buffer_;
+ // A thread-safe list of invalid rectangles, and the size of the most
+ // recently captured screen.
+ CapturerHelper helper_;
+
// Screen size.
int width_;
int height_;
int bytes_per_row_;
+ // The current buffer with valid data for reading.
+ int current_buffer_;
+
+ // Format of pixels returned in buffer.
+ media::VideoFrame::Format pixel_format_;
+
DISALLOW_COPY_AND_ASSIGN(CapturerMac);
};
diff --git a/remoting/host/capturer_mac_unittest.cc b/remoting/host/capturer_mac_unittest.cc
index cf4ef54..4ca85f5 100644
--- a/remoting/host/capturer_mac_unittest.cc
+++ b/remoting/host/capturer_mac_unittest.cc
@@ -17,7 +17,7 @@ namespace remoting {
class CapturerMacTest : public testing::Test {
protected:
virtual void SetUp() {
- capturer_.reset(new CapturerMac(NULL));
+ capturer_.reset(new CapturerMac());
}
void AddDirtyRect() {
diff --git a/remoting/host/chromoting_host.cc b/remoting/host/chromoting_host.cc
index 6b5803e..6dd6a73 100644
--- a/remoting/host/chromoting_host.cc
+++ b/remoting/host/chromoting_host.cc
@@ -34,7 +34,7 @@ namespace remoting {
// static
ChromotingHost* ChromotingHost::Create(ChromotingHostContext* context,
MutableHostConfig* config) {
- Capturer* capturer = Capturer::Create(context->main_message_loop());
+ Capturer* capturer = Capturer::Create();
InputStub* input_stub = CreateEventExecutor(context->ui_message_loop(),
capturer);
return Create(context, config,
diff --git a/remoting/host/chromoting_host_unittest.cc b/remoting/host/chromoting_host_unittest.cc
index 5338c08..7b3c677 100644
--- a/remoting/host/chromoting_host_unittest.cc
+++ b/remoting/host/chromoting_host_unittest.cc
@@ -75,7 +75,7 @@ class ChromotingHostTest : public testing::Test {
EXPECT_CALL(context_, network_message_loop())
.Times(AnyNumber());
- Capturer* capturer = new CapturerFake(context_.main_message_loop());
+ Capturer* capturer = new CapturerFake();
host_stub_ = new MockHostStub();
host_stub2_ = new MockHostStub();
input_stub_ = new MockInputStub();
diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc
index d4d51a5..b0377d9 100644
--- a/remoting/host/host_mock_objects.cc
+++ b/remoting/host/host_mock_objects.cc
@@ -6,7 +6,7 @@
namespace remoting {
-MockCapturer::MockCapturer() : Capturer(NULL) {}
+MockCapturer::MockCapturer() {}
MockCapturer::~MockCapturer() {}
diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h
index de1fe72..37a9b2d 100644
--- a/remoting/host/host_mock_objects.h
+++ b/remoting/host/host_mock_objects.h
@@ -17,14 +17,13 @@ class MockCapturer : public Capturer {
virtual ~MockCapturer();
MOCK_METHOD0(ScreenConfigurationChanged, void());
+ MOCK_CONST_METHOD0(pixel_format, media::VideoFrame::Format());
+ MOCK_METHOD0(ClearInvalidRects, void());
MOCK_METHOD1(InvalidateRects, void(const InvalidRects& inval_rects));
+ MOCK_METHOD1(InvalidateScreen, void(const gfx::Size&));
MOCK_METHOD0(InvalidateFullScreen, void());
- MOCK_METHOD0(CalculateInvalidRects, void());
MOCK_METHOD1(CaptureInvalidRects, void(CaptureCompletedCallback* callback));
- MOCK_METHOD2(CaptureRects, void(const InvalidRects& rects,
- CaptureCompletedCallback* callback));
- MOCK_CONST_METHOD0(width, int());
- MOCK_CONST_METHOD0(height, int());
+ MOCK_CONST_METHOD0(size_most_recent, const gfx::Size&());
private:
DISALLOW_COPY_AND_ASSIGN(MockCapturer);
diff --git a/remoting/host/screen_recorder_unittest.cc b/remoting/host/screen_recorder_unittest.cc
index 979e961..b5e8f8a 100644
--- a/remoting/host/screen_recorder_unittest.cc
+++ b/remoting/host/screen_recorder_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -115,11 +115,8 @@ TEST_F(ScreenRecorderTest, OneRecordCycle) {
planes.data[i] = reinterpret_cast<uint8*>(i);
planes.strides[i] = kWidth * 4;
}
- scoped_refptr<CaptureData> data(new CaptureData(planes,
- gfx::Size(kWidth, kHeight),
- kFormat));
- EXPECT_CALL(capturer_, width()).WillRepeatedly(Return(kWidth));
- EXPECT_CALL(capturer_, height()).WillRepeatedly(Return(kHeight));
+ gfx::Size size(kWidth, kHeight);
+ scoped_refptr<CaptureData> data(new CaptureData(planes, size, kFormat));
EXPECT_CALL(capturer_, InvalidateFullScreen());
// First the capturer is called.
@@ -167,11 +164,9 @@ TEST_F(ScreenRecorderTest, StartAndStop) {
planes.data[i] = reinterpret_cast<uint8*>(i);
planes.strides[i] = kWidth * 4;
}
- scoped_refptr<CaptureData> data(new CaptureData(planes,
- gfx::Size(kWidth, kHeight),
- kFormat));
- EXPECT_CALL(capturer_, width()).WillRepeatedly(Return(kWidth));
- EXPECT_CALL(capturer_, height()).WillRepeatedly(Return(kHeight));
+
+ gfx::Size size(kWidth, kHeight);
+ scoped_refptr<CaptureData> data(new CaptureData(planes, size, kFormat));
EXPECT_CALL(capturer_, InvalidateFullScreen());
// First the capturer is called.
diff --git a/remoting/host/simple_host_process.cc b/remoting/host/simple_host_process.cc
index aa8c1bc..e28c1c0 100644
--- a/remoting/host/simple_host_process.cc
+++ b/remoting/host/simple_host_process.cc
@@ -129,7 +129,7 @@ int main(int argc, char** argv) {
bool fake = cmd_line->HasSwitch(kFakeSwitchName);
if (fake) {
remoting::Capturer* capturer =
- new remoting::CapturerFake(context.main_message_loop());
+ new remoting::CapturerFake();
remoting::protocol::InputStub* input_stub =
CreateEventExecutor(context.ui_message_loop(), capturer);
host = ChromotingHost::Create(
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index c402b27..65eb195 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -199,8 +199,9 @@
'sources': [
'host/access_verifier.cc',
'host/access_verifier.h',
- 'host/capturer.cc',
'host/capturer.h',
+ 'host/capturer_helper.cc',
+ 'host/capturer_helper.h',
'host/capturer_fake.cc',
'host/capturer_fake.h',
'host/chromoting_host.cc',