/* * Copyright (c) 2020 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. */ #ifndef MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_ #define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_ #include #include #include #include #include #include "modules/desktop_capture/desktop_capture_options.h" #include "modules/desktop_capture/desktop_capturer.h" #include "modules/desktop_capture/win/screen_capture_utils.h" #include "modules/desktop_capture/win/wgc_capture_session.h" #include "modules/desktop_capture/win/wgc_capture_source.h" #include "modules/desktop_capture/win/window_capture_utils.h" namespace webrtc { // Checks if the WGC API is present and supported on the system. bool IsWgcSupported(CaptureType capture_type); // WgcCapturerWin is initialized with an implementation of this base class, // which it uses to find capturable sources of a particular type. This way, // WgcCapturerWin can remain source-agnostic. class SourceEnumerator { public: virtual ~SourceEnumerator() = default; virtual bool FindAllSources(DesktopCapturer::SourceList* sources) = 0; }; class WindowEnumerator final : public SourceEnumerator { public: explicit WindowEnumerator(bool enumerate_current_process_windows) : enumerate_current_process_windows_(enumerate_current_process_windows) {} WindowEnumerator(const WindowEnumerator&) = delete; WindowEnumerator& operator=(const WindowEnumerator&) = delete; ~WindowEnumerator() override = default; bool FindAllSources(DesktopCapturer::SourceList* sources) override { // WGC fails to capture windows with the WS_EX_TOOLWINDOW style, so we // provide it as a filter to ensure windows with the style are not returned. return window_capture_helper_.EnumerateCapturableWindows( sources, enumerate_current_process_windows_, WS_EX_TOOLWINDOW); } private: WindowCaptureHelperWin window_capture_helper_; bool enumerate_current_process_windows_; }; class ScreenEnumerator final : public SourceEnumerator { public: ScreenEnumerator() = default; ScreenEnumerator(const ScreenEnumerator&) = delete; ScreenEnumerator& operator=(const ScreenEnumerator&) = delete; ~ScreenEnumerator() override = default; bool FindAllSources(DesktopCapturer::SourceList* sources) override { return webrtc::GetScreenList(sources); } }; // A capturer that uses the Window.Graphics.Capture APIs. It is suitable for // both window and screen capture (but only one type per instance). Consumers // should not instantiate this class directly, instead they should use // `CreateRawWindowCapturer()` or `CreateRawScreenCapturer()` to receive a // capturer appropriate for the type of source they want to capture. class WgcCapturerWin : public DesktopCapturer { public: WgcCapturerWin(const DesktopCaptureOptions& options, std::unique_ptr source_factory, std::unique_ptr source_enumerator, bool allow_delayed_capturable_check); WgcCapturerWin(const WgcCapturerWin&) = delete; WgcCapturerWin& operator=(const WgcCapturerWin&) = delete; ~WgcCapturerWin() override; static std::unique_ptr CreateRawWindowCapturer( const DesktopCaptureOptions& options, bool allow_delayed_capturable_check = false); static std::unique_ptr CreateRawScreenCapturer( const DesktopCaptureOptions& options); // DesktopCapturer interface. bool GetSourceList(SourceList* sources) override; bool SelectSource(SourceId id) override; bool FocusOnSelectedSource() override; void Start(Callback* callback) override; void CaptureFrame() override; // Used in WgcCapturerTests. bool IsSourceBeingCaptured(SourceId id); private: typedef HRESULT(WINAPI* CreateDispatcherQueueControllerFunc)( DispatcherQueueOptions, ABI::Windows::System::IDispatcherQueueController**); DesktopCaptureOptions options_; // We need to either create or ensure that someone else created a // `DispatcherQueue` on the current thread so that events will be delivered // on the current thread rather than an arbitrary thread. A // `DispatcherQueue`'s lifetime is tied to the thread's, and we don't post // any work to it, so we don't need to hold a reference. bool dispatcher_queue_created_ = false; // Statically linking to CoreMessaging.lib is disallowed in Chromium, so we // load it at runtime. HMODULE core_messaging_library_ = NULL; CreateDispatcherQueueControllerFunc create_dispatcher_queue_controller_func_ = nullptr; // Factory to create a WgcCaptureSource for us whenever SelectSource is // called. Initialized at construction with a source-specific implementation. std::unique_ptr source_factory_; // The source enumerator helps us find capturable sources of the appropriate // type. Initialized at construction with a source-specific implementation. std::unique_ptr source_enumerator_; // The WgcCaptureSource represents the source we are capturing. It tells us // if the source is capturable and it creates the GraphicsCaptureItem for us. std::unique_ptr capture_source_; // A map of all the sources we are capturing and the associated // WgcCaptureSession. Frames for the current source (indicated via // SelectSource) will be retrieved from the appropriate session when // requested via CaptureFrame. // This helps us efficiently capture multiple sources (e.g. when consumers // are trying to display a list of available capture targets with thumbnails). std::map ongoing_captures_; // The callback that we deliver frames to, synchronously, before CaptureFrame // returns. Callback* callback_ = nullptr; // WgcCaptureSource::IsCapturable is expensive to run. So, caller can // delay capturable check till capture frame is called if the WgcCapturerWin // is used as a fallback capturer. bool allow_delayed_capturable_check_ = false; // A Direct3D11 device that is shared amongst the WgcCaptureSessions, who // require one to perform the capture. Microsoft::WRL::ComPtr<::ID3D11Device> d3d11_device_; }; } // namespace webrtc #endif // MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_