• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include <memory>
12 
13 #include "modules/desktop_capture/desktop_capture_options.h"
14 #include "modules/desktop_capture/desktop_capturer.h"
15 #include "modules/desktop_capture/desktop_frame.h"
16 #include "modules/desktop_capture/desktop_region.h"
17 #include "modules/desktop_capture/mock_desktop_capturer_callback.h"
18 #include "rtc_base/constructor_magic.h"
19 #include "rtc_base/logging.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22 
23 #if defined(WEBRTC_WIN)
24 #include "modules/desktop_capture/win/screen_capturer_win_directx.h"
25 #endif  // defined(WEBRTC_WIN)
26 
27 using ::testing::_;
28 
29 const int kTestSharedMemoryId = 123;
30 
31 namespace webrtc {
32 
33 class ScreenCapturerTest : public ::testing::Test {
34  public:
SetUp()35   void SetUp() override {
36     capturer_ = DesktopCapturer::CreateScreenCapturer(
37         DesktopCaptureOptions::CreateDefault());
38     ASSERT_TRUE(capturer_);
39   }
40 
41  protected:
42 #if defined(WEBRTC_WIN)
43   // Enable allow_directx_capturer in DesktopCaptureOptions, but let
44   // DesktopCapturer::CreateScreenCapturer to decide whether a DirectX capturer
45   // should be used.
MaybeCreateDirectxCapturer()46   void MaybeCreateDirectxCapturer() {
47     DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
48     options.set_allow_directx_capturer(true);
49     capturer_ = DesktopCapturer::CreateScreenCapturer(options);
50   }
51 
CreateDirectxCapturer()52   bool CreateDirectxCapturer() {
53     if (!ScreenCapturerWinDirectx::IsSupported()) {
54       RTC_LOG(LS_WARNING) << "Directx capturer is not supported";
55       return false;
56     }
57 
58     MaybeCreateDirectxCapturer();
59     return true;
60   }
61 
CreateMagnifierCapturer()62   void CreateMagnifierCapturer() {
63     DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault());
64     options.set_allow_use_magnification_api(true);
65     capturer_ = DesktopCapturer::CreateScreenCapturer(options);
66   }
67 #endif  // defined(WEBRTC_WIN)
68 
69   std::unique_ptr<DesktopCapturer> capturer_;
70   MockDesktopCapturerCallback callback_;
71 };
72 
73 class FakeSharedMemory : public SharedMemory {
74  public:
FakeSharedMemory(char * buffer,size_t size)75   FakeSharedMemory(char* buffer, size_t size)
76       : SharedMemory(buffer, size, 0, kTestSharedMemoryId), buffer_(buffer) {}
~FakeSharedMemory()77   ~FakeSharedMemory() override { delete[] buffer_; }
78 
79  private:
80   char* buffer_;
81   RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
82 };
83 
84 class FakeSharedMemoryFactory : public SharedMemoryFactory {
85  public:
FakeSharedMemoryFactory()86   FakeSharedMemoryFactory() {}
~FakeSharedMemoryFactory()87   ~FakeSharedMemoryFactory() override {}
88 
CreateSharedMemory(size_t size)89   std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
90     return std::unique_ptr<SharedMemory>(
91         new FakeSharedMemory(new char[size], size));
92   }
93 
94  private:
95   RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
96 };
97 
ACTION_P(SaveUniquePtrArg,dest)98 ACTION_P(SaveUniquePtrArg, dest) {
99   *dest = std::move(*arg1);
100 }
101 
TEST_F(ScreenCapturerTest,GetScreenListAndSelectScreen)102 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
103   webrtc::DesktopCapturer::SourceList screens;
104   EXPECT_TRUE(capturer_->GetSourceList(&screens));
105   for (const auto& screen : screens) {
106     EXPECT_TRUE(capturer_->SelectSource(screen.id));
107   }
108 }
109 
110 // Flaky on Linux. See: crbug.com/webrtc/7830
111 #if defined(WEBRTC_LINUX)
112 #define MAYBE_StartCapturer DISABLED_StartCaptuerer
113 #else
114 #define MAYBE_StartCapturer StartCapturer
115 #endif
TEST_F(ScreenCapturerTest,MAYBE_StartCapturer)116 TEST_F(ScreenCapturerTest, MAYBE_StartCapturer) {
117   capturer_->Start(&callback_);
118 }
119 
120 #if defined(WEBRTC_LINUX)
121 #define MAYBE_Capture DISABLED_Capture
122 #else
123 #define MAYBE_Capture Capture
124 #endif
TEST_F(ScreenCapturerTest,MAYBE_Capture)125 TEST_F(ScreenCapturerTest, MAYBE_Capture) {
126   // Assume that Start() treats the screen as invalid initially.
127   std::unique_ptr<DesktopFrame> frame;
128   EXPECT_CALL(callback_,
129               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
130       .WillOnce(SaveUniquePtrArg(&frame));
131 
132   capturer_->Start(&callback_);
133   capturer_->CaptureFrame();
134 
135   ASSERT_TRUE(frame);
136   EXPECT_GT(frame->size().width(), 0);
137   EXPECT_GT(frame->size().height(), 0);
138   EXPECT_GE(frame->stride(),
139             frame->size().width() * DesktopFrame::kBytesPerPixel);
140   EXPECT_TRUE(frame->shared_memory() == NULL);
141 
142   // Verify that the region contains whole screen.
143   EXPECT_FALSE(frame->updated_region().is_empty());
144   DesktopRegion::Iterator it(frame->updated_region());
145   ASSERT_TRUE(!it.IsAtEnd());
146   EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
147   it.Advance();
148   EXPECT_TRUE(it.IsAtEnd());
149 }
150 
151 #if defined(WEBRTC_WIN)
152 
TEST_F(ScreenCapturerTest,UseSharedBuffers)153 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
154   std::unique_ptr<DesktopFrame> frame;
155   EXPECT_CALL(callback_,
156               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
157       .WillOnce(SaveUniquePtrArg(&frame));
158 
159   capturer_->Start(&callback_);
160   capturer_->SetSharedMemoryFactory(
161       std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
162   capturer_->CaptureFrame();
163 
164   ASSERT_TRUE(frame);
165   ASSERT_TRUE(frame->shared_memory());
166   EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
167 }
168 
TEST_F(ScreenCapturerTest,UseMagnifier)169 TEST_F(ScreenCapturerTest, UseMagnifier) {
170   CreateMagnifierCapturer();
171   std::unique_ptr<DesktopFrame> frame;
172   EXPECT_CALL(callback_,
173               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
174       .WillOnce(SaveUniquePtrArg(&frame));
175 
176   capturer_->Start(&callback_);
177   capturer_->CaptureFrame();
178   ASSERT_TRUE(frame);
179 }
180 
TEST_F(ScreenCapturerTest,UseDirectxCapturer)181 TEST_F(ScreenCapturerTest, UseDirectxCapturer) {
182   if (!CreateDirectxCapturer()) {
183     return;
184   }
185 
186   std::unique_ptr<DesktopFrame> frame;
187   EXPECT_CALL(callback_,
188               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
189       .WillOnce(SaveUniquePtrArg(&frame));
190 
191   capturer_->Start(&callback_);
192   capturer_->CaptureFrame();
193   ASSERT_TRUE(frame);
194 }
195 
TEST_F(ScreenCapturerTest,UseDirectxCapturerWithSharedBuffers)196 TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) {
197   if (!CreateDirectxCapturer()) {
198     return;
199   }
200 
201   std::unique_ptr<DesktopFrame> frame;
202   EXPECT_CALL(callback_,
203               OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
204       .WillOnce(SaveUniquePtrArg(&frame));
205 
206   capturer_->Start(&callback_);
207   capturer_->SetSharedMemoryFactory(
208       std::unique_ptr<SharedMemoryFactory>(new FakeSharedMemoryFactory()));
209   capturer_->CaptureFrame();
210   ASSERT_TRUE(frame);
211   ASSERT_TRUE(frame->shared_memory());
212   EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
213 }
214 
215 #endif  // defined(WEBRTC_WIN)
216 
217 }  // namespace webrtc
218