blob: 494047dd034ed12dec7c260a9dd55a5c4db0e66e [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
11#include "webrtc/modules/desktop_capture/cropping_window_capturer.h"
12
13#include "webrtc/modules/desktop_capture/cropped_desktop_frame.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020014#include "webrtc/rtc_base/logging.h"
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000015
16namespace webrtc {
17
18CroppingWindowCapturer::CroppingWindowCapturer(
19 const DesktopCaptureOptions& options)
20 : options_(options),
21 callback_(NULL),
zijiehe30455892016-11-09 16:37:48 -080022 window_capturer_(DesktopCapturer::CreateRawWindowCapturer(options)),
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000023 selected_window_(kNullWindowId),
zijiehe98903d22016-11-10 21:57:10 -080024 excluded_window_(kNullWindowId) {}
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000025
26CroppingWindowCapturer::~CroppingWindowCapturer() {}
27
28void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) {
29 callback_ = callback;
30 window_capturer_->Start(callback);
31}
32
sergeyucc9669c2016-02-09 15:13:26 -080033void CroppingWindowCapturer::SetSharedMemoryFactory(
kwiberg84be5112016-04-27 01:19:58 -070034 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) {
sergeyucc9669c2016-02-09 15:13:26 -080035 window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
36}
37
zijiehe91902cb2016-10-13 16:47:49 -070038void CroppingWindowCapturer::CaptureFrame() {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000039 if (ShouldUseScreenCapturer()) {
40 if (!screen_capturer_.get()) {
zijiehe30455892016-11-09 16:37:48 -080041 screen_capturer_ = DesktopCapturer::CreateRawScreenCapturer(options_);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000042 if (excluded_window_) {
43 screen_capturer_->SetExcludedWindow(excluded_window_);
44 }
45 screen_capturer_->Start(this);
46 }
zijiehe91902cb2016-10-13 16:47:49 -070047 screen_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000048 } else {
zijiehe91902cb2016-10-13 16:47:49 -070049 window_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000050 }
51}
52
53void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
54 excluded_window_ = window;
55 if (screen_capturer_.get()) {
56 screen_capturer_->SetExcludedWindow(window);
57 }
58}
59
zijiehefce49052016-11-07 15:25:18 -080060bool CroppingWindowCapturer::GetSourceList(SourceList* sources) {
61 return window_capturer_->GetSourceList(sources);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000062}
63
zijiehefce49052016-11-07 15:25:18 -080064bool CroppingWindowCapturer::SelectSource(SourceId id) {
65 if (window_capturer_->SelectSource(id)) {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000066 selected_window_ = id;
67 return true;
68 }
69 return false;
70}
71
zijiehefce49052016-11-07 15:25:18 -080072bool CroppingWindowCapturer::FocusOnSelectedSource() {
73 return window_capturer_->FocusOnSelectedSource();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000074}
75
sergeyu5d910282016-06-07 16:41:58 -070076void CroppingWindowCapturer::OnCaptureResult(
77 DesktopCapturer::Result result,
78 std::unique_ptr<DesktopFrame> screen_frame) {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000079 if (!ShouldUseScreenCapturer()) {
80 LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
zijiehe249beee2016-10-18 23:13:29 -070081 window_capturer_->CaptureFrame();
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000082 return;
83 }
84
sergeyu5d910282016-06-07 16:41:58 -070085 if (result != Result::SUCCESS) {
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000086 LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
sergeyu5d910282016-06-07 16:41:58 -070087 callback_->OnCaptureResult(result, nullptr);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000088 return;
89 }
90
91 DesktopRect window_rect = GetWindowRectInVirtualScreen();
92 if (window_rect.is_empty()) {
93 LOG(LS_WARNING) << "Window rect is empty";
sergeyu5d910282016-06-07 16:41:58 -070094 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
jiayl@webrtc.org0e710702014-11-11 18:15:55 +000095 return;
96 }
97
sergeyu5d910282016-06-07 16:41:58 -070098 callback_->OnCaptureResult(
99 Result::SUCCESS,
100 CreateCroppedDesktopFrame(std::move(screen_frame), window_rect));
jiayl@webrtc.org0e710702014-11-11 18:15:55 +0000101}
102
Zijie He9cad5012017-09-14 08:32:46 -0700103bool CroppingWindowCapturer::IsOccluded(const DesktopVector& pos) {
104 // Returns true if either capturer returns true.
105 if (window_capturer_->IsOccluded(pos)) {
106 return true;
107 }
108 if (screen_capturer_ != nullptr && screen_capturer_->IsOccluded(pos)) {
109 return true;
110 }
111 return false;
112}
113
jiayl@webrtc.org90b9b082014-11-12 20:53:00 +0000114#if !defined(WEBRTC_WIN)
zijiehe1b0e3aa2016-11-21 13:54:26 -0800115// CroppingWindowCapturer is implemented only for windows. On other platforms
116// the regular window capturer is used.
zijiehec9a6e4a2016-11-11 15:13:32 -0800117// static
118std::unique_ptr<DesktopCapturer> CroppingWindowCapturer::CreateCapturer(
119 const DesktopCaptureOptions& options) {
120 return DesktopCapturer::CreateWindowCapturer(options);
121}
jiayl@webrtc.org0e710702014-11-11 18:15:55 +0000122#endif
123
124} // namespace webrtc