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

Side by Side Diff: webrtc/modules/desktop_capture/screen_capturer_x11.cc

Issue 2030333003: Revert of Use std::unique_ptr<> to pass frame ownership in DesktopCapturer impls. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 6 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 // SharedXDisplay::XEventHandler interface. 59 // SharedXDisplay::XEventHandler interface.
60 bool HandleXEvent(const XEvent& event) override; 60 bool HandleXEvent(const XEvent& event) override;
61 61
62 void InitXDamage(); 62 void InitXDamage();
63 63
64 // Capture screen pixels to the current buffer in the queue. In the DAMAGE 64 // Capture screen pixels to the current buffer in the queue. In the DAMAGE
65 // case, the ScreenCapturerHelper already holds the list of invalid rectangles 65 // case, the ScreenCapturerHelper already holds the list of invalid rectangles
66 // from HandleXEvent(). In the non-DAMAGE case, this captures the 66 // from HandleXEvent(). In the non-DAMAGE case, this captures the
67 // whole screen, then calculates some invalid rectangles that include any 67 // whole screen, then calculates some invalid rectangles that include any
68 // differences between this and the previous capture. 68 // differences between this and the previous capture.
69 std::unique_ptr<DesktopFrame> CaptureScreen(); 69 DesktopFrame* CaptureScreen();
70 70
71 // Called when the screen configuration is changed. 71 // Called when the screen configuration is changed.
72 void ScreenConfigurationChanged(); 72 void ScreenConfigurationChanged();
73 73
74 // Synchronize the current buffer with |last_buffer_|, by copying pixels from 74 // Synchronize the current buffer with |last_buffer_|, by copying pixels from
75 // the area of |last_invalid_rects|. 75 // the area of |last_invalid_rects|.
76 // Note this only works on the assumption that kNumBuffers == 2, as 76 // Note this only works on the assumption that kNumBuffers == 2, as
77 // |last_invalid_rects| holds the differences from the previous buffer and 77 // |last_invalid_rects| holds the differences from the previous buffer and
78 // the one prior to that (which will then be the current buffer). 78 // the one prior to that (which will then be the current buffer).
79 void SynchronizeFrame(); 79 void SynchronizeFrame();
80 80
81 void DeinitXlib(); 81 void DeinitXlib();
82 82
83 DesktopCaptureOptions options_; 83 DesktopCaptureOptions options_;
84 84
85 Callback* callback_ = nullptr; 85 Callback* callback_;
86 86
87 // X11 graphics context. 87 // X11 graphics context.
88 GC gc_ = nullptr; 88 GC gc_;
89 Window root_window_ = BadValue; 89 Window root_window_;
90 90
91 // XFixes. 91 // XFixes.
92 bool has_xfixes_ = false; 92 bool has_xfixes_;
93 int xfixes_event_base_ = -1; 93 int xfixes_event_base_;
94 int xfixes_error_base_ = -1; 94 int xfixes_error_base_;
95 95
96 // XDamage information. 96 // XDamage information.
97 bool use_damage_ = false; 97 bool use_damage_;
98 Damage damage_handle_ = 0; 98 Damage damage_handle_;
99 int damage_event_base_ = -1; 99 int damage_event_base_;
100 int damage_error_base_ = -1; 100 int damage_error_base_;
101 XserverRegion damage_region_ = 0; 101 XserverRegion damage_region_;
102 102
103 // Access to the X Server's pixel buffer. 103 // Access to the X Server's pixel buffer.
104 XServerPixelBuffer x_server_pixel_buffer_; 104 XServerPixelBuffer x_server_pixel_buffer_;
105 105
106 // A thread-safe list of invalid rectangles, and the size of the most 106 // A thread-safe list of invalid rectangles, and the size of the most
107 // recently captured screen. 107 // recently captured screen.
108 ScreenCapturerHelper helper_; 108 ScreenCapturerHelper helper_;
109 109
110 // Queue of the frames buffers. 110 // Queue of the frames buffers.
111 ScreenCaptureFrameQueue<SharedDesktopFrame> queue_; 111 ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
112 112
113 // Invalid region from the previous capture. This is used to synchronize the 113 // Invalid region from the previous capture. This is used to synchronize the
114 // current with the last buffer used. 114 // current with the last buffer used.
115 DesktopRegion last_invalid_region_; 115 DesktopRegion last_invalid_region_;
116 116
117 // |Differ| for use when polling for changes. 117 // |Differ| for use when polling for changes.
118 std::unique_ptr<Differ> differ_; 118 std::unique_ptr<Differ> differ_;
119 119
120 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux); 120 RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux);
121 }; 121 };
122 122
123 ScreenCapturerLinux::ScreenCapturerLinux() { 123 ScreenCapturerLinux::ScreenCapturerLinux()
124 : callback_(NULL),
125 gc_(NULL),
126 root_window_(BadValue),
127 has_xfixes_(false),
128 xfixes_event_base_(-1),
129 xfixes_error_base_(-1),
130 use_damage_(false),
131 damage_handle_(0),
132 damage_event_base_(-1),
133 damage_error_base_(-1),
134 damage_region_(0) {
124 helper_.SetLogGridSize(4); 135 helper_.SetLogGridSize(4);
125 } 136 }
126 137
127 ScreenCapturerLinux::~ScreenCapturerLinux() { 138 ScreenCapturerLinux::~ScreenCapturerLinux() {
128 options_.x_display()->RemoveEventHandler(ConfigureNotify, this); 139 options_.x_display()->RemoveEventHandler(ConfigureNotify, this);
129 if (use_damage_) { 140 if (use_damage_) {
130 options_.x_display()->RemoveEventHandler( 141 options_.x_display()->RemoveEventHandler(
131 damage_event_base_ + XDamageNotify, this); 142 damage_event_base_ + XDamageNotify, this);
132 } 143 }
133 DeinitXlib(); 144 DeinitXlib();
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared()); 242 RTC_DCHECK(!queue_.current_frame() || !queue_.current_frame()->IsShared());
232 243
233 // Process XEvents for XDamage and cursor shape tracking. 244 // Process XEvents for XDamage and cursor shape tracking.
234 options_.x_display()->ProcessPendingXEvents(); 245 options_.x_display()->ProcessPendingXEvents();
235 246
236 // ProcessPendingXEvents() may call ScreenConfigurationChanged() which 247 // ProcessPendingXEvents() may call ScreenConfigurationChanged() which
237 // reinitializes |x_server_pixel_buffer_|. Check if the pixel buffer is still 248 // reinitializes |x_server_pixel_buffer_|. Check if the pixel buffer is still
238 // in a good shape. 249 // in a good shape.
239 if (!x_server_pixel_buffer_.is_initialized()) { 250 if (!x_server_pixel_buffer_.is_initialized()) {
240 // We failed to initialize pixel buffer. 251 // We failed to initialize pixel buffer.
241 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); 252 callback_->OnCaptureCompleted(NULL);
242 return; 253 return;
243 } 254 }
244 255
245 // If the current frame is from an older generation then allocate a new one. 256 // If the current frame is from an older generation then allocate a new one.
246 // 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
247 // may still be reading from them. 258 // may still be reading from them.
248 if (!queue_.current_frame()) { 259 if (!queue_.current_frame()) {
249 queue_.ReplaceCurrentFrame( 260 std::unique_ptr<DesktopFrame> frame(
250 SharedDesktopFrame::Wrap(std::unique_ptr<DesktopFrame>( 261 new BasicDesktopFrame(x_server_pixel_buffer_.window_size()));
251 new BasicDesktopFrame(x_server_pixel_buffer_.window_size())))); 262 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(frame.release()));
252 } 263 }
253 264
254 // Refresh the Differ helper used by CaptureFrame(), if needed. 265 // Refresh the Differ helper used by CaptureFrame(), if needed.
255 DesktopFrame* frame = queue_.current_frame(); 266 DesktopFrame* frame = queue_.current_frame();
256 if (!use_damage_ && 267 if (!use_damage_ && (
257 (!differ_ || (differ_->width() != frame->size().width()) || 268 !differ_.get() ||
258 (differ_->height() != frame->size().height()) || 269 (differ_->width() != frame->size().width()) ||
259 (differ_->bytes_per_row() != frame->stride()))) { 270 (differ_->height() != frame->size().height()) ||
271 (differ_->bytes_per_row() != frame->stride()))) {
260 differ_.reset(new Differ(frame->size().width(), frame->size().height(), 272 differ_.reset(new Differ(frame->size().width(), frame->size().height(),
261 DesktopFrame::kBytesPerPixel, frame->stride())); 273 DesktopFrame::kBytesPerPixel,
274 frame->stride()));
262 } 275 }
263 276
264 std::unique_ptr<DesktopFrame> result = CaptureScreen(); 277 DesktopFrame* result = CaptureScreen();
265 last_invalid_region_ = result->updated_region(); 278 last_invalid_region_ = result->updated_region();
266 result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / 279 result->set_capture_time_ms(
267 rtc::kNumNanosecsPerMillisec); 280 (rtc::TimeNanos() - capture_start_time_nanos) /
268 callback_->OnCaptureResult(Result::SUCCESS, std::move(result)); 281 rtc::kNumNanosecsPerMillisec);
282 callback_->OnCaptureCompleted(result);
269 } 283 }
270 284
271 bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) { 285 bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) {
272 RTC_DCHECK(screens->size() == 0); 286 RTC_DCHECK(screens->size() == 0);
273 // TODO(jiayl): implement screen enumeration. 287 // TODO(jiayl): implement screen enumeration.
274 Screen default_screen; 288 Screen default_screen;
275 default_screen.id = 0; 289 default_screen.id = 0;
276 screens->push_back(default_screen); 290 screens->push_back(default_screen);
277 return true; 291 return true;
278 } 292 }
(...skipping 11 matching lines...) Expand all
290 return false; 304 return false;
291 RTC_DCHECK(damage_event->level == XDamageReportNonEmpty); 305 RTC_DCHECK(damage_event->level == XDamageReportNonEmpty);
292 return true; 306 return true;
293 } else if (event.type == ConfigureNotify) { 307 } else if (event.type == ConfigureNotify) {
294 ScreenConfigurationChanged(); 308 ScreenConfigurationChanged();
295 return true; 309 return true;
296 } 310 }
297 return false; 311 return false;
298 } 312 }
299 313
300 std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() { 314 DesktopFrame* ScreenCapturerLinux::CaptureScreen() {
301 std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share(); 315 DesktopFrame* frame = queue_.current_frame()->Share();
302 assert(x_server_pixel_buffer_.window_size().equals(frame->size())); 316 assert(x_server_pixel_buffer_.window_size().equals(frame->size()));
303 317
304 // Pass the screen size to the helper, so it can clip the invalid region if it 318 // Pass the screen size to the helper, so it can clip the invalid region if it
305 // expands that region to a grid. 319 // expands that region to a grid.
306 helper_.set_size_most_recent(frame->size()); 320 helper_.set_size_most_recent(frame->size());
307 321
308 // In the DAMAGE case, ensure the frame is up-to-date with the previous frame 322 // In the DAMAGE case, ensure the frame is up-to-date with the previous frame
309 // if any. If there isn't a previous frame, that means a screen-resolution 323 // if any. If there isn't a previous frame, that means a screen-resolution
310 // change occurred, and |invalid_rects| will be updated to include the whole 324 // change occurred, and |invalid_rects| will be updated to include the whole
311 // screen. 325 // screen.
(...skipping 21 matching lines...) Expand all
333 helper_.TakeInvalidRegion(updated_region); 347 helper_.TakeInvalidRegion(updated_region);
334 348
335 // Clip the damaged portions to the current screen size, just in case some 349 // Clip the damaged portions to the current screen size, just in case some
336 // spurious XDamage notifications were received for a previous (larger) 350 // spurious XDamage notifications were received for a previous (larger)
337 // screen size. 351 // screen size.
338 updated_region->IntersectWith( 352 updated_region->IntersectWith(
339 DesktopRect::MakeSize(x_server_pixel_buffer_.window_size())); 353 DesktopRect::MakeSize(x_server_pixel_buffer_.window_size()));
340 354
341 for (DesktopRegion::Iterator it(*updated_region); 355 for (DesktopRegion::Iterator it(*updated_region);
342 !it.IsAtEnd(); it.Advance()) { 356 !it.IsAtEnd(); it.Advance()) {
343 x_server_pixel_buffer_.CaptureRect(it.rect(), frame.get()); 357 x_server_pixel_buffer_.CaptureRect(it.rect(), frame);
344 } 358 }
345 } else { 359 } else {
346 // Doing full-screen polling, or this is the first capture after a 360 // Doing full-screen polling, or this is the first capture after a
347 // screen-resolution change. In either case, need a full-screen capture. 361 // screen-resolution change. In either case, need a full-screen capture.
348 DesktopRect screen_rect = DesktopRect::MakeSize(frame->size()); 362 DesktopRect screen_rect = DesktopRect::MakeSize(frame->size());
349 x_server_pixel_buffer_.CaptureRect(screen_rect, frame.get()); 363 x_server_pixel_buffer_.CaptureRect(screen_rect, frame);
350 364
351 if (queue_.previous_frame()) { 365 if (queue_.previous_frame()) {
352 // Full-screen polling, so calculate the invalid rects here, based on the 366 // Full-screen polling, so calculate the invalid rects here, based on the
353 // changed pixels between current and previous buffers. 367 // changed pixels between current and previous buffers.
354 RTC_DCHECK(differ_); 368 RTC_DCHECK(differ_.get() != NULL);
355 RTC_DCHECK(queue_.previous_frame()->data()); 369 RTC_DCHECK(queue_.previous_frame()->data());
356 differ_->CalcDirtyRegion(queue_.previous_frame()->data(), 370 differ_->CalcDirtyRegion(queue_.previous_frame()->data(),
357 frame->data(), updated_region); 371 frame->data(), updated_region);
358 } else { 372 } else {
359 // No previous buffer, so always invalidate the whole screen, whether 373 // No previous buffer, so always invalidate the whole screen, whether
360 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a 374 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a
361 // full-screen notification after a screen-resolution change, so 375 // full-screen notification after a screen-resolution change, so
362 // this is done here. 376 // this is done here.
363 updated_region->SetRect(screen_rect); 377 updated_region->SetRect(screen_rect);
364 } 378 }
365 } 379 }
366 380
367 return std::move(frame); 381 return frame;
368 } 382 }
369 383
370 void ScreenCapturerLinux::ScreenConfigurationChanged() { 384 void ScreenCapturerLinux::ScreenConfigurationChanged() {
371 // Make sure the frame buffers will be reallocated. 385 // Make sure the frame buffers will be reallocated.
372 queue_.Reset(); 386 queue_.Reset();
373 387
374 helper_.ClearInvalidRegion(); 388 helper_.ClearInvalidRegion();
375 if (!x_server_pixel_buffer_.Init(display(), DefaultRootWindow(display()))) { 389 if (!x_server_pixel_buffer_.Init(display(), DefaultRootWindow(display()))) {
376 LOG(LS_ERROR) << "Failed to initialize pixel buffer after screen " 390 LOG(LS_ERROR) << "Failed to initialize pixel buffer after screen "
377 "configuration change."; 391 "configuration change.";
(...skipping 16 matching lines...) Expand all
394 RTC_DCHECK(current != last); 408 RTC_DCHECK(current != last);
395 for (DesktopRegion::Iterator it(last_invalid_region_); 409 for (DesktopRegion::Iterator it(last_invalid_region_);
396 !it.IsAtEnd(); it.Advance()) { 410 !it.IsAtEnd(); it.Advance()) {
397 current->CopyPixelsFrom(*last, it.rect().top_left(), it.rect()); 411 current->CopyPixelsFrom(*last, it.rect().top_left(), it.rect());
398 } 412 }
399 } 413 }
400 414
401 void ScreenCapturerLinux::DeinitXlib() { 415 void ScreenCapturerLinux::DeinitXlib() {
402 if (gc_) { 416 if (gc_) {
403 XFreeGC(display(), gc_); 417 XFreeGC(display(), gc_);
404 gc_ = nullptr; 418 gc_ = NULL;
405 } 419 }
406 420
407 x_server_pixel_buffer_.Release(); 421 x_server_pixel_buffer_.Release();
408 422
409 if (display()) { 423 if (display()) {
410 if (damage_handle_) { 424 if (damage_handle_) {
411 XDamageDestroy(display(), damage_handle_); 425 XDamageDestroy(display(), damage_handle_);
412 damage_handle_ = 0; 426 damage_handle_ = 0;
413 } 427 }
414 428
415 if (damage_region_) { 429 if (damage_region_) {
416 XFixesDestroyRegion(display(), damage_region_); 430 XFixesDestroyRegion(display(), damage_region_);
417 damage_region_ = 0; 431 damage_region_ = 0;
418 } 432 }
419 } 433 }
420 } 434 }
421 435
422 } // namespace 436 } // namespace
423 437
424 // static 438 // static
425 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) { 439 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
426 if (!options.x_display()) 440 if (!options.x_display())
427 return nullptr; 441 return NULL;
428 442
429 std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux()); 443 std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
430 if (!capturer->Init(options)) 444 if (!capturer->Init(options))
431 capturer.reset(); 445 capturer.reset();
432 return capturer.release(); 446 return capturer.release();
433 } 447 }
434 448
435 } // namespace webrtc 449 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/desktop_capture/screen_capturer_unittest.cc ('k') | webrtc/modules/desktop_capture/shared_desktop_frame.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698