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 callback_->OnCaptureResult(
103 Result::SUCCESS,
104 CreateCroppedDesktopFrame(std::move(screen_frame), window_rect));
105 }
106
IsOccluded(const DesktopVector & pos)107 bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) {
108 // Returns true if either capturer returns true.
109 if (window_capturer_->IsOccluded(pos)) {
110 return true;
111 }
112 if (screen_capturer_ != nullptr && screen_capturer_->IsOccluded(pos)) {
113 return true;
114 }
115 return false;
116 }
117
118 #if !defined(WEBRTC_WIN)
119 // CroppingWindowCapturer is implemented only for windows. On other platforms
120 // the regular window capturer is used.
121 // static
CreateCapturer(const DesktopCaptureOptions & options)122 std::unique_ptr<DesktopCapturer> CroppingWindowCapturer::CreateCapturer(
123 const DesktopCaptureOptions& options) {
124 return DesktopCapturer::CreateWindowCapturer(options);
125 }
126 #endif
127
128 } // namespace webrtc
129