Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: webrtc/modules/desktop_capture/screen_capturer_mac.mm

Issue 1902323002: Modify ScreenCaptureFrameQueue into a template (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix build break in linux Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
26 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" 27 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
27 #include "webrtc/modules/desktop_capture/desktop_frame.h" 28 #include "webrtc/modules/desktop_capture/desktop_frame.h"
28 #include "webrtc/modules/desktop_capture/desktop_geometry.h" 29 #include "webrtc/modules/desktop_capture/desktop_geometry.h"
29 #include "webrtc/modules/desktop_capture/desktop_region.h" 30 #include "webrtc/modules/desktop_capture/desktop_region.h"
30 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h" 31 #include "webrtc/modules/desktop_capture/mac/desktop_configuration.h"
31 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h" 32 #include "webrtc/modules/desktop_capture/mac/desktop_configuration_monitor.h"
32 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h" 33 #include "webrtc/modules/desktop_capture/mac/scoped_pixel_buffer_object.h"
33 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" 34 #include "webrtc/modules/desktop_capture/screen_capture_queue.h"
34 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" 35 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h"
36 #include "webrtc/modules/desktop_capture/shared_desktop_frame.h"
35 #include "webrtc/system_wrappers/include/logging.h" 37 #include "webrtc/system_wrappers/include/logging.h"
36 #include "webrtc/system_wrappers/include/tick_util.h" 38 #include "webrtc/system_wrappers/include/tick_util.h"
37 39
38 namespace webrtc { 40 namespace webrtc {
39 41
40 namespace { 42 namespace {
41 43
42 // Definitions used to dynamic-link to deprecated OS 10.6 functions. 44 // Definitions used to dynamic-link to deprecated OS 10.6 functions.
43 const char* kApplicationServicesLibraryName = 45 const char* kApplicationServicesLibraryName =
44 "/System/Library/Frameworks/ApplicationServices.framework/" 46 "/System/Library/Frameworks/ApplicationServices.framework/"
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 const CGRect *rect_array); 221 const CGRect *rect_array);
220 static void ScreenRefreshCallback(CGRectCount count, 222 static void ScreenRefreshCallback(CGRectCount count,
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 std::unique_ptr<DesktopFrame> CreateFrame();
230 232
231 Callback* callback_; 233 Callback* callback_;
232 234
233 CGLContextObj cgl_context_; 235 CGLContextObj cgl_context_;
234 ScopedPixelBufferObject pixel_buffer_object_; 236 ScopedPixelBufferObject pixel_buffer_object_;
235 237
236 // Queue of the frames buffers. 238 // Queue of the frames buffers.
237 ScreenCaptureFrameQueue queue_; 239 ScreenCaptureQueue<SharedDesktopFrame> queue_;
238 240
239 // Current display configuration. 241 // Current display configuration.
240 MacDesktopConfiguration desktop_config_; 242 MacDesktopConfiguration desktop_config_;
241 243
242 // Currently selected display, or 0 if the full desktop is selected. On OS X 244 // Currently selected display, or 0 if the full desktop is selected. On OS X
243 // 10.6 and before, this is always 0. 245 // 10.6 and before, this is always 0.
244 CGDirectDisplayID current_display_; 246 CGDirectDisplayID current_display_;
245 247
246 // The physical pixel bounds of the current screen. 248 // The physical pixel bounds of the current screen.
247 DesktopRect screen_pixel_bounds_; 249 DesktopRect screen_pixel_bounds_;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) {
384 TickTime capture_start_time = TickTime::Now(); 386 TickTime capture_start_time = TickTime::Now();
385 387
386 queue_.MoveToNextFrame(); 388 queue_.MoveToNext();
389 RTC_DCHECK(!queue_.current() || !queue_.current()->IsShared());
387 390
388 desktop_config_monitor_->Lock(); 391 desktop_config_monitor_->Lock();
389 MacDesktopConfiguration new_config = 392 MacDesktopConfiguration new_config =
390 desktop_config_monitor_->desktop_configuration(); 393 desktop_config_monitor_->desktop_configuration();
391 if (!desktop_config_.Equals(new_config)) { 394 if (!desktop_config_.Equals(new_config)) {
392 desktop_config_ = new_config; 395 desktop_config_ = new_config;
393 // If the display configuraiton has changed then refresh capturer data 396 // If the display configuraiton has changed then refresh capturer data
394 // structures. Occasionally, the refresh and move handlers are lost when 397 // structures. Occasionally, the refresh and move handlers are lost when
395 // the screen mode changes, so re-register them here. 398 // the screen mode changes, so re-register them here.
396 UnregisterRefreshAndMoveHandlers(); 399 UnregisterRefreshAndMoveHandlers();
397 RegisterRefreshAndMoveHandlers(); 400 RegisterRefreshAndMoveHandlers();
398 ScreenConfigurationChanged(); 401 ScreenConfigurationChanged();
399 } 402 }
400 403
401 DesktopRegion region; 404 DesktopRegion region;
402 helper_.TakeInvalidRegion(&region); 405 helper_.TakeInvalidRegion(&region);
403 406
404 // If the current buffer is from an older generation then allocate a new one. 407 // If the current buffer is from an older generation then allocate a new one.
405 // Note that we can't reallocate other buffers at this point, since the caller 408 // Note that we can't reallocate other buffers at this point, since the caller
406 // may still be reading from them. 409 // may still be reading from them.
407 if (!queue_.current_frame()) 410 if (!queue_.current())
408 queue_.ReplaceCurrentFrame(CreateFrame()); 411 queue_.ReplaceCurrent(SharedDesktopFrame::Wrap(CreateFrame()));
409 412
410 DesktopFrame* current_frame = queue_.current_frame(); 413 DesktopFrame* current_frame = queue_.current();
411 414
412 bool flip = false; // GL capturers need flipping. 415 bool flip = false; // GL capturers need flipping.
413 if (rtc::GetOSVersionName() >= rtc::kMacOSLion) { 416 if (rtc::GetOSVersionName() >= rtc::kMacOSLion) {
414 // Lion requires us to use their new APIs for doing screen capture. These 417 // Lion requires us to use their new APIs for doing screen capture. These
415 // APIS currently crash on 10.6.8 if there is no monitor attached. 418 // APIS currently crash on 10.6.8 if there is no monitor attached.
416 if (!CgBlitPostLion(*current_frame, region)) { 419 if (!CgBlitPostLion(*current_frame, region)) {
417 desktop_config_monitor_->Unlock(); 420 desktop_config_monitor_->Unlock();
418 callback_->OnCaptureCompleted(NULL); 421 callback_->OnCaptureCompleted(NULL);
419 return; 422 return;
420 } 423 }
421 } else if (cgl_context_) { 424 } else if (cgl_context_) {
422 flip = true; 425 flip = true;
423 if (pixel_buffer_object_.get() != 0) { 426 if (pixel_buffer_object_.get() != 0) {
424 GlBlitFast(*current_frame, region); 427 GlBlitFast(*current_frame, region);
425 } else { 428 } else {
426 // See comment in ScopedPixelBufferObject::Init about why the slow 429 // See comment in ScopedPixelBufferObject::Init about why the slow
427 // path is always used on 10.5. 430 // path is always used on 10.5.
428 GlBlitSlow(*current_frame); 431 GlBlitSlow(*current_frame);
429 } 432 }
430 } else { 433 } else {
431 CgBlitPreLion(*current_frame, region); 434 CgBlitPreLion(*current_frame, region);
432 } 435 }
433 436
434 DesktopFrame* new_frame = queue_.current_frame()->Share(); 437 DesktopFrame* new_frame = queue_.current()->Share();
435 *new_frame->mutable_updated_region() = region; 438 *new_frame->mutable_updated_region() = region;
436 439
437 if (flip) 440 if (flip)
438 new_frame = new InvertedDesktopFrame(new_frame); 441 new_frame = new InvertedDesktopFrame(new_frame);
439 442
440 helper_.set_size_most_recent(new_frame->size()); 443 helper_.set_size_most_recent(new_frame->size());
441 444
442 // Signal that we are done capturing data from the display framebuffer, 445 // Signal that we are done capturing data from the display framebuffer,
443 // and accessing display structures. 446 // and accessing display structures.
444 desktop_config_monitor_->Unlock(); 447 desktop_config_monitor_->Unlock();
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 } 493 }
491 494
492 ScreenConfigurationChanged(); 495 ScreenConfigurationChanged();
493 return true; 496 return true;
494 } 497 }
495 498
496 void ScreenCapturerMac::GlBlitFast(const DesktopFrame& frame, 499 void ScreenCapturerMac::GlBlitFast(const DesktopFrame& frame,
497 const DesktopRegion& region) { 500 const DesktopRegion& region) {
498 // Clip to the size of our current screen. 501 // Clip to the size of our current screen.
499 DesktopRect clip_rect = DesktopRect::MakeSize(frame.size()); 502 DesktopRect clip_rect = DesktopRect::MakeSize(frame.size());
500 if (queue_.previous_frame()) { 503 if (queue_.previous()) {
501 // We are doing double buffer for the capture data so we just need to copy 504 // We are doing double buffer for the capture data so we just need to copy
502 // the invalid region from the previous capture in the current buffer. 505 // the invalid region from the previous capture in the current buffer.
503 // TODO(hclam): We can reduce the amount of copying here by subtracting 506 // TODO(hclam): We can reduce the amount of copying here by subtracting
504 // |capturer_helper_|s region from |last_invalid_region_|. 507 // |capturer_helper_|s region from |last_invalid_region_|.
505 // http://crbug.com/92354 508 // http://crbug.com/92354
506 509
507 // Since the image obtained from OpenGL is upside-down, need to do some 510 // Since the image obtained from OpenGL is upside-down, need to do some
508 // magic here to copy the correct rectangle. 511 // magic here to copy the correct rectangle.
509 const int y_offset = (frame.size().height() - 1) * frame.stride(); 512 const int y_offset = (frame.size().height() - 1) * frame.stride();
510 for (DesktopRegion::Iterator i(last_invalid_region_); 513 for (DesktopRegion::Iterator i(last_invalid_region_);
511 !i.IsAtEnd(); i.Advance()) { 514 !i.IsAtEnd(); i.Advance()) {
512 DesktopRect copy_rect = i.rect(); 515 DesktopRect copy_rect = i.rect();
513 copy_rect.IntersectWith(clip_rect); 516 copy_rect.IntersectWith(clip_rect);
514 if (!copy_rect.is_empty()) { 517 if (!copy_rect.is_empty()) {
515 CopyRect(queue_.previous_frame()->data() + y_offset, 518 CopyRect(queue_.previous()->data() + y_offset,
516 -frame.stride(), 519 -frame.stride(),
517 frame.data() + y_offset, 520 frame.data() + y_offset,
518 -frame.stride(), 521 -frame.stride(),
519 DesktopFrame::kBytesPerPixel, 522 DesktopFrame::kBytesPerPixel,
520 copy_rect); 523 copy_rect);
521 } 524 }
522 } 525 }
523 } 526 }
524 last_invalid_region_ = region; 527 last_invalid_region_ = region;
525 528
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 glReadPixels(0, 0, frame.size().width(), frame.size().height(), 577 glReadPixels(0, 0, frame.size().width(), frame.size().height(),
575 GL_BGRA, GL_UNSIGNED_BYTE, frame.data()); 578 GL_BGRA, GL_UNSIGNED_BYTE, frame.data());
576 glPopClientAttrib(); 579 glPopClientAttrib();
577 } 580 }
578 581
579 void ScreenCapturerMac::CgBlitPreLion(const DesktopFrame& frame, 582 void ScreenCapturerMac::CgBlitPreLion(const DesktopFrame& frame,
580 const DesktopRegion& region) { 583 const DesktopRegion& region) {
581 // Copy the entire contents of the previous capture buffer, to capture over. 584 // Copy the entire contents of the previous capture buffer, to capture over.
582 // TODO(wez): Get rid of this as per crbug.com/145064, or implement 585 // TODO(wez): Get rid of this as per crbug.com/145064, or implement
583 // crbug.com/92354. 586 // crbug.com/92354.
584 if (queue_.previous_frame()) { 587 if (queue_.previous()) {
585 memcpy(frame.data(), 588 memcpy(frame.data(),
586 queue_.previous_frame()->data(), 589 queue_.previous()->data(),
587 frame.stride() * frame.size().height()); 590 frame.stride() * frame.size().height());
588 } 591 }
589 592
590 for (size_t i = 0; i < desktop_config_.displays.size(); ++i) { 593 for (size_t i = 0; i < desktop_config_.displays.size(); ++i) {
591 const MacDisplayConfiguration& display_config = desktop_config_.displays[i]; 594 const MacDisplayConfiguration& display_config = desktop_config_.displays[i];
592 595
593 // Use deprecated APIs to determine the display buffer layout. 596 // Use deprecated APIs to determine the display buffer layout.
594 assert(cg_display_base_address_ && cg_display_bytes_per_row_ && 597 assert(cg_display_base_address_ && cg_display_bytes_per_row_ &&
595 cg_display_bits_per_pixel_); 598 cg_display_bits_per_pixel_);
596 uint8_t* display_base_address = reinterpret_cast<uint8_t*>( 599 uint8_t* display_base_address = reinterpret_cast<uint8_t*>(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 i.rect()); 632 i.rect());
630 } 633 }
631 } 634 }
632 } 635 }
633 636
634 bool ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame, 637 bool ScreenCapturerMac::CgBlitPostLion(const DesktopFrame& frame,
635 const DesktopRegion& region) { 638 const DesktopRegion& region) {
636 // Copy the entire contents of the previous capture buffer, to capture over. 639 // Copy the entire contents of the previous capture buffer, to capture over.
637 // TODO(wez): Get rid of this as per crbug.com/145064, or implement 640 // TODO(wez): Get rid of this as per crbug.com/145064, or implement
638 // crbug.com/92354. 641 // crbug.com/92354.
639 if (queue_.previous_frame()) { 642 if (queue_.previous()) {
640 memcpy(frame.data(), 643 memcpy(frame.data(),
641 queue_.previous_frame()->data(), 644 queue_.previous()->data(),
642 frame.stride() * frame.size().height()); 645 frame.stride() * frame.size().height());
643 } 646 }
644 647
645 MacDisplayConfigurations displays_to_capture; 648 MacDisplayConfigurations displays_to_capture;
646 if (current_display_) { 649 if (current_display_) {
647 // Capturing a single screen. Note that the screen id may change when 650 // Capturing a single screen. Note that the screen id may change when
648 // screens are added or removed. 651 // screens are added or removed.
649 const MacDisplayConfiguration* config = 652 const MacDisplayConfiguration* config =
650 desktop_config_.FindDisplayConfigurationById(current_display_); 653 desktop_config_.FindDisplayConfigurationById(current_display_);
651 if (config) { 654 if (config) {
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after
957 void ScreenCapturerMac::ScreenUpdateMoveCallback( 960 void ScreenCapturerMac::ScreenUpdateMoveCallback(
958 CGScreenUpdateMoveDelta delta, 961 CGScreenUpdateMoveDelta delta,
959 size_t count, 962 size_t count,
960 const CGRect* rect_array, 963 const CGRect* rect_array,
961 void* user_parameter) { 964 void* user_parameter) {
962 ScreenCapturerMac* capturer = 965 ScreenCapturerMac* capturer =
963 reinterpret_cast<ScreenCapturerMac*>(user_parameter); 966 reinterpret_cast<ScreenCapturerMac*>(user_parameter);
964 capturer->ScreenUpdateMove(delta, count, rect_array); 967 capturer->ScreenUpdateMove(delta, count, rect_array);
965 } 968 }
966 969
967 DesktopFrame* ScreenCapturerMac::CreateFrame() { 970 std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() {
968 std::unique_ptr<DesktopFrame> frame( 971 std::unique_ptr<DesktopFrame> frame(
969 new BasicDesktopFrame(screen_pixel_bounds_.size())); 972 new BasicDesktopFrame(screen_pixel_bounds_.size()));
970 973
971 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_, 974 frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_,
972 kStandardDPI * dip_to_pixel_scale_)); 975 kStandardDPI * dip_to_pixel_scale_));
973 return frame.release(); 976 return frame;
974 } 977 }
975 978
976 } // namespace 979 } // namespace
977 980
978 // static 981 // static
979 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { 982 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
980 if (!options.configuration_monitor()) 983 if (!options.configuration_monitor())
981 return NULL; 984 return NULL;
982 985
983 std::unique_ptr<ScreenCapturerMac> capturer( 986 std::unique_ptr<ScreenCapturerMac> capturer(
984 new ScreenCapturerMac(options.configuration_monitor())); 987 new ScreenCapturerMac(options.configuration_monitor()));
985 if (!capturer->Init()) 988 if (!capturer->Init())
986 capturer.reset(); 989 capturer.reset();
987 return capturer.release(); 990 return capturer.release();
988 } 991 }
989 992
990 } // namespace webrtc 993 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698