sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2013 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 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 11 | #ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ |
| 12 | #define MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 13 | |
sergeyu@chromium.org | 3d34f66 | 2013-06-04 18:51:23 | [diff] [blame] | 14 | #include <stddef.h> |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 15 | #include <stdint.h> |
sergeyu@chromium.org | 3d34f66 | 2013-06-04 18:51:23 | [diff] [blame] | 16 | |
kwiberg | 84be511 | 2016-04-27 08:19:58 | [diff] [blame] | 17 | #include <memory> |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 18 | #include <string> |
zijiehe | fce4905 | 2016-11-07 23:25:18 | [diff] [blame] | 19 | #include <type_traits> |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 20 | #include <vector> |
kwiberg | 84be511 | 2016-04-27 08:19:58 | [diff] [blame] | 21 | |
Alex Cooper | b11586f | 2022-08-31 22:01:51 | [diff] [blame] | 22 | // TODO(alcooper): Update include usage in downstream consumers and then change |
| 23 | // this to a forward declaration. |
| 24 | #include "modules/desktop_capture/delegated_source_list_controller.h" |
Salman Malik | 2492778 | 2022-03-31 14:32:24 | [diff] [blame] | 25 | #if defined(WEBRTC_USE_GIO) |
| 26 | #include "modules/desktop_capture/desktop_capture_metadata.h" |
| 27 | #endif // defined(WEBRTC_USE_GIO) |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 28 | #include "modules/desktop_capture/desktop_capture_types.h" |
Yves Gerey | 665174f | 2018-06-19 13:03:05 | [diff] [blame] | 29 | #include "modules/desktop_capture/desktop_frame.h" |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 30 | #include "modules/desktop_capture/shared_memory.h" |
Mirko Bonadei | 3d25530 | 2018-10-11 08:50:45 | [diff] [blame] | 31 | #include "rtc_base/system/rtc_export.h" |
jiayl@webrtc.org | 7ee0c16 | 2014-03-26 15:57:43 | [diff] [blame] | 32 | |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 33 | namespace webrtc { |
| 34 | |
Johannes Kron | b311f6a | 2023-02-03 11:01:52 | [diff] [blame] | 35 | void RTC_EXPORT LogDesktopCapturerFullscreenDetectorUsage(); |
| 36 | |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 37 | class DesktopCaptureOptions; |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 38 | class DesktopFrame; |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 39 | |
| 40 | // Abstract interface for screen and window capturers. |
Mirko Bonadei | 3d25530 | 2018-10-11 08:50:45 | [diff] [blame] | 41 | class RTC_EXPORT DesktopCapturer { |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 42 | public: |
sergeyu | 5d91028 | 2016-06-07 23:41:58 | [diff] [blame] | 43 | enum class Result { |
| 44 | // The frame was captured successfully. |
| 45 | SUCCESS, |
| 46 | |
| 47 | // There was a temporary error. The caller should continue calling |
zijiehe | 249beee | 2016-10-19 06:13:29 | [diff] [blame] | 48 | // CaptureFrame(), in the expectation that it will eventually recover. |
sergeyu | 5d91028 | 2016-06-07 23:41:58 | [diff] [blame] | 49 | ERROR_TEMPORARY, |
| 50 | |
| 51 | // Capture has failed and will keep failing if the caller tries calling |
zijiehe | 249beee | 2016-10-19 06:13:29 | [diff] [blame] | 52 | // CaptureFrame() again. |
sergeyu | 5d91028 | 2016-06-07 23:41:58 | [diff] [blame] | 53 | ERROR_PERMANENT, |
Sergey Ulanov | 4c17abe | 2016-06-15 20:55:44 | [diff] [blame] | 54 | |
| 55 | MAX_VALUE = ERROR_PERMANENT |
sergeyu | 5d91028 | 2016-06-07 23:41:58 | [diff] [blame] | 56 | }; |
| 57 | |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 58 | // Interface that must be implemented by the DesktopCapturer consumers. |
| 59 | class Callback { |
| 60 | public: |
Salman | 6ff7713 | 2023-01-27 22:58:35 | [diff] [blame] | 61 | // Called before a frame capture is started. |
| 62 | virtual void OnFrameCaptureStart() {} |
| 63 | |
Artem Titov | cec4343 | 2021-07-28 21:35:39 | [diff] [blame] | 64 | // Called after a frame has been captured. `frame` is not nullptr if and |
| 65 | // only if `result` is SUCCESS. |
sergeyu | 5d91028 | 2016-06-07 23:41:58 | [diff] [blame] | 66 | virtual void OnCaptureResult(Result result, |
sergeyu | 6ef36e7 | 2016-06-21 23:50:00 | [diff] [blame] | 67 | std::unique_ptr<DesktopFrame> frame) = 0; |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 68 | |
| 69 | protected: |
| 70 | virtual ~Callback() {} |
| 71 | }; |
| 72 | |
Joe Downing | 1d99f49 | 2022-01-13 15:10:16 | [diff] [blame] | 73 | #if defined(CHROMEOS) |
| 74 | typedef int64_t SourceId; |
| 75 | #else |
Brave Yao | ef77ef3 | 2018-12-21 23:22:53 | [diff] [blame] | 76 | typedef intptr_t SourceId; |
Joe Downing | 1d99f49 | 2022-01-13 15:10:16 | [diff] [blame] | 77 | #endif |
Brave Yao | ef77ef3 | 2018-12-21 23:22:53 | [diff] [blame] | 78 | |
zijiehe | fce4905 | 2016-11-07 23:25:18 | [diff] [blame] | 79 | static_assert(std::is_same<SourceId, ScreenId>::value, |
| 80 | "SourceId should be a same type as ScreenId."); |
| 81 | |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 82 | struct Source { |
| 83 | // The unique id to represent a Source of current DesktopCapturer. |
| 84 | SourceId id; |
| 85 | |
| 86 | // Title of the window or screen in UTF-8 encoding, maybe empty. This field |
| 87 | // should not be used to identify a source. |
| 88 | std::string title; |
Alex Cooper | 0d43caa | 2022-09-28 16:43:53 | [diff] [blame] | 89 | |
| 90 | #if defined(CHROMEOS) |
| 91 | // TODO(https://crbug.com/1369162): Remove or refactor this value. |
| 92 | WindowId in_process_id = kNullWindowId; |
| 93 | #endif |
Simon Hangl | cdc769d | 2022-11-10 14:06:39 | [diff] [blame] | 94 | |
| 95 | // The display's unique ID. If no ID is defined, it will hold the value |
| 96 | // kInvalidDisplayId. |
| 97 | int64_t display_id = kInvalidDisplayId; |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 98 | }; |
| 99 | |
| 100 | typedef std::vector<Source> SourceList; |
| 101 | |
| 102 | virtual ~DesktopCapturer(); |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 103 | |
Artem Titov | cec4343 | 2021-07-28 21:35:39 | [diff] [blame] | 104 | // Called at the beginning of a capturing session. `callback` must remain |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 105 | // valid until capturer is destroyed. |
| 106 | virtual void Start(Callback* callback) = 0; |
| 107 | |
Salman | 26340b0 | 2023-01-27 18:26:05 | [diff] [blame] | 108 | // Sets max frame rate for the capturer. This is best effort and may not be |
| 109 | // supported by all capturers. This will only affect the frequency at which |
| 110 | // new frames are available, not the frequency at which you are allowed to |
| 111 | // capture the frames. |
| 112 | virtual void SetMaxFrameRate(uint32_t max_frame_rate) {} |
| 113 | |
Alex Cooper | 86015a6 | 2022-08-31 17:31:11 | [diff] [blame] | 114 | // Returns a valid pointer if the capturer requires the user to make a |
| 115 | // selection from a source list provided by the capturer. |
| 116 | // Returns nullptr if the capturer does not provide a UI for the user to make |
| 117 | // a selection. |
| 118 | // |
| 119 | // Callers should not take ownership of the returned pointer, but it is |
| 120 | // guaranteed to be valid as long as the desktop_capturer is valid. |
| 121 | // Note that consumers should still use GetSourceList and SelectSource, but |
| 122 | // their behavior may be modified if this returns a value. See those methods |
| 123 | // for a more in-depth discussion of those potential modifications. |
| 124 | virtual DelegatedSourceListController* GetDelegatedSourceListController(); |
| 125 | |
sergeyu | cc9669c | 2016-02-09 23:13:26 | [diff] [blame] | 126 | // Sets SharedMemoryFactory that will be used to create buffers for the |
| 127 | // captured frames. The factory can be invoked on a thread other than the one |
zijiehe | 249beee | 2016-10-19 06:13:29 | [diff] [blame] | 128 | // where CaptureFrame() is called. It will be destroyed on the same thread. |
| 129 | // Shared memory is currently supported only by some DesktopCapturer |
| 130 | // implementations. |
sergeyu | cc9669c | 2016-02-09 23:13:26 | [diff] [blame] | 131 | virtual void SetSharedMemoryFactory( |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 132 | std::unique_ptr<SharedMemoryFactory> shared_memory_factory); |
sergeyu | cc9669c | 2016-02-09 23:13:26 | [diff] [blame] | 133 | |
zijiehe | 91902cb | 2016-10-13 23:47:49 | [diff] [blame] | 134 | // Captures next frame, and involve callback provided by Start() function. |
| 135 | // Pending capture requests are canceled when DesktopCapturer is deleted. |
zijiehe | 249beee | 2016-10-19 06:13:29 | [diff] [blame] | 136 | virtual void CaptureFrame() = 0; |
jiayl@webrtc.org | 7ee0c16 | 2014-03-26 15:57:43 | [diff] [blame] | 137 | |
| 138 | // Sets the window to be excluded from the captured image in the future |
| 139 | // Capture calls. Used to exclude the screenshare notification window for |
| 140 | // screen capturing. |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 141 | virtual void SetExcludedWindow(WindowId window); |
| 142 | |
| 143 | // TODO(zijiehe): Following functions should be pure virtual. The default |
| 144 | // implementations are for backward compatibility only. Remove default |
| 145 | // implementations once all DesktopCapturer implementations in Chromium have |
| 146 | // implemented these functions. |
| 147 | |
| 148 | // Gets a list of sources current capturer supports. Returns false in case of |
| 149 | // a failure. |
Zijie He | b010a32 | 2017-08-07 22:25:01 | [diff] [blame] | 150 | // For DesktopCapturer implementations to capture screens, this function |
| 151 | // should return monitors. |
| 152 | // For DesktopCapturer implementations to capture windows, this function |
| 153 | // should only return root windows owned by applications. |
Alex Cooper | 86015a6 | 2022-08-31 17:31:11 | [diff] [blame] | 154 | // |
| 155 | // Note that capturers who use a delegated source list will return a |
| 156 | // SourceList with exactly one value, but it may not be viable for capture |
| 157 | // (e.g. CaptureFrame will return ERROR_TEMPORARY) until a selection has been |
| 158 | // made. |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 159 | virtual bool GetSourceList(SourceList* sources); |
| 160 | |
| 161 | // Selects a source to be captured. Returns false in case of a failure (e.g. |
| 162 | // if there is no source with the specified type and id.) |
Alex Cooper | 86015a6 | 2022-08-31 17:31:11 | [diff] [blame] | 163 | // |
| 164 | // Note that some capturers with delegated source lists may also support |
| 165 | // selecting a SourceID that is not in the returned source list as a form of |
| 166 | // restore token. |
zijiehe | b68d655 | 2016-10-29 00:35:11 | [diff] [blame] | 167 | virtual bool SelectSource(SourceId id); |
| 168 | |
| 169 | // Brings the selected source to the front and sets the input focus on it. |
| 170 | // Returns false in case of a failure or no source has been selected or the |
| 171 | // implementation does not support this functionality. |
| 172 | virtual bool FocusOnSelectedSource(); |
zijiehe | 54fd579 | 2016-11-02 21:49:35 | [diff] [blame] | 173 | |
Artem Titov | cec4343 | 2021-07-28 21:35:39 | [diff] [blame] | 174 | // Returns true if the `pos` on the selected source is covered by other |
Zijie He | 1282711 | 2017-08-29 18:19:13 | [diff] [blame] | 175 | // elements on the display, and is not visible to the users. |
Artem Titov | cec4343 | 2021-07-28 21:35:39 | [diff] [blame] | 176 | // `pos` is in full desktop coordinates, i.e. the top-left monitor always |
Zijie He | 1282711 | 2017-08-29 18:19:13 | [diff] [blame] | 177 | // starts from (0, 0). |
Artem Titov | cec4343 | 2021-07-28 21:35:39 | [diff] [blame] | 178 | // The return value if `pos` is out of the scope of the source is undefined. |
Zijie He | 1282711 | 2017-08-29 18:19:13 | [diff] [blame] | 179 | virtual bool IsOccluded(const DesktopVector& pos); |
| 180 | |
zijiehe | 54fd579 | 2016-11-02 21:49:35 | [diff] [blame] | 181 | // Creates a DesktopCapturer instance which targets to capture windows. |
| 182 | static std::unique_ptr<DesktopCapturer> CreateWindowCapturer( |
| 183 | const DesktopCaptureOptions& options); |
| 184 | |
| 185 | // Creates a DesktopCapturer instance which targets to capture screens. |
| 186 | static std::unique_ptr<DesktopCapturer> CreateScreenCapturer( |
| 187 | const DesktopCaptureOptions& options); |
| 188 | |
Jan Grulich | 0e9556a | 2023-07-12 11:15:40 | [diff] [blame] | 189 | // Creates a DesktopCapturer instance which targets to capture windows and |
| 190 | // screens. |
| 191 | static std::unique_ptr<DesktopCapturer> CreateGenericCapturer( |
| 192 | const DesktopCaptureOptions& options); |
| 193 | |
Patrik Höglund | 0808a8c | 2019-12-12 10:20:07 | [diff] [blame] | 194 | #if defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) |
Tomas Popela | 318da51 | 2018-11-13 05:32:23 | [diff] [blame] | 195 | static bool IsRunningUnderWayland(); |
Salman Malik | 45a22ff | 2022-05-26 17:50:15 | [diff] [blame] | 196 | |
Jonas Oreland | 865d9c5 | 2022-05-31 08:10:49 | [diff] [blame] | 197 | virtual void UpdateResolution(uint32_t width, uint32_t height) {} |
Patrik Höglund | 0808a8c | 2019-12-12 10:20:07 | [diff] [blame] | 198 | #endif // defined(WEBRTC_USE_PIPEWIRE) || defined(WEBRTC_USE_X11) |
Tomas Popela | 318da51 | 2018-11-13 05:32:23 | [diff] [blame] | 199 | |
Salman Malik | 2492778 | 2022-03-31 14:32:24 | [diff] [blame] | 200 | #if defined(WEBRTC_USE_GIO) |
| 201 | // Populates implementation specific metadata into the passed in pointer. |
| 202 | // Classes can choose to override it or use the default no-op implementation. |
| 203 | virtual DesktopCaptureMetadata GetMetadata() { return {}; } |
| 204 | #endif // defined(WEBRTC_USE_GIO) |
| 205 | |
zijiehe | 54fd579 | 2016-11-02 21:49:35 | [diff] [blame] | 206 | protected: |
| 207 | // CroppingWindowCapturer needs to create raw capturers without wrappers, so |
| 208 | // the following two functions are protected. |
| 209 | |
| 210 | // Creates a platform specific DesktopCapturer instance which targets to |
| 211 | // capture windows. |
| 212 | static std::unique_ptr<DesktopCapturer> CreateRawWindowCapturer( |
| 213 | const DesktopCaptureOptions& options); |
| 214 | |
| 215 | // Creates a platform specific DesktopCapturer instance which targets to |
| 216 | // capture screens. |
| 217 | static std::unique_ptr<DesktopCapturer> CreateRawScreenCapturer( |
| 218 | const DesktopCaptureOptions& options); |
sergeyu@chromium.org | 15e32cc | 2013-04-29 20:10:57 | [diff] [blame] | 219 | }; |
| 220 | |
| 221 | } // namespace webrtc |
| 222 | |
Mirko Bonadei | 92ea95e | 2017-09-15 04:47:31 | [diff] [blame] | 223 | #endif // MODULES_DESKTOP_CAPTURE_DESKTOP_CAPTURER_H_ |