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

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

Issue 11470028: Move screen capturers to remoting/capturer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years 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
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/capturer/video_frame_capturer.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/file_path.h" 11 #include "base/file_path.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
14 #include "base/scoped_native_library.h" 14 #include "base/scoped_native_library.h"
15 #include "base/time.h" 15 #include "base/time.h"
16 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
17 #include "base/win/scoped_gdi_object.h" 17 #include "base/win/scoped_gdi_object.h"
18 #include "base/win/scoped_hdc.h" 18 #include "base/win/scoped_hdc.h"
19 #include "remoting/base/capture_data.h" 19 #include "remoting/capturer/capture_data.h"
20 #include "remoting/base/shared_buffer_factory.h" 20 #include "remoting/capturer/differ.h"
21 #include "remoting/host/differ.h" 21 #include "remoting/capturer/mouse_cursor_shape.h"
22 #include "remoting/host/video_frame.h" 22 #include "remoting/capturer/shared_buffer_factory.h"
23 #include "remoting/host/video_frame_capturer_helper.h" 23 #include "remoting/capturer/video_frame.h"
24 #include "remoting/host/video_frame_queue.h" 24 #include "remoting/capturer/video_frame_capturer_helper.h"
25 #include "remoting/host/win/desktop.h" 25 #include "remoting/capturer/video_frame_queue.h"
26 #include "remoting/host/win/scoped_thread_desktop.h" 26 #include "remoting/capturer/win/desktop.h"
27 #include "remoting/capturer/win/scoped_thread_desktop.h"
27 #include "remoting/proto/control.pb.h" 28 #include "remoting/proto/control.pb.h"
28 #include "third_party/skia/include/core/SkColorPriv.h" 29 #include "third_party/skia/include/core/SkColorPriv.h"
29 30
30 namespace remoting { 31 namespace remoting {
31 32
32 namespace { 33 namespace {
33 34
34 // Constants from dwmapi.h. 35 // Constants from dwmapi.h.
35 const UINT DWM_EC_DISABLECOMPOSITION = 0; 36 const UINT DWM_EC_DISABLECOMPOSITION = 0;
36 const UINT DWM_EC_ENABLECOMPOSITION = 1; 37 const UINT DWM_EC_ENABLECOMPOSITION = 1;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 113
113 Delegate* delegate_; 114 Delegate* delegate_;
114 115
115 // A thread-safe list of invalid rectangles, and the size of the most 116 // A thread-safe list of invalid rectangles, and the size of the most
116 // recently captured screen. 117 // recently captured screen.
117 VideoFrameCapturerHelper helper_; 118 VideoFrameCapturerHelper helper_;
118 119
119 // Snapshot of the last cursor bitmap we sent to the client. This is used 120 // Snapshot of the last cursor bitmap we sent to the client. This is used
120 // to diff against the current cursor so we only send a cursor-change 121 // to diff against the current cursor so we only send a cursor-change
121 // message when the shape has changed. 122 // message when the shape has changed.
122 scoped_array<uint8> last_cursor_; 123 MouseCursorShape last_cursor_;
123 SkISize last_cursor_size_;
124 124
125 ScopedThreadDesktop desktop_; 125 ScopedThreadDesktop desktop_;
126 126
127 // GDI resources used for screen capture. 127 // GDI resources used for screen capture.
128 scoped_ptr<base::win::ScopedGetDC> desktop_dc_; 128 scoped_ptr<base::win::ScopedGetDC> desktop_dc_;
129 base::win::ScopedCreateDC memory_dc_; 129 base::win::ScopedCreateDC memory_dc_;
130 130
131 // Queue of the frames buffers. 131 // Queue of the frames buffers.
132 VideoFrameQueue queue_; 132 VideoFrameQueue queue_;
133 133
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 set_pixels(reinterpret_cast<uint8*>(data)); 207 set_pixels(reinterpret_cast<uint8*>(data));
208 set_dimensions(SkISize::Make(bmi.bmiHeader.biWidth, 208 set_dimensions(SkISize::Make(bmi.bmiHeader.biWidth,
209 std::abs(bmi.bmiHeader.biHeight))); 209 std::abs(bmi.bmiHeader.biHeight)));
210 set_bytes_per_row( 210 set_bytes_per_row(
211 bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight)); 211 bmi.bmiHeader.biSizeImage / std::abs(bmi.bmiHeader.biHeight));
212 } 212 }
213 213
214 VideoFrameCapturerWin::VideoFrameCapturerWin() 214 VideoFrameCapturerWin::VideoFrameCapturerWin()
215 : shared_buffer_factory_(NULL), 215 : shared_buffer_factory_(NULL),
216 delegate_(NULL), 216 delegate_(NULL),
217 last_cursor_size_(SkISize::Make(0, 0)),
218 desktop_dc_rect_(SkIRect::MakeEmpty()), 217 desktop_dc_rect_(SkIRect::MakeEmpty()),
219 pixel_format_(media::VideoFrame::RGB32), 218 pixel_format_(media::VideoFrame::RGB32),
220 composition_func_(NULL) { 219 composition_func_(NULL) {
221 } 220 }
222 221
223 VideoFrameCapturerWin::VideoFrameCapturerWin( 222 VideoFrameCapturerWin::VideoFrameCapturerWin(
224 SharedBufferFactory* shared_buffer_factory) 223 SharedBufferFactory* shared_buffer_factory)
225 : shared_buffer_factory_(shared_buffer_factory), 224 : shared_buffer_factory_(shared_buffer_factory),
226 delegate_(NULL), 225 delegate_(NULL),
227 last_cursor_size_(SkISize::Make(0, 0)),
228 desktop_dc_rect_(SkIRect::MakeEmpty()), 226 desktop_dc_rect_(SkIRect::MakeEmpty()),
229 pixel_format_(media::VideoFrame::RGB32), 227 pixel_format_(media::VideoFrame::RGB32),
230 composition_func_(NULL) { 228 composition_func_(NULL) {
231 } 229 }
232 230
233 VideoFrameCapturerWin::~VideoFrameCapturerWin() { 231 VideoFrameCapturerWin::~VideoFrameCapturerWin() {
234 } 232 }
235 233
236 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const { 234 media::VideoFrame::Format VideoFrameCapturerWin::pixel_format() const {
237 return pixel_format_; 235 return pixel_format_;
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 int width = bitmap.bmWidth; 496 int width = bitmap.bmWidth;
499 int height = bitmap.bmHeight; 497 int height = bitmap.bmHeight;
500 // For non-color cursors, the mask contains both an AND and an XOR mask and 498 // For non-color cursors, the mask contains both an AND and an XOR mask and
501 // the height includes both. Thus, the width is correct, but we need to 499 // the height includes both. Thus, the width is correct, but we need to
502 // divide by 2 to get the correct mask height. 500 // divide by 2 to get the correct mask height.
503 if (!color_bitmap) { 501 if (!color_bitmap) {
504 height /= 2; 502 height /= 2;
505 } 503 }
506 int data_size = height * width * kBytesPerPixel; 504 int data_size = height * width * kBytesPerPixel;
507 505
508 scoped_ptr<protocol::CursorShapeInfo> cursor_proto( 506 scoped_ptr<MouseCursorShape> cursor;
509 new protocol::CursorShapeInfo()); 507 cursor->data.resize(data_size);
510 cursor_proto->mutable_data()->resize(data_size); 508 uint8* cursor_dst_data =
511 uint8* cursor_dst_data = const_cast<uint8*>(reinterpret_cast<const uint8*>( 509 reinterpret_cast<uint8*>(string_as_array(&cursor->data));
512 cursor_proto->mutable_data()->data()));
513 510
514 // Copy/convert cursor bitmap into format needed by chromotocol. 511 // Copy/convert cursor bitmap into format needed by chromotocol.
515 int row_bytes = bitmap.bmWidthBytes; 512 int row_bytes = bitmap.bmWidthBytes;
516 if (color_bitmap) { 513 if (color_bitmap) {
517 if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 32) { 514 if (bitmap.bmPlanes != 1 || bitmap.bmBitsPixel != 32) {
518 VLOG(3) << "Unsupported color cursor format. Error = " << GetLastError(); 515 VLOG(3) << "Unsupported color cursor format. Error = " << GetLastError();
519 return; 516 return;
520 } 517 }
521 518
522 // Copy across colour cursor imagery. 519 // Copy across colour cursor imagery.
523 // CursorShapeInfo stores imagery top-down, and premultiplied 520 // MouseCursorShape stores imagery top-down, and premultiplied
524 // by the alpha channel, whereas windows stores them bottom-up 521 // by the alpha channel, whereas windows stores them bottom-up
525 // and not premultiplied. 522 // and not premultiplied.
526 uint8* cursor_src_data = reinterpret_cast<uint8*>(bitmap.bmBits); 523 uint8* cursor_src_data = reinterpret_cast<uint8*>(bitmap.bmBits);
527 uint8* src = cursor_src_data + ((height - 1) * row_bytes); 524 uint8* src = cursor_src_data + ((height - 1) * row_bytes);
528 uint8* dst = cursor_dst_data; 525 uint8* dst = cursor_dst_data;
529 for (int row = 0; row < height; ++row) { 526 for (int row = 0; row < height; ++row) {
530 for (int column = 0; column < width; ++column) { 527 for (int column = 0; column < width; ++column) {
531 dst[0] = SkAlphaMul(src[0], src[3]); 528 dst[0] = SkAlphaMul(src[0], src[3]);
532 dst[1] = SkAlphaMul(src[1], src[3]); 529 dst[1] = SkAlphaMul(src[1], src[3]);
533 dst[2] = SkAlphaMul(src[2], src[3]); 530 dst[2] = SkAlphaMul(src[2], src[3]);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 add_outline = true; 577 add_outline = true;
581 } 578 }
582 } 579 }
583 } 580 }
584 if (add_outline) { 581 if (add_outline) {
585 AddCursorOutline(width, height, 582 AddCursorOutline(width, height,
586 reinterpret_cast<uint32*>(cursor_dst_data)); 583 reinterpret_cast<uint32*>(cursor_dst_data));
587 } 584 }
588 } 585 }
589 586
587 cursor->size.set(width, height);
588 cursor->hotspot.set(hotspot_x, hotspot_y);
589
590 // Compare the current cursor with the last one we sent to the client. If 590 // Compare the current cursor with the last one we sent to the client. If
591 // they're the same, then don't bother sending the cursor again. 591 // they're the same, then don't bother sending the cursor again.
592 if (last_cursor_size_.equals(width, height) && 592 if (last_cursor_ == *cursor) {
593 memcmp(last_cursor_.get(), cursor_dst_data, data_size) == 0) {
594 return; 593 return;
595 } 594 }
596 595
597 VLOG(3) << "Sending updated cursor: " << width << "x" << height; 596 VLOG(3) << "Sending updated cursor: " << width << "x" << height;
598 597
599 cursor_proto->set_width(width); 598 // Record the last cursor image that we sent to the client.
600 cursor_proto->set_height(height); 599 last_cursor_ = *cursor;
601 cursor_proto->set_hotspot_x(hotspot_x);
602 cursor_proto->set_hotspot_y(hotspot_y);
603 600
604 // Record the last cursor image that we sent to the client. 601 delegate_->OnCursorShapeChanged(cursor.Pass());
605 last_cursor_.reset(new uint8[data_size]);
606 memcpy(last_cursor_.get(), cursor_dst_data, data_size);
607 last_cursor_size_ = SkISize::Make(width, height);
608
609 delegate_->OnCursorShapeChanged(cursor_proto.Pass());
610 } 602 }
611 603
612 } // namespace 604 } // namespace
613 605
614 // static 606 // static
615 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::Create() { 607 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::Create() {
616 return scoped_ptr<VideoFrameCapturer>(new VideoFrameCapturerWin()); 608 return scoped_ptr<VideoFrameCapturer>(new VideoFrameCapturerWin());
617 } 609 }
618 610
619 // static 611 // static
620 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory( 612 scoped_ptr<VideoFrameCapturer> VideoFrameCapturer::CreateWithFactory(
621 SharedBufferFactory* shared_buffer_factory) { 613 SharedBufferFactory* shared_buffer_factory) {
622 scoped_ptr<VideoFrameCapturerWin> capturer( 614 scoped_ptr<VideoFrameCapturerWin> capturer(
623 new VideoFrameCapturerWin(shared_buffer_factory)); 615 new VideoFrameCapturerWin(shared_buffer_factory));
624 return capturer.PassAs<VideoFrameCapturer>(); 616 return capturer.PassAs<VideoFrameCapturer>();
625 } 617 }
626 618
627 } // namespace remoting 619 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698