OLD | NEW |
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 12 matching lines...) Expand all Loading... |
23 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 23 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
24 #include "webrtc/modules/desktop_capture/differ.h" | 24 #include "webrtc/modules/desktop_capture/differ.h" |
25 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" | 25 #include "webrtc/modules/desktop_capture/screen_capture_frame_queue.h" |
26 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" | 26 #include "webrtc/modules/desktop_capture/screen_capturer_helper.h" |
27 #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" | 27 #include "webrtc/modules/desktop_capture/x11/x_server_pixel_buffer.h" |
28 #include "webrtc/system_wrappers/interface/logging.h" | 28 #include "webrtc/system_wrappers/interface/logging.h" |
29 #include "webrtc/system_wrappers/interface/tick_util.h" | 29 #include "webrtc/system_wrappers/interface/tick_util.h" |
30 | 30 |
31 // TODO(sergeyu): Move this to a header where it can be shared. | 31 // TODO(sergeyu): Move this to a header where it can be shared. |
32 #if defined(NDEBUG) | 32 #if defined(NDEBUG) |
33 #define DCHECK(condition) (void)(condition) | 33 #define RTC_DCHECK(condition) (void)(condition) |
34 #else // NDEBUG | 34 #else // NDEBUG |
35 #define DCHECK(condition) if (!(condition)) {abort();} | 35 #define RTC_DCHECK(condition) \ |
| 36 if (!(condition)) { \ |
| 37 abort(); \ |
| 38 } |
36 #endif | 39 #endif |
37 | 40 |
38 namespace webrtc { | 41 namespace webrtc { |
39 | 42 |
40 namespace { | 43 namespace { |
41 | 44 |
42 // A class to perform video frame capturing for Linux. | 45 // A class to perform video frame capturing for Linux. |
43 class ScreenCapturerLinux : public ScreenCapturer, | 46 class ScreenCapturerLinux : public ScreenCapturer, |
44 public SharedXDisplay::XEventHandler { | 47 public SharedXDisplay::XEventHandler { |
45 public: | 48 public: |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 } | 229 } |
227 | 230 |
228 options_.x_display()->AddEventHandler( | 231 options_.x_display()->AddEventHandler( |
229 damage_event_base_ + XDamageNotify, this); | 232 damage_event_base_ + XDamageNotify, this); |
230 | 233 |
231 use_damage_ = true; | 234 use_damage_ = true; |
232 LOG(LS_INFO) << "Using XDamage extension."; | 235 LOG(LS_INFO) << "Using XDamage extension."; |
233 } | 236 } |
234 | 237 |
235 void ScreenCapturerLinux::Start(Callback* callback) { | 238 void ScreenCapturerLinux::Start(Callback* callback) { |
236 DCHECK(!callback_); | 239 RTC_DCHECK(!callback_); |
237 DCHECK(callback); | 240 RTC_DCHECK(callback); |
238 | 241 |
239 callback_ = callback; | 242 callback_ = callback; |
240 } | 243 } |
241 | 244 |
242 void ScreenCapturerLinux::Capture(const DesktopRegion& region) { | 245 void ScreenCapturerLinux::Capture(const DesktopRegion& region) { |
243 TickTime capture_start_time = TickTime::Now(); | 246 TickTime capture_start_time = TickTime::Now(); |
244 | 247 |
245 queue_.MoveToNextFrame(); | 248 queue_.MoveToNextFrame(); |
246 | 249 |
247 // Process XEvents for XDamage and cursor shape tracking. | 250 // Process XEvents for XDamage and cursor shape tracking. |
(...skipping 30 matching lines...) Expand all Loading... |
278 } | 281 } |
279 | 282 |
280 DesktopFrame* result = CaptureScreen(); | 283 DesktopFrame* result = CaptureScreen(); |
281 last_invalid_region_ = result->updated_region(); | 284 last_invalid_region_ = result->updated_region(); |
282 result->set_capture_time_ms( | 285 result->set_capture_time_ms( |
283 (TickTime::Now() - capture_start_time).Milliseconds()); | 286 (TickTime::Now() - capture_start_time).Milliseconds()); |
284 callback_->OnCaptureCompleted(result); | 287 callback_->OnCaptureCompleted(result); |
285 } | 288 } |
286 | 289 |
287 bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) { | 290 bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) { |
288 DCHECK(screens->size() == 0); | 291 RTC_DCHECK(screens->size() == 0); |
289 // TODO(jiayl): implement screen enumeration. | 292 // TODO(jiayl): implement screen enumeration. |
290 Screen default_screen; | 293 Screen default_screen; |
291 default_screen.id = 0; | 294 default_screen.id = 0; |
292 screens->push_back(default_screen); | 295 screens->push_back(default_screen); |
293 return true; | 296 return true; |
294 } | 297 } |
295 | 298 |
296 bool ScreenCapturerLinux::SelectScreen(ScreenId id) { | 299 bool ScreenCapturerLinux::SelectScreen(ScreenId id) { |
297 // TODO(jiayl): implement screen selection. | 300 // TODO(jiayl): implement screen selection. |
298 return true; | 301 return true; |
299 } | 302 } |
300 | 303 |
301 bool ScreenCapturerLinux::HandleXEvent(const XEvent& event) { | 304 bool ScreenCapturerLinux::HandleXEvent(const XEvent& event) { |
302 if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) { | 305 if (use_damage_ && (event.type == damage_event_base_ + XDamageNotify)) { |
303 const XDamageNotifyEvent* damage_event = | 306 const XDamageNotifyEvent* damage_event = |
304 reinterpret_cast<const XDamageNotifyEvent*>(&event); | 307 reinterpret_cast<const XDamageNotifyEvent*>(&event); |
305 if (damage_event->damage != damage_handle_) | 308 if (damage_event->damage != damage_handle_) |
306 return false; | 309 return false; |
307 DCHECK(damage_event->level == XDamageReportNonEmpty); | 310 RTC_DCHECK(damage_event->level == XDamageReportNonEmpty); |
308 return true; | 311 return true; |
309 } else if (event.type == ConfigureNotify) { | 312 } else if (event.type == ConfigureNotify) { |
310 ScreenConfigurationChanged(); | 313 ScreenConfigurationChanged(); |
311 return true; | 314 return true; |
312 } | 315 } |
313 return false; | 316 return false; |
314 } | 317 } |
315 | 318 |
316 DesktopFrame* ScreenCapturerLinux::CaptureScreen() { | 319 DesktopFrame* ScreenCapturerLinux::CaptureScreen() { |
317 DesktopFrame* frame = queue_.current_frame()->Share(); | 320 DesktopFrame* frame = queue_.current_frame()->Share(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 } | 363 } |
361 } else { | 364 } else { |
362 // Doing full-screen polling, or this is the first capture after a | 365 // Doing full-screen polling, or this is the first capture after a |
363 // screen-resolution change. In either case, need a full-screen capture. | 366 // screen-resolution change. In either case, need a full-screen capture. |
364 DesktopRect screen_rect = DesktopRect::MakeSize(frame->size()); | 367 DesktopRect screen_rect = DesktopRect::MakeSize(frame->size()); |
365 x_server_pixel_buffer_.CaptureRect(screen_rect, frame); | 368 x_server_pixel_buffer_.CaptureRect(screen_rect, frame); |
366 | 369 |
367 if (queue_.previous_frame()) { | 370 if (queue_.previous_frame()) { |
368 // Full-screen polling, so calculate the invalid rects here, based on the | 371 // Full-screen polling, so calculate the invalid rects here, based on the |
369 // changed pixels between current and previous buffers. | 372 // changed pixels between current and previous buffers. |
370 DCHECK(differ_.get() != NULL); | 373 RTC_DCHECK(differ_.get() != NULL); |
371 DCHECK(queue_.previous_frame()->data()); | 374 RTC_DCHECK(queue_.previous_frame()->data()); |
372 differ_->CalcDirtyRegion(queue_.previous_frame()->data(), | 375 differ_->CalcDirtyRegion(queue_.previous_frame()->data(), |
373 frame->data(), updated_region); | 376 frame->data(), updated_region); |
374 } else { | 377 } else { |
375 // No previous buffer, so always invalidate the whole screen, whether | 378 // No previous buffer, so always invalidate the whole screen, whether |
376 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a | 379 // or not DAMAGE is being used. DAMAGE doesn't necessarily send a |
377 // full-screen notification after a screen-resolution change, so | 380 // full-screen notification after a screen-resolution change, so |
378 // this is done here. | 381 // this is done here. |
379 updated_region->SetRect(screen_rect); | 382 updated_region->SetRect(screen_rect); |
380 } | 383 } |
381 } | 384 } |
(...skipping 14 matching lines...) Expand all Loading... |
396 | 399 |
397 void ScreenCapturerLinux::SynchronizeFrame() { | 400 void ScreenCapturerLinux::SynchronizeFrame() { |
398 // Synchronize the current buffer with the previous one since we do not | 401 // Synchronize the current buffer with the previous one since we do not |
399 // capture the entire desktop. Note that encoder may be reading from the | 402 // capture the entire desktop. Note that encoder may be reading from the |
400 // previous buffer at this time so thread access complaints are false | 403 // previous buffer at this time so thread access complaints are false |
401 // positives. | 404 // positives. |
402 | 405 |
403 // TODO(hclam): We can reduce the amount of copying here by subtracting | 406 // TODO(hclam): We can reduce the amount of copying here by subtracting |
404 // |capturer_helper_|s region from |last_invalid_region_|. | 407 // |capturer_helper_|s region from |last_invalid_region_|. |
405 // http://crbug.com/92354 | 408 // http://crbug.com/92354 |
406 DCHECK(queue_.previous_frame()); | 409 RTC_DCHECK(queue_.previous_frame()); |
407 | 410 |
408 DesktopFrame* current = queue_.current_frame(); | 411 DesktopFrame* current = queue_.current_frame(); |
409 DesktopFrame* last = queue_.previous_frame(); | 412 DesktopFrame* last = queue_.previous_frame(); |
410 DCHECK(current != last); | 413 RTC_DCHECK(current != last); |
411 for (DesktopRegion::Iterator it(last_invalid_region_); | 414 for (DesktopRegion::Iterator it(last_invalid_region_); |
412 !it.IsAtEnd(); it.Advance()) { | 415 !it.IsAtEnd(); it.Advance()) { |
413 current->CopyPixelsFrom(*last, it.rect().top_left(), it.rect()); | 416 current->CopyPixelsFrom(*last, it.rect().top_left(), it.rect()); |
414 } | 417 } |
415 } | 418 } |
416 | 419 |
417 void ScreenCapturerLinux::DeinitXlib() { | 420 void ScreenCapturerLinux::DeinitXlib() { |
418 if (gc_) { | 421 if (gc_) { |
419 XFreeGC(display(), gc_); | 422 XFreeGC(display(), gc_); |
420 gc_ = NULL; | 423 gc_ = NULL; |
(...skipping 21 matching lines...) Expand all Loading... |
442 if (!options.x_display()) | 445 if (!options.x_display()) |
443 return NULL; | 446 return NULL; |
444 | 447 |
445 rtc::scoped_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux()); | 448 rtc::scoped_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux()); |
446 if (!capturer->Init(options)) | 449 if (!capturer->Init(options)) |
447 capturer.reset(); | 450 capturer.reset(); |
448 return capturer.release(); | 451 return capturer.release(); |
449 } | 452 } |
450 | 453 |
451 } // namespace webrtc | 454 } // namespace webrtc |
OLD | NEW |