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

Side by Side Diff: remoting/host/video_frame_capturer_win.cc

Issue 11363128: Converted VideoFrameCapturer callbacks into a VideoFrameCapturer::Delegate interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More Mac compilation issues. Created 8 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « remoting/host/video_frame_capturer_unittest.cc ('k') | remoting/host/video_scheduler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 30 matching lines...) Expand all
41 // VideoFrameCapturerWin captures 32bit RGB using GDI. 41 // VideoFrameCapturerWin captures 32bit RGB using GDI.
42 // 42 //
43 // VideoFrameCapturerWin is double-buffered as required by VideoFrameCapturer. 43 // VideoFrameCapturerWin is double-buffered as required by VideoFrameCapturer.
44 // See remoting/host/video_frame_capturer.h. 44 // See remoting/host/video_frame_capturer.h.
45 class VideoFrameCapturerWin : public VideoFrameCapturer { 45 class VideoFrameCapturerWin : public VideoFrameCapturer {
46 public: 46 public:
47 VideoFrameCapturerWin(); 47 VideoFrameCapturerWin();
48 virtual ~VideoFrameCapturerWin(); 48 virtual ~VideoFrameCapturerWin();
49 49
50 // Overridden from VideoFrameCapturer: 50 // Overridden from VideoFrameCapturer:
51 virtual void Start(const CursorShapeChangedCallback& callback) OVERRIDE; 51 virtual void Start(Delegate* delegate) OVERRIDE;
52 virtual void Stop() OVERRIDE; 52 virtual void Stop() OVERRIDE;
53 virtual media::VideoFrame::Format pixel_format() const OVERRIDE; 53 virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
54 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE; 54 virtual void InvalidateRegion(const SkRegion& invalid_region) OVERRIDE;
55 virtual void CaptureInvalidRegion( 55 virtual void CaptureInvalidRegion() OVERRIDE;
56 const CaptureCompletedCallback& callback) OVERRIDE;
57 virtual const SkISize& size_most_recent() const OVERRIDE; 56 virtual const SkISize& size_most_recent() const OVERRIDE;
58 57
59 private: 58 private:
60 struct VideoFrameBuffer { 59 struct VideoFrameBuffer {
61 VideoFrameBuffer(); 60 VideoFrameBuffer();
62 61
63 void* data; 62 void* data;
64 SkISize size; 63 SkISize size;
65 int bytes_per_pixel; 64 int bytes_per_pixel;
66 int bytes_per_row; 65 int bytes_per_row;
67 int resource_generation; 66 int resource_generation;
68 }; 67 };
69 68
70 // Make sure that the device contexts and the current buffer match the screen 69 // Make sure that the device contexts and the current buffer match the screen
71 // configuration. 70 // configuration.
72 void PrepareCaptureResources(); 71 void PrepareCaptureResources();
73 72
74 // Allocates the specified capture buffer using the current device contexts 73 // Allocates the specified capture buffer using the current device contexts
75 // and desktop dimensions, releasing any pre-existing buffer. 74 // and desktop dimensions, releasing any pre-existing buffer.
76 void AllocateBuffer(int buffer_index, int resource_generation); 75 void AllocateBuffer(int buffer_index, int resource_generation);
77 76
78 // Compares the most recently captured screen contents with the previous 77 // Compares the most recently captured screen contents with the previous
79 // contents reported to the caller, to determine the dirty region. 78 // contents reported to the caller, to determine the dirty region.
80 void CalculateInvalidRegion(); 79 void CalculateInvalidRegion();
81 80
82 // Creates a CaptureData instance wrapping the current framebuffer and calls 81 // Creates a CaptureData instance wrapping the current framebuffer and
83 // |callback| with it. 82 // notifies |delegate_|.
84 void CaptureRegion(const SkRegion& region, 83 void CaptureRegion(const SkRegion& region);
85 const CaptureCompletedCallback& callback);
86 84
87 // Captures the current screen contents into the next available framebuffer. 85 // Captures the current screen contents into the next available framebuffer.
88 void CaptureImage(); 86 void CaptureImage();
89 87
90 // Expand the cursor shape to add a white outline for visibility against 88 // Expand the cursor shape to add a white outline for visibility against
91 // dark backgrounds. 89 // dark backgrounds.
92 void AddCursorOutline(int width, int height, uint32* dst); 90 void AddCursorOutline(int width, int height, uint32* dst);
93 91
94 // Capture the current cursor shape. 92 // Capture the current cursor shape.
95 void CaptureCursor(); 93 void CaptureCursor();
96 94
95 Delegate* delegate_;
96
97 // A thread-safe list of invalid rectangles, and the size of the most 97 // A thread-safe list of invalid rectangles, and the size of the most
98 // recently captured screen. 98 // recently captured screen.
99 VideoFrameCapturerHelper helper_; 99 VideoFrameCapturerHelper helper_;
100 100
101 // Callback notified whenever the cursor shape is changed.
102 CursorShapeChangedCallback cursor_shape_changed_callback_;
103
104 // Snapshot of the last cursor bitmap we sent to the client. This is used 101 // Snapshot of the last cursor bitmap we sent to the client. This is used
105 // to diff against the current cursor so we only send a cursor-change 102 // to diff against the current cursor so we only send a cursor-change
106 // message when the shape has changed. 103 // message when the shape has changed.
107 scoped_array<uint8> last_cursor_; 104 scoped_array<uint8> last_cursor_;
108 SkISize last_cursor_size_; 105 SkISize last_cursor_size_;
109 106
110 // There are two buffers for the screen images, as required by Capturer. 107 // There are two buffers for the screen images, as required by Capturer.
111 static const int kNumBuffers = 2; 108 static const int kNumBuffers = 2;
112 VideoFrameBuffer buffers_[kNumBuffers]; 109 VideoFrameBuffer buffers_[kNumBuffers];
113 110
(...skipping 30 matching lines...) Expand all
144 141
145 VideoFrameCapturerWin::VideoFrameBuffer::VideoFrameBuffer() 142 VideoFrameCapturerWin::VideoFrameBuffer::VideoFrameBuffer()
146 : data(NULL), 143 : data(NULL),
147 size(SkISize::Make(0, 0)), 144 size(SkISize::Make(0, 0)),
148 bytes_per_pixel(0), 145 bytes_per_pixel(0),
149 bytes_per_row(0), 146 bytes_per_row(0),
150 resource_generation(0) { 147 resource_generation(0) {
151 } 148 }
152 149
153 VideoFrameCapturerWin::VideoFrameCapturerWin() 150 VideoFrameCapturerWin::VideoFrameCapturerWin()
154 : last_cursor_size_(SkISize::Make(0, 0)), 151 : delegate_(NULL),
152 last_cursor_size_(SkISize::Make(0, 0)),
155 desktop_dc_rect_(SkIRect::MakeEmpty()), 153 desktop_dc_rect_(SkIRect::MakeEmpty()),
156 resource_generation_(0), 154 resource_generation_(0),
157 current_buffer_(0), 155 current_buffer_(0),
158 pixel_format_(media::VideoFrame::RGB32), 156 pixel_format_(media::VideoFrame::RGB32),
159 composition_func_(NULL) { 157 composition_func_(NULL) {
160 } 158 }
161 159
162 VideoFrameCapturerWin::~VideoFrameCapturerWin() { 160 VideoFrameCapturerWin::~VideoFrameCapturerWin() {
163 } 161 }
164 162
165 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const { 163 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const {
166 return pixel_format_; 164 return pixel_format_;
167 } 165 }
168 166
169 void VideoFrameCapturerWin::InvalidateRegion(const SkRegion& invalid_region) { 167 void VideoFrameCapturerWin::InvalidateRegion(const SkRegion& invalid_region) {
170 helper_.InvalidateRegion(invalid_region); 168 helper_.InvalidateRegion(invalid_region);
171 } 169 }
172 170
173 void VideoFrameCapturerWin::CaptureInvalidRegion( 171 void VideoFrameCapturerWin::CaptureInvalidRegion() {
174 const CaptureCompletedCallback& callback) {
175 // Force the system to power-up display hardware, if it has been suspended. 172 // Force the system to power-up display hardware, if it has been suspended.
176 SetThreadExecutionState(ES_DISPLAY_REQUIRED); 173 SetThreadExecutionState(ES_DISPLAY_REQUIRED);
177 174
178 // Perform the capture. 175 // Perform the capture.
179 CalculateInvalidRegion(); 176 CalculateInvalidRegion();
180 SkRegion invalid_region; 177 SkRegion invalid_region;
181 helper_.SwapInvalidRegion(&invalid_region); 178 helper_.SwapInvalidRegion(&invalid_region);
182 CaptureRegion(invalid_region, callback); 179 CaptureRegion(invalid_region);
183 180
184 // Check for cursor shape update. 181 // Check for cursor shape update.
185 CaptureCursor(); 182 CaptureCursor();
186 } 183 }
187 184
188 const SkISize& VideoFrameCapturerWin::size_most_recent() const { 185 const SkISize& VideoFrameCapturerWin::size_most_recent() const {
189 return helper_.size_most_recent(); 186 return helper_.size_most_recent();
190 } 187 }
191 188
192 void VideoFrameCapturerWin::Start( 189 void VideoFrameCapturerWin::Start(Delegate* delegate) {
193 const CursorShapeChangedCallback& callback) { 190 DCHECK(delegate_ == NULL);
194 cursor_shape_changed_callback_ = callback; 191
192 delegate_ = delegate;
195 193
196 // Load dwmapi.dll dynamically since it is not available on XP. 194 // Load dwmapi.dll dynamically since it is not available on XP.
197 if (!dwmapi_library_.is_valid()) { 195 if (!dwmapi_library_.is_valid()) {
198 FilePath path(base::GetNativeLibraryName(UTF8ToUTF16(kDwmapiLibraryName))); 196 FilePath path(base::GetNativeLibraryName(UTF8ToUTF16(kDwmapiLibraryName)));
199 dwmapi_library_.Reset(base::LoadNativeLibrary(path, NULL)); 197 dwmapi_library_.Reset(base::LoadNativeLibrary(path, NULL));
200 } 198 }
201 199
202 if (dwmapi_library_.is_valid() && composition_func_ == NULL) { 200 if (dwmapi_library_.is_valid() && composition_func_ == NULL) {
203 composition_func_ = static_cast<DwmEnableCompositionFunc>( 201 composition_func_ = static_cast<DwmEnableCompositionFunc>(
204 dwmapi_library_.GetFunctionPointer("DwmEnableComposition")); 202 dwmapi_library_.GetFunctionPointer("DwmEnableComposition"));
205 } 203 }
206 204
207 // Vote to disable Aero composited desktop effects while capturing. Windows 205 // Vote to disable Aero composited desktop effects while capturing. Windows
208 // will restore Aero automatically if the process exits. This has no effect 206 // will restore Aero automatically if the process exits. This has no effect
209 // under Windows 8 or higher. See crbug.com/124018. 207 // under Windows 8 or higher. See crbug.com/124018.
210 if (composition_func_ != NULL) { 208 if (composition_func_ != NULL) {
211 (*composition_func_)(DWM_EC_DISABLECOMPOSITION); 209 (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
212 } 210 }
213 } 211 }
214 212
215 void VideoFrameCapturerWin::Stop() { 213 void VideoFrameCapturerWin::Stop() {
216 // Restore Aero. 214 // Restore Aero.
217 if (composition_func_ != NULL) { 215 if (composition_func_ != NULL) {
218 (*composition_func_)(DWM_EC_ENABLECOMPOSITION); 216 (*composition_func_)(DWM_EC_ENABLECOMPOSITION);
219 } 217 }
218
219 delegate_ = NULL;
220 } 220 }
221 221
222 void VideoFrameCapturerWin::PrepareCaptureResources() { 222 void VideoFrameCapturerWin::PrepareCaptureResources() {
223 // Switch to the desktop receiving user input if different from the current 223 // Switch to the desktop receiving user input if different from the current
224 // one. 224 // one.
225 scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop(); 225 scoped_ptr<Desktop> input_desktop = Desktop::GetInputDesktop();
226 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { 226 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
227 // Release GDI resources otherwise SetThreadDesktop will fail. 227 // Release GDI resources otherwise SetThreadDesktop will fail.
228 desktop_dc_.reset(); 228 desktop_dc_.reset();
229 memory_dc_.Set(NULL); 229 memory_dc_.Set(NULL);
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 differ_.reset(new Differ(current.size.width(), current.size.height(), 340 differ_.reset(new Differ(current.size.width(), current.size.height(),
341 current.bytes_per_pixel, current.bytes_per_row)); 341 current.bytes_per_pixel, current.bytes_per_row));
342 } 342 }
343 343
344 SkRegion region; 344 SkRegion region;
345 differ_->CalcDirtyRegion(prev.data, current.data, &region); 345 differ_->CalcDirtyRegion(prev.data, current.data, &region);
346 346
347 InvalidateRegion(region); 347 InvalidateRegion(region);
348 } 348 }
349 349
350 void VideoFrameCapturerWin::CaptureRegion( 350 void VideoFrameCapturerWin::CaptureRegion(const SkRegion& region) {
351 const SkRegion& region,
352 const CaptureCompletedCallback& callback) {
353 const VideoFrameBuffer& buffer = buffers_[current_buffer_]; 351 const VideoFrameBuffer& buffer = buffers_[current_buffer_];
354 current_buffer_ = (current_buffer_ + 1) % kNumBuffers; 352 current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
355 353
356 DataPlanes planes; 354 DataPlanes planes;
357 planes.data[0] = static_cast<uint8*>(buffer.data); 355 planes.data[0] = static_cast<uint8*>(buffer.data);
358 planes.strides[0] = buffer.bytes_per_row; 356 planes.strides[0] = buffer.bytes_per_row;
359 357
360 scoped_refptr<CaptureData> data(new CaptureData(planes, 358 scoped_refptr<CaptureData> data(new CaptureData(planes,
361 buffer.size, 359 buffer.size,
362 pixel_format_)); 360 pixel_format_));
363 data->mutable_dirty_region() = region; 361 data->mutable_dirty_region() = region;
364 362
365 helper_.set_size_most_recent(data->size()); 363 helper_.set_size_most_recent(data->size());
366 364
367 callback.Run(data); 365 delegate_->OnCaptureCompleted(data);
368 } 366 }
369 367
370 void VideoFrameCapturerWin::CaptureImage() { 368 void VideoFrameCapturerWin::CaptureImage() {
371 // Make sure the GDI capture resources are up-to-date. 369 // Make sure the GDI capture resources are up-to-date.
372 PrepareCaptureResources(); 370 PrepareCaptureResources();
373 371
374 // Select the target bitmap into the memory dc. 372 // Select the target bitmap into the memory dc.
375 SelectObject(memory_dc_, target_bitmap_[current_buffer_]); 373 SelectObject(memory_dc_, target_bitmap_[current_buffer_]);
376 374
377 // And then copy the rect from desktop to memory. 375 // And then copy the rect from desktop to memory.
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 cursor_proto->set_width(width); 552 cursor_proto->set_width(width);
555 cursor_proto->set_height(height); 553 cursor_proto->set_height(height);
556 cursor_proto->set_hotspot_x(hotspot_x); 554 cursor_proto->set_hotspot_x(hotspot_x);
557 cursor_proto->set_hotspot_y(hotspot_y); 555 cursor_proto->set_hotspot_y(hotspot_y);
558 556
559 // Record the last cursor image that we sent to the client. 557 // Record the last cursor image that we sent to the client.
560 last_cursor_.reset(new uint8[data_size]); 558 last_cursor_.reset(new uint8[data_size]);
561 memcpy(last_cursor_.get(), cursor_dst_data, data_size); 559 memcpy(last_cursor_.get(), cursor_dst_data, data_size);
562 last_cursor_size_ = SkISize::Make(width, height); 560 last_cursor_size_ = SkISize::Make(width, height);
563 561
564 cursor_shape_changed_callback_.Run(cursor_proto.Pass()); 562 delegate_->OnCursorShapeChanged(cursor_proto.Pass());
565 } 563 }
566 564
567 } // namespace 565 } // namespace
568 566
569 // static 567 // static
570 VideoFrameCapturer* VideoFrameCapturer::Create() { 568 VideoFrameCapturer* VideoFrameCapturer::Create() {
571 return new VideoFrameCapturerWin(); 569 return new VideoFrameCapturerWin();
572 } 570 }
573 571
574 } // namespace remoting 572 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/video_frame_capturer_unittest.cc ('k') | remoting/host/video_scheduler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698