xref: /aosp_15_r20/external/webrtc/modules/desktop_capture/cropping_window_capturer.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright (c) 2014 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/cropping_window_capturer.h"
12 
13 #include <stddef.h>
14 
15 #include <utility>
16 
17 #include "modules/desktop_capture/cropped_desktop_frame.h"
18 #include "rtc_base/logging.h"
19 
20 namespace webrtc {
21 
CroppingWindowCapturer(const DesktopCaptureOptions & options)22 CroppingWindowCapturer::CroppingWindowCapturer(
23     const DesktopCaptureOptions& options)
24     : options_(options),
25       callback_(NULL),
26       window_capturer_(DesktopCapturer::CreateRawWindowCapturer(options)),
27       selected_window_(kNullWindowId),
28       excluded_window_(kNullWindowId) {}
29 
~CroppingWindowCapturer()30 CroppingWindowCapturer::~CroppingWindowCapturer() {}
31 
Start(DesktopCapturer::Callback * callback)32 void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) {
33   callback_ = callback;
34   window_capturer_->Start(callback);
35 }
36 
SetSharedMemoryFactory(std::unique_ptr<SharedMemoryFactory> shared_memory_factory)37 void CroppingWindowCapturer::SetSharedMemoryFactory(
38     std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
39   window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
40 }
41 
CaptureFrame()42 void CroppingWindowCapturer::CaptureFrame() {
43   if (ShouldUseScreenCapturer()) {
44     if (!screen_capturer_.get()) {
45       screen_capturer_ = DesktopCapturer::CreateRawScreenCapturer(options_);
46       if (excluded_window_) {
47         screen_capturer_->SetExcludedWindow(excluded_window_);
48       }
49       screen_capturer_->Start(this);
50     }
51     screen_capturer_->CaptureFrame();
52   } else {
53     window_capturer_->CaptureFrame();
54   }
55 }
56 
SetExcludedWindow(WindowId window)57 void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
58   excluded_window_ = window;
59   if (screen_capturer_.get()) {
60     screen_capturer_->SetExcludedWindow(window);
61   }
62 }
63 
GetSourceList(SourceList * sources)64 bool CroppingWindowCapturer::GetSourceList(SourceList* sources) {
65   return window_capturer_->GetSourceList(sources);
66 }
67 
SelectSource(SourceId id)68 bool CroppingWindowCapturer::SelectSource(SourceId id) {
69   if (window_capturer_->SelectSource(id)) {
70     selected_window_ = id;
71     return true;
72   }
73   return false;
74 }
75 
FocusOnSelectedSource()76 bool CroppingWindowCapturer::FocusOnSelectedSource() {
77   return window_capturer_->FocusOnSelectedSource();
78 }
79 
OnCaptureResult(DesktopCapturer::Result result,std::unique_ptr<DesktopFrame> screen_frame)80 void CroppingWindowCapturer::OnCaptureResult(
81     DesktopCapturer::Result result,
82     std::unique_ptr<DesktopFrame> screen_frame) {
83   if (!ShouldUseScreenCapturer()) {
84     RTC_LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
85     window_capturer_->CaptureFrame();
86     return;
87   }
88 
89   if (result != Result::SUCCESS) {
90     RTC_LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
91     callback_->OnCaptureResult(result, nullptr);
92     return;
93   }
94 
95   DesktopRect window_rect = GetWindowRectInVirtualScreen();
96   if (window_rect.is_empty()) {
97     RTC_LOG(LS_WARNING) << "Window rect is empty";
98     callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
99     return;
100   }
101 
102   std::unique_ptr<DesktopFrame> cropped_frame =
103       CreateCroppedDesktopFrame(std::move(screen_frame), window_rect);
104 
105   if (!cropped_frame) {
106     RTC_LOG(LS_WARNING) << "Window is outside of the captured display";
107     callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
108     return;
109   }
110 
111   callback_->OnCaptureResult(Result::SUCCESS, std::move(cropped_frame));
112 }
113 
IsOccluded(const DesktopVector & pos)114 bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) {
115   // Returns true if either capturer returns true.
116   if (window_capturer_->IsOccluded(pos)) {
117     return true;
118   }
119   if (screen_capturer_ != nullptr && screen_capturer_->IsOccluded(pos)) {
120     return true;
121   }
122   return false;
123 }
124 
125 #if !defined(WEBRTC_WIN)
126 // CroppingWindowCapturer is implemented only for windows. On other platforms
127 // the regular window capturer is used.
128 // static
CreateCapturer(const DesktopCaptureOptions & options)129 std::unique_ptr<DesktopCapturer> CroppingWindowCapturer::CreateCapturer(
130     const DesktopCaptureOptions& options) {
131   return DesktopCapturer::CreateWindowCapturer(options);
132 }
133 #endif
134 
135 }  // namespace webrtc
136