Skip to content

Commit

Permalink
Add ShapedScreenCapturer
Browse files Browse the repository at this point in the history
ShapedScreenCapturer is a layer on top regular screen capturer that captures
desktop shape and attaches it to the generated frames.

R=wez@chromium.org

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=241614

Review URL: https://codereview.chromium.org/93973006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241692 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
sergeyu@chromium.org committed Dec 18, 2013
1 parent 80f8f84 commit ca743bf
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
56 changes: 56 additions & 0 deletions remoting/host/shaped_screen_capturer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright 2013 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/shaped_screen_capturer.h"

#include "remoting/host/desktop_shape_tracker.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_capture_options.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"

namespace remoting {

// static
scoped_ptr<ShapedScreenCapturer> ShapedScreenCapturer::Create(
webrtc::DesktopCaptureOptions options) {
return scoped_ptr<ShapedScreenCapturer>(
new ShapedScreenCapturer(scoped_ptr<webrtc::ScreenCapturer>(
webrtc::ScreenCapturer::Create(options)),
DesktopShapeTracker::Create(options)));
}

ShapedScreenCapturer::ShapedScreenCapturer(
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
scoped_ptr<DesktopShapeTracker> shape_tracker)
: screen_capturer_(screen_capturer.Pass()),
shape_tracker_(shape_tracker.Pass()),
callback_(NULL) {
}

ShapedScreenCapturer::~ShapedScreenCapturer() {}

void ShapedScreenCapturer::Start(webrtc::ScreenCapturer::Callback* callback) {
callback_ = callback;
screen_capturer_->Start(this);
}

void ShapedScreenCapturer::Capture(const webrtc::DesktopRegion& region) {
screen_capturer_->Capture(region);
}

void ShapedScreenCapturer::SetMouseShapeObserver(
MouseShapeObserver* mouse_shape_observer) {
screen_capturer_->SetMouseShapeObserver(mouse_shape_observer);
}

webrtc::SharedMemory* ShapedScreenCapturer::CreateSharedMemory(size_t size) {
return callback_->CreateSharedMemory(size);
}

void ShapedScreenCapturer::OnCaptureCompleted(webrtc::DesktopFrame* frame) {
shape_tracker_->RefreshDesktopShape();
frame->set_shape(new webrtc::DesktopRegion(shape_tracker_->desktop_shape()));
callback_->OnCaptureCompleted(frame);
}

} // namespace remoting
46 changes: 46 additions & 0 deletions remoting/host/shaped_screen_capturer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2013 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_SHAPED_SCREEN_CAPTURER_H_
#define REMOTING_HOST_SHAPED_SCREEN_CAPTURER_H_

#include "base/memory/scoped_ptr.h"
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"

namespace remoting {

class DesktopShapeTracker;

// Screen capturer that also captures desktop shape.
class ShapedScreenCapturer : public webrtc::ScreenCapturer,
public webrtc::DesktopCapturer::Callback {
public:
static scoped_ptr<ShapedScreenCapturer> Create(
webrtc::DesktopCaptureOptions options);

ShapedScreenCapturer(scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
scoped_ptr<DesktopShapeTracker> shape_tracker);
virtual ~ShapedScreenCapturer();

// webrtc::ScreenCapturer interface.
virtual void Start(webrtc::ScreenCapturer::Callback* callback) OVERRIDE;
virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE;
virtual void SetMouseShapeObserver(
MouseShapeObserver* mouse_shape_observer) OVERRIDE;

private:
// webrtc::ScreenCapturer::Callback interface.
virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE;

scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
scoped_ptr<DesktopShapeTracker> shape_tracker_;
webrtc::ScreenCapturer::Callback* callback_;

DISALLOW_COPY_AND_ASSIGN(ShapedScreenCapturer);
};

} // namespace remoting

#endif // REMOTING_HOST_SHAPED_SCREEN_CAPTURER_H_
95 changes: 95 additions & 0 deletions remoting/host/shaped_screen_capturer_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2013 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/shaped_screen_capturer.h"

#include "remoting/host/desktop_shape_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_region.h"

namespace remoting {

const int kScreenSize = 10;

class FakeScreenCapturer : public webrtc::ScreenCapturer {
public:
FakeScreenCapturer() {}
virtual ~FakeScreenCapturer() {}

virtual void Start(Callback* callback) OVERRIDE {
callback_ = callback;
}

virtual void Capture(const webrtc::DesktopRegion& region) OVERRIDE {
webrtc::DesktopFrame* frame = new webrtc::BasicDesktopFrame(
webrtc::DesktopSize(kScreenSize, kScreenSize));
memset(frame->data(), 0, frame->stride() * kScreenSize);
callback_->OnCaptureCompleted(frame);
}

virtual void SetMouseShapeObserver(
MouseShapeObserver* mouse_shape_observer) OVERRIDE {
}

private:
Callback* callback_;
};

class FakeDesktopShapeTracker : public DesktopShapeTracker {
public:
FakeDesktopShapeTracker() {}
virtual ~FakeDesktopShapeTracker() {}

static webrtc::DesktopRegion CreateShape() {
webrtc::DesktopRegion result;
result.AddRect(webrtc::DesktopRect::MakeXYWH(0, 0, 5, 5));
result.AddRect(webrtc::DesktopRect::MakeXYWH(5, 5, 5, 5));
return result;
}

virtual void RefreshDesktopShape() OVERRIDE {
shape_ = CreateShape();
}

virtual const webrtc::DesktopRegion& desktop_shape() OVERRIDE {
// desktop_shape() can't be called before RefreshDesktopShape().
EXPECT_FALSE(shape_.is_empty());
return shape_;
}

private:
webrtc::DesktopRegion shape_;
};

class ShapedScreenCapturerTest : public testing::Test,
public webrtc::DesktopCapturer::Callback {
public:
// webrtc::DesktopCapturer::Callback interface
virtual webrtc::SharedMemory* CreateSharedMemory(size_t size) OVERRIDE {
return NULL;
}

virtual void OnCaptureCompleted(webrtc::DesktopFrame* frame) OVERRIDE {
last_frame_.reset(frame);
}

scoped_ptr<webrtc::DesktopFrame> last_frame_;
};

// Verify that captured frame have shape.
TEST_F(ShapedScreenCapturerTest, Basic) {
ShapedScreenCapturer capturer(
scoped_ptr<webrtc::ScreenCapturer>(new FakeScreenCapturer()),
scoped_ptr<DesktopShapeTracker>(new FakeDesktopShapeTracker()));
capturer.Start(this);
capturer.Capture(webrtc::DesktopRegion());
ASSERT_TRUE(last_frame_.get());
ASSERT_TRUE(last_frame_->shape());
EXPECT_TRUE(
FakeDesktopShapeTracker::CreateShape().Equals(*last_frame_->shape()));
}

} // namespace remoting
3 changes: 3 additions & 0 deletions remoting/remoting.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,8 @@
'host/service_urls.h',
'host/session_manager_factory.cc',
'host/session_manager_factory.h',
'host/shaped_screen_capturer.cc',
'host/shaped_screen_capturer.h',
'host/signaling_connector.cc',
'host/signaling_connector.h',
'host/token_validator_factory_impl.cc',
Expand Down Expand Up @@ -2884,6 +2886,7 @@
'host/setup/me2me_native_messaging_host_unittest.cc',
'host/setup/oauth_helper_unittest.cc',
'host/setup/pin_validator_unittest.cc',
'host/shaped_screen_capturer_unittest.cc',
'host/token_validator_factory_impl_unittest.cc',
'host/video_scheduler_unittest.cc',
'host/win/rdp_client_unittest.cc',
Expand Down

0 comments on commit ca743bf

Please sign in to comment.