1 /* 2 * Copyright (c) 2016 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_SCREEN_CAPTURER_WIN_DIRECTX_H_ 12 #define MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_DIRECTX_H_ 13 14 #include <d3dcommon.h> 15 16 #include <memory> 17 #include <unordered_map> 18 #include <vector> 19 20 #include "api/scoped_refptr.h" 21 #include "modules/desktop_capture/desktop_capture_options.h" 22 #include "modules/desktop_capture/desktop_capturer.h" 23 #include "modules/desktop_capture/desktop_region.h" 24 #include "modules/desktop_capture/screen_capture_frame_queue.h" 25 #include "modules/desktop_capture/win/dxgi_duplicator_controller.h" 26 #include "modules/desktop_capture/win/dxgi_frame.h" 27 #include "rtc_base/system/rtc_export.h" 28 29 namespace webrtc { 30 31 // ScreenCapturerWinDirectx captures 32bit RGBA using DirectX. 32 class RTC_EXPORT ScreenCapturerWinDirectx : public DesktopCapturer { 33 public: 34 using D3dInfo = DxgiDuplicatorController::D3dInfo; 35 36 // Whether the system supports DirectX based capturing. 37 static bool IsSupported(); 38 39 // Returns a most recent D3dInfo composed by 40 // DxgiDuplicatorController::Initialize() function. This function implicitly 41 // calls DxgiDuplicatorController::Initialize() if it has not been 42 // initialized. This function returns false and output parameter is kept 43 // unchanged if DxgiDuplicatorController::Initialize() failed. 44 // The D3dInfo may change based on hardware configuration even without 45 // restarting the hardware and software. Refer to https://goo.gl/OOCppq. So 46 // consumers should not cache the result returned by this function. 47 static bool RetrieveD3dInfo(D3dInfo* info); 48 49 // Whether current process is running in a Windows session which is supported 50 // by ScreenCapturerWinDirectx. 51 // Usually using ScreenCapturerWinDirectx in unsupported sessions will fail. 52 // But this behavior may vary on different Windows version. So consumers can 53 // always try IsSupported() function. 54 static bool IsCurrentSessionSupported(); 55 56 // Maps `device_names` with the result from GetScreenList() and creates a new 57 // SourceList to include only the ones in `device_names`. If this function 58 // returns true, consumers can always assume `device_names`.size() equals to 59 // `screens`->size(), meanwhile `device_names`[i] and `screens`[i] indicate 60 // the same monitor on the system. 61 // Public for test only. 62 static bool GetScreenListFromDeviceNames( 63 const std::vector<std::string>& device_names, 64 DesktopCapturer::SourceList* screens); 65 66 // Maps `id` with the result from GetScreenListFromDeviceNames() and returns 67 // the index of the entity in `device_names`. This function returns -1 if `id` 68 // cannot be found. 69 // Public for test only. 70 static int GetIndexFromScreenId(ScreenId id, 71 const std::vector<std::string>& device_names); 72 73 explicit ScreenCapturerWinDirectx(); 74 75 ~ScreenCapturerWinDirectx() override; 76 77 ScreenCapturerWinDirectx(const ScreenCapturerWinDirectx&) = delete; 78 ScreenCapturerWinDirectx& operator=(const ScreenCapturerWinDirectx&) = delete; 79 80 // DesktopCapturer implementation. 81 void Start(Callback* callback) override; 82 void SetSharedMemoryFactory( 83 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override; 84 void CaptureFrame() override; 85 bool GetSourceList(SourceList* sources) override; 86 bool SelectSource(SourceId id) override; 87 88 private: 89 const rtc::scoped_refptr<DxgiDuplicatorController> controller_; 90 91 // The underlying DxgiDuplicators may retain a reference to the frames that 92 // we ask them to duplicate so that they can continue returning valid frames 93 // in the event that the target has not been updated. Thus, we need to ensure 94 // that we have a separate frame queue for each source id, so that these held 95 // frames don't get overwritten with the data from another Duplicator/monitor. 96 std::unordered_map<SourceId, ScreenCaptureFrameQueue<DxgiFrame>> 97 frame_queue_map_; 98 std::unique_ptr<SharedMemoryFactory> shared_memory_factory_; 99 Callback* callback_ = nullptr; 100 SourceId current_screen_id_ = kFullDesktopScreenId; 101 }; 102 103 } // namespace webrtc 104 105 #endif // MODULES_DESKTOP_CAPTURE_WIN_SCREEN_CAPTURER_WIN_DIRECTX_H_ 106