| Index: webrtc/modules/desktop_capture/screen_capturer_mock_objects.cc
|
| diff --git a/webrtc/modules/desktop_capture/screen_capturer_mock_objects.cc b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1f712ab7e9b012ffb600ccf2824f7827fe3d290b
|
| --- /dev/null
|
| +++ b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.cc
|
| @@ -0,0 +1,135 @@
|
| +/*
|
| + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
| + *
|
| + * Use of this source code is governed by a BSD-style license
|
| + * that can be found in the LICENSE file in the root of the source
|
| + * tree. An additional intellectual property rights grant can be found
|
| + * in the file PATENTS. All contributing project authors may
|
| + * be found in the AUTHORS file in the root of the source tree.
|
| + */
|
| +
|
| +#include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h"
|
| +
|
| +#include <stdint.h>
|
| +#include <string.h>
|
| +
|
| +#include <utility>
|
| +
|
| +#include "webrtc/base/random.h"
|
| +#include "webrtc/base/timeutils.h"
|
| +#include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
|
| +
|
| +namespace webrtc {
|
| +
|
| +namespace {
|
| +
|
| +// Creates a DesktopFrame according to the input |factory|, and paints it to
|
| +// white.
|
| +std::unique_ptr<DesktopFrame> CreateDesktopFrame(
|
| + DesktopSize size,
|
| + SharedMemoryFactory* factory) {
|
| + std::unique_ptr<DesktopFrame> frame(
|
| + factory ?
|
| + SharedMemoryDesktopFrame::Create(size, factory).release() :
|
| + new BasicDesktopFrame(size));
|
| + memset(frame->data(), 0, frame->stride() * frame->size().height());
|
| + return SharedDesktopFrame::Wrap(std::move(frame));
|
| +}
|
| +
|
| +// Paints pixels in |rect| of |frame| to |color|.
|
| +void PaintRect(DesktopFrame* frame, DesktopRect rect, uint32_t color) {
|
| + static_assert(DesktopFrame::kBytesPerPixel == sizeof(uint32_t),
|
| + "kBytesPerPixel should be 4.");
|
| + ASSERT_TRUE(frame->size().width() >= rect.width() &&
|
| + frame->size().height() >= rect.height());
|
| + int row = rect.top() * frame->stride();
|
| + for (int i = 0; i < rect.height(); i++) {
|
| + int column = rect.left() * DesktopFrame::kBytesPerPixel;
|
| + for (int j = 0; j < rect.width(); j++) {
|
| + memcpy(&frame->data()[row + column], &color, sizeof(color));
|
| + column += DesktopFrame::kBytesPerPixel;
|
| + }
|
| + row += frame->stride();
|
| + }
|
| +}
|
| +
|
| +// Paints pixels in |region| of |frame| to |color|.
|
| +void PaintRegion(DesktopFrame* frame,
|
| + const DesktopRegion& region,
|
| + uint32_t color) {
|
| + for (DesktopRegion::Iterator it(region); !it.IsAtEnd(); it.Advance()) {
|
| + PaintRect(frame, it.rect(), color);
|
| + }
|
| +}
|
| +
|
| +// Sets dirty region of |frame| to |dirty_region|. If |enlarge_dirty_region| is
|
| +// true, this function will randomly enlarge each DesktopRect in |dirty_region|.
|
| +// But the enlarged DesktopRegion won't excceed the frame->size().
|
| +void SetDirtyRegion(DesktopFrame* frame,
|
| + const DesktopRegion& dirty_region,
|
| + bool enlarge_dirty_region) {
|
| + DesktopRect screen_rect = DesktopRect::MakeSize(frame->size());
|
| + Random random(rtc::TimeMicros());
|
| + frame->mutable_updated_region()->Clear();
|
| + for (DesktopRegion::Iterator it(dirty_region); !it.IsAtEnd(); it.Advance()) {
|
| + DesktopRect rect = it.rect();
|
| + if (enlarge_dirty_region) {
|
| + rect = DesktopRect::MakeLTRB(rect.left() - random.Rand(20),
|
| + rect.top() - random.Rand(20),
|
| + rect.right() + random.Rand(20),
|
| + rect.bottom() + random.Rand(20));
|
| + rect.IntersectWith(screen_rect);
|
| + }
|
| + frame->mutable_updated_region()->AddRect(rect);
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +MockScreenCapturer::MockScreenCapturer()
|
| + : callback_(nullptr),
|
| + size_(1024, 768),
|
| + result_(Result::SUCCESS),
|
| + return_frame_(true),
|
| + provide_dirty_region_hints_(false),
|
| + enlarge_dirty_region_(false) {
|
| + ON_CALL(*this, Start(testing::_))
|
| + .WillByDefault(testing::Invoke([this](Callback* callback) {
|
| + callback_ = callback;
|
| + }));
|
| +
|
| + ON_CALL(*this, Capture(testing::_))
|
| + .WillByDefault(testing::Invoke([this](const DesktopRegion& region) {
|
| + // A typical ScreenCapturer won't use the |region| parameter.
|
| + ASSERT_TRUE(callback_);
|
| + if (return_frame_) {
|
| + std::unique_ptr<DesktopFrame> frame =
|
| + CreateDesktopFrame(size_, shared_memory_factory_.get());
|
| + PaintRegion(frame.get(), dirty_region_, UINT32_MAX);
|
| + if (provide_dirty_region_hints_) {
|
| + SetDirtyRegion(frame.get(), dirty_region_, enlarge_dirty_region_);
|
| + }
|
| + dirty_region_.Clear();
|
| + callback_->OnCaptureResult(result_, std::move(frame));
|
| + } else {
|
| + callback_->OnCaptureResult(result_, std::unique_ptr<DesktopFrame>());
|
| + }
|
| + }));
|
| +
|
| + ON_CALL(*this, GetScreenList(testing::_))
|
| + .WillByDefault(testing::Return(true));
|
| +
|
| + ON_CALL(*this, SelectScreen(testing::_))
|
| + .WillByDefault(testing::Invoke([](ScreenId id) {
|
| + return id == kFullDesktopScreenId;
|
| + }));
|
| +}
|
| +
|
| +MockScreenCapturer::~MockScreenCapturer() = default;
|
| +
|
| +void MockScreenCapturer::SetSharedMemoryFactory(
|
| + std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
|
| + shared_memory_factory_ = std::move(shared_memory_factory);
|
| +}
|
| +
|
| +} // namespace webrtc
|
|
|