| 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..9b93020eb205cb7b4763c7b6ed3678f3dccaea20
|
| --- /dev/null
|
| +++ b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.cc
|
| @@ -0,0 +1,148 @@
|
| +/*
|
| + * 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,
|
| + int enlarge_range,
|
| + bool random_dirty_region) {
|
| + RTC_DCHECK(enlarge_range > 0);
|
| + const 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(enlarge_range),
|
| + rect.top() - random.Rand(enlarge_range),
|
| + rect.right() + random.Rand(enlarge_range),
|
| + rect.bottom() + random.Rand(enlarge_range));
|
| + rect.IntersectWith(screen_rect);
|
| + }
|
| + frame->mutable_updated_region()->AddRect(rect);
|
| + }
|
| +
|
| + if (random_dirty_region) {
|
| + for (int i = random.Rand(10); i >= 0; i--) {
|
| + // At least a 1 x 1 dirty region.
|
| + const int left = random.Rand(0, frame->size().width() - 2);
|
| + const int top = random.Rand(0, frame->size().height() - 2);
|
| + const int right = random.Rand(left + 1, frame->size().width());
|
| + const int bottom = random.Rand(top + 1, frame->size().height());
|
| + frame->mutable_updated_region()->AddRect(
|
| + DesktopRect::MakeLTRB(left, top, right, bottom));
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +MockScreenCapturer::MockScreenCapturer()
|
| + : callback_(nullptr),
|
| + size_(1024, 768),
|
| + result_(Result::SUCCESS),
|
| + return_frame_(true),
|
| + provide_dirty_region_hints_(false),
|
| + enlarge_dirty_region_(false),
|
| + enlarge_range_(20) {
|
| + 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_,
|
| + enlarge_range_, random_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
|
|
|