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