| 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 <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
| 8 #include <X11/Xutil.h> | 8 #include <X11/Xutil.h> |
| 9 #include <X11/extensions/Xdamage.h> | 9 #include <X11/extensions/Xdamage.h> |
| 10 #include <X11/extensions/Xfixes.h> | 10 #include <X11/extensions/Xfixes.h> |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 class VideoFrameCapturerLinux : public VideoFrameCapturer { | 75 class VideoFrameCapturerLinux : public VideoFrameCapturer { |
| 76 public: | 76 public: |
| 77 VideoFrameCapturerLinux(); | 77 VideoFrameCapturerLinux(); |
| 78 virtual ~VideoFrameCapturerLinux(); | 78 virtual ~VideoFrameCapturerLinux(); |
| 79 | 79 |
| 80 bool Init(); // TODO(ajwong): Do we really want this to be synchronous? | 80 bool Init(); // TODO(ajwong): Do we really want this to be synchronous? |
| 81 | 81 |
| 82 // Capturer interface. | 82 // Capturer interface. |
| 83 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; | 83 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; |
| 84 virtual void Stop() OVERRIDE; | 84 virtual void Stop() OVERRIDE; |
| 85 virtual void ScreenConfigurationChanged() OVERRIDE; | |
| 86 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; | 85 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; |
| 87 virtual void ClearInvalidRegion() OVERRIDE; | |
| 88 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; | 86 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; |
| 89 virtual void InvalidateScreen(const SkISize& size) OVERRIDE; | |
| 90 virtual void InvalidateFullScreen() OVERRIDE; | |
| 91 virtual void CaptureInvalidRegion( | 87 virtual void CaptureInvalidRegion( |
| 92 const CaptureCompletedCallback& callback) OVERRIDE; | 88 const CaptureCompletedCallback& callback) OVERRIDE; |
| 93 virtual const SkISize& size_most_recent() const OVERRIDE; | 89 virtual const SkISize& size_most_recent() const OVERRIDE; |
| 94 | 90 |
| 95 private: | 91 private: |
| 96 void InitXDamage(); | 92 void InitXDamage(); |
| 97 | 93 |
| 98 // Read and handle all currently-pending XEvents. | 94 // Read and handle all currently-pending XEvents. |
| 99 // In the DAMAGE case, process the XDamage events and store the resulting | 95 // In the DAMAGE case, process the XDamage events and store the resulting |
| 100 // damage rectangles in the VideoFrameCapturerHelper. | 96 // damage rectangles in the VideoFrameCapturerHelper. |
| 101 // In all cases, call ScreenConfigurationChanged() in response to any | 97 // In all cases, call ScreenConfigurationChanged() in response to any |
| 102 // ConfigNotify events. | 98 // ConfigNotify events. |
| 103 void ProcessPendingXEvents(); | 99 void ProcessPendingXEvents(); |
| 104 | 100 |
| 105 // Capture screen pixels, and return the data in a new CaptureData object, | 101 // Capture screen pixels, and return the data in a new CaptureData object, |
| 106 // to be freed by the caller. | 102 // to be freed by the caller. |
| 107 // In the DAMAGE case, the VideoFrameCapturerHelper already holds the list of | 103 // In the DAMAGE case, the VideoFrameCapturerHelper already holds the list of |
| 108 // invalid rectangles from ProcessPendingXEvents(). | 104 // invalid rectangles from ProcessPendingXEvents(). |
| 109 // In the non-DAMAGE case, this captures the whole screen, then calculates | 105 // In the non-DAMAGE case, this captures the whole screen, then calculates |
| 110 // some invalid rectangles that include any differences between this and the | 106 // some invalid rectangles that include any differences between this and the |
| 111 // previous capture. | 107 // previous capture. |
| 112 CaptureData* CaptureFrame(); | 108 CaptureData* CaptureFrame(); |
| 113 | 109 |
| 114 // Capture the cursor image and call the CursorShapeChangedCallback if it | 110 // Capture the cursor image and call the CursorShapeChangedCallback if it |
| 115 // has been set (using SetCursorShapeChangedCallback). | 111 // has been set (using SetCursorShapeChangedCallback). |
| 116 void CaptureCursor(); | 112 void CaptureCursor(); |
| 117 | 113 |
| 114 // Called when the screen configuration is changed. |
| 115 void ScreenConfigurationChanged(); |
| 116 |
| 118 // Synchronize the current buffer with |last_buffer_|, by copying pixels from | 117 // Synchronize the current buffer with |last_buffer_|, by copying pixels from |
| 119 // the area of |last_invalid_rects|. | 118 // the area of |last_invalid_rects|. |
| 120 // Note this only works on the assumption that kNumBuffers == 2, as | 119 // Note this only works on the assumption that kNumBuffers == 2, as |
| 121 // |last_invalid_rects| holds the differences from the previous buffer and | 120 // |last_invalid_rects| holds the differences from the previous buffer and |
| 122 // the one prior to that (which will then be the current buffer). | 121 // the one prior to that (which will then be the current buffer). |
| 123 void SynchronizeFrame(); | 122 void SynchronizeFrame(); |
| 124 | 123 |
| 125 void DeinitXlib(); | 124 void DeinitXlib(); |
| 126 | 125 |
| 127 // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into | 126 // Capture a rectangle from |x_server_pixel_buffer_|, and copy the data into |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 } | 291 } |
| 293 | 292 |
| 294 void VideoFrameCapturerLinux::Start( | 293 void VideoFrameCapturerLinux::Start( |
| 295 const CursorShapeChangedCallback& callback) { | 294 const CursorShapeChangedCallback& callback) { |
| 296 cursor_shape_changed_callback_ = callback; | 295 cursor_shape_changed_callback_ = callback; |
| 297 } | 296 } |
| 298 | 297 |
| 299 void VideoFrameCapturerLinux::Stop() { | 298 void VideoFrameCapturerLinux::Stop() { |
| 300 } | 299 } |
| 301 | 300 |
| 302 void VideoFrameCapturerLinux::ScreenConfigurationChanged() { | |
| 303 last_buffer_ = NULL; | |
| 304 for (int i = 0; i < kNumBuffers; ++i) { | |
| 305 buffers_[i].set_needs_update(); | |
| 306 } | |
| 307 helper_.ClearInvalidRegion(); | |
| 308 x_server_pixel_buffer_.Init(display_); | |
| 309 } | |
| 310 | |
| 311 media::VideoFrame::Format VideoFrameCapturerLinux::pixel_format() const { | 301 media::VideoFrame::Format VideoFrameCapturerLinux::pixel_format() const { |
| 312 return pixel_format_; | 302 return pixel_format_; |
| 313 } | 303 } |
| 314 | 304 |
| 315 void VideoFrameCapturerLinux::ClearInvalidRegion() { | |
| 316 helper_.ClearInvalidRegion(); | |
| 317 } | |
| 318 | |
| 319 void VideoFrameCapturerLinux::InvalidateRegion(const SkRegion& invalid_region) { | 305 void VideoFrameCapturerLinux::InvalidateRegion(const SkRegion& invalid_region) { |
| 320 helper_.InvalidateRegion(invalid_region); | 306 helper_.InvalidateRegion(invalid_region); |
| 321 } | 307 } |
| 322 | 308 |
| 323 void VideoFrameCapturerLinux::InvalidateScreen(const SkISize& size) { | |
| 324 helper_.InvalidateScreen(size); | |
| 325 } | |
| 326 | |
| 327 void VideoFrameCapturerLinux::InvalidateFullScreen() { | |
| 328 helper_.InvalidateFullScreen(); | |
| 329 last_buffer_ = NULL; | |
| 330 } | |
| 331 | |
| 332 void VideoFrameCapturerLinux::CaptureInvalidRegion( | 309 void VideoFrameCapturerLinux::CaptureInvalidRegion( |
| 333 const CaptureCompletedCallback& callback) { | 310 const CaptureCompletedCallback& callback) { |
| 334 // Process XEvents for XDamage and cursor shape tracking. | 311 // Process XEvents for XDamage and cursor shape tracking. |
| 335 ProcessPendingXEvents(); | 312 ProcessPendingXEvents(); |
| 336 | 313 |
| 337 // Resize the current buffer if there was a recent change of | 314 // Resize the current buffer if there was a recent change of |
| 338 // screen-resolution. | 315 // screen-resolution. |
| 339 VideoFrameBuffer ¤t = buffers_[current_buffer_]; | 316 VideoFrameBuffer ¤t = buffers_[current_buffer_]; |
| 340 current.Update(display_, root_window_); | 317 current.Update(display_, root_window_); |
| 341 // Also refresh the Differ helper used by CaptureFrame(), if needed. | 318 // Also refresh the Differ helper used by CaptureFrame(), if needed. |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 invalid_region.op(screen_rect, SkRegion::kUnion_Op); | 454 invalid_region.op(screen_rect, SkRegion::kUnion_Op); |
| 478 } | 455 } |
| 479 } | 456 } |
| 480 | 457 |
| 481 capture_data->mutable_dirty_region() = invalid_region; | 458 capture_data->mutable_dirty_region() = invalid_region; |
| 482 last_invalid_region_ = invalid_region; | 459 last_invalid_region_ = invalid_region; |
| 483 last_buffer_ = buffer.ptr(); | 460 last_buffer_ = buffer.ptr(); |
| 484 return capture_data; | 461 return capture_data; |
| 485 } | 462 } |
| 486 | 463 |
| 464 void VideoFrameCapturerLinux::ScreenConfigurationChanged() { |
| 465 last_buffer_ = NULL; |
| 466 for (int i = 0; i < kNumBuffers; ++i) { |
| 467 buffers_[i].set_needs_update(); |
| 468 } |
| 469 helper_.ClearInvalidRegion(); |
| 470 x_server_pixel_buffer_.Init(display_); |
| 471 } |
| 472 |
| 487 void VideoFrameCapturerLinux::SynchronizeFrame() { | 473 void VideoFrameCapturerLinux::SynchronizeFrame() { |
| 488 // Synchronize the current buffer with the previous one since we do not | 474 // Synchronize the current buffer with the previous one since we do not |
| 489 // capture the entire desktop. Note that encoder may be reading from the | 475 // capture the entire desktop. Note that encoder may be reading from the |
| 490 // previous buffer at this time so thread access complaints are false | 476 // previous buffer at this time so thread access complaints are false |
| 491 // positives. | 477 // positives. |
| 492 | 478 |
| 493 // TODO(hclam): We can reduce the amount of copying here by subtracting | 479 // TODO(hclam): We can reduce the amount of copying here by subtracting |
| 494 // |capturer_helper_|s region from |last_invalid_region_|. | 480 // |capturer_helper_|s region from |last_invalid_region_|. |
| 495 // http://crbug.com/92354 | 481 // http://crbug.com/92354 |
| 496 DCHECK(last_buffer_); | 482 DCHECK(last_buffer_); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 } | 615 } |
| 630 return capturer; | 616 return capturer; |
| 631 } | 617 } |
| 632 | 618 |
| 633 // static | 619 // static |
| 634 void VideoFrameCapturer::EnableXDamage(bool enable) { | 620 void VideoFrameCapturer::EnableXDamage(bool enable) { |
| 635 g_should_use_x_damage = enable; | 621 g_should_use_x_damage = enable; |
| 636 } | 622 } |
| 637 | 623 |
| 638 } // namespace remoting | 624 } // namespace remoting |
| OLD | NEW |