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

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

Issue 6780014: Clean up remoting project (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: got rid of ref counting on user authenticator Created 9 years, 8 months 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/capturer_linux.h ('k') | remoting/host/capturer_linux_unittest.cc » ('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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/capturer_linux.h" 5 #include "remoting/host/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 10
11 #include <set> 11 #include <set>
12 12
13 #include "base/basictypes.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h"
14 #include "remoting/base/types.h" 16 #include "remoting/base/types.h"
15 #include "remoting/host/capturer_helper.h" 17 #include "remoting/host/capturer_helper.h"
16 #include "remoting/host/x_server_pixel_buffer.h" 18 #include "remoting/host/x_server_pixel_buffer.h"
17 19
18 namespace remoting { 20 namespace remoting {
19 21
20 // Private Implementation pattern to avoid leaking the X11 types into the header 22 namespace {
21 // file. 23
22 class CapturerLinuxPimpl : public Capturer { 24 // A class to perform capturing for Linux.
25 class CapturerLinux : public Capturer {
23 public: 26 public:
24 CapturerLinuxPimpl(); 27 CapturerLinux();
25 virtual ~CapturerLinuxPimpl(); 28 virtual ~CapturerLinux();
26 29
27 bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
28 30
29 // Capturer interface. 31 // Capturer interface.
30 virtual void ScreenConfigurationChanged(); 32 virtual void ScreenConfigurationChanged() OVERRIDE;
31 virtual media::VideoFrame::Format pixel_format() const; 33 virtual media::VideoFrame::Format pixel_format() const OVERRIDE;
32 virtual void ClearInvalidRects(); 34 virtual void ClearInvalidRects() OVERRIDE;
33 virtual void InvalidateRects(const InvalidRects& inval_rects); 35 virtual void InvalidateRects(const InvalidRects& inval_rects) OVERRIDE;
34 virtual void InvalidateScreen(const gfx::Size& size); 36 virtual void InvalidateScreen(const gfx::Size& size) OVERRIDE;
35 virtual void InvalidateFullScreen(); 37 virtual void InvalidateFullScreen() OVERRIDE;
36 virtual void CaptureInvalidRects(CaptureCompletedCallback* callback); 38 virtual void CaptureInvalidRects(CaptureCompletedCallback* callback) OVERRIDE;
37 virtual const gfx::Size& size_most_recent() const; 39 virtual const gfx::Size& size_most_recent() const OVERRIDE;
38 40
39 private: 41 private:
42 bool Init(); // TODO(ajwong): Do we really want this to be synchronous?
40 void CalculateInvalidRects(); 43 void CalculateInvalidRects();
41 void CaptureRects(const InvalidRects& rects, 44 void CaptureRects(const InvalidRects& rects,
42 Capturer::CaptureCompletedCallback* callback); 45 Capturer::CaptureCompletedCallback* callback);
43 46
44 void DeinitXlib(); 47 void DeinitXlib();
45 // We expose two forms of blitting to handle variations in the pixel format. 48 // We expose two forms of blitting to handle variations in the pixel format.
46 // In FastBlit, the operation is effectively a memcpy. 49 // In FastBlit, the operation is effectively a memcpy.
47 void FastBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); 50 void FastBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data);
48 void SlowBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data); 51 void SlowBlit(uint8* image, const gfx::Rect& rect, CaptureData* capture_data);
49 52
(...skipping 27 matching lines...) Expand all
77 80
78 // Format of pixels returned in buffer. 81 // Format of pixels returned in buffer.
79 media::VideoFrame::Format pixel_format_; 82 media::VideoFrame::Format pixel_format_;
80 83
81 // Invalid rects in the last capture. This is used to synchronize current with 84 // Invalid rects in the last capture. This is used to synchronize current with
82 // the previous buffer used. 85 // the previous buffer used.
83 InvalidRects last_invalid_rects_; 86 InvalidRects last_invalid_rects_;
84 87
85 // Last capture buffer used. 88 // Last capture buffer used.
86 uint8* last_buffer_; 89 uint8* last_buffer_;
90
91 DISALLOW_COPY_AND_ASSIGN(CapturerLinux);
87 }; 92 };
88 93
89 CapturerLinux::CapturerLinux() 94 CapturerLinux::CapturerLinux()
90 : pimpl_(new CapturerLinuxPimpl()) {
91 // TODO(ajwong): This should be moved into an Init() method on Capturer
92 // itself. Then we can remove the CHECK.
93 CHECK(pimpl_->Init());
94 }
95
96 CapturerLinux::~CapturerLinux() {
97 }
98
99 void CapturerLinux::ScreenConfigurationChanged() {
100 pimpl_->ScreenConfigurationChanged();
101 }
102
103 media::VideoFrame::Format CapturerLinux::pixel_format() const {
104 return pimpl_->pixel_format();
105 }
106
107 void CapturerLinux::ClearInvalidRects() {
108 pimpl_->ClearInvalidRects();
109 }
110
111 void CapturerLinux::InvalidateRects(const InvalidRects& inval_rects) {
112 pimpl_->InvalidateRects(inval_rects);
113 }
114
115 void CapturerLinux::InvalidateScreen(const gfx::Size& size) {
116 pimpl_->InvalidateScreen(size);
117 }
118
119 void CapturerLinux::InvalidateFullScreen() {
120 pimpl_->InvalidateFullScreen();
121 }
122
123 void CapturerLinux::CaptureInvalidRects(CaptureCompletedCallback* callback) {
124 pimpl_->CaptureInvalidRects(callback);
125 }
126
127 const gfx::Size& CapturerLinux::size_most_recent() const {
128 return pimpl_->size_most_recent();
129 }
130
131 CapturerLinuxPimpl::CapturerLinuxPimpl()
132 : display_(NULL), 95 : display_(NULL),
133 gc_(NULL), 96 gc_(NULL),
134 root_window_(BadValue), 97 root_window_(BadValue),
135 width_(0), 98 width_(0),
136 height_(0), 99 height_(0),
137 damage_handle_(BadValue), 100 damage_handle_(BadValue),
138 damage_event_base_(-1), 101 damage_event_base_(-1),
139 damage_error_base_(-1), 102 damage_error_base_(-1),
140 current_buffer_(0), 103 current_buffer_(0),
141 stride_(0), 104 stride_(0),
142 capture_fullscreen_(true), 105 capture_fullscreen_(true),
143 pixel_format_(media::VideoFrame::RGB32), 106 pixel_format_(media::VideoFrame::RGB32),
144 last_buffer_(NULL) { 107 last_buffer_(NULL) {
145 for (int i = 0; i < kNumBuffers; i++) { 108 for (int i = 0; i < kNumBuffers; i++) {
146 buffers_[i] = NULL; 109 buffers_[i] = NULL;
147 } 110 }
111 CHECK(Init());
148 } 112 }
149 113
150 CapturerLinuxPimpl::~CapturerLinuxPimpl() { 114 CapturerLinux::~CapturerLinux() {
151 DeinitXlib(); 115 DeinitXlib();
152 116
153 for (int i = 0; i < kNumBuffers; i++) { 117 for (int i = 0; i < kNumBuffers; i++) {
154 delete [] buffers_[i]; 118 delete [] buffers_[i];
155 buffers_[i] = NULL; 119 buffers_[i] = NULL;
156 } 120 }
157 } 121 }
158 122
159 bool CapturerLinuxPimpl::Init() { 123 bool CapturerLinux::Init() {
160 // TODO(ajwong): We should specify the display string we are attaching to 124 // TODO(ajwong): We should specify the display string we are attaching to
161 // in the constructor. 125 // in the constructor.
162 display_ = XOpenDisplay(NULL); 126 display_ = XOpenDisplay(NULL);
163 if (!display_) { 127 if (!display_) {
164 LOG(ERROR) << "Unable to open display"; 128 LOG(ERROR) << "Unable to open display";
165 return false; 129 return false;
166 } 130 }
167 131
168 x_server_pixel_buffer_.Init(display_); 132 x_server_pixel_buffer_.Init(display_);
169 133
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 VLOG(1) << "Initialized with Geometry: " << width_ << "x" << height_; 173 VLOG(1) << "Initialized with Geometry: " << width_ << "x" << height_;
210 174
211 // Allocate the screen buffers. 175 // Allocate the screen buffers.
212 for (int i = 0; i < kNumBuffers; i++) { 176 for (int i = 0; i < kNumBuffers; i++) {
213 buffers_[i] = new uint8[width_ * height_ * kBytesPerPixel]; 177 buffers_[i] = new uint8[width_ * height_ * kBytesPerPixel];
214 } 178 }
215 179
216 return true; 180 return true;
217 } 181 }
218 182
219 void CapturerLinuxPimpl::ScreenConfigurationChanged() { 183 void CapturerLinux::ScreenConfigurationChanged() {
220 // TODO(ajwong): Support resolution changes. 184 // TODO(ajwong): Support resolution changes.
221 NOTIMPLEMENTED(); 185 NOTIMPLEMENTED();
222 } 186 }
223 187
224 media::VideoFrame::Format CapturerLinuxPimpl::pixel_format() const { 188 media::VideoFrame::Format CapturerLinux::pixel_format() const {
225 return pixel_format_; 189 return pixel_format_;
226 } 190 }
227 191
228 void CapturerLinuxPimpl::ClearInvalidRects() { 192 void CapturerLinux::ClearInvalidRects() {
229 helper_.ClearInvalidRects(); 193 helper_.ClearInvalidRects();
230 } 194 }
231 195
232 void CapturerLinuxPimpl::InvalidateRects(const InvalidRects& inval_rects) { 196 void CapturerLinux::InvalidateRects(const InvalidRects& inval_rects) {
233 helper_.InvalidateRects(inval_rects); 197 helper_.InvalidateRects(inval_rects);
234 } 198 }
235 199
236 void CapturerLinuxPimpl::InvalidateScreen(const gfx::Size& size) { 200 void CapturerLinux::InvalidateScreen(const gfx::Size& size) {
237 helper_.InvalidateScreen(size); 201 helper_.InvalidateScreen(size);
238 } 202 }
239 203
240 void CapturerLinuxPimpl::InvalidateFullScreen() { 204 void CapturerLinux::InvalidateFullScreen() {
241 helper_.InvalidateFullScreen(); 205 helper_.InvalidateFullScreen();
242 } 206 }
243 207
244 void CapturerLinuxPimpl::CaptureInvalidRects( 208 void CapturerLinux::CaptureInvalidRects(
245 CaptureCompletedCallback* callback) { 209 CaptureCompletedCallback* callback) {
246 CalculateInvalidRects(); 210 CalculateInvalidRects();
247 211
248 InvalidRects rects; 212 InvalidRects rects;
249 helper_.SwapInvalidRects(rects); 213 helper_.SwapInvalidRects(rects);
250 214
251 CaptureRects(rects, callback); 215 CaptureRects(rects, callback);
252 } 216 }
253 217
254 void CapturerLinuxPimpl::CalculateInvalidRects() { 218 void CapturerLinux::CalculateInvalidRects() {
255 if (helper_.IsCaptureFullScreen(gfx::Size(width_, height_))) 219 if (helper_.IsCaptureFullScreen(gfx::Size(width_, height_)))
256 capture_fullscreen_ = true; 220 capture_fullscreen_ = true;
257 221
258 // TODO(ajwong): The capture_fullscreen_ logic here is very ugly. Refactor. 222 // TODO(ajwong): The capture_fullscreen_ logic here is very ugly. Refactor.
259 223
260 // Find the number of events that are outstanding "now." We don't just loop 224 // Find the number of events that are outstanding "now." We don't just loop
261 // on XPending because we want to guarantee this terminates. 225 // on XPending because we want to guarantee this terminates.
262 int events_to_process = XPending(display_); 226 int events_to_process = XPending(display_);
263 XEvent e; 227 XEvent e;
264 InvalidRects invalid_rects; 228 InvalidRects invalid_rects;
(...skipping 22 matching lines...) Expand all
287 251
288 if (capture_fullscreen_) { 252 if (capture_fullscreen_) {
289 // TODO(hclam): Check the new dimension again. 253 // TODO(hclam): Check the new dimension again.
290 helper_.InvalidateScreen(gfx::Size(width_, height_)); 254 helper_.InvalidateScreen(gfx::Size(width_, height_));
291 capture_fullscreen_ = false; 255 capture_fullscreen_ = false;
292 } else { 256 } else {
293 helper_.InvalidateRects(invalid_rects); 257 helper_.InvalidateRects(invalid_rects);
294 } 258 }
295 } 259 }
296 260
297 void CapturerLinuxPimpl::CaptureRects( 261 void CapturerLinux::CaptureRects(
298 const InvalidRects& rects, 262 const InvalidRects& rects,
299 Capturer::CaptureCompletedCallback* callback) { 263 Capturer::CaptureCompletedCallback* callback) {
300 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback); 264 scoped_ptr<CaptureCompletedCallback> callback_deleter(callback);
301 265
302 uint8* buffer = buffers_[current_buffer_]; 266 uint8* buffer = buffers_[current_buffer_];
303 DataPlanes planes; 267 DataPlanes planes;
304 planes.data[0] = buffer; 268 planes.data[0] = buffer;
305 planes.strides[0] = stride_; 269 planes.strides[0] = stride_;
306 270
307 scoped_refptr<CaptureData> capture_data(new CaptureData( 271 scoped_refptr<CaptureData> capture_data(new CaptureData(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 capture_data->mutable_dirty_rects() = rects; 311 capture_data->mutable_dirty_rects() = rects;
348 last_invalid_rects_ = rects; 312 last_invalid_rects_ = rects;
349 last_buffer_ = buffer; 313 last_buffer_ = buffer;
350 314
351 current_buffer_ = (current_buffer_ + 1) % kNumBuffers; 315 current_buffer_ = (current_buffer_ + 1) % kNumBuffers;
352 helper_.set_size_most_recent(capture_data->size()); 316 helper_.set_size_most_recent(capture_data->size());
353 317
354 callback->Run(capture_data); 318 callback->Run(capture_data);
355 } 319 }
356 320
357 void CapturerLinuxPimpl::DeinitXlib() { 321 void CapturerLinux::DeinitXlib() {
358 if (gc_) { 322 if (gc_) {
359 XFreeGC(display_, gc_); 323 XFreeGC(display_, gc_);
360 gc_ = NULL; 324 gc_ = NULL;
361 } 325 }
362 326
363 if (display_) { 327 if (display_) {
364 XCloseDisplay(display_); 328 XCloseDisplay(display_);
365 display_ = NULL; 329 display_ = NULL;
366 } 330 }
367 } 331 }
368 332
369 void CapturerLinuxPimpl::FastBlit(uint8* image, const gfx::Rect& rect, 333 void CapturerLinux::FastBlit(uint8* image, const gfx::Rect& rect,
370 CaptureData* capture_data) { 334 CaptureData* capture_data) {
371 uint8* src_pos = image; 335 uint8* src_pos = image;
372 int src_stride = x_server_pixel_buffer_.GetStride(); 336 int src_stride = x_server_pixel_buffer_.GetStride();
373 int dst_x = rect.x(), dst_y = rect.y(); 337 int dst_x = rect.x(), dst_y = rect.y();
374 338
375 DataPlanes planes = capture_data->data_planes(); 339 DataPlanes planes = capture_data->data_planes();
376 uint8* dst_buffer = planes.data[0]; 340 uint8* dst_buffer = planes.data[0];
377 341
378 const int dst_stride = planes.strides[0]; 342 const int dst_stride = planes.strides[0];
379 343
380 uint8* dst_pos = dst_buffer + dst_stride * dst_y; 344 uint8* dst_pos = dst_buffer + dst_stride * dst_y;
381 dst_pos += dst_x * kBytesPerPixel; 345 dst_pos += dst_x * kBytesPerPixel;
382 346
383 int height = rect.height(), row_bytes = rect.width() * kBytesPerPixel; 347 int height = rect.height(), row_bytes = rect.width() * kBytesPerPixel;
384 for (int y = 0; y < height; ++y) { 348 for (int y = 0; y < height; ++y) {
385 memcpy(dst_pos, src_pos, row_bytes); 349 memcpy(dst_pos, src_pos, row_bytes);
386 src_pos += src_stride; 350 src_pos += src_stride;
387 dst_pos += dst_stride; 351 dst_pos += dst_stride;
388 } 352 }
389 } 353 }
390 354
391 void CapturerLinuxPimpl::SlowBlit(uint8* image, const gfx::Rect& rect, 355 void CapturerLinux::SlowBlit(uint8* image, const gfx::Rect& rect,
392 CaptureData* capture_data) { 356 CaptureData* capture_data) {
393 DataPlanes planes = capture_data->data_planes(); 357 DataPlanes planes = capture_data->data_planes();
394 uint8* dst_buffer = planes.data[0]; 358 uint8* dst_buffer = planes.data[0];
395 const int dst_stride = planes.strides[0]; 359 const int dst_stride = planes.strides[0];
396 int src_stride = x_server_pixel_buffer_.GetStride(); 360 int src_stride = x_server_pixel_buffer_.GetStride();
397 int dst_x = rect.x(), dst_y = rect.y(); 361 int dst_x = rect.x(), dst_y = rect.y();
398 int width = rect.width(), height = rect.height(); 362 int width = rect.width(), height = rect.height();
399 363
400 unsigned int red_mask = x_server_pixel_buffer_.GetRedMask(); 364 unsigned int red_mask = x_server_pixel_buffer_.GetRedMask();
401 unsigned int blue_mask = x_server_pixel_buffer_.GetBlueMask(); 365 unsigned int blue_mask = x_server_pixel_buffer_.GetBlueMask();
(...skipping 30 matching lines...) Expand all
432 uint32_t b = (((pixel & blue_mask) >> blue_shift) * 255) / max_blue; 396 uint32_t b = (((pixel & blue_mask) >> blue_shift) * 255) / max_blue;
433 uint32_t g = (((pixel & green_mask) >> green_shift) * 255) / max_green; 397 uint32_t g = (((pixel & green_mask) >> green_shift) * 255) / max_green;
434 // Write as 32-bit RGB. 398 // Write as 32-bit RGB.
435 dst_pos_32[x] = r << 16 | g << 8 | b; 399 dst_pos_32[x] = r << 16 | g << 8 | b;
436 } 400 }
437 dst_pos += dst_stride; 401 dst_pos += dst_stride;
438 src_pos += src_stride; 402 src_pos += src_stride;
439 } 403 }
440 } 404 }
441 405
442 const gfx::Size& CapturerLinuxPimpl::size_most_recent() const { 406 const gfx::Size& CapturerLinux::size_most_recent() const {
443 return helper_.size_most_recent(); 407 return helper_.size_most_recent();
444 } 408 }
445 409
410 } // namespace
411
446 // static 412 // static
447 Capturer* Capturer::Create() { 413 Capturer* Capturer::Create() {
448 return new CapturerLinux(); 414 return new CapturerLinux();
449 } 415 }
450 416
451 } // namespace remoting 417 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/capturer_linux.h ('k') | remoting/host/capturer_linux_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698