summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/client_session_unittest.cc2
-rw-r--r--remoting/host/host_mock_objects.cc13
-rw-r--r--remoting/host/host_mock_objects.h34
-rw-r--r--remoting/host/video_frame_capturer.h47
-rw-r--r--remoting/host/video_frame_capturer_fake.cc8
-rw-r--r--remoting/host/video_frame_capturer_fake.h8
-rw-r--r--remoting/host/video_frame_capturer_linux.cc32
-rw-r--r--remoting/host/video_frame_capturer_mac.mm32
-rw-r--r--remoting/host/video_frame_capturer_mac_unittest.cc84
-rw-r--r--remoting/host/video_frame_capturer_unittest.cc26
-rw-r--r--remoting/host/video_frame_capturer_win.cc42
-rw-r--r--remoting/host/video_scheduler.cc70
-rw-r--r--remoting/host/video_scheduler.h17
-rw-r--r--remoting/host/video_scheduler_unittest.cc34
14 files changed, 211 insertions, 238 deletions
diff --git a/remoting/host/client_session_unittest.cc b/remoting/host/client_session_unittest.cc
index 0a7cf48..1d32056 100644
--- a/remoting/host/client_session_unittest.cc
+++ b/remoting/host/client_session_unittest.cc
@@ -101,7 +101,7 @@ class ClientSessionTest : public testing::Test {
EXPECT_CALL(*capturer, Start(_));
EXPECT_CALL(*capturer, Stop());
EXPECT_CALL(*capturer, InvalidateRegion(_)).Times(AnyNumber());
- EXPECT_CALL(*capturer, CaptureInvalidRegion(_)).Times(AnyNumber());
+ EXPECT_CALL(*capturer, CaptureInvalidRegion()).Times(AnyNumber());
EXPECT_CALL(*capturer, size_most_recent())
.WillRepeatedly(ReturnRef(screen_size_));
diff --git a/remoting/host/host_mock_objects.cc b/remoting/host/host_mock_objects.cc
index 3f5cfee..952699b 100644
--- a/remoting/host/host_mock_objects.cc
+++ b/remoting/host/host_mock_objects.cc
@@ -17,13 +17,16 @@ MockVideoFrameCapturer::MockVideoFrameCapturer() {}
MockVideoFrameCapturer::~MockVideoFrameCapturer() {}
-MockCaptureCompletedCallback::MockCaptureCompletedCallback() {}
+MockVideoFrameCapturerDelegate::MockVideoFrameCapturerDelegate() {
+}
-MockCaptureCompletedCallback::~MockCaptureCompletedCallback() {}
+MockVideoFrameCapturerDelegate::~MockVideoFrameCapturerDelegate() {
+}
-void MockCaptureCompletedCallback::CaptureCompleted(
- scoped_refptr<CaptureData> capture_data) {
- CaptureCompletedPtr(capture_data.get());
+void MockVideoFrameCapturerDelegate::OnCursorShapeChanged(
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
+ // Notify the mock method.
+ OnCursorShapeChangedPtr(cursor_shape.get());
}
MockDesktopEnvironmentFactory::MockDesktopEnvironmentFactory()
diff --git a/remoting/host/host_mock_objects.h b/remoting/host/host_mock_objects.h
index d5ebcdb..4eaee55 100644
--- a/remoting/host/host_mock_objects.h
+++ b/remoting/host/host_mock_objects.h
@@ -6,6 +6,7 @@
#define REMOTING_HOST_HOST_MOCK_OBJECTS_H_
#include "net/base/ip_endpoint.h"
+#include "remoting/base/capture_data.h"
#include "remoting/host/video_frame_capturer.h"
#include "remoting/host/chromoting_host_context.h"
#include "remoting/host/client_session.h"
@@ -17,39 +18,42 @@
#include "remoting/host/host_status_observer.h"
#include "remoting/host/local_input_monitor.h"
#include "remoting/host/user_authenticator.h"
+#include "remoting/proto/control.pb.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace remoting {
-class MockCaptureCompletedCallback {
- public:
- MockCaptureCompletedCallback();
- virtual ~MockCaptureCompletedCallback();
-
- MOCK_METHOD1(CaptureCompletedPtr, void(CaptureData* capture_data));
- void CaptureCompleted(scoped_refptr<CaptureData> capture_data);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockCaptureCompletedCallback);
-};
-
class MockVideoFrameCapturer : public VideoFrameCapturer {
public:
MockVideoFrameCapturer();
virtual ~MockVideoFrameCapturer();
- MOCK_METHOD1(Start, void(const CursorShapeChangedCallback& callback));
+ MOCK_METHOD1(Start, void(Delegate* delegate));
MOCK_METHOD0(Stop, void());
MOCK_CONST_METHOD0(pixel_format, media::VideoFrame::Format());
MOCK_METHOD1(InvalidateRegion, void(const SkRegion& invalid_region));
- MOCK_METHOD1(CaptureInvalidRegion,
- void(const CaptureCompletedCallback& callback));
+ MOCK_METHOD0(CaptureInvalidRegion, void());
MOCK_CONST_METHOD0(size_most_recent, const SkISize&());
private:
DISALLOW_COPY_AND_ASSIGN(MockVideoFrameCapturer);
};
+class MockVideoFrameCapturerDelegate : public VideoFrameCapturer::Delegate {
+ public:
+ MockVideoFrameCapturerDelegate();
+ virtual ~MockVideoFrameCapturerDelegate();
+
+ virtual void OnCursorShapeChanged(
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) OVERRIDE;
+
+ MOCK_METHOD1(OnCaptureCompleted, void(scoped_refptr<CaptureData>));
+ MOCK_METHOD1(OnCursorShapeChangedPtr, void(protocol::CursorShapeInfo*));
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockVideoFrameCapturerDelegate);
+};
+
class MockDisconnectWindow : public DisconnectWindow {
public:
MockDisconnectWindow();
diff --git a/remoting/host/video_frame_capturer.h b/remoting/host/video_frame_capturer.h
index e2db2b9..7cc863e 100644
--- a/remoting/host/video_frame_capturer.h
+++ b/remoting/host/video_frame_capturer.h
@@ -50,13 +50,21 @@ class CaptureData;
// Since data can be read while another capture action is happening.
class VideoFrameCapturer {
public:
- // CaptureCompletedCallback is called when the capturer has completed.
- typedef base::Callback<void(scoped_refptr<CaptureData>)>
- CaptureCompletedCallback;
-
- // CursorShapeChangedCallback is called when the cursor shape has changed.
- typedef base::Callback<void(scoped_ptr<protocol::CursorShapeInfo>)>
- CursorShapeChangedCallback;
+ // Provides callbacks used by the capturer to pass captured video frames and
+ // mouse cursor shapes to the processing pipeline.
+ class Delegate {
+ public:
+ virtual ~Delegate() {}
+
+ // Called when the capturer has completed. |capture_data| describes
+ // a captured frame.
+ virtual void OnCaptureCompleted(
+ scoped_refptr<CaptureData> capture_data) = 0;
+
+ // Called when the cursor shape has changed.
+ virtual void OnCursorShapeChanged(
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) = 0;
+ };
virtual ~VideoFrameCapturer() {}
@@ -78,30 +86,27 @@ class VideoFrameCapturer {
static void EnableXDamage(bool enable);
#endif // defined(OS_LINUX)
- // Called at the beginning of a capturing session.
- virtual void Start(
- const CursorShapeChangedCallback& callback) = 0;
+ // Called at the beginning of a capturing session. |delegate| must remain
+ // valid until Stop() is called.
+ virtual void Start(Delegate* delegate) = 0;
// Called at the end of a capturing session.
virtual void Stop() = 0;
- // Return the pixel format of the screen.
+ // Returns the pixel format of the screen.
virtual media::VideoFrame::Format pixel_format() const = 0;
- // Invalidate the specified region.
+ // Invalidates the specified region.
virtual void InvalidateRegion(const SkRegion& invalid_region) = 0;
- // Capture the screen data associated with each of the accumulated
- // dirty region.
- // When the capture is complete, |callback| is called even if the dirty region
- // is empty.
+ // Captures the screen data associated with each of the accumulated
+ // dirty region. When the capture is complete, the delegate is notified even
+ // if the dirty region is empty.
//
// It is OK to call this method while another thread is reading
- // data of the previous capture.
- // There can be at most one concurrent read going on when this
- // method is called.
- virtual void CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) = 0;
+ // data of the previous capture. There can be at most one concurrent read
+ // going on when this method is called.
+ virtual void CaptureInvalidRegion() = 0;
// Get the size of the most recently captured screen.
virtual const SkISize& size_most_recent() const = 0;
diff --git a/remoting/host/video_frame_capturer_fake.cc b/remoting/host/video_frame_capturer_fake.cc
index aff8f3e..6d34fa2 100644
--- a/remoting/host/video_frame_capturer_fake.cc
+++ b/remoting/host/video_frame_capturer_fake.cc
@@ -39,7 +39,8 @@ VideoFrameCapturerFake::VideoFrameCapturerFake()
VideoFrameCapturerFake::~VideoFrameCapturerFake() {
}
-void VideoFrameCapturerFake::Start(const CursorShapeChangedCallback& callback) {
+void VideoFrameCapturerFake::Start(Delegate* delegate) {
+ delegate_ = delegate;
}
void VideoFrameCapturerFake::Stop() {
@@ -53,8 +54,7 @@ void VideoFrameCapturerFake::InvalidateRegion(const SkRegion& invalid_region) {
helper_.InvalidateRegion(invalid_region);
}
-void VideoFrameCapturerFake::CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) {
+void VideoFrameCapturerFake::CaptureInvalidRegion() {
GenerateImage();
helper_.InvalidateScreen(size_);
@@ -73,7 +73,7 @@ void VideoFrameCapturerFake::CaptureInvalidRegion(
helper_.set_size_most_recent(capture_data->size());
- callback.Run(capture_data);
+ delegate_->OnCaptureCompleted(capture_data);
}
const SkISize& VideoFrameCapturerFake::size_most_recent() const {
diff --git a/remoting/host/video_frame_capturer_fake.h b/remoting/host/video_frame_capturer_fake.h
index ac4b19a..5cb7d53 100644
--- a/remoting/host/video_frame_capturer_fake.h
+++ b/remoting/host/video_frame_capturer_fake.h
@@ -21,13 +21,11 @@ class VideoFrameCapturerFake : public VideoFrameCapturer {
virtual ~VideoFrameCapturerFake();
// Overridden from VideoFrameCapturer:
- virtual void Start(
- const CursorShapeChangedCallback& callback) OVERRIDE;
+ virtual void Start(Delegate* delegate) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
- virtual void CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) OVERRIDE;
+ virtual void CaptureInvalidRegion() OVERRIDE;
virtual const SkISize& size_most_recent() const OVERRIDE;
private:
@@ -37,6 +35,8 @@ class VideoFrameCapturerFake : public VideoFrameCapturer {
// Called when the screen configuration is changed.
void ScreenConfigurationChanged();
+ Delegate* delegate_;
+
SkISize size_;
int bytes_per_row_;
int box_pos_x_;
diff --git a/remoting/host/video_frame_capturer_linux.cc b/remoting/host/video_frame_capturer_linux.cc
index c472f49..522eac7 100644
--- a/remoting/host/video_frame_capturer_linux.cc
+++ b/remoting/host/video_frame_capturer_linux.cc
@@ -83,12 +83,11 @@ class VideoFrameCapturerLinux : public VideoFrameCapturer {
bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
// Capturer interface.
- virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE;
+ virtual void Start(Delegate* delegate) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
- virtual void CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) OVERRIDE;
+ virtual void CaptureInvalidRegion() OVERRIDE;
virtual const SkISize& size_most_recent() const OVERRIDE;
private:
@@ -110,8 +109,7 @@ class VideoFrameCapturerLinux : public VideoFrameCapturer {
// previous capture.
CaptureData* CaptureFrame();
- // Capture the cursor image and call the CursorShapeChangedCallback if it
- // has been set (using SetCursorShapeChangedCallback).
+ // Capture the cursor image and notify the delegate if it was captured.
void CaptureCursor();
// Called when the screen configuration is changed.
@@ -135,6 +133,8 @@ class VideoFrameCapturerLinux : public VideoFrameCapturer {
void FastBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data);
void SlowBlit(uint8* image, const SkIRect& rect, CaptureData* capture_data);
+ Delegate* delegate_;
+
// X11 graphics context.
Display* display_;
GC gc_;
@@ -159,9 +159,6 @@ class VideoFrameCapturerLinux : public VideoFrameCapturer {
// recently captured screen.
VideoFrameCapturerHelper helper_;
- // Callback notified whenever the cursor shape is changed.
- CursorShapeChangedCallback cursor_shape_changed_callback_;
-
// Capture state.
static const int kNumBuffers = 2;
VideoFrameBuffer buffers_[kNumBuffers];
@@ -184,7 +181,8 @@ class VideoFrameCapturerLinux : public VideoFrameCapturer {
};
VideoFrameCapturerLinux::VideoFrameCapturerLinux()
- : display_(NULL),
+ : delegate_(NULL),
+ display_(NULL),
gc_(NULL),
root_window_(BadValue),
has_xfixes_(false),
@@ -293,9 +291,10 @@ void VideoFrameCapturerLinux::InitXDamage() {
LOG(INFO) << "Using XDamage extension.";
}
-void VideoFrameCapturerLinux::Start(
- const CursorShapeChangedCallback& callback) {
- cursor_shape_changed_callback_ = callback;
+void VideoFrameCapturerLinux::Start(Delegate* delegate) {
+ DCHECK(delegate_ == NULL);
+
+ delegate_ = delegate;
}
void VideoFrameCapturerLinux::Stop() {
@@ -309,8 +308,7 @@ void VideoFrameCapturerLinux::InvalidateRegion(const SkRegion& invalid_region) {
helper_.InvalidateRegion(invalid_region);
}
-void VideoFrameCapturerLinux::CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) {
+void VideoFrameCapturerLinux::CaptureInvalidRegion() {
// Process XEvents for XDamage and cursor shape tracking.
ProcessPendingXEvents();
@@ -337,7 +335,7 @@ void VideoFrameCapturerLinux::CaptureInvalidRegion(
last_buffer_ = current_buffer_;
current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
- callback.Run(capture_data);
+ delegate_->OnCaptureCompleted(capture_data);
}
void VideoFrameCapturerLinux::ProcessPendingXEvents() {
@@ -368,8 +366,6 @@ void VideoFrameCapturerLinux::ProcessPendingXEvents() {
void VideoFrameCapturerLinux::CaptureCursor() {
DCHECK(has_xfixes_);
- if (cursor_shape_changed_callback_.is_null())
- return;
XFixesCursorImage* img = XFixesGetCursorImage(display_);
if (!img) {
@@ -400,7 +396,7 @@ void VideoFrameCapturerLinux::CaptureCursor() {
}
XFree(img);
- cursor_shape_changed_callback_.Run(cursor_proto.Pass());
+ delegate_->OnCursorShapeChanged(cursor_proto.Pass());
}
CaptureData* VideoFrameCapturerLinux::CaptureFrame() {
diff --git a/remoting/host/video_frame_capturer_mac.mm b/remoting/host/video_frame_capturer_mac.mm
index ca85c0d..456b01f 100644
--- a/remoting/host/video_frame_capturer_mac.mm
+++ b/remoting/host/video_frame_capturer_mac.mm
@@ -113,12 +113,11 @@ class VideoFrameCapturerMac : public VideoFrameCapturer {
bool Init();
// Overridden from VideoFrameCapturer:
- virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE;
+ virtual void Start(Delegate* delegate) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
- virtual void CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) OVERRIDE;
+ virtual void CaptureInvalidRegion() OVERRIDE;
virtual const SkISize& size_most_recent() const OVERRIDE;
private:
@@ -128,8 +127,6 @@ class VideoFrameCapturerMac : public VideoFrameCapturer {
void GlBlitSlow(const VideoFrameBuffer& buffer);
void CgBlitPreLion(const VideoFrameBuffer& buffer, const SkRegion& region);
void CgBlitPostLion(const VideoFrameBuffer& buffer, const SkRegion& region);
- void CaptureRegion(const SkRegion& region,
- const CaptureCompletedCallback& callback);
// Called when the screen configuration is changed.
void ScreenConfigurationChanged();
@@ -153,6 +150,8 @@ class VideoFrameCapturerMac : public VideoFrameCapturer {
void ReleaseBuffers();
+ Delegate* delegate_;
+
CGLContextObj cgl_context_;
static const int kNumBuffers = 2;
ScopedPixelBufferObject pixel_buffer_object_;
@@ -166,9 +165,6 @@ class VideoFrameCapturerMac : public VideoFrameCapturer {
// recently captured screen.
VideoFrameCapturerHelper helper_;
- // Callback notified whenever the cursor shape is changed.
- CursorShapeChangedCallback cursor_shape_changed_callback_;
-
// Image of the last cursor that we sent to the client.
base::mac::ScopedCFTypeRef<CGImageRef> current_cursor_;
@@ -207,7 +203,8 @@ class VideoFrameCapturerMac : public VideoFrameCapturer {
};
VideoFrameCapturerMac::VideoFrameCapturerMac()
- : cgl_context_(NULL),
+ : delegate_(NULL),
+ cgl_context_(NULL),
current_buffer_(0),
last_buffer_(NULL),
pixel_format_(media::VideoFrame::RGB32),
@@ -273,8 +270,10 @@ void VideoFrameCapturerMac::ReleaseBuffers() {
}
}
-void VideoFrameCapturerMac::Start(const CursorShapeChangedCallback& callback) {
- cursor_shape_changed_callback_ = callback;
+void VideoFrameCapturerMac::Start(Delegate* delegate) {
+ DCHECK(delegate_ == NULL);
+
+ delegate_ = delegate;
// Create power management assertions to wake the display and prevent it from
// going to sleep on user idle.
@@ -311,8 +310,7 @@ void VideoFrameCapturerMac::InvalidateRegion(const SkRegion& invalid_region) {
helper_.InvalidateRegion(invalid_region);
}
-void VideoFrameCapturerMac::CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) {
+void VideoFrameCapturerMac::CaptureInvalidRegion() {
// Only allow captures when the display configuration is not occurring.
scoped_refptr<CaptureData> data;
@@ -362,14 +360,10 @@ void VideoFrameCapturerMac::CaptureInvalidRegion(
CaptureCursor();
- callback.Run(data);
+ delegate_->OnCaptureCompleted(data);
}
void VideoFrameCapturerMac::CaptureCursor() {
- if (cursor_shape_changed_callback_.is_null()) {
- return;
- }
-
NSCursor* cursor = [NSCursor currentSystemCursor];
if (cursor == nil) {
return;
@@ -445,7 +439,7 @@ void VideoFrameCapturerMac::CaptureCursor() {
cursor_proto->set_height(size.height);
cursor_proto->set_hotspot_x(hotspot.x);
cursor_proto->set_hotspot_y(hotspot.y);
- cursor_shape_changed_callback_.Run(cursor_proto.Pass());
+ delegate_->OnCursorShapeChanged(cursor_proto.Pass());
// Record the last cursor image that we sent.
current_cursor_.reset(CGImageCreateCopy(image));
diff --git a/remoting/host/video_frame_capturer_mac_unittest.cc b/remoting/host/video_frame_capturer_mac_unittest.cc
index 0bd3e11..ced13dc 100644
--- a/remoting/host/video_frame_capturer_mac_unittest.cc
+++ b/remoting/host/video_frame_capturer_mac_unittest.cc
@@ -12,9 +12,13 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "remoting/base/capture_data.h"
+#include "remoting/host/host_mock_objects.h"
#include "remoting/proto/control.pb.h"
#include "testing/gtest/include/gtest/gtest.h"
+using ::testing::_;
+using ::testing::AnyNumber;
+
namespace remoting {
// Verify that the OS is at least Snow Leopard (10.6).
@@ -27,6 +31,14 @@ bool CheckSnowLeopard() {
}
class VideoFrameCapturerMacTest : public testing::Test {
+ public:
+ // Verifies that the whole screen is initially dirty.
+ void CaptureDoneCallback1(scoped_refptr<CaptureData> capture_data);
+
+ // Verifies that a rectangle explicitly marked as dirty is propagated
+ // correctly.
+ void CaptureDoneCallback2(scoped_refptr<CaptureData> capture_data);
+
protected:
virtual void SetUp() OVERRIDE {
capturer_.reset(VideoFrameCapturer::Create());
@@ -38,21 +50,11 @@ class VideoFrameCapturerMacTest : public testing::Test {
}
scoped_ptr<VideoFrameCapturer> capturer_;
+ MockVideoFrameCapturerDelegate delegate_;
SkRegion region_;
};
-// CapturerCallback1 verifies that the whole screen is initially dirty.
-class VideoFrameCapturerCallback1 {
- public:
- VideoFrameCapturerCallback1() {}
-
- void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerCallback1);
-};
-
-void VideoFrameCapturerCallback1::CaptureDoneCallback(
+void VideoFrameCapturerMacTest::CaptureDoneCallback1(
scoped_refptr<CaptureData> capture_data) {
CGDirectDisplayID mainDevice = CGMainDisplayID();
int width = CGDisplayPixelsWide(mainDevice);
@@ -61,29 +63,13 @@ void VideoFrameCapturerCallback1::CaptureDoneCallback(
EXPECT_EQ(initial_region, capture_data->dirty_region());
}
-// VideoFrameCapturerCallback2 verifies that a rectangle explicitly marked as
-// dirty is propagated correctly.
-class VideoFrameCapturerCallback2 {
- public:
- explicit VideoFrameCapturerCallback2(const SkRegion& expected_dirty_region)
- : expected_dirty_region_(expected_dirty_region) {}
-
- void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data);
-
- protected:
- SkRegion expected_dirty_region_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerCallback2);
-};
-
-void VideoFrameCapturerCallback2::CaptureDoneCallback(
+void VideoFrameCapturerMacTest::CaptureDoneCallback2(
scoped_refptr<CaptureData> capture_data) {
CGDirectDisplayID mainDevice = CGMainDisplayID();
int width = CGDisplayPixelsWide(mainDevice);
int height = CGDisplayPixelsHigh(mainDevice);
- EXPECT_EQ(expected_dirty_region_, capture_data->dirty_region());
+ EXPECT_EQ(region_, capture_data->dirty_region());
EXPECT_EQ(width, capture_data->size().width());
EXPECT_EQ(height, capture_data->size().height());
const DataPlanes &planes = capture_data->data_planes();
@@ -98,42 +84,28 @@ void VideoFrameCapturerCallback2::CaptureDoneCallback(
EXPECT_EQ(0, planes.strides[2]);
}
-class CursorCallback {
- public:
- CursorCallback() {}
-
- void CursorShapeChangedCallback(
- scoped_ptr<protocol::CursorShapeInfo> cursor_data);
-
- private:
- DISALLOW_COPY_AND_ASSIGN(CursorCallback);
-};
-
-void CursorCallback::CursorShapeChangedCallback(
- scoped_ptr<protocol::CursorShapeInfo> cursor_data) {
-}
-
TEST_F(VideoFrameCapturerMacTest, Capture) {
if (!CheckSnowLeopard()) {
return;
}
+ EXPECT_CALL(delegate_, OnCaptureCompleted(_))
+ .Times(2)
+ .WillOnce(Invoke(this, &VideoFrameCapturerMacTest::CaptureDoneCallback1))
+ .WillOnce(Invoke(this, &VideoFrameCapturerMacTest::CaptureDoneCallback2));
+ EXPECT_CALL(delegate_, OnCursorShapeChangedPtr(_))
+ .Times(AnyNumber());
+
SCOPED_TRACE("");
- CursorCallback cursor_callback;
- capturer_->Start(base::Bind(&CursorCallback::CursorShapeChangedCallback,
- base::Unretained(&cursor_callback)));
+ capturer_->Start(&delegate_);
+
// Check that we get an initial full-screen updated.
- VideoFrameCapturerCallback1 callback1;
- capturer_->CaptureInvalidRegion(base::Bind(
- &VideoFrameCapturerCallback1::CaptureDoneCallback,
- base::Unretained(&callback1)));
+ capturer_->CaptureInvalidRegion();
+
// Check that subsequent dirty rects are propagated correctly.
AddDirtyRect();
- VideoFrameCapturerCallback2 callback2(region_);
capturer_->InvalidateRegion(region_);
- capturer_->CaptureInvalidRegion(base::Bind(
- &VideoFrameCapturerCallback2::CaptureDoneCallback,
- base::Unretained(&callback2)));
+ capturer_->CaptureInvalidRegion();
capturer_->Stop();
}
diff --git a/remoting/host/video_frame_capturer_unittest.cc b/remoting/host/video_frame_capturer_unittest.cc
index 4ad0a1b..0b10161 100644
--- a/remoting/host/video_frame_capturer_unittest.cc
+++ b/remoting/host/video_frame_capturer_unittest.cc
@@ -14,14 +14,10 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-namespace remoting {
-
-namespace {
+using ::testing::_;
+using ::testing::AnyNumber;
-void IgnoreCursorShapeChanged(scoped_ptr<protocol::CursorShapeInfo> info) {
-}
-
-} // namespace
+namespace remoting {
MATCHER(DirtyRegionIsNonEmptyRect, "") {
const SkRegion& dirty_region = arg->dirty_region();
@@ -39,23 +35,23 @@ class VideoFrameCapturerTest : public testing::Test {
}
scoped_ptr<VideoFrameCapturer> capturer_;
- MockCaptureCompletedCallback capture_completed_callback_;
+ MockVideoFrameCapturerDelegate delegate_;
};
TEST_F(VideoFrameCapturerTest, StartCapturer) {
- capturer_->Start(base::Bind(&IgnoreCursorShapeChanged));
+ capturer_->Start(&delegate_);
capturer_->Stop();
}
TEST_F(VideoFrameCapturerTest, Capture) {
// Assume that Start() treats the screen as invalid initially.
- EXPECT_CALL(capture_completed_callback_,
- CaptureCompletedPtr(DirtyRegionIsNonEmptyRect()));
+ EXPECT_CALL(delegate_,
+ OnCaptureCompleted(DirtyRegionIsNonEmptyRect()));
+ EXPECT_CALL(delegate_, OnCursorShapeChangedPtr(_))
+ .Times(AnyNumber());
- capturer_->Start(base::Bind(&IgnoreCursorShapeChanged));
- capturer_->CaptureInvalidRegion(base::Bind(
- &MockCaptureCompletedCallback::CaptureCompleted,
- base::Unretained(&capture_completed_callback_)));
+ capturer_->Start(&delegate_);
+ capturer_->CaptureInvalidRegion();
capturer_->Stop();
}
diff --git a/remoting/host/video_frame_capturer_win.cc b/remoting/host/video_frame_capturer_win.cc
index 3f40592..8d33620 100644
--- a/remoting/host/video_frame_capturer_win.cc
+++ b/remoting/host/video_frame_capturer_win.cc
@@ -48,12 +48,11 @@ class VideoFrameCapturerWin : public VideoFrameCapturer {
virtual ~VideoFrameCapturerWin();
// Overridden from VideoFrameCapturer:
- virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE;
+ virtual void Start(Delegate* delegate) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
- virtual void CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) OVERRIDE;
+ virtual void CaptureInvalidRegion() OVERRIDE;
virtual const SkISize& size_most_recent() const OVERRIDE;
private:
@@ -79,10 +78,9 @@ class VideoFrameCapturerWin : public VideoFrameCapturer {
// contents reported to the caller, to determine the dirty region.
void CalculateInvalidRegion();
- // Creates a CaptureData instance wrapping the current framebuffer and calls
- // |callback| with it.
- void CaptureRegion(const SkRegion& region,
- const CaptureCompletedCallback& callback);
+ // Creates a CaptureData instance wrapping the current framebuffer and
+ // notifies |delegate_|.
+ void CaptureRegion(const SkRegion& region);
// Captures the current screen contents into the next available framebuffer.
void CaptureImage();
@@ -94,13 +92,12 @@ class VideoFrameCapturerWin : public VideoFrameCapturer {
// Capture the current cursor shape.
void CaptureCursor();
+ Delegate* delegate_;
+
// A thread-safe list of invalid rectangles, and the size of the most
// recently captured screen.
VideoFrameCapturerHelper helper_;
- // Callback notified whenever the cursor shape is changed.
- CursorShapeChangedCallback cursor_shape_changed_callback_;
-
// Snapshot of the last cursor bitmap we sent to the client. This is used
// to diff against the current cursor so we only send a cursor-change
// message when the shape has changed.
@@ -151,7 +148,8 @@ VideoFrameCapturerWin::VideoFrameBuffer::VideoFrameBuffer()
}
VideoFrameCapturerWin::VideoFrameCapturerWin()
- : last_cursor_size_(SkISize::Make(0, 0)),
+ : delegate_(NULL),
+ last_cursor_size_(SkISize::Make(0, 0)),
desktop_dc_rect_(SkIRect::MakeEmpty()),
resource_generation_(0),
current_buffer_(0),
@@ -170,8 +168,7 @@ void VideoFrameCapturerWin::InvalidateRegion(const SkRegion& invalid_region) {
helper_.InvalidateRegion(invalid_region);
}
-void VideoFrameCapturerWin::CaptureInvalidRegion(
- const CaptureCompletedCallback& callback) {
+void VideoFrameCapturerWin::CaptureInvalidRegion() {
// Force the system to power-up display hardware, if it has been suspended.
SetThreadExecutionState(ES_DISPLAY_REQUIRED);
@@ -179,7 +176,7 @@ void VideoFrameCapturerWin::CaptureInvalidRegion(
CalculateInvalidRegion();
SkRegion invalid_region;
helper_.SwapInvalidRegion(&invalid_region);
- CaptureRegion(invalid_region, callback);
+ CaptureRegion(invalid_region);
// Check for cursor shape update.
CaptureCursor();
@@ -189,9 +186,10 @@ const SkISize& VideoFrameCapturerWin::size_most_recent() const {
return helper_.size_most_recent();
}
-void VideoFrameCapturerWin::Start(
- const CursorShapeChangedCallback& callback) {
- cursor_shape_changed_callback_ = callback;
+void VideoFrameCapturerWin::Start(Delegate* delegate) {
+ DCHECK(delegate_ == NULL);
+
+ delegate_ = delegate;
// Load dwmapi.dll dynamically since it is not available on XP.
if (!dwmapi_library_.is_valid()) {
@@ -217,6 +215,8 @@ void VideoFrameCapturerWin::Stop() {
if (composition_func_ != NULL) {
(*composition_func_)(DWM_EC_ENABLECOMPOSITION);
}
+
+ delegate_ = NULL;
}
void VideoFrameCapturerWin::PrepareCaptureResources() {
@@ -347,9 +347,7 @@ void VideoFrameCapturerWin::CalculateInvalidRegion() {
InvalidateRegion(region);
}
-void VideoFrameCapturerWin::CaptureRegion(
- const SkRegion& region,
- const CaptureCompletedCallback& callback) {
+void VideoFrameCapturerWin::CaptureRegion(const SkRegion& region) {
const VideoFrameBuffer& buffer = buffers_[current_buffer_];
current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
@@ -364,7 +362,7 @@ void VideoFrameCapturerWin::CaptureRegion(
helper_.set_size_most_recent(data->size());
- callback.Run(data);
+ delegate_->OnCaptureCompleted(data);
}
void VideoFrameCapturerWin::CaptureImage() {
@@ -561,7 +559,7 @@ void VideoFrameCapturerWin::CaptureCursor() {
memcpy(last_cursor_.get(), cursor_dst_data, data_size);
last_cursor_size_ = SkISize::Make(width, height);
- cursor_shape_changed_callback_.Run(cursor_proto.Pass());
+ delegate_->OnCursorShapeChanged(cursor_proto.Pass());
}
} // namespace
diff --git a/remoting/host/video_scheduler.cc b/remoting/host/video_scheduler.cc
index ded48dc..6c1d30d 100644
--- a/remoting/host/video_scheduler.cc
+++ b/remoting/host/video_scheduler.cc
@@ -60,6 +60,38 @@ VideoScheduler::VideoScheduler(
// Public methods --------------------------------------------------------------
+void VideoScheduler::OnCaptureCompleted(
+ scoped_refptr<CaptureData> capture_data) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+ if (capture_data) {
+ base::TimeDelta capture_time = base::Time::Now() - capture_start_time_;
+ int capture_time_ms =
+ static_cast<int>(capture_time.InMilliseconds());
+ capture_data->set_capture_time_ms(capture_time_ms);
+ scheduler_.RecordCaptureTime(capture_time);
+
+ // The best way to get this value is by binding the sequence number to
+ // the callback when calling CaptureInvalidRects(). However the callback
+ // system doesn't allow this. Reading from the member variable is
+ // accurate as long as capture is synchronous as the following statement
+ // will obtain the most recent sequence number received.
+ capture_data->set_client_sequence_number(sequence_number_);
+ }
+
+ encode_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this, capture_data));
+}
+
+void VideoScheduler::OnCursorShapeChanged(
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
+ DCHECK(capture_task_runner_->BelongsToCurrentThread());
+
+ network_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this,
+ base::Passed(&cursor_shape)));
+}
+
void VideoScheduler::Stop(const base::Closure& done_task) {
DCHECK(network_task_runner_->BelongsToCurrentThread());
DCHECK(!done_task.is_null());
@@ -112,8 +144,7 @@ void VideoScheduler::StartOnCaptureThread() {
DCHECK(capture_task_runner_->BelongsToCurrentThread());
// Start the capturer and let it notify us of cursor shape changes.
- capturer_->Start(
- base::Bind(&VideoScheduler::CursorShapeChangedCallback, this));
+ capturer_->Start(this);
capture_timer_.reset(new base::OneShotTimer<VideoScheduler>());
@@ -171,40 +202,7 @@ void VideoScheduler::CaptureNextFrame() {
// And finally perform one capture.
capture_start_time_ = base::Time::Now();
- capturer_->CaptureInvalidRegion(
- base::Bind(&VideoScheduler::CaptureDoneCallback, this));
-}
-
-void VideoScheduler::CaptureDoneCallback(
- scoped_refptr<CaptureData> capture_data) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
- if (capture_data) {
- base::TimeDelta capture_time = base::Time::Now() - capture_start_time_;
- int capture_time_ms =
- static_cast<int>(capture_time.InMilliseconds());
- capture_data->set_capture_time_ms(capture_time_ms);
- scheduler_.RecordCaptureTime(capture_time);
-
- // The best way to get this value is by binding the sequence number to
- // the callback when calling CaptureInvalidRects(). However the callback
- // system doesn't allow this. Reading from the member variable is
- // accurate as long as capture is synchronous as the following statement
- // will obtain the most recent sequence number received.
- capture_data->set_client_sequence_number(sequence_number_);
- }
-
- encode_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoScheduler::EncodeFrame, this, capture_data));
-}
-
-void VideoScheduler::CursorShapeChangedCallback(
- scoped_ptr<protocol::CursorShapeInfo> cursor_shape) {
- DCHECK(capture_task_runner_->BelongsToCurrentThread());
-
- network_task_runner_->PostTask(
- FROM_HERE, base::Bind(&VideoScheduler::SendCursorShape, this,
- base::Passed(&cursor_shape)));
+ capturer_->CaptureInvalidRegion();
}
void VideoScheduler::FrameCaptureCompleted() {
diff --git a/remoting/host/video_scheduler.h b/remoting/host/video_scheduler.h
index 92cc1bd..98c4d41 100644
--- a/remoting/host/video_scheduler.h
+++ b/remoting/host/video_scheduler.h
@@ -15,6 +15,7 @@
#include "base/timer.h"
#include "remoting/codec/video_encoder.h"
#include "remoting/host/capture_scheduler.h"
+#include "remoting/host/video_frame_capturer.h"
#include "remoting/proto/video.pb.h"
namespace base {
@@ -68,7 +69,8 @@ class VideoStub;
// rate-limit captures to avoid overloading the host system, either by consuming
// too much CPU, or hogging the host's graphics subsystem.
-class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler> {
+class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler>,
+ public VideoFrameCapturer::Delegate {
public:
// Creates a VideoScheduler running capture, encode and network tasks on the
// supplied TaskRunners. Video and cursor shape updates will be pumped to
@@ -84,6 +86,12 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler> {
protocol::ClientStub* client_stub,
protocol::VideoStub* video_stub);
+ // VideoFrameCapturer::Delegate implementation
+ virtual void OnCaptureCompleted(
+ scoped_refptr<CaptureData> capture_data) OVERRIDE;
+ virtual void OnCursorShapeChanged(
+ scoped_ptr<protocol::CursorShapeInfo> cursor_shape) OVERRIDE;
+
// Stop scheduling frame captures. |done_task| is executed on the network
// thread when capturing has stopped. This object cannot be re-used once
// it has been stopped.
@@ -116,13 +124,6 @@ class VideoScheduler : public base::RefCountedThreadSafe<VideoScheduler> {
// Starts the next frame capture, unless there are already too many pending.
void CaptureNextFrame();
- // Called when a frame capture completes.
- void CaptureDoneCallback(scoped_refptr<CaptureData> capture_data);
-
- // Called when the cursor shape changes.
- void CursorShapeChangedCallback(
- scoped_ptr<protocol::CursorShapeInfo> cursor_data);
-
// Called when a frame capture has been encoded & sent to the client.
void FrameCaptureCompleted();
diff --git a/remoting/host/video_scheduler_unittest.cc b/remoting/host/video_scheduler_unittest.cc
index 54b572c..8ca7d7a 100644
--- a/remoting/host/video_scheduler_unittest.cc
+++ b/remoting/host/video_scheduler_unittest.cc
@@ -34,12 +34,6 @@ namespace remoting {
namespace {
-ACTION_P2(RunCallback, region, data) {
- SkRegion& dirty_region = data->mutable_dirty_region();
- dirty_region.op(region, SkRegion::kUnion_Op);
- arg0.Run(data);
-}
-
ACTION(FinishEncode) {
scoped_ptr<VideoPacket> packet(new VideoPacket());
packet->set_flags(VideoPacket::LAST_PACKET | VideoPacket::LAST_PARTITION);
@@ -82,7 +76,7 @@ MockVideoEncoder::~MockVideoEncoder() {}
class VideoSchedulerTest : public testing::Test {
public:
- VideoSchedulerTest() {
+ VideoSchedulerTest() : size_(SkISize::Make(0, 0)) {
}
virtual void SetUp() OVERRIDE {
@@ -100,6 +94,8 @@ class VideoSchedulerTest : public testing::Test {
&video_stub_);
}
+ void GenerateOnCaptureCompleted();
+
protected:
MessageLoop message_loop_;
scoped_refptr<VideoScheduler> scheduler_;
@@ -111,16 +107,25 @@ class VideoSchedulerTest : public testing::Test {
// The following mock objects are owned by VideoScheduler.
MockVideoEncoder* encoder_;
+ SkISize size_;
+ scoped_refptr<CaptureData> data_;
+
private:
DISALLOW_COPY_AND_ASSIGN(VideoSchedulerTest);
};
+void VideoSchedulerTest::GenerateOnCaptureCompleted() {
+ SkRegion update_region(SkIRect::MakeXYWH(0, 0, 10, 10));
+ data_->mutable_dirty_region().op(update_region, SkRegion::kUnion_Op);
+
+ scheduler_->OnCaptureCompleted(data_);
+}
+
// This test mocks capturer, encoder and network layer to simulate one capture
// cycle. When the first encoded packet is submitted to the network
// VideoScheduler is instructed to come to a complete stop. We expect the stop
// sequence to be executed successfully.
TEST_F(VideoSchedulerTest, StartAndStop) {
- SkRegion update_region(SkIRect::MakeXYWH(0, 0, 10, 10));
DataPlanes planes;
for (int i = 0; i < DataPlanes::kPlaneCount; ++i) {
planes.data[i] = reinterpret_cast<uint8*>(i);
@@ -129,22 +134,23 @@ TEST_F(VideoSchedulerTest, StartAndStop) {
Expectation capturer_start = EXPECT_CALL(capturer_, Start(_));
- SkISize size(SkISize::Make(kWidth, kHeight));
- scoped_refptr<CaptureData> data(new CaptureData(planes, size, kFormat));
+ size_.set(kWidth, kHeight);
+ data_ = new CaptureData(planes, size_, kFormat);
// Create a RunLoop through which to drive |message_loop_|.
base::RunLoop run_loop;
EXPECT_CALL(capturer_, size_most_recent())
- .WillRepeatedly(ReturnRef(size));
+ .WillRepeatedly(ReturnRef(size_));
// First the capturer is called.
- Expectation capturer_capture = EXPECT_CALL(capturer_, CaptureInvalidRegion(_))
+ Expectation capturer_capture = EXPECT_CALL(capturer_, CaptureInvalidRegion())
.After(capturer_start)
- .WillRepeatedly(RunCallback(update_region, data));
+ .WillRepeatedly(InvokeWithoutArgs(
+ this, &VideoSchedulerTest::GenerateOnCaptureCompleted));
// Expect the encoder be called.
- EXPECT_CALL(*encoder_, Encode(data, false, _))
+ EXPECT_CALL(*encoder_, Encode(data_, false, _))
.WillRepeatedly(FinishEncode());
// By default delete the arguments when ProcessVideoPacket is received.