| 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 <windows.h> | 7 #include <windows.h> |
| 8 | 8 |
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 // VideoFrameCapturerWin is double-buffered as required by VideoFrameCapturer. | 42 // VideoFrameCapturerWin is double-buffered as required by VideoFrameCapturer. |
| 43 // See remoting/host/video_frame_capturer.h. | 43 // See remoting/host/video_frame_capturer.h. |
| 44 class VideoFrameCapturerWin : public VideoFrameCapturer { | 44 class VideoFrameCapturerWin : public VideoFrameCapturer { |
| 45 public: | 45 public: |
| 46 VideoFrameCapturerWin(); | 46 VideoFrameCapturerWin(); |
| 47 virtual ~VideoFrameCapturerWin(); | 47 virtual ~VideoFrameCapturerWin(); |
| 48 | 48 |
| 49 // Overridden from VideoFrameCapturer: | 49 // Overridden from VideoFrameCapturer: |
| 50 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; | 50 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; |
| 51 virtual void Stop() OVERRIDE; | 51 virtual void Stop() OVERRIDE; |
| 52 virtual void ScreenConfigurationChanged() OVERRIDE; | |
| 53 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; | 52 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; |
| 54 virtual void ClearInvalidRegion() OVERRIDE; | |
| 55 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; | 53 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; |
| 56 virtual void InvalidateScreen(const SkISize& size) OVERRIDE; | |
| 57 virtual void InvalidateFullScreen() OVERRIDE; | |
| 58 virtual void CaptureInvalidRegion( | 54 virtual void CaptureInvalidRegion( |
| 59 const CaptureCompletedCallback& callback) OVERRIDE; | 55 const CaptureCompletedCallback& callback) OVERRIDE; |
| 60 virtual const SkISize& size_most_recent() const OVERRIDE; | 56 virtual const SkISize& size_most_recent() const OVERRIDE; |
| 61 | 57 |
| 62 private: | 58 private: |
| 63 struct VideoFrameBuffer { | 59 struct VideoFrameBuffer { |
| 64 VideoFrameBuffer(void* data, const SkISize& size, int bytes_per_pixel, | 60 VideoFrameBuffer(void* data, const SkISize& size, int bytes_per_pixel, |
| 65 int bytes_per_row) | 61 int bytes_per_row) |
| 66 : data(data), size(size), bytes_per_pixel(bytes_per_pixel), | 62 : data(data), size(size), bytes_per_pixel(bytes_per_pixel), |
| 67 bytes_per_row(bytes_per_row) { | 63 bytes_per_row(bytes_per_row) { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 // 32 bit RGBA is 4 bytes per pixel. | 145 // 32 bit RGBA is 4 bytes per pixel. |
| 150 static const int kBytesPerPixel = 4; | 146 static const int kBytesPerPixel = 4; |
| 151 | 147 |
| 152 VideoFrameCapturerWin::VideoFrameCapturerWin() | 148 VideoFrameCapturerWin::VideoFrameCapturerWin() |
| 153 : last_cursor_size_(SkISize::Make(0, 0)), | 149 : last_cursor_size_(SkISize::Make(0, 0)), |
| 154 desktop_dc_rect_(SkIRect::MakeEmpty()), | 150 desktop_dc_rect_(SkIRect::MakeEmpty()), |
| 155 resource_generation_(0), | 151 resource_generation_(0), |
| 156 current_buffer_(0), | 152 current_buffer_(0), |
| 157 pixel_format_(media::VideoFrame::RGB32), | 153 pixel_format_(media::VideoFrame::RGB32), |
| 158 composition_func_(NULL) { | 154 composition_func_(NULL) { |
| 159 ScreenConfigurationChanged(); | |
| 160 } | 155 } |
| 161 | 156 |
| 162 VideoFrameCapturerWin::~VideoFrameCapturerWin() { | 157 VideoFrameCapturerWin::~VideoFrameCapturerWin() { |
| 163 } | 158 } |
| 164 | 159 |
| 165 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const { | 160 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const { |
| 166 return pixel_format_; | 161 return pixel_format_; |
| 167 } | 162 } |
| 168 | 163 |
| 169 void VideoFrameCapturerWin::ClearInvalidRegion() { | |
| 170 helper_.ClearInvalidRegion(); | |
| 171 } | |
| 172 | |
| 173 void VideoFrameCapturerWin::InvalidateRegion(const SkRegion& invalid_region) { | 164 void VideoFrameCapturerWin::InvalidateRegion(const SkRegion& invalid_region) { |
| 174 helper_.InvalidateRegion(invalid_region); | 165 helper_.InvalidateRegion(invalid_region); |
| 175 } | 166 } |
| 176 | 167 |
| 177 void VideoFrameCapturerWin::InvalidateScreen(const SkISize& size) { | |
| 178 helper_.InvalidateScreen(size); | |
| 179 } | |
| 180 | |
| 181 void VideoFrameCapturerWin::InvalidateFullScreen() { | |
| 182 helper_.InvalidateFullScreen(); | |
| 183 } | |
| 184 | |
| 185 void VideoFrameCapturerWin::CaptureInvalidRegion( | 168 void VideoFrameCapturerWin::CaptureInvalidRegion( |
| 186 const CaptureCompletedCallback& callback) { | 169 const CaptureCompletedCallback& callback) { |
| 187 // Force the system to power-up display hardware, if it has been suspended. | 170 // Force the system to power-up display hardware, if it has been suspended. |
| 188 SetThreadExecutionState(ES_DISPLAY_REQUIRED); | 171 SetThreadExecutionState(ES_DISPLAY_REQUIRED); |
| 189 | 172 |
| 190 // Perform the capture. | 173 // Perform the capture. |
| 191 CalculateInvalidRegion(); | 174 CalculateInvalidRegion(); |
| 192 SkRegion invalid_region; | 175 SkRegion invalid_region; |
| 193 helper_.SwapInvalidRegion(&invalid_region); | 176 helper_.SwapInvalidRegion(&invalid_region); |
| 194 CaptureRegion(invalid_region, callback); | 177 CaptureRegion(invalid_region, callback); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 224 } | 207 } |
| 225 } | 208 } |
| 226 | 209 |
| 227 void VideoFrameCapturerWin::Stop() { | 210 void VideoFrameCapturerWin::Stop() { |
| 228 // Restore Aero. | 211 // Restore Aero. |
| 229 if (composition_func_ != NULL) { | 212 if (composition_func_ != NULL) { |
| 230 (*composition_func_)(DWM_EC_ENABLECOMPOSITION); | 213 (*composition_func_)(DWM_EC_ENABLECOMPOSITION); |
| 231 } | 214 } |
| 232 } | 215 } |
| 233 | 216 |
| 234 void VideoFrameCapturerWin::ScreenConfigurationChanged() { | |
| 235 // We poll for screen configuration changes, so ignore notifications. | |
| 236 } | |
| 237 | |
| 238 void VideoFrameCapturerWin::PrepareCaptureResources() { | 217 void VideoFrameCapturerWin::PrepareCaptureResources() { |
| 239 // Switch to the desktop receiving user input if different from the current | 218 // Switch to the desktop receiving user input if different from the current |
| 240 // one. | 219 // one. |
| 241 scoped_ptr<DesktopWin> input_desktop = DesktopWin::GetInputDesktop(); | 220 scoped_ptr<DesktopWin> input_desktop = DesktopWin::GetInputDesktop(); |
| 242 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { | 221 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { |
| 243 // Release GDI resources otherwise SetThreadDesktop will fail. | 222 // Release GDI resources otherwise SetThreadDesktop will fail. |
| 244 desktop_dc_.reset(); | 223 desktop_dc_.reset(); |
| 245 memory_dc_.Set(NULL); | 224 memory_dc_.Set(NULL); |
| 246 | 225 |
| 247 // If SetThreadDesktop() fails, the thread is still assigned a desktop. | 226 // If SetThreadDesktop() fails, the thread is still assigned a desktop. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 272 desktop_dc_rect_ = screen_rect; | 251 desktop_dc_rect_ = screen_rect; |
| 273 | 252 |
| 274 ++resource_generation_; | 253 ++resource_generation_; |
| 275 } | 254 } |
| 276 | 255 |
| 277 // If the current buffer is from an older generation then allocate a new one. | 256 // If the current buffer is from an older generation then allocate a new one. |
| 278 // Note that we can't reallocate other buffers at this point, since the caller | 257 // Note that we can't reallocate other buffers at this point, since the caller |
| 279 // may still be reading from them. | 258 // may still be reading from them. |
| 280 if (resource_generation_ != buffers_[current_buffer_].resource_generation) { | 259 if (resource_generation_ != buffers_[current_buffer_].resource_generation) { |
| 281 AllocateBuffer(current_buffer_); | 260 AllocateBuffer(current_buffer_); |
| 282 InvalidateFullScreen(); | 261 |
| 262 SkRegion region; |
| 263 region.op(SkIRect::MakeSize(helper_.size_most_recent()), |
| 264 SkRegion::kUnion_Op); |
| 265 InvalidateRegion(region); |
| 283 } | 266 } |
| 284 } | 267 } |
| 285 | 268 |
| 286 void VideoFrameCapturerWin::AllocateBuffer(int buffer_index) { | 269 void VideoFrameCapturerWin::AllocateBuffer(int buffer_index) { |
| 287 DCHECK(desktop_dc_.get() != NULL); | 270 DCHECK(desktop_dc_.get() != NULL); |
| 288 DCHECK(memory_dc_.Get() != NULL); | 271 DCHECK(memory_dc_.Get() != NULL); |
| 289 // Windows requires DIB sections' rows to start DWORD-aligned, which is | 272 // Windows requires DIB sections' rows to start DWORD-aligned, which is |
| 290 // implicit when working with RGB32 pixels. | 273 // implicit when working with RGB32 pixels. |
| 291 DCHECK_EQ(pixel_format_, media::VideoFrame::RGB32); | 274 DCHECK_EQ(pixel_format_, media::VideoFrame::RGB32); |
| 292 | 275 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 int prev_buffer_id = current_buffer_ - 1; | 307 int prev_buffer_id = current_buffer_ - 1; |
| 325 if (prev_buffer_id < 0) { | 308 if (prev_buffer_id < 0) { |
| 326 prev_buffer_id = kNumBuffers - 1; | 309 prev_buffer_id = kNumBuffers - 1; |
| 327 } | 310 } |
| 328 const VideoFrameBuffer& prev = buffers_[prev_buffer_id]; | 311 const VideoFrameBuffer& prev = buffers_[prev_buffer_id]; |
| 329 | 312 |
| 330 // Maybe the previous and current screens can't be differenced. | 313 // Maybe the previous and current screens can't be differenced. |
| 331 if ((current.size != prev.size) || | 314 if ((current.size != prev.size) || |
| 332 (current.bytes_per_pixel != prev.bytes_per_pixel) || | 315 (current.bytes_per_pixel != prev.bytes_per_pixel) || |
| 333 (current.bytes_per_row != prev.bytes_per_row)) { | 316 (current.bytes_per_row != prev.bytes_per_row)) { |
| 334 InvalidateScreen(current.size); | 317 helper_.InvalidateScreen(current.size); |
| 335 return; | 318 return; |
| 336 } | 319 } |
| 337 | 320 |
| 338 // Make sure the differencer is set up correctly for these previous and | 321 // Make sure the differencer is set up correctly for these previous and |
| 339 // current screens. | 322 // current screens. |
| 340 if (!differ_.get() || | 323 if (!differ_.get() || |
| 341 (differ_->width() != current.size.width()) || | 324 (differ_->width() != current.size.width()) || |
| 342 (differ_->height() != current.size.height()) || | 325 (differ_->height() != current.size.height()) || |
| 343 (differ_->bytes_per_pixel() != current.bytes_per_pixel) || | 326 (differ_->bytes_per_pixel() != current.bytes_per_pixel) || |
| 344 (differ_->bytes_per_row() != current.bytes_per_row)) { | 327 (differ_->bytes_per_row() != current.bytes_per_row)) { |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 545 } |
| 563 | 546 |
| 564 } // namespace | 547 } // namespace |
| 565 | 548 |
| 566 // static | 549 // static |
| 567 VideoFrameCapturer* VideoFrameCapturer::Create() { | 550 VideoFrameCapturer* VideoFrameCapturer::Create() { |
| 568 return new VideoFrameCapturerWin(); | 551 return new VideoFrameCapturerWin(); |
| 569 } | 552 } |
| 570 | 553 |
| 571 } // namespace remoting | 554 } // namespace remoting |
| OLD | NEW |