OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "webrtc/modules/desktop_capture/mac/window_list_utils.h" | 25 #include "webrtc/modules/desktop_capture/mac/window_list_utils.h" |
26 #include "webrtc/system_wrappers/include/logging.h" | 26 #include "webrtc/system_wrappers/include/logging.h" |
27 | 27 |
28 namespace webrtc { | 28 namespace webrtc { |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 // Returns true if the window exists. | 32 // Returns true if the window exists. |
33 bool IsWindowValid(CGWindowID id) { | 33 bool IsWindowValid(CGWindowID id) { |
34 CFArrayRef window_id_array = | 34 CFArrayRef window_id_array = |
35 CFArrayCreate(nullptr, reinterpret_cast<const void**>(&id), 1, nullptr); | 35 CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL); |
36 CFArrayRef window_array = | 36 CFArrayRef window_array = |
37 CGWindowListCreateDescriptionFromArray(window_id_array); | 37 CGWindowListCreateDescriptionFromArray(window_id_array); |
38 bool valid = window_array && CFArrayGetCount(window_array); | 38 bool valid = window_array && CFArrayGetCount(window_array); |
39 CFRelease(window_id_array); | 39 CFRelease(window_id_array); |
40 CFRelease(window_array); | 40 CFRelease(window_array); |
41 | 41 |
42 return valid; | 42 return valid; |
43 } | 43 } |
44 | 44 |
45 class WindowCapturerMac : public WindowCapturer { | 45 class WindowCapturerMac : public WindowCapturer { |
46 public: | 46 public: |
47 explicit WindowCapturerMac(rtc::scoped_refptr<FullScreenChromeWindowDetector> | 47 explicit WindowCapturerMac(rtc::scoped_refptr<FullScreenChromeWindowDetector> |
48 full_screen_chrome_window_detector); | 48 full_screen_chrome_window_detector); |
49 virtual ~WindowCapturerMac(); | 49 virtual ~WindowCapturerMac(); |
50 | 50 |
51 // WindowCapturer interface. | 51 // WindowCapturer interface. |
52 bool GetWindowList(WindowList* windows) override; | 52 bool GetWindowList(WindowList* windows) override; |
53 bool SelectWindow(WindowId id) override; | 53 bool SelectWindow(WindowId id) override; |
54 bool BringSelectedWindowToFront() override; | 54 bool BringSelectedWindowToFront() override; |
55 | 55 |
56 // DesktopCapturer interface. | 56 // DesktopCapturer interface. |
57 void Start(Callback* callback) override; | 57 void Start(Callback* callback) override; |
58 void Capture(const DesktopRegion& region) override; | 58 void Capture(const DesktopRegion& region) override; |
59 | 59 |
60 private: | 60 private: |
61 Callback* callback_ = nullptr; | 61 Callback* callback_; |
62 | 62 |
63 // The window being captured. | 63 // The window being captured. |
64 CGWindowID window_id_ = 0; | 64 CGWindowID window_id_; |
65 | 65 |
66 rtc::scoped_refptr<FullScreenChromeWindowDetector> | 66 rtc::scoped_refptr<FullScreenChromeWindowDetector> |
67 full_screen_chrome_window_detector_; | 67 full_screen_chrome_window_detector_; |
68 | 68 |
69 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerMac); | 69 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerMac); |
70 }; | 70 }; |
71 | 71 |
72 WindowCapturerMac::WindowCapturerMac( | 72 WindowCapturerMac::WindowCapturerMac(rtc::scoped_refptr< |
73 rtc::scoped_refptr<FullScreenChromeWindowDetector> | 73 FullScreenChromeWindowDetector> full_screen_chrome_window_detector) |
74 full_screen_chrome_window_detector) | 74 : callback_(NULL), |
75 : full_screen_chrome_window_detector_(full_screen_chrome_window_detector) {} | 75 window_id_(0), |
| 76 full_screen_chrome_window_detector_(full_screen_chrome_window_detector) { |
| 77 } |
76 | 78 |
77 WindowCapturerMac::~WindowCapturerMac() {} | 79 WindowCapturerMac::~WindowCapturerMac() { |
| 80 } |
78 | 81 |
79 bool WindowCapturerMac::GetWindowList(WindowList* windows) { | 82 bool WindowCapturerMac::GetWindowList(WindowList* windows) { |
80 // Only get on screen, non-desktop windows. | 83 // Only get on screen, non-desktop windows. |
81 CFArrayRef window_array = CGWindowListCopyWindowInfo( | 84 CFArrayRef window_array = CGWindowListCopyWindowInfo( |
82 kCGWindowListExcludeDesktopElements, | 85 kCGWindowListExcludeDesktopElements, |
83 kCGNullWindowID); | 86 kCGNullWindowID); |
84 if (!window_array) | 87 if (!window_array) |
85 return false; | 88 return false; |
86 MacDesktopConfiguration desktop_config = MacDesktopConfiguration::GetCurrent( | 89 MacDesktopConfiguration desktop_config = MacDesktopConfiguration::GetCurrent( |
87 MacDesktopConfiguration::TopLeftOrigin); | 90 MacDesktopConfiguration::TopLeftOrigin); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 return true; | 135 return true; |
133 } | 136 } |
134 | 137 |
135 bool WindowCapturerMac::BringSelectedWindowToFront() { | 138 bool WindowCapturerMac::BringSelectedWindowToFront() { |
136 if (!window_id_) | 139 if (!window_id_) |
137 return false; | 140 return false; |
138 | 141 |
139 CGWindowID ids[1]; | 142 CGWindowID ids[1]; |
140 ids[0] = window_id_; | 143 ids[0] = window_id_; |
141 CFArrayRef window_id_array = | 144 CFArrayRef window_id_array = |
142 CFArrayCreate(nullptr, reinterpret_cast<const void**>(&ids), 1, nullptr); | 145 CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL); |
143 | 146 |
144 CFArrayRef window_array = | 147 CFArrayRef window_array = |
145 CGWindowListCreateDescriptionFromArray(window_id_array); | 148 CGWindowListCreateDescriptionFromArray(window_id_array); |
146 if (!window_array || 0 == CFArrayGetCount(window_array)) { | 149 if (window_array == NULL || 0 == CFArrayGetCount(window_array)) { |
147 // Could not find the window. It might have been closed. | 150 // Could not find the window. It might have been closed. |
148 LOG(LS_INFO) << "Window not found"; | 151 LOG(LS_INFO) << "Window not found"; |
149 CFRelease(window_id_array); | 152 CFRelease(window_id_array); |
150 return false; | 153 return false; |
151 } | 154 } |
152 | 155 |
153 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( | 156 CFDictionaryRef window = reinterpret_cast<CFDictionaryRef>( |
154 CFArrayGetValueAtIndex(window_array, 0)); | 157 CFArrayGetValueAtIndex(window_array, 0)); |
155 CFNumberRef pid_ref = reinterpret_cast<CFNumberRef>( | 158 CFNumberRef pid_ref = reinterpret_cast<CFNumberRef>( |
156 CFDictionaryGetValue(window, kCGWindowOwnerPID)); | 159 CFDictionaryGetValue(window, kCGWindowOwnerPID)); |
(...skipping 14 matching lines...) Expand all Loading... |
171 | 174 |
172 void WindowCapturerMac::Start(Callback* callback) { | 175 void WindowCapturerMac::Start(Callback* callback) { |
173 assert(!callback_); | 176 assert(!callback_); |
174 assert(callback); | 177 assert(callback); |
175 | 178 |
176 callback_ = callback; | 179 callback_ = callback; |
177 } | 180 } |
178 | 181 |
179 void WindowCapturerMac::Capture(const DesktopRegion& region) { | 182 void WindowCapturerMac::Capture(const DesktopRegion& region) { |
180 if (!IsWindowValid(window_id_)) { | 183 if (!IsWindowValid(window_id_)) { |
181 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 184 callback_->OnCaptureCompleted(NULL); |
182 return; | 185 return; |
183 } | 186 } |
184 | 187 |
185 CGWindowID on_screen_window = window_id_; | 188 CGWindowID on_screen_window = window_id_; |
186 if (full_screen_chrome_window_detector_) { | 189 if (full_screen_chrome_window_detector_) { |
187 CGWindowID full_screen_window = | 190 CGWindowID full_screen_window = |
188 full_screen_chrome_window_detector_->FindFullScreenWindow(window_id_); | 191 full_screen_chrome_window_detector_->FindFullScreenWindow(window_id_); |
189 | 192 |
190 if (full_screen_window != kCGNullWindowID) | 193 if (full_screen_window != kCGNullWindowID) |
191 on_screen_window = full_screen_window; | 194 on_screen_window = full_screen_window; |
192 } | 195 } |
193 | 196 |
194 CGImageRef window_image = CGWindowListCreateImage( | 197 CGImageRef window_image = CGWindowListCreateImage( |
195 CGRectNull, kCGWindowListOptionIncludingWindow, | 198 CGRectNull, kCGWindowListOptionIncludingWindow, |
196 on_screen_window, kCGWindowImageBoundsIgnoreFraming); | 199 on_screen_window, kCGWindowImageBoundsIgnoreFraming); |
197 | 200 |
198 if (!window_image) { | 201 if (!window_image) { |
199 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); | 202 callback_->OnCaptureCompleted(NULL); |
200 return; | 203 return; |
201 } | 204 } |
202 | 205 |
203 int bits_per_pixel = CGImageGetBitsPerPixel(window_image); | 206 int bits_per_pixel = CGImageGetBitsPerPixel(window_image); |
204 if (bits_per_pixel != 32) { | 207 if (bits_per_pixel != 32) { |
205 LOG(LS_ERROR) << "Unsupported window image depth: " << bits_per_pixel; | 208 LOG(LS_ERROR) << "Unsupported window image depth: " << bits_per_pixel; |
206 CFRelease(window_image); | 209 CFRelease(window_image); |
207 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 210 callback_->OnCaptureCompleted(NULL); |
208 return; | 211 return; |
209 } | 212 } |
210 | 213 |
211 int width = CGImageGetWidth(window_image); | 214 int width = CGImageGetWidth(window_image); |
212 int height = CGImageGetHeight(window_image); | 215 int height = CGImageGetHeight(window_image); |
213 CGDataProviderRef provider = CGImageGetDataProvider(window_image); | 216 CGDataProviderRef provider = CGImageGetDataProvider(window_image); |
214 CFDataRef cf_data = CGDataProviderCopyData(provider); | 217 CFDataRef cf_data = CGDataProviderCopyData(provider); |
215 std::unique_ptr<DesktopFrame> frame( | 218 DesktopFrame* frame = new BasicDesktopFrame( |
216 new BasicDesktopFrame(DesktopSize(width, height))); | 219 DesktopSize(width, height)); |
217 | 220 |
218 int src_stride = CGImageGetBytesPerRow(window_image); | 221 int src_stride = CGImageGetBytesPerRow(window_image); |
219 const uint8_t* src_data = CFDataGetBytePtr(cf_data); | 222 const uint8_t* src_data = CFDataGetBytePtr(cf_data); |
220 for (int y = 0; y < height; ++y) { | 223 for (int y = 0; y < height; ++y) { |
221 memcpy(frame->data() + frame->stride() * y, src_data + src_stride * y, | 224 memcpy(frame->data() + frame->stride() * y, src_data + src_stride * y, |
222 DesktopFrame::kBytesPerPixel * width); | 225 DesktopFrame::kBytesPerPixel * width); |
223 } | 226 } |
224 | 227 |
225 CFRelease(cf_data); | 228 CFRelease(cf_data); |
226 CFRelease(window_image); | 229 CFRelease(window_image); |
227 | 230 |
228 frame->mutable_updated_region()->SetRect( | 231 frame->mutable_updated_region()->SetRect( |
229 DesktopRect::MakeSize(frame->size())); | 232 DesktopRect::MakeSize(frame->size())); |
230 | 233 |
231 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | 234 callback_->OnCaptureCompleted(frame); |
232 | 235 |
233 if (full_screen_chrome_window_detector_) | 236 if (full_screen_chrome_window_detector_) |
234 full_screen_chrome_window_detector_->UpdateWindowListIfNeeded(window_id_); | 237 full_screen_chrome_window_detector_->UpdateWindowListIfNeeded(window_id_); |
235 } | 238 } |
236 | 239 |
237 } // namespace | 240 } // namespace |
238 | 241 |
239 // static | 242 // static |
240 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { | 243 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { |
241 return new WindowCapturerMac(options.full_screen_chrome_window_detector()); | 244 return new WindowCapturerMac(options.full_screen_chrome_window_detector()); |
242 } | 245 } |
243 | 246 |
244 } // namespace webrtc | 247 } // namespace webrtc |
OLD | NEW |