OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/host/video_frame_capturer.h" | 5 #include "remoting/host/video_frame_capturer.h" |
6 | 6 |
7 #include <ApplicationServices/ApplicationServices.h> | 7 #include <ApplicationServices/ApplicationServices.h> |
8 #include <Cocoa/Cocoa.h> | 8 #include <Cocoa/Cocoa.h> |
9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
10 #include <IOKit/pwr_mgt/IOPMLib.h> | 10 #include <IOKit/pwr_mgt/IOPMLib.h> |
(...skipping 19 matching lines...) Expand all Loading... | |
30 SkIRect CGRectToSkIRect(const CGRect& rect) { | 30 SkIRect CGRectToSkIRect(const CGRect& rect) { |
31 SkIRect sk_rect = { | 31 SkIRect sk_rect = { |
32 SkScalarRound(rect.origin.x), | 32 SkScalarRound(rect.origin.x), |
33 SkScalarRound(rect.origin.y), | 33 SkScalarRound(rect.origin.y), |
34 SkScalarRound(rect.origin.x + rect.size.width), | 34 SkScalarRound(rect.origin.x + rect.size.width), |
35 SkScalarRound(rect.origin.y + rect.size.height) | 35 SkScalarRound(rect.origin.y + rect.size.height) |
36 }; | 36 }; |
37 return sk_rect; | 37 return sk_rect; |
38 } | 38 } |
39 | 39 |
40 #if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5) | |
41 // Possibly remove VideoFrameCapturerMac::CgBlitPreLion as well depending on | |
42 // performance of VideoFrameCapturerMac::CgBlitPostLion on 10.6. | |
43 #error No longer need to import CGDisplayCreateImage. | |
44 #else | |
45 // Declared here because CGDisplayCreateImage does not exist in the 10.5 SDK, | |
46 // which we are currently compiling against, and it is required on 10.7 to do | |
47 // screen capture. | |
48 typedef CGImageRef (*CGDisplayCreateImageFunc)(CGDirectDisplayID displayID); | |
49 #endif | |
50 | |
51 // The amount of time allowed for displays to reconfigure. | 40 // The amount of time allowed for displays to reconfigure. |
52 const int64 kDisplayReconfigurationTimeoutInSeconds = 10; | 41 const int64 kDisplayReconfigurationTimeoutInSeconds = 10; |
53 | 42 |
54 class scoped_pixel_buffer_object { | 43 class scoped_pixel_buffer_object { |
55 public: | 44 public: |
56 scoped_pixel_buffer_object(); | 45 scoped_pixel_buffer_object(); |
57 ~scoped_pixel_buffer_object(); | 46 ~scoped_pixel_buffer_object(); |
58 | 47 |
59 bool Init(CGLContextObj cgl_context, int size_in_bytes); | 48 bool Init(CGLContextObj cgl_context, int size_in_bytes); |
60 void Release(); | 49 void Release(); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
236 // Contains an invalid region from the previous capture. | 225 // Contains an invalid region from the previous capture. |
237 SkRegion last_invalid_region_; | 226 SkRegion last_invalid_region_; |
238 | 227 |
239 // Format of pixels returned in buffer. | 228 // Format of pixels returned in buffer. |
240 media::VideoFrame::Format pixel_format_; | 229 media::VideoFrame::Format pixel_format_; |
241 | 230 |
242 // Acts as a critical section around our display configuration data | 231 // Acts as a critical section around our display configuration data |
243 // structures. Specifically cgl_context_ and pixel_buffer_object_. | 232 // structures. Specifically cgl_context_ and pixel_buffer_object_. |
244 base::WaitableEvent display_configuration_capture_event_; | 233 base::WaitableEvent display_configuration_capture_event_; |
245 | 234 |
246 // Will be non-null on lion. | |
247 CGDisplayCreateImageFunc display_create_image_func_; | |
248 | |
249 // Power management assertion to prevent the screen from sleeping. | 235 // Power management assertion to prevent the screen from sleeping. |
250 IOPMAssertionID power_assertion_id_display_; | 236 IOPMAssertionID power_assertion_id_display_; |
251 | 237 |
252 // Power management assertion to indicate that the user is active. | 238 // Power management assertion to indicate that the user is active. |
253 IOPMAssertionID power_assertion_id_user_; | 239 IOPMAssertionID power_assertion_id_user_; |
254 | 240 |
255 DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerMac); | 241 DISALLOW_COPY_AND_ASSIGN(VideoFrameCapturerMac); |
256 }; | 242 }; |
257 | 243 |
258 VideoFrameCapturerMac::VideoFrameCapturerMac() | 244 VideoFrameCapturerMac::VideoFrameCapturerMac() |
259 : cgl_context_(NULL), | 245 : cgl_context_(NULL), |
260 current_buffer_(0), | 246 current_buffer_(0), |
261 last_buffer_(NULL), | 247 last_buffer_(NULL), |
262 pixel_format_(media::VideoFrame::RGB32), | 248 pixel_format_(media::VideoFrame::RGB32), |
263 display_configuration_capture_event_(false, true), | 249 display_configuration_capture_event_(false, true), |
264 display_create_image_func_(NULL), | |
265 power_assertion_id_display_(kIOPMNullAssertionID), | 250 power_assertion_id_display_(kIOPMNullAssertionID), |
266 power_assertion_id_user_(kIOPMNullAssertionID) { | 251 power_assertion_id_user_(kIOPMNullAssertionID) { |
267 } | 252 } |
268 | 253 |
269 VideoFrameCapturerMac::~VideoFrameCapturerMac() { | 254 VideoFrameCapturerMac::~VideoFrameCapturerMac() { |
270 ReleaseBuffers(); | 255 ReleaseBuffers(); |
271 CGUnregisterScreenRefreshCallback( | 256 CGUnregisterScreenRefreshCallback( |
272 VideoFrameCapturerMac::ScreenRefreshCallback, this); | 257 VideoFrameCapturerMac::ScreenRefreshCallback, this); |
273 CGScreenUnregisterMoveCallback( | 258 CGScreenUnregisterMoveCallback( |
274 VideoFrameCapturerMac::ScreenUpdateMoveCallback, this); | 259 VideoFrameCapturerMac::ScreenUpdateMoveCallback, this); |
(...skipping 18 matching lines...) Expand all Loading... | |
293 LOG(ERROR) << "CGScreenRegisterMoveCallback " << err; | 278 LOG(ERROR) << "CGScreenRegisterMoveCallback " << err; |
294 return false; | 279 return false; |
295 } | 280 } |
296 err = CGDisplayRegisterReconfigurationCallback( | 281 err = CGDisplayRegisterReconfigurationCallback( |
297 VideoFrameCapturerMac::DisplaysReconfiguredCallback, this); | 282 VideoFrameCapturerMac::DisplaysReconfiguredCallback, this); |
298 if (err != kCGErrorSuccess) { | 283 if (err != kCGErrorSuccess) { |
299 LOG(ERROR) << "CGDisplayRegisterReconfigurationCallback " << err; | 284 LOG(ERROR) << "CGDisplayRegisterReconfigurationCallback " << err; |
300 return false; | 285 return false; |
301 } | 286 } |
302 | 287 |
303 if (base::mac::IsOSLionOrLater()) { | |
304 display_create_image_func_ = | |
305 reinterpret_cast<CGDisplayCreateImageFunc>( | |
306 dlsym(RTLD_NEXT, "CGDisplayCreateImage")); | |
307 if (!display_create_image_func_) { | |
308 LOG(ERROR) << "Unable to load CGDisplayCreateImage on Lion"; | |
309 return false; | |
310 } | |
311 } | |
312 ScreenConfigurationChanged(); | 288 ScreenConfigurationChanged(); |
313 return true; | 289 return true; |
314 } | 290 } |
315 | 291 |
316 void VideoFrameCapturerMac::ReleaseBuffers() { | 292 void VideoFrameCapturerMac::ReleaseBuffers() { |
317 if (cgl_context_) { | 293 if (cgl_context_) { |
318 pixel_buffer_object_.Release(); | 294 pixel_buffer_object_.Release(); |
319 CGLDestroyContext(cgl_context_); | 295 CGLDestroyContext(cgl_context_); |
320 cgl_context_ = NULL; | 296 cgl_context_ = NULL; |
321 } | 297 } |
322 // The buffers might be in use by the encoder, so don't delete them here. | 298 // The buffers might be in use by the encoder, so don't delete them here. |
323 // Instead, mark them as "needs update"; next time the buffers are used by | 299 // Instead, mark them as "needs update"; next time the buffers are used by |
324 // the capturer, they will be recreated if necessary. | 300 // the capturer, they will be recreated if necessary. |
325 for (int i = 0; i < kNumBuffers; ++i) { | 301 for (int i = 0; i < kNumBuffers; ++i) { |
326 buffers_[i].set_needs_update(); | 302 buffers_[i].set_needs_update(); |
327 } | 303 } |
328 } | 304 } |
329 | 305 |
330 void VideoFrameCapturerMac::Start(const CursorShapeChangedCallback& callback) { | 306 void VideoFrameCapturerMac::Start(const CursorShapeChangedCallback& callback) { |
331 cursor_shape_changed_callback_ = callback; | 307 cursor_shape_changed_callback_ = callback; |
332 | 308 |
333 // Create power management assertions to wake the display and prevent it from | 309 // Create power management assertions to wake the display and prevent it from |
334 // going to sleep on user idle. | 310 // going to sleep on user idle. |
335 IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, | 311 // TODO(jamiewalch): Use IOPMAssertionDeclareUserActivity on 10.7.3 and above. |
336 kIOPMAssertionLevelOn, | 312 IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, |
337 &power_assertion_id_display_); | 313 kIOPMAssertionLevelOn, |
338 IOPMAssertionCreate(CFSTR("UserIsActive"), | 314 CFSTR("Chrome Remote Desktop connection active"), |
339 kIOPMAssertionLevelOn, | 315 &power_assertion_id_display_); |
340 &power_assertion_id_user_); | 316 IOPMAssertionCreateWithName(CFSTR("UserIsActive"), |
Avi (use Gerrit)
2012/07/30 21:04:36
Can you please put in a brief note as to where you
Jamie
2012/07/30 23:47:15
Done.
| |
317 kIOPMAssertionLevelOn, | |
318 CFSTR("Chrome Remote Desktop connection active"), | |
319 &power_assertion_id_user_); | |
341 } | 320 } |
342 | 321 |
343 void VideoFrameCapturerMac::Stop() { | 322 void VideoFrameCapturerMac::Stop() { |
344 if (power_assertion_id_display_ != kIOPMNullAssertionID) { | 323 if (power_assertion_id_display_ != kIOPMNullAssertionID) { |
345 IOPMAssertionRelease(power_assertion_id_display_); | 324 IOPMAssertionRelease(power_assertion_id_display_); |
346 power_assertion_id_display_ = kIOPMNullAssertionID; | 325 power_assertion_id_display_ = kIOPMNullAssertionID; |
347 } | 326 } |
348 if (power_assertion_id_user_ != kIOPMNullAssertionID) { | 327 if (power_assertion_id_user_ != kIOPMNullAssertionID) { |
349 IOPMAssertionRelease(power_assertion_id_user_); | 328 IOPMAssertionRelease(power_assertion_id_user_); |
350 power_assertion_id_user_ = kIOPMNullAssertionID; | 329 power_assertion_id_user_ = kIOPMNullAssertionID; |
(...skipping 15 matching lines...) Expand all Loading... | |
366 | 345 |
367 // Critical section shared with DisplaysReconfigured(...). | 346 // Critical section shared with DisplaysReconfigured(...). |
368 CHECK(display_configuration_capture_event_.TimedWait( | 347 CHECK(display_configuration_capture_event_.TimedWait( |
369 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); | 348 base::TimeDelta::FromSeconds(kDisplayReconfigurationTimeoutInSeconds))); |
370 SkRegion region; | 349 SkRegion region; |
371 helper_.SwapInvalidRegion(®ion); | 350 helper_.SwapInvalidRegion(®ion); |
372 VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; | 351 VideoFrameBuffer& current_buffer = buffers_[current_buffer_]; |
373 current_buffer.Update(); | 352 current_buffer.Update(); |
374 | 353 |
375 bool flip = false; // GL capturers need flipping. | 354 bool flip = false; // GL capturers need flipping. |
376 if (display_create_image_func_ != NULL) { | 355 if (base::mac::IsOSLionOrLater()) { |
377 // Lion requires us to use their new APIs for doing screen capture. | 356 // Lion requires us to use their new APIs for doing screen capture. These |
357 // APIS currently crash on 10.6.8 if there is no monitor attached. | |
378 CgBlitPostLion(current_buffer, region); | 358 CgBlitPostLion(current_buffer, region); |
379 } else if (cgl_context_) { | 359 } else if (cgl_context_) { |
380 flip = true; | 360 flip = true; |
381 if (pixel_buffer_object_.get() != 0) { | 361 if (pixel_buffer_object_.get() != 0) { |
382 GlBlitFast(current_buffer, region); | 362 GlBlitFast(current_buffer, region); |
383 } else { | 363 } else { |
384 // See comment in scoped_pixel_buffer_object::Init about why the slow | 364 // See comment in scoped_pixel_buffer_object::Init about why the slow |
385 // path is always used on 10.5. | 365 // path is always used on 10.5. |
386 GlBlitSlow(current_buffer); | 366 GlBlitSlow(current_buffer); |
387 } | 367 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 const int buffer_height = buffer.size().height(); | 564 const int buffer_height = buffer.size().height(); |
585 const int buffer_width = buffer.size().width(); | 565 const int buffer_width = buffer.size().width(); |
586 | 566 |
587 // Clip to the size of our current screen. | 567 // Clip to the size of our current screen. |
588 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); | 568 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); |
589 | 569 |
590 if (last_buffer_) | 570 if (last_buffer_) |
591 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); | 571 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); |
592 last_buffer_ = buffer.ptr(); | 572 last_buffer_ = buffer.ptr(); |
593 CGDirectDisplayID main_display = CGMainDisplayID(); | 573 CGDirectDisplayID main_display = CGMainDisplayID(); |
574 #pragma clang diagnostic push | |
575 #pragma clang diagnostic ignored "-Wdeprecated-declarations" | |
594 uint8* display_base_address = | 576 uint8* display_base_address = |
595 reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display)); | 577 reinterpret_cast<uint8*>(CGDisplayBaseAddress(main_display)); |
596 CHECK(display_base_address); | 578 CHECK(display_base_address); |
597 int src_bytes_per_row = CGDisplayBytesPerRow(main_display); | 579 int src_bytes_per_row = CGDisplayBytesPerRow(main_display); |
598 int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8; | 580 int src_bytes_per_pixel = CGDisplayBitsPerPixel(main_display) / 8; |
581 #pragma clang diagnostic pop | |
599 // TODO(hclam): We can reduce the amount of copying here by subtracting | 582 // TODO(hclam): We can reduce the amount of copying here by subtracting |
600 // |capturer_helper_|s region from |last_invalid_region_|. | 583 // |capturer_helper_|s region from |last_invalid_region_|. |
601 // http://crbug.com/92354 | 584 // http://crbug.com/92354 |
602 for(SkRegion::Iterator i(region); !i.done(); i.next()) { | 585 for(SkRegion::Iterator i(region); !i.done(); i.next()) { |
603 SkIRect copy_rect = i.rect(); | 586 SkIRect copy_rect = i.rect(); |
604 if (copy_rect.intersect(clip_rect)) { | 587 if (copy_rect.intersect(clip_rect)) { |
605 CopyRect(display_base_address, | 588 CopyRect(display_base_address, |
606 src_bytes_per_row, | 589 src_bytes_per_row, |
607 buffer.ptr(), | 590 buffer.ptr(), |
608 buffer.bytes_per_row(), | 591 buffer.bytes_per_row(), |
609 src_bytes_per_pixel, | 592 src_bytes_per_pixel, |
610 copy_rect); | 593 copy_rect); |
611 } | 594 } |
612 } | 595 } |
613 } | 596 } |
614 | 597 |
615 void VideoFrameCapturerMac::CgBlitPostLion(const VideoFrameBuffer& buffer, | 598 void VideoFrameCapturerMac::CgBlitPostLion(const VideoFrameBuffer& buffer, |
616 const SkRegion& region) { | 599 const SkRegion& region) { |
617 const int buffer_height = buffer.size().height(); | 600 const int buffer_height = buffer.size().height(); |
618 const int buffer_width = buffer.size().width(); | 601 const int buffer_width = buffer.size().width(); |
619 | 602 |
620 // Clip to the size of our current screen. | 603 // Clip to the size of our current screen. |
621 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); | 604 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); |
622 | 605 |
623 if (last_buffer_) | 606 if (last_buffer_) |
624 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); | 607 memcpy(buffer.ptr(), last_buffer_, buffer.bytes_per_row() * buffer_height); |
625 last_buffer_ = buffer.ptr(); | 608 last_buffer_ = buffer.ptr(); |
626 CGDirectDisplayID display = CGMainDisplayID(); | 609 CGDirectDisplayID display = CGMainDisplayID(); |
627 base::mac::ScopedCFTypeRef<CGImageRef> image( | 610 base::mac::ScopedCFTypeRef<CGImageRef> image( |
628 display_create_image_func_(display)); | 611 CGDisplayCreateImage(display)); |
629 if (image.get() == NULL) | 612 if (image.get() == NULL) |
630 return; | 613 return; |
631 CGDataProviderRef provider = CGImageGetDataProvider(image); | 614 CGDataProviderRef provider = CGImageGetDataProvider(image); |
632 base::mac::ScopedCFTypeRef<CFDataRef> data(CGDataProviderCopyData(provider)); | 615 base::mac::ScopedCFTypeRef<CFDataRef> data(CGDataProviderCopyData(provider)); |
633 if (data.get() == NULL) | 616 if (data.get() == NULL) |
634 return; | 617 return; |
635 const uint8* display_base_address = CFDataGetBytePtr(data); | 618 const uint8* display_base_address = CFDataGetBytePtr(data); |
636 int src_bytes_per_row = CGImageGetBytesPerRow(image); | 619 int src_bytes_per_row = CGImageGetBytesPerRow(image); |
637 int src_bytes_per_pixel = CGImageGetBitsPerPixel(image) / 8; | 620 int src_bytes_per_pixel = CGImageGetBitsPerPixel(image) / 8; |
638 // TODO(hclam): We can reduce the amount of copying here by subtracting | 621 // TODO(hclam): We can reduce the amount of copying here by subtracting |
(...skipping 19 matching lines...) Expand all Loading... | |
658 void VideoFrameCapturerMac::ScreenConfigurationChanged() { | 641 void VideoFrameCapturerMac::ScreenConfigurationChanged() { |
659 ReleaseBuffers(); | 642 ReleaseBuffers(); |
660 helper_.ClearInvalidRegion(); | 643 helper_.ClearInvalidRegion(); |
661 last_buffer_ = NULL; | 644 last_buffer_ = NULL; |
662 | 645 |
663 CGDirectDisplayID mainDevice = CGMainDisplayID(); | 646 CGDirectDisplayID mainDevice = CGMainDisplayID(); |
664 int width = CGDisplayPixelsWide(mainDevice); | 647 int width = CGDisplayPixelsWide(mainDevice); |
665 int height = CGDisplayPixelsHigh(mainDevice); | 648 int height = CGDisplayPixelsHigh(mainDevice); |
666 helper_.InvalidateScreen(SkISize::Make(width, height)); | 649 helper_.InvalidateScreen(SkISize::Make(width, height)); |
667 | 650 |
668 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { | 651 if (base::mac::IsOSLionOrLater()) { |
669 VLOG(3) << "OpenGL support not available."; | 652 LOG(INFO) << "Using CgBlitPostLion."; |
Robert Sesek
2012/07/30 21:50:37
This will be spammy, along with the other LOG stat
Jamie
2012/07/30 21:55:53
It should only be logged once per Chromoting sessi
| |
670 return; | |
671 } | |
672 | |
673 if (display_create_image_func_ != NULL) { | |
674 // No need for any OpenGL support on Lion | 653 // No need for any OpenGL support on Lion |
675 return; | 654 return; |
676 } | 655 } |
677 | 656 |
657 if (!CGDisplayUsesOpenGLAcceleration(mainDevice)) { | |
658 LOG(INFO) << "Using CgBlitPreLion."; | |
659 return; | |
660 } | |
661 | |
662 LOG(INFO) << "Using GlBlit"; | |
663 | |
678 CGLPixelFormatAttribute attributes[] = { | 664 CGLPixelFormatAttribute attributes[] = { |
679 kCGLPFAFullScreen, | 665 kCGLPFAFullScreen, |
680 kCGLPFADisplayMask, | 666 kCGLPFADisplayMask, |
681 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), | 667 (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice), |
682 (CGLPixelFormatAttribute)0 | 668 (CGLPixelFormatAttribute)0 |
683 }; | 669 }; |
684 CGLPixelFormatObj pixel_format = NULL; | 670 CGLPixelFormatObj pixel_format = NULL; |
685 GLint matching_pixel_format_count = 0; | 671 GLint matching_pixel_format_count = 0; |
686 CGLError err = CGLChoosePixelFormat(attributes, | 672 CGLError err = CGLChoosePixelFormat(attributes, |
687 &pixel_format, | 673 &pixel_format, |
688 &matching_pixel_format_count); | 674 &matching_pixel_format_count); |
689 DCHECK_EQ(err, kCGLNoError); | 675 DCHECK_EQ(err, kCGLNoError); |
690 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); | 676 err = CGLCreateContext(pixel_format, NULL, &cgl_context_); |
691 DCHECK_EQ(err, kCGLNoError); | 677 DCHECK_EQ(err, kCGLNoError); |
692 CGLDestroyPixelFormat(pixel_format); | 678 CGLDestroyPixelFormat(pixel_format); |
693 CGLSetFullScreen(cgl_context_); | 679 CGLSetFullScreenOnDisplay(cgl_context_, |
680 CGDisplayIDToOpenGLDisplayMask(mainDevice)); | |
694 CGLSetCurrentContext(cgl_context_); | 681 CGLSetCurrentContext(cgl_context_); |
695 | 682 |
696 size_t buffer_size = width * height * sizeof(uint32_t); | 683 size_t buffer_size = width * height * sizeof(uint32_t); |
697 pixel_buffer_object_.Init(cgl_context_, buffer_size); | 684 pixel_buffer_object_.Init(cgl_context_, buffer_size); |
698 } | 685 } |
699 | 686 |
700 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, | 687 void VideoFrameCapturerMac::ScreenRefresh(CGRectCount count, |
701 const CGRect* rect_array) { | 688 const CGRect* rect_array) { |
702 SkIRect skirect_array[count]; | 689 SkIRect skirect_array[count]; |
703 for (CGRectCount i = 0; i < count; ++i) { | 690 for (CGRectCount i = 0; i < count; ++i) { |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 VideoFrameCapturer* VideoFrameCapturer::Create() { | 761 VideoFrameCapturer* VideoFrameCapturer::Create() { |
775 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); | 762 VideoFrameCapturerMac* capturer = new VideoFrameCapturerMac(); |
776 if (!capturer->Init()) { | 763 if (!capturer->Init()) { |
777 delete capturer; | 764 delete capturer; |
778 capturer = NULL; | 765 capturer = NULL; |
779 } | 766 } |
780 return capturer; | 767 return capturer; |
781 } | 768 } |
782 | 769 |
783 } // namespace remoting | 770 } // namespace remoting |
OLD | NEW |