| 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 |