tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

wgc_capturer_win.h (7567B)


      1 /*
      2 *  Copyright (c) 2020 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 #ifndef MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_
     12 #define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_
     13 
     14 #include <dispatcherqueue.h>
     15 #include <d3d11.h>
     16 #include <wrl/client.h>
     17 
     18 #include <cstddef>
     19 #include <map>
     20 #include <memory>
     21 
     22 #include "api/scoped_refptr.h"
     23 #include "modules/desktop_capture/desktop_capture_options.h"
     24 #include "modules/desktop_capture/desktop_capture_types.h"
     25 #include "modules/desktop_capture/desktop_capturer.h"
     26 #include "modules/desktop_capture/full_screen_window_detector.h"
     27 #include "modules/desktop_capture/win/screen_capture_utils.h"
     28 #include "modules/desktop_capture/win/wgc_capture_session.h"
     29 #include "modules/desktop_capture/win/wgc_capture_source.h"
     30 #include "modules/desktop_capture/win/window_capture_utils.h"
     31 
     32 namespace webrtc {
     33 
     34 // Checks if the WGC API is present and supported on the system.
     35 bool IsWgcSupported(CaptureType capture_type);
     36 
     37 // WgcCapturerWin is initialized with an implementation of this base class,
     38 // which it uses to find capturable sources of a particular type. This way,
     39 // WgcCapturerWin can remain source-agnostic.
     40 class SourceEnumerator {
     41 public:
     42  virtual ~SourceEnumerator() = default;
     43 
     44  virtual bool FindAllSources(DesktopCapturer::SourceList* sources) = 0;
     45 };
     46 
     47 class WindowEnumerator final : public SourceEnumerator {
     48 public:
     49  explicit WindowEnumerator(bool enumerate_current_process_windows)
     50      : enumerate_current_process_windows_(enumerate_current_process_windows) {}
     51 
     52  WindowEnumerator(const WindowEnumerator&) = delete;
     53  WindowEnumerator& operator=(const WindowEnumerator&) = delete;
     54 
     55  ~WindowEnumerator() override = default;
     56 
     57  bool FindAllSources(DesktopCapturer::SourceList* sources) override {
     58    // WGC fails to capture windows with the WS_EX_TOOLWINDOW style, so we
     59    // provide it as a filter to ensure windows with the style are not returned.
     60    return window_capture_helper_.EnumerateCapturableWindows(
     61        sources, enumerate_current_process_windows_, WS_EX_TOOLWINDOW);
     62  }
     63 
     64 private:
     65  WindowCaptureHelperWin window_capture_helper_;
     66  bool enumerate_current_process_windows_;
     67 };
     68 
     69 class ScreenEnumerator final : public SourceEnumerator {
     70 public:
     71  ScreenEnumerator() = default;
     72 
     73  ScreenEnumerator(const ScreenEnumerator&) = delete;
     74  ScreenEnumerator& operator=(const ScreenEnumerator&) = delete;
     75 
     76  ~ScreenEnumerator() override = default;
     77 
     78  bool FindAllSources(DesktopCapturer::SourceList* sources) override {
     79    return GetScreenList(sources);
     80  }
     81 };
     82 
     83 // A capturer that uses the Window.Graphics.Capture APIs. It is suitable for
     84 // both window and screen capture (but only one type per instance). Consumers
     85 // should not instantiate this class directly, instead they should use
     86 // `CreateRawWindowCapturer()` or `CreateRawScreenCapturer()` to receive a
     87 // capturer appropriate for the type of source they want to capture.
     88 class WgcCapturerWin : public DesktopCapturer {
     89 public:
     90  WgcCapturerWin(const DesktopCaptureOptions& options,
     91                 std::unique_ptr<WgcCaptureSourceFactory> source_factory,
     92                 std::unique_ptr<SourceEnumerator> source_enumerator,
     93                 bool allow_delayed_capturable_check);
     94 
     95  WgcCapturerWin(const WgcCapturerWin&) = delete;
     96  WgcCapturerWin& operator=(const WgcCapturerWin&) = delete;
     97 
     98  ~WgcCapturerWin() override;
     99 
    100  static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer(
    101      const DesktopCaptureOptions& options,
    102      bool allow_delayed_capturable_check = false);
    103 
    104  static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer(
    105      const DesktopCaptureOptions& options);
    106 
    107  // DesktopCapturer interface.
    108  bool GetSourceList(SourceList* sources) override;
    109  bool SelectSource(SourceId id) override;
    110  bool FocusOnSelectedSource() override;
    111  void Start(Callback* callback) override;
    112  void CaptureFrame() override;
    113 
    114  // Used in WgcCapturerTests.
    115  bool IsSourceBeingCaptured(SourceId id);
    116  void SetUpFullScreenDetectorForTest(
    117      bool use_heuristic,
    118      DesktopCapturer::SourceId source_id,
    119      bool fullscreen_slide_show_started_after_capture_start = true);
    120 
    121 private:
    122  typedef HRESULT(WINAPI* CreateDispatcherQueueControllerFunc)(
    123      DispatcherQueueOptions,
    124      ABI::Windows::System::IDispatcherQueueController**);
    125 
    126  DesktopCaptureOptions options_;
    127 
    128  // We need to either create or ensure that someone else created a
    129  // `DispatcherQueue` on the current thread so that events will be delivered
    130  // on the current thread rather than an arbitrary thread. A
    131  // `DispatcherQueue`'s lifetime is tied to the thread's, and we don't post
    132  // any work to it, so we don't need to hold a reference.
    133  bool dispatcher_queue_created_ = false;
    134 
    135  // Statically linking to CoreMessaging.lib is disallowed in Chromium, so we
    136  // load it at runtime.
    137  HMODULE core_messaging_library_ = NULL;
    138  CreateDispatcherQueueControllerFunc create_dispatcher_queue_controller_func_ =
    139      nullptr;
    140 
    141  // Factory to create a WgcCaptureSource for us whenever SelectSource is
    142  // called. Initialized at construction with a source-specific implementation.
    143  std::unique_ptr<WgcCaptureSourceFactory> source_factory_;
    144 
    145  // The source enumerator helps us find capturable sources of the appropriate
    146  // type. Initialized at construction with a source-specific implementation.
    147  std::unique_ptr<SourceEnumerator> source_enumerator_;
    148 
    149  // The WgcCaptureSource represents the source we are capturing. It tells us
    150  // if the source is capturable and it creates the GraphicsCaptureItem for us.
    151  std::unique_ptr<WgcCaptureSource> capture_source_;
    152 
    153  // DesktopCapturer::SourceId of the source that was selected by the user. It
    154  // might not necessarily correspond to the `capture_source_` when the
    155  // `full_screen_window_detector_` is active.
    156  DesktopCapturer::SourceId selected_source_id_;
    157 
    158  // A map of all the sources we are capturing and the associated
    159  // WgcCaptureSession. Frames for the current source (indicated via
    160  // SelectSource) will be retrieved from the appropriate session when
    161  // requested via CaptureFrame.
    162  // This helps us efficiently capture multiple sources (e.g. when consumers
    163  // are trying to display a list of available capture targets with thumbnails).
    164  std::map<SourceId, WgcCaptureSession> ongoing_captures_;
    165 
    166  // The callback that we deliver frames to, synchronously, before CaptureFrame
    167  // returns.
    168  Callback* callback_ = nullptr;
    169 
    170  // WgcCaptureSource::IsCapturable is expensive to run. So, caller can
    171  // delay capturable check till capture frame is called if the WgcCapturerWin
    172  // is used as a fallback capturer.
    173  bool allow_delayed_capturable_check_ = false;
    174 
    175  // A Direct3D11 device that is shared amongst the WgcCaptureSessions, who
    176  // require one to perform the capture.
    177  Microsoft::WRL::ComPtr<::ID3D11Device> d3d11_device_;
    178 
    179  // This allows us to find full screen windows for applications in some
    180  // specific cases.
    181  scoped_refptr<FullScreenWindowDetector> full_screen_window_detector_;
    182 
    183  // Used to make sure that we only log the usage of fullscreen detection once.
    184  bool fullscreen_usage_logged_ = false;
    185 };
    186 
    187 }  // namespace webrtc
    188 
    189 #endif  // MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURER_WIN_H_