blob: bd1ba46315d0925b68a8e8f64657cf4c0ba77541 [file] [log] [blame]
jiayl@webrtc.org0e710702014-11-11 18:15:55 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/desktop_capture/cropping_window_capturer.h"
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Yves Gerey3e707812018-11-28 16:47:49 +010015#include <utility>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/desktop_capture/cropped_desktop_frame.h"
18#include "rtc_base/logging.h"
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000019
20namespace webrtc {
21
22CroppingWindowCapturer::CroppingWindowCapturer(
23 const DesktopCaptureOptions& options)
24 : options_(options),
25 callback_(NULL),
zijiehe30455892016-11-09 16:37:48 -080026 window_capturer_(DesktopCapturer::CreateRawWindowCapturer(options)),
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000027 selected_window_(kNullWindowId),
zijiehe98903d22016-11-10 21:57:10 -080028 excluded_window_(kNullWindowId) {}
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000029
30CroppingWindowCapturer::~CroppingWindowCapturer() {}
31
32void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) {
33 callback_ = callback;
34 window_capturer_->Start(callback);
35}
36
sergeyucc9669c2016-02-09 15:13:26 -080037void CroppingWindowCapturer::SetSharedMemoryFactory(
kwiberg84be5112016-04-27 01:19:58 -070038 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
sergeyucc9669c2016-02-09 15:13:26 -080039 window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
40}
41
zijiehe91902cb2016-10-13 16:47:49 -070042void CroppingWindowCapturer::CaptureFrame() {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000043 if (ShouldUseScreenCapturer()) {
44 if (!screen_capturer_.get()) {
zijiehe30455892016-11-09 16:37:48 -080045 screen_capturer_ = DesktopCapturer::CreateRawScreenCapturer(options_);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000046 if (excluded_window_) {
47 screen_capturer_->SetExcludedWindow(excluded_window_);
48 }
49 screen_capturer_->Start(this);
50 }
zijiehe91902cb2016-10-13 16:47:49 -070051 screen_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000052 } else {
zijiehe91902cb2016-10-13 16:47:49 -070053 window_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000054 }
55}
56
57void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
58 excluded_window_ = window;
59 if (screen_capturer_.get()) {
60 screen_capturer_->SetExcludedWindow(window);
61 }
62}
63
zijiehefce49052016-11-07 15:25:18 -080064bool CroppingWindowCapturer::GetSourceList(SourceList* sources) {
65 return window_capturer_->GetSourceList(sources);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000066}
67
zijiehefce49052016-11-07 15:25:18 -080068bool CroppingWindowCapturer::SelectSource(SourceId id) {
69 if (window_capturer_->SelectSource(id)) {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000070 selected_window_ = id;
71 return true;
72 }
73 return false;
74}
75
zijiehefce49052016-11-07 15:25:18 -080076bool CroppingWindowCapturer::FocusOnSelectedSource() {
77 return window_capturer_->FocusOnSelectedSource();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000078}
79
sergeyu5d910282016-06-07 16:41:58 -070080void CroppingWindowCapturer::OnCaptureResult(
81 DesktopCapturer::Result result,
82 std::unique_ptr<DesktopFrame> screen_frame) {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000083 if (!ShouldUseScreenCapturer()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010084 RTC_LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
zijiehe249beee2016-10-18 23:13:29 -070085 window_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000086 return;
87 }
88
sergeyu5d910282016-06-07 16:41:58 -070089 if (result != Result::SUCCESS) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010090 RTC_LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
sergeyu5d910282016-06-07 16:41:58 -070091 callback_->OnCaptureResult(result, nullptr);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000092 return;
93 }
94
95 DesktopRect window_rect = GetWindowRectInVirtualScreen();
96 if (window_rect.is_empty()) {
Mirko Bonadei675513b2017-11-09 11:09:25 +010097 RTC_LOG(LS_WARNING) << "Window rect is empty";
sergeyu5d910282016-06-07 16:41:58 -070098 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000099 return;
100 }
101
sergeyu5d910282016-06-07 16:41:58 -0700102 callback_->OnCaptureResult(
103 Result::SUCCESS,
104 CreateCroppedDesktopFrame(std::move(screen_frame), window_rect));
jiayl@webrtc.org0e710702014-11-11 18:15:55 +0000105}
106
Zijie He9cad5012017-09-14 08:32:46 -0700107bool 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
jiayl@webrtc.org90b9b082014-11-12 20:53:00 +0000118#if !defined(WEBRTC_WIN)
zijiehe1b0e3aa2016-11-21 13:54:26 -0800119// CroppingWindowCapturer is implemented only for windows. On other platforms
120// the regular window capturer is used.
zijiehec9a6e4a2016-11-11 15:13:32 -0800121// static
122std::unique_ptr<DesktopCapturer> CroppingWindowCapturer::CreateCapturer(
123 const DesktopCaptureOptions& options) {
124 return DesktopCapturer::CreateWindowCapturer(options);
125}
jiayl@webrtc.org0e710702014-11-11 18:15:55 +0000126#endif
127
128} // namespace webrtc