| /* | |
| * 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 <d3d11.h> | |
| #include <wrl/client.h> | |
| #include <map> | |
| #include <memory> | |
| #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 { | |
| // 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(std::unique_ptr<WgcCaptureSourceFactory> source_factory, | |
| std::unique_ptr<SourceEnumerator> source_enumerator); | |
| WgcCapturerWin(const WgcCapturerWin&) = delete; | |
| WgcCapturerWin& operator=(const WgcCapturerWin&) = delete; | |
| ~WgcCapturerWin() override; | |
| static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer( | |
| const DesktopCaptureOptions& options); | |
| static std::unique_ptr<DesktopCapturer> 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: | |
| // Factory to create a WgcCaptureSource for us whenever SelectSource is | |
| // called. Initialized at construction with a source-specific implementation. | |
| std::unique_ptr<WgcCaptureSourceFactory> 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<SourceEnumerator> 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<WgcCaptureSource> 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<SourceId, WgcCaptureSession> ongoing_captures_; | |
| // The callback that we deliver frames to, synchronously, before CaptureFrame | |
| // returns. | |
| Callback* callback_ = nullptr; | |
| // 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_ |