desktop_capturer.cc (5750B)
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 #include "modules/desktop_capture/desktop_capturer.h" 12 13 #include <cstdlib> 14 #include <cstring> 15 #include <memory> 16 #include <utility> 17 18 #include "modules/desktop_capture/delegated_source_list_controller.h" 19 #include "modules/desktop_capture/desktop_capture_options.h" 20 #include "modules/desktop_capture/desktop_capture_types.h" 21 #include "modules/desktop_capture/desktop_capturer_differ_wrapper.h" 22 #include "modules/desktop_capture/desktop_geometry.h" 23 #include "modules/desktop_capture/shared_memory.h" 24 #include "rtc_base/logging.h" 25 #include "system_wrappers/include/metrics.h" 26 27 #if defined(WEBRTC_WIN) 28 #include "modules/desktop_capture/cropping_window_capturer.h" 29 #endif // defined(WEBRTC_WIN) 30 31 #if defined(RTC_ENABLE_WIN_WGC) 32 #include "modules/desktop_capture/win/wgc_capturer_win.h" 33 #include "rtc_base/win/windows_version.h" 34 #endif // defined(RTC_ENABLE_WIN_WGC) 35 36 #if defined(WEBRTC_USE_PIPEWIRE) 37 #include "modules/desktop_capture/linux/wayland/base_capturer_pipewire.h" 38 #endif // defined(WEBRTC_USE_PIPEWIRE) 39 40 #if defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 41 #include "modules/desktop_capture/mac/screen_capturer_sck.h" 42 #endif // defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 43 44 namespace webrtc { 45 46 void LogDesktopCapturerFullscreenDetectorUsage() { 47 RTC_HISTOGRAM_BOOLEAN("WebRTC.Screenshare.DesktopCapturerFullscreenDetector", 48 true); 49 } 50 51 DesktopCapturer::~DesktopCapturer() = default; 52 53 DelegatedSourceListController* 54 DesktopCapturer::GetDelegatedSourceListController() { 55 return nullptr; 56 } 57 58 void DesktopCapturer::SetSharedMemoryFactory( 59 std::unique_ptr<SharedMemoryFactory> /* shared_memory_factory */) {} 60 61 void DesktopCapturer::SetExcludedWindow(WindowId /* window */) {} 62 63 bool DesktopCapturer::GetSourceList(SourceList* /* sources */) { 64 return true; 65 } 66 67 bool DesktopCapturer::SelectSource(SourceId /* id */) { 68 return false; 69 } 70 71 bool DesktopCapturer::FocusOnSelectedSource() { 72 return false; 73 } 74 75 bool DesktopCapturer::IsOccluded(const DesktopVector& /* pos */) { 76 return false; 77 } 78 79 // static 80 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateWindowCapturer( 81 const DesktopCaptureOptions& options) { 82 #if defined(RTC_ENABLE_WIN_WGC) 83 if (options.allow_wgc_window_capturer() && 84 IsWgcSupported(CaptureType::kWindow)) { 85 RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateWindowCapturer " 86 "creates DesktopCapturer of type WgcCapturerWin"; 87 return WgcCapturerWin::CreateRawWindowCapturer(options); 88 } 89 #endif // defined(RTC_ENABLE_WIN_WGC) 90 91 #if defined(WEBRTC_WIN) 92 if (options.allow_cropping_window_capturer()) { 93 RTC_LOG(LS_INFO) 94 << "video capture: DesktopCapturer::CreateWindowCapturer " 95 "creates DesktopCapturer of type CroppingWindowCapturerWin"; 96 return CroppingWindowCapturer::CreateCapturer(options); 97 } 98 #endif // defined(WEBRTC_WIN) 99 100 std::unique_ptr<DesktopCapturer> capturer = CreateRawWindowCapturer(options); 101 if (capturer && options.detect_updated_region()) { 102 RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateWindowCapturer " 103 "creates DesktopCapturer of type " 104 "DesktopCapturerDifferWrapper over a base capturer"; 105 capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); 106 } 107 108 return capturer; 109 } 110 111 // static 112 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateScreenCapturer( 113 const DesktopCaptureOptions& options) { 114 #if defined(RTC_ENABLE_WIN_WGC) 115 if (options.allow_wgc_screen_capturer() && 116 IsWgcSupported(CaptureType::kScreen)) { 117 RTC_LOG(LS_INFO) << "video capture: DesktopCapturer::CreateScreenCapturer " 118 "creates DesktopCapturer of type WgcCapturerWin"; 119 return WgcCapturerWin::CreateRawScreenCapturer(options); 120 } 121 #endif // defined(RTC_ENABLE_WIN_WGC) 122 123 std::unique_ptr<DesktopCapturer> capturer = CreateRawScreenCapturer(options); 124 if (capturer && options.detect_updated_region()) { 125 RTC_LOG(LS_INFO) 126 << "video capture: DesktopCapturer::CreateScreenCapturer creates " 127 "DesktopCapturer of type DesktopCapturerDifferWrapper over a base " 128 "capturer"; 129 capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); 130 } 131 132 return capturer; 133 } 134 135 // static 136 std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateGenericCapturer( 137 [[maybe_unused]] const DesktopCaptureOptions& options) { 138 std::unique_ptr<DesktopCapturer> capturer; 139 140 #if defined(WEBRTC_USE_PIPEWIRE) 141 if (options.allow_pipewire() && DesktopCapturer::IsRunningUnderWayland()) { 142 capturer = std::make_unique<BaseCapturerPipeWire>( 143 options, CaptureType::kAnyScreenContent); 144 } 145 #elif defined(WEBRTC_MAC) && !defined(WEBRTC_IOS) 146 capturer = CreateGenericCapturerSck(options); 147 #endif 148 149 if (capturer && options.detect_updated_region()) { 150 capturer.reset(new DesktopCapturerDifferWrapper(std::move(capturer))); 151 } 152 153 return capturer; 154 } 155 156 #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) 157 bool DesktopCapturer::IsRunningUnderWayland() { 158 const char* xdg_session_type = getenv("XDG_SESSION_TYPE"); 159 if (!xdg_session_type || strncmp(xdg_session_type, "wayland", 7) != 0) 160 return false; 161 162 if (!(getenv("WAYLAND_DISPLAY"))) 163 return false; 164 165 return true; 166 } 167 #endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) 168 169 } // namespace webrtc