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 |
11 #include "webrtc/modules/desktop_capture/screen_capturer.h" | 11 #include "webrtc/modules/desktop_capture/screen_capturer.h" |
12 | 12 |
13 #include <stddef.h> | 13 #include <stddef.h> |
14 | 14 |
15 #include <memory> | 15 #include <memory> |
16 #include <set> | 16 #include <set> |
17 | 17 |
18 #include <ApplicationServices/ApplicationServices.h> | 18 #include <ApplicationServices/ApplicationServices.h> |
19 #include <Cocoa/Cocoa.h> | 19 #include <Cocoa/Cocoa.h> |
20 #include <dlfcn.h> | 20 #include <dlfcn.h> |
21 #include <IOKit/pwr_mgt/IOPMLib.h> | 21 #include <IOKit/pwr_mgt/IOPMLib.h> |
22 #include <OpenGL/CGLMacro.h> | 22 #include <OpenGL/CGLMacro.h> |
23 #include <OpenGL/OpenGL.h> | 23 #include <OpenGL/OpenGL.h> |
24 | 24 |
| 25 #include "webrtc/base/checks.h" |
25 #include "webrtc/base/macutils.h" | 26 #include "webrtc/base/macutils.h" |
| 27 #include "webrtc/base/thread_checker.h" |
26 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 28 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
27 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 29 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
28 #include "webrtc/modules/desktop_capture/desktop_geometry.h" | 30 #include "webrtc/modules/desktop_capture/desktop_geometry.h" |
29 #include "webrtc/modules/desktop_capture/desktop_region.h" | 31 #include "webrtc/modules/desktop_capture/desktop_region.h" |
30 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" | 32 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" |
31 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" | 33 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" |
32 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" | 34 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" |
33 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" | 35 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" |
34 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" | 36 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" |
35 #include "webrtc/system_wrappers/include/logging.h" | 37 #include "webrtc/system_wrappers/include/logging.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 window_bounds, window_list, kCGWindowImageDefault); | 183 window_bounds, window_list, kCGWindowImageDefault); |
182 } | 184 } |
183 | 185 |
184 // A class to perform video frame capturing for mac. | 186 // A class to perform video frame capturing for mac. |
185 class ScreenCapturerMac : public ScreenCapturer { | 187 class ScreenCapturerMac : public ScreenCapturer { |
186 public: | 188 public: |
187 explicit ScreenCapturerMac( | 189 explicit ScreenCapturerMac( |
188 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor); | 190 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor); |
189 virtual ~ScreenCapturerMac(); | 191 virtual ~ScreenCapturerMac(); |
190 | 192 |
191 bool Init(); | |
192 | |
193 // Overridden from ScreenCapturer: | 193 // Overridden from ScreenCapturer: |
194 void Start(Callback* callback) override; | 194 void Start(Callback* callback) override; |
195 void Capture(const DesktopRegion& region) override; | 195 void Capture(const DesktopRegion& region) override; |
196 void SetExcludedWindow(WindowId window) override; | 196 void SetExcludedWindow(WindowId window) override; |
197 bool GetScreenList(ScreenList* screens) override; | 197 bool GetScreenList(ScreenList* screens) override; |
198 bool SelectScreen(ScreenId id) override; | 198 bool SelectScreen(ScreenId id) override; |
199 | 199 |
200 private: | 200 private: |
| 201 bool Initialize(); |
| 202 |
201 void GlBlitFast(const DesktopFrame& frame, | 203 void GlBlitFast(const DesktopFrame& frame, |
202 const DesktopRegion& region); | 204 const DesktopRegion& region); |
203 void GlBlitSlow(const DesktopFrame& frame); | 205 void GlBlitSlow(const DesktopFrame& frame); |
204 void CgBlitPreLion(const DesktopFrame& frame, | 206 void CgBlitPreLion(const DesktopFrame& frame, |
205 const DesktopRegion& region); | 207 const DesktopRegion& region); |
206 // Returns false if the selected screen is no longer valid. | 208 // Returns false if the selected screen is no longer valid. |
207 bool CgBlitPostLion(const DesktopFrame& frame, | 209 bool CgBlitPostLion(const DesktopFrame& frame, |
208 const DesktopRegion& region); | 210 const DesktopRegion& region); |
209 | 211 |
210 // Called when the screen configuration is changed. | 212 // Called when the screen configuration is changed. |
(...skipping 10 matching lines...) Expand all Loading... |
221 const CGRect *rect_array, | 223 const CGRect *rect_array, |
222 void *user_parameter); | 224 void *user_parameter); |
223 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, | 225 static void ScreenUpdateMoveCallback(CGScreenUpdateMoveDelta delta, |
224 size_t count, | 226 size_t count, |
225 const CGRect *rect_array, | 227 const CGRect *rect_array, |
226 void *user_parameter); | 228 void *user_parameter); |
227 void ReleaseBuffers(); | 229 void ReleaseBuffers(); |
228 | 230 |
229 DesktopFrame* CreateFrame(); | 231 DesktopFrame* CreateFrame(); |
230 | 232 |
231 Callback* callback_; | 233 rtc::ThreadChecker thread_checker_; |
232 | 234 |
233 CGLContextObj cgl_context_; | 235 Callback* callback_ = nullptr; |
| 236 |
| 237 CGLContextObj cgl_context_ = nullptr; |
234 ScopedPixelBufferObject pixel_buffer_object_; | 238 ScopedPixelBufferObject pixel_buffer_object_; |
235 | 239 |
236 // Queue of the frames buffers. | 240 // Queue of the frames buffers. |
237 ScreenCaptureFrameQueue queue_; | 241 ScreenCaptureFrameQueue queue_; |
238 | 242 |
239 // Current display configuration. | 243 // Current display configuration. |
240 MacDesktopConfiguration desktop_config_; | 244 MacDesktopConfiguration desktop_config_; |
241 | 245 |
242 // Currently selected display, or 0 if the full desktop is selected. On OS X | 246 // Currently selected display, or 0 if the full desktop is selected. On OS X |
243 // 10.6 and before, this is always 0. | 247 // 10.6 and before, this is always 0. |
244 CGDirectDisplayID current_display_; | 248 CGDirectDisplayID current_display_ = 0; |
245 | 249 |
246 // The physical pixel bounds of the current screen. | 250 // The physical pixel bounds of the current screen. |
247 DesktopRect screen_pixel_bounds_; | 251 DesktopRect screen_pixel_bounds_; |
248 | 252 |
249 // The dip to physical pixel scale of the current screen. | 253 // The dip to physical pixel scale of the current screen. |
250 float dip_to_pixel_scale_; | 254 float dip_to_pixel_scale_ = 1.0f; |
251 | 255 |
252 // A thread-safe list of invalid rectangles, and the size of the most | 256 // A thread-safe list of invalid rectangles, and the size of the most |
253 // recently captured screen. | 257 // recently captured screen. |
254 ScreenCapturerHelper helper_; | 258 ScreenCapturerHelper helper_; |
255 | 259 |
256 // Contains an invalid region from the previous capture. | 260 // Contains an invalid region from the previous capture. |
257 DesktopRegion last_invalid_region_; | 261 DesktopRegion last_invalid_region_; |
258 | 262 |
259 // Monitoring display reconfiguration. | 263 // Monitoring display reconfiguration. |
260 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_; | 264 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_; |
261 | 265 |
262 // Power management assertion to prevent the screen from sleeping. | 266 // Power management assertion to prevent the screen from sleeping. |
263 IOPMAssertionID power_assertion_id_display_; | 267 IOPMAssertionID power_assertion_id_display_ = kIOPMNullAssertionID; |
264 | 268 |
265 // Power management assertion to indicate that the user is active. | 269 // Power management assertion to indicate that the user is active. |
266 IOPMAssertionID power_assertion_id_user_; | 270 IOPMAssertionID power_assertion_id_user_ = kIOPMNullAssertionID; |
267 | 271 |
268 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. | 272 // Dynamically link to deprecated APIs for Mac OS X 10.6 support. |
269 void* app_services_library_; | 273 void* app_services_library_ = nullptr; |
270 CGDisplayBaseAddressFunc cg_display_base_address_; | 274 CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr; |
271 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_; | 275 CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr; |
272 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_; | 276 CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr; |
273 void* opengl_library_; | 277 void* opengl_library_ = nullptr; |
274 CGLSetFullScreenFunc cgl_set_full_screen_; | 278 CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr; |
275 | 279 |
276 CGWindowID excluded_window_; | 280 CGWindowID excluded_window_ = 0; |
277 | 281 |
278 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); | 282 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac); |
279 }; | 283 }; |
280 | 284 |
281 // DesktopFrame wrapper that flips wrapped frame upside down by inverting | 285 // DesktopFrame wrapper that flips wrapped frame upside down by inverting |
282 // stride. | 286 // stride. |
283 class InvertedDesktopFrame : public DesktopFrame { | 287 class InvertedDesktopFrame : public DesktopFrame { |
284 public: | 288 public: |
285 // Takes ownership of |frame|. | 289 // Takes ownership of |frame|. |
286 InvertedDesktopFrame(DesktopFrame* frame) | 290 InvertedDesktopFrame(DesktopFrame* frame) |
287 : DesktopFrame( | 291 : DesktopFrame( |
288 frame->size(), -frame->stride(), | 292 frame->size(), -frame->stride(), |
289 frame->data() + (frame->size().height() - 1) * frame->stride(), | 293 frame->data() + (frame->size().height() - 1) * frame->stride(), |
290 frame->shared_memory()), | 294 frame->shared_memory()), |
291 original_frame_(frame) { | 295 original_frame_(frame) { |
292 set_dpi(frame->dpi()); | 296 set_dpi(frame->dpi()); |
293 set_capture_time_ms(frame->capture_time_ms()); | 297 set_capture_time_ms(frame->capture_time_ms()); |
294 mutable_updated_region()->Swap(frame->mutable_updated_region()); | 298 mutable_updated_region()->Swap(frame->mutable_updated_region()); |
295 } | 299 } |
296 virtual ~InvertedDesktopFrame() {} | 300 virtual ~InvertedDesktopFrame() {} |
297 | 301 |
298 private: | 302 private: |
299 std::unique_ptr<DesktopFrame> original_frame_; | 303 std::unique_ptr<DesktopFrame> original_frame_; |
300 | 304 |
301 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); | 305 RTC_DISALLOW_COPY_AND_ASSIGN(InvertedDesktopFrame); |
302 }; | 306 }; |
303 | 307 |
304 ScreenCapturerMac::ScreenCapturerMac( | 308 ScreenCapturerMac::ScreenCapturerMac( |
305 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) | 309 rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor) |
306 : callback_(NULL), | 310 : desktop_config_monitor_(desktop_config_monitor) { |
307 cgl_context_(NULL), | 311 // ScreenCapturer can be used on a thread different from the thread on which |
308 current_display_(0), | 312 // it's created. |
309 dip_to_pixel_scale_(1.0f), | 313 thread_checker_.DetachFromThread(); |
310 desktop_config_monitor_(desktop_config_monitor), | |
311 power_assertion_id_display_(kIOPMNullAssertionID), | |
312 power_assertion_id_user_(kIOPMNullAssertionID), | |
313 app_services_library_(NULL), | |
314 cg_display_base_address_(NULL), | |
315 cg_display_bytes_per_row_(NULL), | |
316 cg_display_bits_per_pixel_(NULL), | |
317 opengl_library_(NULL), | |
318 cgl_set_full_screen_(NULL), | |
319 excluded_window_(0) { | |
320 } | 314 } |
321 | 315 |
322 ScreenCapturerMac::~ScreenCapturerMac() { | 316 ScreenCapturerMac::~ScreenCapturerMac() { |
| 317 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 318 |
323 if (power_assertion_id_display_ != kIOPMNullAssertionID) { | 319 if (power_assertion_id_display_ != kIOPMNullAssertionID) { |
324 IOPMAssertionRelease(power_assertion_id_display_); | 320 IOPMAssertionRelease(power_assertion_id_display_); |
325 power_assertion_id_display_ = kIOPMNullAssertionID; | 321 power_assertion_id_display_ = kIOPMNullAssertionID; |
326 } | 322 } |
327 if (power_assertion_id_user_ != kIOPMNullAssertionID) { | 323 if (power_assertion_id_user_ != kIOPMNullAssertionID) { |
328 IOPMAssertionRelease(power_assertion_id_user_); | 324 IOPMAssertionRelease(power_assertion_id_user_); |
329 power_assertion_id_user_ = kIOPMNullAssertionID; | 325 power_assertion_id_user_ = kIOPMNullAssertionID; |
330 } | 326 } |
331 | 327 |
332 ReleaseBuffers(); | 328 ReleaseBuffers(); |
333 UnregisterRefreshAndMoveHandlers(); | 329 UnregisterRefreshAndMoveHandlers(); |
334 dlclose(app_services_library_); | 330 dlclose(app_services_library_); |
335 dlclose(opengl_library_); | 331 dlclose(opengl_library_); |
336 } | 332 } |
337 | 333 |
338 bool ScreenCapturerMac::Init() { | 334 bool ScreenCapturerMac::Initialize() { |
339 if (!RegisterRefreshAndMoveHandlers()) { | 335 if (!RegisterRefreshAndMoveHandlers()) { |
340 return false; | 336 return false; |
341 } | 337 } |
342 desktop_config_monitor_->Lock(); | 338 desktop_config_monitor_->Lock(); |
343 desktop_config_ = desktop_config_monitor_->desktop_configuration(); | 339 desktop_config_ = desktop_config_monitor_->desktop_configuration(); |
344 desktop_config_monitor_->Unlock(); | 340 desktop_config_monitor_->Unlock(); |
345 ScreenConfigurationChanged(); | 341 ScreenConfigurationChanged(); |
346 return true; | 342 return true; |
347 } | 343 } |
348 | 344 |
349 void ScreenCapturerMac::ReleaseBuffers() { | 345 void ScreenCapturerMac::ReleaseBuffers() { |
350 if (cgl_context_) { | 346 if (cgl_context_) { |
351 pixel_buffer_object_.Release(); | 347 pixel_buffer_object_.Release(); |
352 CGLDestroyContext(cgl_context_); | 348 CGLDestroyContext(cgl_context_); |
353 cgl_context_ = NULL; | 349 cgl_context_ = NULL; |
354 } | 350 } |
355 // The buffers might be in use by the encoder, so don't delete them here. | 351 // The buffers might be in use by the encoder, so don't delete them here. |
356 // Instead, mark them as "needs update"; next time the buffers are used by | 352 // Instead, mark them as "needs update"; next time the buffers are used by |
357 // the capturer, they will be recreated if necessary. | 353 // the capturer, they will be recreated if necessary. |
358 queue_.Reset(); | 354 queue_.Reset(); |
359 } | 355 } |
360 | 356 |
361 void ScreenCapturerMac::Start(Callback* callback) { | 357 void ScreenCapturerMac::Start(Callback* callback) { |
362 assert(!callback_); | 358 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
363 assert(callback); | 359 RTC_DCHECK(!callback_); |
| 360 RTC_DCHECK(callback); |
364 | 361 |
365 callback_ = callback; | 362 callback_ = callback; |
366 | 363 |
| 364 if (!Initialize()) { |
| 365 callback_->OnInitializationFailed(); |
| 366 return; |
| 367 } |
| 368 |
367 // Create power management assertions to wake the display and prevent it from | 369 // Create power management assertions to wake the display and prevent it from |
368 // going to sleep on user idle. | 370 // going to sleep on user idle. |
369 // TODO(jamiewalch): Use IOPMAssertionDeclareUserActivity on 10.7.3 and above | 371 // TODO(jamiewalch): Use IOPMAssertionDeclareUserActivity on 10.7.3 and above |
370 // instead of the following two assertions. | 372 // instead of the following two assertions. |
371 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, | 373 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, |
372 kIOPMAssertionLevelOn, | 374 kIOPMAssertionLevelOn, |
373 CFSTR("Chrome Remote Desktop connection active"), | 375 CFSTR("Chrome Remote Desktop connection active"), |
374 &power_assertion_id_display_); | 376 &power_assertion_id_display_); |
375 // This assertion ensures that the display is woken up if it already asleep | 377 // This assertion ensures that the display is woken up if it already asleep |
376 // (as used by Apple Remote Desktop). | 378 // (as used by Apple Remote Desktop). |
377 IOPMAssertionCreateWithName(CFSTR("UserIsActive"), | 379 IOPMAssertionCreateWithName(CFSTR("UserIsActive"), |
378 kIOPMAssertionLevelOn, | 380 kIOPMAssertionLevelOn, |
379 CFSTR("Chrome Remote Desktop connection active"), | 381 CFSTR("Chrome Remote Desktop connection active"), |
380 &power_assertion_id_user_); | 382 &power_assertion_id_user_); |
381 } | 383 } |
382 | 384 |
383 void ScreenCapturerMac::Capture(const DesktopRegion& region_to_capture) { | 385 void ScreenCapturerMac::Capture(const DesktopRegion& region_to_capture) { |
| 386 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 387 |
384 TickTime capture_start_time = TickTime::Now(); | 388 TickTime capture_start_time = TickTime::Now(); |
385 | 389 |
386 queue_.MoveToNextFrame(); | 390 queue_.MoveToNextFrame(); |
387 | 391 |
388 desktop_config_monitor_->Lock(); | 392 desktop_config_monitor_->Lock(); |
389 MacDesktopConfiguration new_config = | 393 MacDesktopConfiguration new_config = |
390 desktop_config_monitor_->desktop_configuration(); | 394 desktop_config_monitor_->desktop_configuration(); |
391 if (!desktop_config_.Equals(new_config)) { | 395 if (!desktop_config_.Equals(new_config)) { |
392 desktop_config_ = new_config; | 396 desktop_config_ = new_config; |
393 // If the display configuraiton has changed then refresh capturer data | 397 // If the display configuraiton has changed then refresh capturer data |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 // Signal that we are done capturing data from the display framebuffer, | 446 // Signal that we are done capturing data from the display framebuffer, |
443 // and accessing display structures. | 447 // and accessing display structures. |
444 desktop_config_monitor_->Unlock(); | 448 desktop_config_monitor_->Unlock(); |
445 | 449 |
446 new_frame->set_capture_time_ms( | 450 new_frame->set_capture_time_ms( |
447 (TickTime::Now() - capture_start_time).Milliseconds()); | 451 (TickTime::Now() - capture_start_time).Milliseconds()); |
448 callback_->OnCaptureCompleted(new_frame); | 452 callback_->OnCaptureCompleted(new_frame); |
449 } | 453 } |
450 | 454 |
451 void ScreenCapturerMac::SetExcludedWindow(WindowId window) { | 455 void ScreenCapturerMac::SetExcludedWindow(WindowId window) { |
| 456 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
452 excluded_window_ = window; | 457 excluded_window_ = window; |
453 } | 458 } |
454 | 459 |
455 bool ScreenCapturerMac::GetScreenList(ScreenList* screens) { | 460 bool ScreenCapturerMac::GetScreenList(ScreenList* screens) { |
456 assert(screens->size() == 0); | 461 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 462 RTC_DCHECK(screens->size() == 0); |
| 463 |
457 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { | 464 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { |
458 // Single monitor cast is not supported on pre OS X 10.7. | 465 // Single monitor cast is not supported on pre OS X 10.7. |
459 Screen screen; | 466 Screen screen; |
460 screen.id = kFullDesktopScreenId; | 467 screen.id = kFullDesktopScreenId; |
461 screens->push_back(screen); | 468 screens->push_back(screen); |
462 return true; | 469 return true; |
463 } | 470 } |
464 | 471 |
465 for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin(); | 472 for (MacDisplayConfigurations::iterator it = desktop_config_.displays.begin(); |
466 it != desktop_config_.displays.end(); ++it) { | 473 it != desktop_config_.displays.end(); ++it) { |
467 Screen screen; | 474 Screen screen; |
468 screen.id = static_cast<ScreenId>(it->id); | 475 screen.id = static_cast<ScreenId>(it->id); |
469 screens->push_back(screen); | 476 screens->push_back(screen); |
470 } | 477 } |
471 return true; | 478 return true; |
472 } | 479 } |
473 | 480 |
474 bool ScreenCapturerMac::SelectScreen(ScreenId id) { | 481 bool ScreenCapturerMac::SelectScreen(ScreenId id) { |
| 482 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
| 483 |
475 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { | 484 if (rtc::GetOSVersionName() < rtc::kMacOSLion) { |
476 // Ignore the screen selection on unsupported OS. | 485 // Ignore the screen selection on unsupported OS. |
477 assert(!current_display_); | 486 assert(!current_display_); |
478 return id == kFullDesktopScreenId; | 487 return id == kFullDesktopScreenId; |
479 } | 488 } |
480 | 489 |
481 if (id == kFullDesktopScreenId) { | 490 if (id == kFullDesktopScreenId) { |
482 current_display_ = 0; | 491 current_display_ = 0; |
483 } else { | 492 } else { |
484 const MacDisplayConfiguration* config = | 493 const MacDisplayConfiguration* config = |
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
973 return frame.release(); | 982 return frame.release(); |
974 } | 983 } |
975 | 984 |
976 } // namespace | 985 } // namespace |
977 | 986 |
978 // static | 987 // static |
979 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { | 988 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { |
980 if (!options.configuration_monitor()) | 989 if (!options.configuration_monitor()) |
981 return NULL; | 990 return NULL; |
982 | 991 |
983 std::unique_ptr<ScreenCapturerMac> capturer( | 992 return new ScreenCapturerMac(options.configuration_monitor()); |
984 new ScreenCapturerMac(options.configuration_monitor())); | |
985 if (!capturer->Init()) | |
986 capturer.reset(); | |
987 return capturer.release(); | |
988 } | 993 } |
989 | 994 |
990 } // namespace webrtc | 995 } // namespace webrtc |
OLD | NEW |