diff --git a/webrtc/modules/BUILD.gn b/webrtc/modules/BUILD.gn index ee18569ff8..8f90a00f16 100644 --- a/webrtc/modules/BUILD.gn +++ b/webrtc/modules/BUILD.gn @@ -71,6 +71,7 @@ if (rtc_include_tests) { "../system_wrappers", "../test:test_support", "../test:test_support_main", + "//testing/gmock", "//testing/gtest", ] @@ -96,6 +97,11 @@ if (rtc_include_tests) { "video_coding/codecs/vp8/test/vp8_impl_unittest.cc", ] + if (rtc_desktop_capture_supported) { + deps += [ "desktop_capture:desktop_capture_test_tools" ] + sources += [ "desktop_capture/screen_capturer_integration_test.cc" ] + } + data = modules_tests_resources if (is_android) { @@ -534,7 +540,7 @@ if (rtc_include_tests) { } if (rtc_desktop_capture_supported) { - deps += [ "desktop_capture" ] + deps += [ "desktop_capture:desktop_capture_test_tools" ] sources += [ "desktop_capture/desktop_and_cursor_composer_unittest.cc", "desktop_capture/desktop_frame_generator.cc", @@ -543,20 +549,13 @@ if (rtc_include_tests) { "desktop_capture/fake_screen_capturer.cc", "desktop_capture/fake_screen_capturer.h", "desktop_capture/mouse_cursor_monitor_unittest.cc", - "desktop_capture/rgba_color.cc", - "desktop_capture/rgba_color.h", "desktop_capture/rgba_color_unittest.cc", "desktop_capture/screen_capturer_differ_wrapper_unittest.cc", "desktop_capture/screen_capturer_helper_unittest.cc", "desktop_capture/screen_capturer_mac_unittest.cc", "desktop_capture/screen_capturer_mock_objects.h", "desktop_capture/screen_capturer_unittest.cc", - "desktop_capture/screen_drawer.cc", - "desktop_capture/screen_drawer.h", - "desktop_capture/screen_drawer_linux.cc", - "desktop_capture/screen_drawer_mac.cc", "desktop_capture/screen_drawer_unittest.cc", - "desktop_capture/screen_drawer_win.cc", "desktop_capture/win/cursor_unittest.cc", "desktop_capture/win/cursor_unittest_resources.h", "desktop_capture/win/cursor_unittest_resources.rc", diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn index 19bc2379c0..1583066dc6 100644 --- a/webrtc/modules/desktop_capture/BUILD.gn +++ b/webrtc/modules/desktop_capture/BUILD.gn @@ -30,6 +30,26 @@ rtc_static_library("primitives") { ] } +if (rtc_include_tests) { + source_set("desktop_capture_test_tools") { + testonly = true + + public_deps = [ + ":desktop_capture", + ] + + sources = [ + "rgba_color.cc", + "rgba_color.h", + "screen_drawer.cc", + "screen_drawer.h", + "screen_drawer_linux.cc", + "screen_drawer_mac.cc", + "screen_drawer_win.cc", + ] + } +} + rtc_static_library("desktop_capture") { sources = [ "cropped_desktop_frame.cc", diff --git a/webrtc/modules/desktop_capture/screen_capturer_integration_test.cc b/webrtc/modules/desktop_capture/screen_capturer_integration_test.cc new file mode 100644 index 0000000000..f208f14f59 --- /dev/null +++ b/webrtc/modules/desktop_capture/screen_capturer_integration_test.cc @@ -0,0 +1,277 @@ +/* + * 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 + +#include +#include +#include +#include + +#include "webrtc/modules/desktop_capture/screen_capturer.h" + +#include "webrtc/test/gmock.h" +#include "webrtc/test/gtest.h" +#include "webrtc/base/checks.h" +#include "webrtc/base/constructormagic.h" +#include "webrtc/base/logging.h" +#include "webrtc/modules/desktop_capture/rgba_color.h" +#include "webrtc/modules/desktop_capture/desktop_capture_options.h" +#include "webrtc/modules/desktop_capture/desktop_frame.h" +#include "webrtc/modules/desktop_capture/desktop_region.h" +#include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" +#include "webrtc/modules/desktop_capture/screen_drawer.h" + +#if defined(WEBRTC_WIN) +#include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" +#endif // defined(WEBRTC_WIN) + +using ::testing::_; + +namespace webrtc { + +namespace { + +ACTION_P(SaveUniquePtrArg, dest) { + *dest = std::move(*arg1); +} + +// Returns true if color in |rect| of |frame| is |color|. +bool ArePixelsColoredBy(const DesktopFrame& frame, + DesktopRect rect, + RgbaColor color, + bool may_partially_draw) { + if (!may_partially_draw) { + // updated_region() should cover the painted area. + DesktopRegion updated_region(frame.updated_region()); + updated_region.IntersectWith(rect); + if (!updated_region.Equals(DesktopRegion(rect))) { + return false; + } + } + + // Color in the |rect| should be |color|. + uint8_t* row = frame.GetFrameDataAtPos(rect.top_left()); + for (int i = 0; i < rect.height(); i++) { + uint8_t* column = row; + for (int j = 0; j < rect.width(); j++) { + if (color != RgbaColor(column)) { + return false; + } + column += DesktopFrame::kBytesPerPixel; + } + row += frame.stride(); + } + return true; +} + +} // namespace + +class ScreenCapturerIntegrationTest : public testing::Test { + public: + void SetUp() override { + capturer_.reset( + ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault())); + } + + protected: + void TestCaptureUpdatedRegion( + std::initializer_list capturers) { + RTC_DCHECK(capturers.size() > 0); + // A large enough area for the tests, which should be able to fulfill by + // most of systems. + const int kTestArea = 512; + const int kRectSize = 32; + std::unique_ptr drawer = ScreenDrawer::Create(); + if (!drawer || drawer->DrawableRegion().is_empty()) { + LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform."; + return; + } + if (drawer->DrawableRegion().width() < kTestArea || + drawer->DrawableRegion().height() < kTestArea) { + LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the " + "CaptureUpdatedRegion tests."; + return; + } + + for (ScreenCapturer* capturer : capturers) { + capturer->Start(&callback_); + } + + // Draw a set of |kRectSize| by |kRectSize| rectangles at (|i|, |i|), or + // |i| by |i| rectangles at (|kRectSize|, |kRectSize|). One of (controlled + // by |c|) its primary colors is |i|, and the other two are 0x7f. So we + // won't draw a black or white rectangle. + for (int c = 0; c < 3; c++) { + // A fixed size rectangle. + for (int i = 0; i < kTestArea - kRectSize; i += 16) { + DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize); + rect.Translate(drawer->DrawableRegion().top_left()); + RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), + (c == 1 ? (i & 0xff) : 0x7f), + (c == 2 ? (i & 0xff) : 0x7f)); + TestCaptureOneFrame(capturers, drawer.get(), rect, color); + } + + // A variable-size rectangle. + for (int i = 0; i < kTestArea - kRectSize; i += 16) { + DesktopRect rect = DesktopRect::MakeXYWH(kRectSize, kRectSize, i, i); + rect.Translate(drawer->DrawableRegion().top_left()); + RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), + (c == 1 ? (i & 0xff) : 0x7f), + (c == 2 ? (i & 0xff) : 0x7f)); + TestCaptureOneFrame(capturers, drawer.get(), rect, color); + } + } + } + + void TestCaptureUpdatedRegion() { + TestCaptureUpdatedRegion({capturer_.get()}); + } + +#if defined(WEBRTC_WIN) + // Enable allow_directx_capturer in DesktopCaptureOptions, but let + // ScreenCapturer::Create to decide whether a DirectX capturer should be used. + void MaybeCreateDirectxCapturer() { + DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); + options.set_allow_directx_capturer(true); + capturer_.reset(ScreenCapturer::Create(options)); + } + + bool CreateDirectxCapturer() { + if (!ScreenCapturerWinDirectx::IsSupported()) { + LOG(LS_WARNING) << "Directx capturer is not supported"; + return false; + } + + MaybeCreateDirectxCapturer(); + return true; + } + + void CreateMagnifierCapturer() { + DesktopCaptureOptions options(DesktopCaptureOptions::CreateDefault()); + options.set_allow_use_magnification_api(true); + capturer_.reset(ScreenCapturer::Create(options)); + } +#endif // defined(WEBRTC_WIN) + + std::unique_ptr capturer_; + MockScreenCapturerCallback callback_; + + private: + // Repeats capturing the frame by using |capturers| one-by-one for 600 times, + // typically 30 seconds, until they succeeded captured a |color| rectangle at + // |rect|. This function uses |drawer|->WaitForPendingDraws() between two + // attempts to wait for the screen to update. + void TestCaptureOneFrame(std::vector capturers, + ScreenDrawer* drawer, + DesktopRect rect, + RgbaColor color) { + const int wait_capture_round = 600; + drawer->Clear(); + size_t succeeded_capturers = 0; + for (int i = 0; i < wait_capture_round; i++) { + drawer->DrawRectangle(rect, color); + drawer->WaitForPendingDraws(); + for (size_t j = 0; j < capturers.size(); j++) { + if (capturers[j] == nullptr) { + // ScreenCapturer should return an empty updated_region() if no + // update detected. So we won't test it again if it has captured + // the rectangle we drew. + continue; + } + std::unique_ptr frame = CaptureFrame(capturers[j]); + if (!frame) { + // CaptureFrame() has triggered an assertion failure already, we + // only need to return here. + return; + } + + if (ArePixelsColoredBy( + *frame, rect, color, drawer->MayDrawIncompleteShapes())) { + capturers[j] = nullptr; + succeeded_capturers++; + } + } + + if (succeeded_capturers == capturers.size()) { + break; + } + } + + ASSERT_EQ(succeeded_capturers, capturers.size()); + } + + // Expects |capturer| to successfully capture a frame, and returns it. + std::unique_ptr CaptureFrame(ScreenCapturer* capturer) { + std::unique_ptr frame; + EXPECT_CALL(callback_, + OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) + .WillOnce(SaveUniquePtrArg(&frame)); + capturer->CaptureFrame(); + EXPECT_TRUE(frame); + return frame; + } +}; + +TEST_F(ScreenCapturerIntegrationTest, CaptureUpdatedRegion) { + TestCaptureUpdatedRegion(); +} + +TEST_F(ScreenCapturerIntegrationTest, TwoCapturers) { + std::unique_ptr capturer2 = std::move(capturer_); + SetUp(); + TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); +} + +#if defined(WEBRTC_WIN) + +TEST_F(ScreenCapturerIntegrationTest, CaptureUpdatedRegionWithDirectxCapturer) { + if (!CreateDirectxCapturer()) { + return; + } + + TestCaptureUpdatedRegion(); +} + +TEST_F(ScreenCapturerIntegrationTest, TwoDirectxCapturers) { + if (!CreateDirectxCapturer()) { + return; + } + + std::unique_ptr capturer2 = std::move(capturer_); + RTC_CHECK(CreateDirectxCapturer()); + TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); +} + +TEST_F(ScreenCapturerIntegrationTest, + CaptureUpdatedRegionWithMagnifierCapturer) { + CreateMagnifierCapturer(); + TestCaptureUpdatedRegion(); +} + +TEST_F(ScreenCapturerIntegrationTest, TwoMagnifierCapturers) { + CreateMagnifierCapturer(); + std::unique_ptr capturer2 = std::move(capturer_); + CreateMagnifierCapturer(); + TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); +} + +TEST_F(ScreenCapturerIntegrationTest, + MaybeCaptureUpdatedRegionWithDirectxCapturer) { + // Even DirectX capturer is not supported in current system, we should be able + // to select a usable capturer. + MaybeCreateDirectxCapturer(); + TestCaptureUpdatedRegion(); +} + +#endif // defined(WEBRTC_WIN) + +} // namespace webrtc diff --git a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc index ce18812fd5..41c08f006b 100644 --- a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc +++ b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc @@ -8,77 +8,29 @@ * be found in the AUTHORS file in the root of the source tree. */ -#include - -#include -#include #include -#include #include "webrtc/modules/desktop_capture/screen_capturer.h" #include "webrtc/test/gmock.h" #include "webrtc/test/gtest.h" -#include "webrtc/base/checks.h" #include "webrtc/base/constructormagic.h" #include "webrtc/base/logging.h" -#include "webrtc/modules/desktop_capture/rgba_color.h" #include "webrtc/modules/desktop_capture/desktop_capture_options.h" #include "webrtc/modules/desktop_capture/desktop_frame.h" #include "webrtc/modules/desktop_capture/desktop_region.h" #include "webrtc/modules/desktop_capture/screen_capturer_mock_objects.h" -#include "webrtc/modules/desktop_capture/screen_drawer.h" -#include "webrtc/system_wrappers/include/sleep.h" #if defined(WEBRTC_WIN) #include "webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h" #endif // defined(WEBRTC_WIN) using ::testing::_; -using ::testing::AnyNumber; -using ::testing::Return; const int kTestSharedMemoryId = 123; namespace webrtc { -namespace { - -ACTION_P(SaveUniquePtrArg, dest) { - *dest = std::move(*arg1); -} - -// Returns true if color in |rect| of |frame| is |color|. -bool ArePixelsColoredBy(const DesktopFrame& frame, - DesktopRect rect, - RgbaColor color, - bool may_partially_draw) { - if (!may_partially_draw) { - // updated_region() should cover the painted area. - DesktopRegion updated_region(frame.updated_region()); - updated_region.IntersectWith(rect); - if (!updated_region.Equals(DesktopRegion(rect))) { - return false; - } - } - - // Color in the |rect| should be |color|. - uint8_t* row = frame.GetFrameDataAtPos(rect.top_left()); - for (int i = 0; i < rect.height(); i++) { - uint8_t* column = row; - for (int j = 0; j < rect.width(); j++) { - if (color != RgbaColor(column)) { - return false; - } - column += DesktopFrame::kBytesPerPixel; - } - row += frame.stride(); - } - return true; -} - -} // namespace - class ScreenCapturerTest : public testing::Test { public: void SetUp() override { @@ -87,60 +39,6 @@ class ScreenCapturerTest : public testing::Test { } protected: - void TestCaptureUpdatedRegion( - std::initializer_list capturers) { - RTC_DCHECK(capturers.size() > 0); - // A large enough area for the tests, which should be able to fulfill by - // most of systems. - const int kTestArea = 512; - const int kRectSize = 32; - std::unique_ptr drawer = ScreenDrawer::Create(); - if (!drawer || drawer->DrawableRegion().is_empty()) { - LOG(LS_WARNING) << "No ScreenDrawer implementation for current platform."; - return; - } - if (drawer->DrawableRegion().width() < kTestArea || - drawer->DrawableRegion().height() < kTestArea) { - LOG(LS_WARNING) << "ScreenDrawer::DrawableRegion() is too small for the " - "CaptureUpdatedRegion tests."; - return; - } - - for (ScreenCapturer* capturer : capturers) { - capturer->Start(&callback_); - } - - // Draw a set of |kRectSize| by |kRectSize| rectangles at (|i|, |i|), or - // |i| by |i| rectangles at (|kRectSize|, |kRectSize|). One of (controlled - // by |c|) its primary colors is |i|, and the other two are 0x7f. So we - // won't draw a black or white rectangle. - for (int c = 0; c < 3; c++) { - // A fixed size rectangle. - for (int i = 0; i < kTestArea - kRectSize; i += 16) { - DesktopRect rect = DesktopRect::MakeXYWH(i, i, kRectSize, kRectSize); - rect.Translate(drawer->DrawableRegion().top_left()); - RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), - (c == 1 ? (i & 0xff) : 0x7f), - (c == 2 ? (i & 0xff) : 0x7f)); - TestCaptureOneFrame(capturers, drawer.get(), rect, color); - } - - // A variable-size rectangle. - for (int i = 0; i < kTestArea - kRectSize; i += 16) { - DesktopRect rect = DesktopRect::MakeXYWH(kRectSize, kRectSize, i, i); - rect.Translate(drawer->DrawableRegion().top_left()); - RgbaColor color((c == 0 ? (i & 0xff) : 0x7f), - (c == 1 ? (i & 0xff) : 0x7f), - (c == 2 ? (i & 0xff) : 0x7f)); - TestCaptureOneFrame(capturers, drawer.get(), rect, color); - } - } - } - - void TestCaptureUpdatedRegion() { - TestCaptureUpdatedRegion({capturer_.get()}); - } - #if defined(WEBRTC_WIN) // Enable allow_directx_capturer in DesktopCaptureOptions, but let // ScreenCapturer::Create to decide whether a DirectX capturer should be used. @@ -169,61 +67,6 @@ class ScreenCapturerTest : public testing::Test { std::unique_ptr capturer_; MockScreenCapturerCallback callback_; - - private: - // Repeats capturing the frame by using |capturers| one-by-one for 600 times, - // typically 30 seconds, until they succeeded captured a |color| rectangle at - // |rect|. This function uses |drawer|->WaitForPendingDraws() between two - // attempts to wait for the screen to update. - void TestCaptureOneFrame(std::vector capturers, - ScreenDrawer* drawer, - DesktopRect rect, - RgbaColor color) { - const int wait_capture_round = 600; - drawer->Clear(); - size_t succeeded_capturers = 0; - for (int i = 0; i < wait_capture_round; i++) { - drawer->DrawRectangle(rect, color); - drawer->WaitForPendingDraws(); - for (size_t j = 0; j < capturers.size(); j++) { - if (capturers[j] == nullptr) { - // ScreenCapturer should return an empty updated_region() if no - // update detected. So we won't test it again if it has captured - // the rectangle we drew. - continue; - } - std::unique_ptr frame = CaptureFrame(capturers[j]); - if (!frame) { - // CaptureFrame() has triggered an assertion failure already, we - // only need to return here. - return; - } - - if (ArePixelsColoredBy( - *frame, rect, color, drawer->MayDrawIncompleteShapes())) { - capturers[j] = nullptr; - succeeded_capturers++; - } - } - - if (succeeded_capturers == capturers.size()) { - break; - } - } - - ASSERT_EQ(succeeded_capturers, capturers.size()); - } - - // Expects |capturer| to successfully capture a frame, and returns it. - std::unique_ptr CaptureFrame(ScreenCapturer* capturer) { - std::unique_ptr frame; - EXPECT_CALL(callback_, - OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) - .WillOnce(SaveUniquePtrArg(&frame)); - capturer->CaptureFrame(); - EXPECT_TRUE(frame); - return frame; - } }; class FakeSharedMemory : public SharedMemory { @@ -254,11 +97,15 @@ class FakeSharedMemoryFactory : public SharedMemoryFactory { RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory); }; +ACTION_P(SaveUniquePtrArg, dest) { + *dest = std::move(*arg1); +} + TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) { webrtc::ScreenCapturer::ScreenList screens; EXPECT_TRUE(capturer_->GetScreenList(&screens)); for (webrtc::ScreenCapturer::ScreenList::iterator it = screens.begin(); - it != screens.end(); ++it) { + it != screens.end(); ++it) { EXPECT_TRUE(capturer_->SelectScreen(it->id)); } } @@ -293,20 +140,6 @@ TEST_F(ScreenCapturerTest, Capture) { EXPECT_TRUE(it.IsAtEnd()); } -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegion) { - TestCaptureUpdatedRegion(); -} - -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_TwoCapturers) { - std::unique_ptr capturer2 = std::move(capturer_); - SetUp(); - TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); -} - #if defined(WEBRTC_WIN) TEST_F(ScreenCapturerTest, UseSharedBuffers) { @@ -327,7 +160,6 @@ TEST_F(ScreenCapturerTest, UseSharedBuffers) { TEST_F(ScreenCapturerTest, UseMagnifier) { CreateMagnifierCapturer(); - std::unique_ptr frame; EXPECT_CALL(callback_, OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _)) @@ -372,54 +204,6 @@ TEST_F(ScreenCapturerTest, UseDirectxCapturerWithSharedBuffers) { EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId); } -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegionWithDirectxCapturer) { - if (!CreateDirectxCapturer()) { - return; - } - - TestCaptureUpdatedRegion(); -} - -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_TwoDirectxCapturers) { - if (!CreateDirectxCapturer()) { - return; - } - - std::unique_ptr capturer2 = std::move(capturer_); - RTC_CHECK(CreateDirectxCapturer()); - TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); -} - -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_CaptureUpdatedRegionWithMagnifierCapturer) { - CreateMagnifierCapturer(); - TestCaptureUpdatedRegion(); -} - -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, DISABLED_TwoMagnifierCapturers) { - CreateMagnifierCapturer(); - std::unique_ptr capturer2 = std::move(capturer_); - CreateMagnifierCapturer(); - TestCaptureUpdatedRegion({capturer_.get(), capturer2.get()}); -} - -// Disabled due to being flaky due to the fact that it uses rendering / UI, see -// webrtc/6366. -TEST_F(ScreenCapturerTest, - DISABLED_MaybeCaptureUpdatedRegionWithDirectxCapturer) { - // Even DirectX capturer is not supported in current system, we should be able - // to select a usable capturer. - MaybeCreateDirectxCapturer(); - TestCaptureUpdatedRegion(); -} - #endif // defined(WEBRTC_WIN) } // namespace webrtc diff --git a/webrtc/modules/desktop_capture/screen_drawer_linux.cc b/webrtc/modules/desktop_capture/screen_drawer_linux.cc index c745205df0..4f96b7e92c 100644 --- a/webrtc/modules/desktop_capture/screen_drawer_linux.cc +++ b/webrtc/modules/desktop_capture/screen_drawer_linux.cc @@ -30,7 +30,7 @@ static constexpr char kSemaphoreName[] = class ScreenDrawerLockLinux : public ScreenDrawerLock { public: ScreenDrawerLockLinux(); - ~ScreenDrawerLockLinux(); + ~ScreenDrawerLockLinux() override; private: sem_t* semaphore_; diff --git a/webrtc/modules/desktop_capture/screen_drawer_win.cc b/webrtc/modules/desktop_capture/screen_drawer_win.cc index 1bc591b9c7..437a6d3fe7 100644 --- a/webrtc/modules/desktop_capture/screen_drawer_win.cc +++ b/webrtc/modules/desktop_capture/screen_drawer_win.cc @@ -25,7 +25,7 @@ static constexpr TCHAR kMutexName[] = class ScreenDrawerLockWin : public ScreenDrawerLock { public: ScreenDrawerLockWin(); - ~ScreenDrawerLockWin(); + ~ScreenDrawerLockWin() override; private: HANDLE mutex_;