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/capturer/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> |
11 #include <OpenGL/CGLMacro.h> | 11 #include <OpenGL/CGLMacro.h> |
12 #include <OpenGL/OpenGL.h> | 12 #include <OpenGL/OpenGL.h> |
13 #include <set> | 13 #include <set> |
14 #include <stddef.h> | 14 #include <stddef.h> |
15 | 15 |
16 #include "base/logging.h" | 16 #include "base/logging.h" |
17 #include "base/file_path.h" | 17 #include "base/file_path.h" |
18 #include "base/mac/mac_util.h" | 18 #include "base/mac/mac_util.h" |
19 #include "base/mac/scoped_cftyperef.h" | 19 #include "base/mac/scoped_cftyperef.h" |
20 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
21 #include "base/scoped_native_library.h" | 21 #include "base/scoped_native_library.h" |
22 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
23 #include "base/time.h" | 23 #include "base/time.h" |
24 #include "remoting/base/capture_data.h" | 24 #include "remoting/capturer/capture_data.h" |
25 #include "remoting/base/util.h" | 25 #include "remoting/capturer/mac/scoped_pixel_buffer_object.h" |
26 #include "remoting/host/mac/scoped_pixel_buffer_object.h" | 26 #include "remoting/capturer/mouse_cursor_shape.h" |
27 #include "remoting/host/video_frame.h" | 27 #include "remoting/capturer/video_frame.h" |
28 #include "remoting/host/video_frame_capturer_helper.h" | 28 #include "remoting/capturer/video_frame_capturer_helper.h" |
29 #include "remoting/host/video_frame_queue.h" | 29 #include "remoting/capturer/video_frame_queue.h" |
30 #include "remoting/proto/control.pb.h" | |
31 | 30 |
32 namespace remoting { | 31 namespace remoting { |
33 | 32 |
34 namespace { | 33 namespace { |
35 | 34 |
36 // Definitions used to dynamic-link to deprecated OS 10.6 functions. | 35 // Definitions used to dynamic-link to deprecated OS 10.6 functions. |
37 const char* kApplicationServicesLibraryName = | 36 const char* kApplicationServicesLibraryName = |
38 "/System/Library/Frameworks/ApplicationServices.framework/" | 37 "/System/Library/Frameworks/ApplicationServices.framework/" |
39 "ApplicationServices"; | 38 "ApplicationServices"; |
40 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); | 39 typedef void* (*CGDisplayBaseAddressFunc)(CGDirectDisplayID); |
41 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); | 40 typedef size_t (*CGDisplayBytesPerRowFunc)(CGDirectDisplayID); |
42 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); | 41 typedef size_t (*CGDisplayBitsPerPixelFunc)(CGDirectDisplayID); |
43 const char* kOpenGlLibraryName = | 42 const char* kOpenGlLibraryName = |
44 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; | 43 "/System/Library/Frameworks/OpenGL.framework/OpenGL"; |
45 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); | 44 typedef CGLError (*CGLSetFullScreenFunc)(CGLContextObj); |
46 | 45 |
47 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). | 46 // skia/ext/skia_utils_mac.h only defines CGRectToSkRect(). |
48 SkIRect CGRectToSkIRect(const CGRect& rect) { | 47 SkIRect CGRectToSkIRect(const CGRect& rect) { |
49 SkIRect sk_rect = { | 48 SkIRect sk_rect = { |
50 SkScalarRound(rect.origin.x), | 49 SkScalarRound(rect.origin.x), |
51 SkScalarRound(rect.origin.y), | 50 SkScalarRound(rect.origin.y), |
52 SkScalarRound(rect.origin.x + rect.size.width), | 51 SkScalarRound(rect.origin.x + rect.size.width), |
53 SkScalarRound(rect.origin.y + rect.size.height) | 52 SkScalarRound(rect.origin.y + rect.size.height) |
54 }; | 53 }; |
55 return sk_rect; | 54 return sk_rect; |
56 } | 55 } |
57 | 56 |
| 57 // Copy pixels in the |rect| from |src_place| to |dest_plane|. |
| 58 void CopyRect(const uint8* src_plane, |
| 59 int src_plane_stride, |
| 60 uint8* dest_plane, |
| 61 int dest_plane_stride, |
| 62 int bytes_per_pixel, |
| 63 const SkIRect& rect) { |
| 64 // Get the address of the starting point. |
| 65 const int src_y_offset = src_plane_stride * rect.top(); |
| 66 const int dest_y_offset = dest_plane_stride * rect.top(); |
| 67 const int x_offset = bytes_per_pixel * rect.left(); |
| 68 src_plane += src_y_offset + x_offset; |
| 69 dest_plane += dest_y_offset + x_offset; |
| 70 |
| 71 // Copy pixels in the rectangle line by line. |
| 72 const int bytes_per_line = bytes_per_pixel * rect.width(); |
| 73 const int height = rect.height(); |
| 74 for (int i = 0 ; i < height; ++i) { |
| 75 memcpy(dest_plane, src_plane, bytes_per_line); |
| 76 src_plane += src_plane_stride; |
| 77 dest_plane += dest_plane_stride; |
| 78 } |
| 79 } |
| 80 |
58 // The amount of time allowed for displays to reconfigure. | 81 // The amount of time allowed for displays to reconfigure. |
59 const int64 kDisplayConfigurationEventTimeoutInSeconds = 10; | 82 const int64 kDisplayConfigurationEventTimeoutInSeconds = 10; |
60 | 83 |
61 // A class representing a full-frame pixel buffer. | 84 // A class representing a full-frame pixel buffer. |
62 class VideoFrameMac : public VideoFrame { | 85 class VideoFrameMac : public VideoFrame { |
63 public: | 86 public: |
64 explicit VideoFrameMac(const SkISize& size); | 87 explicit VideoFrameMac(const SkISize& size); |
65 virtual ~VideoFrameMac(); | 88 virtual ~VideoFrameMac(); |
66 | 89 |
67 const SkIPoint& dpi() const { return dpi_; } | 90 const SkIPoint& dpi() const { return dpi_; } |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 CHECK(data_size == CFDataGetLength(data_ref_current)); | 437 CHECK(data_size == CFDataGetLength(data_ref_current)); |
415 const uint8* data_new = CFDataGetBytePtr(data_ref_new); | 438 const uint8* data_new = CFDataGetBytePtr(data_ref_new); |
416 const uint8* data_current = CFDataGetBytePtr(data_ref_current); | 439 const uint8* data_current = CFDataGetBytePtr(data_ref_current); |
417 if (memcmp(data_new, data_current, data_size) == 0) { | 440 if (memcmp(data_new, data_current, data_size) == 0) { |
418 return; | 441 return; |
419 } | 442 } |
420 } | 443 } |
421 } | 444 } |
422 } | 445 } |
423 | 446 |
| 447 // Record the last cursor image. |
| 448 current_cursor_.reset(CGImageCreateCopy(image)); |
| 449 |
424 VLOG(3) << "Sending cursor: " << size.width << "x" << size.height; | 450 VLOG(3) << "Sending cursor: " << size.width << "x" << size.height; |
425 | 451 |
426 CGDataProviderRef provider = CGImageGetDataProvider(image); | 452 CGDataProviderRef provider = CGImageGetDataProvider(image); |
427 base::mac::ScopedCFTypeRef<CFDataRef> image_data_ref( | 453 base::mac::ScopedCFTypeRef<CFDataRef> image_data_ref( |
428 CGDataProviderCopyData(provider)); | 454 CGDataProviderCopyData(provider)); |
429 if (image_data_ref.get() == NULL) { | 455 if (image_data_ref.get() == NULL) { |
430 return; | 456 return; |
431 } | 457 } |
432 const uint8* cursor_src_data = CFDataGetBytePtr(image_data_ref); | 458 const char* cursor_src_data = |
| 459 reinterpret_cast<const char*>(CFDataGetBytePtr(image_data_ref)); |
433 int data_size = CFDataGetLength(image_data_ref); | 460 int data_size = CFDataGetLength(image_data_ref); |
434 | 461 |
435 // Create a CursorShapeInfo proto that describes the cursor and pass it to | 462 // Create a MouseCursorShape that describes the cursor and pass it to |
436 // the client. | 463 // the client. |
437 scoped_ptr<protocol::CursorShapeInfo> cursor_proto( | 464 scoped_ptr<MouseCursorShape> cursor_shape(new MouseCursorShape()); |
438 new protocol::CursorShapeInfo()); | 465 cursor_shape->size.set(size.width, size.height); |
439 cursor_proto->mutable_data()->resize(data_size); | 466 cursor_shape->hotspot.set(hotspot.x, hotspot.y); |
440 uint8* cursor_tgt_data = const_cast<uint8*>(reinterpret_cast<const uint8*>( | 467 cursor_shape->data.assign(cursor_src_data, cursor_src_data + data_size); |
441 cursor_proto->mutable_data()->data())); | |
442 | 468 |
443 memcpy(cursor_tgt_data, cursor_src_data, data_size); | 469 delegate_->OnCursorShapeChanged(cursor_shape.Pass()); |
444 | |
445 cursor_proto->set_width(size.width); | |
446 cursor_proto->set_height(size.height); | |
447 cursor_proto->set_hotspot_x(hotspot.x); | |
448 cursor_proto->set_hotspot_y(hotspot.y); | |
449 delegate_->OnCursorShapeChanged(cursor_proto.Pass()); | |
450 | |
451 // Record the last cursor image that we sent. | |
452 current_cursor_.reset(CGImageCreateCopy(image)); | |
453 } | 470 } |
454 | 471 |
455 void VideoFrameCapturerMac::GlBlitFast(const VideoFrame& buffer, | 472 void VideoFrameCapturerMac::GlBlitFast(const VideoFrame& buffer, |
456 const SkRegion& region) { | 473 const SkRegion& region) { |
457 const int buffer_height = buffer.dimensions().height(); | 474 const int buffer_height = buffer.dimensions().height(); |
458 const int buffer_width = buffer.dimensions().width(); | 475 const int buffer_width = buffer.dimensions().width(); |
459 | 476 |
460 // Clip to the size of our current screen. | 477 // Clip to the size of our current screen. |
461 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); | 478 SkIRect clip_rect = SkIRect::MakeWH(buffer_width, buffer_height); |
462 if (queue_.previous_frame()) { | 479 if (queue_.previous_frame()) { |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 } | 865 } |
849 | 866 |
850 // static | 867 // static |
851 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( | 868 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( |
852 SharedBufferFactory* shared_buffer_factory) { | 869 SharedBufferFactory* shared_buffer_factory) { |
853 NOTIMPLEMENTED(); | 870 NOTIMPLEMENTED(); |
854 return scoped_ptr<VideoFrameCapturer>(); | 871 return scoped_ptr<VideoFrameCapturer>(); |
855 } | 872 } |
856 | 873 |
857 } // namespace remoting | 874 } // namespace remoting |
OLD | NEW |