Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 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 17 matching lines...) Expand all Loading... | |
| 28 | 28 |
| 29 // kMagnifierWindowClass has to be "Magnifier" according to the Magnification | 29 // kMagnifierWindowClass has to be "Magnifier" according to the Magnification |
| 30 // API. The other strings can be anything. | 30 // API. The other strings can be anything. |
| 31 static LPCTSTR kMagnifierHostClass = L"ScreenCapturerWinMagnifierHost"; | 31 static LPCTSTR kMagnifierHostClass = L"ScreenCapturerWinMagnifierHost"; |
| 32 static LPCTSTR kHostWindowName = L"MagnifierHost"; | 32 static LPCTSTR kHostWindowName = L"MagnifierHost"; |
| 33 static LPCTSTR kMagnifierWindowClass = L"Magnifier"; | 33 static LPCTSTR kMagnifierWindowClass = L"Magnifier"; |
| 34 static LPCTSTR kMagnifierWindowName = L"MagnifierWindow"; | 34 static LPCTSTR kMagnifierWindowName = L"MagnifierWindow"; |
| 35 | 35 |
| 36 Atomic32 ScreenCapturerWinMagnifier::tls_index_(TLS_OUT_OF_INDEXES); | 36 Atomic32 ScreenCapturerWinMagnifier::tls_index_(TLS_OUT_OF_INDEXES); |
| 37 | 37 |
| 38 ScreenCapturerWinMagnifier::ScreenCapturerWinMagnifier( | 38 ScreenCapturerWinMagnifier::ScreenCapturerWinMagnifier() = default; |
| 39 std::unique_ptr<DesktopCapturer> fallback_capturer) | |
| 40 : fallback_capturer_(std::move(fallback_capturer)) {} | |
| 41 | |
| 42 ScreenCapturerWinMagnifier::~ScreenCapturerWinMagnifier() { | 39 ScreenCapturerWinMagnifier::~ScreenCapturerWinMagnifier() { |
| 43 // DestroyWindow must be called before MagUninitialize. magnifier_window_ is | 40 // DestroyWindow must be called before MagUninitialize. magnifier_window_ is |
| 44 // destroyed automatically when host_window_ is destroyed. | 41 // destroyed automatically when host_window_ is destroyed. |
| 45 if (host_window_) | 42 if (host_window_) |
| 46 DestroyWindow(host_window_); | 43 DestroyWindow(host_window_); |
| 47 | 44 |
| 48 if (magnifier_initialized_) | 45 if (magnifier_initialized_) |
| 49 mag_uninitialize_func_(); | 46 mag_uninitialize_func_(); |
| 50 | 47 |
| 51 if (mag_lib_handle_) | 48 if (mag_lib_handle_) |
| 52 FreeLibrary(mag_lib_handle_); | 49 FreeLibrary(mag_lib_handle_); |
| 53 | 50 |
| 54 if (desktop_dc_) | 51 if (desktop_dc_) |
| 55 ReleaseDC(NULL, desktop_dc_); | 52 ReleaseDC(NULL, desktop_dc_); |
| 56 } | 53 } |
| 57 | 54 |
| 58 void ScreenCapturerWinMagnifier::Start(Callback* callback) { | 55 void ScreenCapturerWinMagnifier::Start(Callback* callback) { |
| 59 RTC_DCHECK(!callback_); | 56 RTC_DCHECK(!callback_); |
| 60 RTC_DCHECK(callback); | 57 RTC_DCHECK(callback); |
| 61 callback_ = callback; | 58 callback_ = callback; |
| 62 | 59 |
| 63 if (!InitializeMagnifier()) { | 60 if (!InitializeMagnifier()) { |
| 64 LOG_F(LS_WARNING) << "Switching to fallback screen capturer becuase " | 61 LOG_F(LS_WARNING) << "Magnifier initialization failed."; |
| 65 "magnifier initialization failed."; | |
| 66 StartFallbackCapturer(); | |
| 67 } | 62 } |
| 68 } | 63 } |
| 69 | 64 |
| 70 void ScreenCapturerWinMagnifier::SetSharedMemoryFactory( | 65 void ScreenCapturerWinMagnifier::SetSharedMemoryFactory( |
| 71 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { | 66 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { |
| 72 shared_memory_factory_ = std::move(shared_memory_factory); | 67 shared_memory_factory_ = std::move(shared_memory_factory); |
| 73 } | 68 } |
| 74 | 69 |
| 75 void ScreenCapturerWinMagnifier::CaptureFrame() { | 70 void ScreenCapturerWinMagnifier::CaptureFrame() { |
| 76 if (!magnifier_initialized_ || | 71 RTC_DCHECK(callback_); |
| 77 !magnifier_capture_succeeded_ || | 72 if (!magnifier_initialized_) { |
|
Sergey Ulanov
2017/02/21 20:49:31
Previously the capturer was always falling back to
Hzj_jie
2017/02/21 23:27:33
Done.
| |
| 78 GetSystemMetrics(SM_CMONITORS) != 1) { | 73 LOG_F(LS_WARNING) << "Magnifier initialization failed."; |
| 79 // Do not try to use the magnifier if it failed before and in multi-screen | 74 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); |
| 80 // setup (where the API crashes sometimes). | |
| 81 LOG_F(LS_WARNING) << "Switching to the fallback screen capturer because " | |
| 82 "initialization or last capture attempt failed, or " | |
| 83 "execute on multi-screen system."; | |
| 84 StartFallbackCapturer(); | |
| 85 fallback_capturer_->CaptureFrame(); | |
| 86 return; | 75 return; |
| 87 } | 76 } |
| 88 | 77 |
| 89 int64_t capture_start_time_nanos = rtc::TimeNanos(); | 78 int64_t capture_start_time_nanos = rtc::TimeNanos(); |
| 90 | 79 |
| 91 // Switch to the desktop receiving user input if different from the current | 80 // Switch to the desktop receiving user input if different from the current |
| 92 // one. | 81 // one. |
| 93 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop()); | 82 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop()); |
| 94 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { | 83 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { |
| 95 // Release GDI resources otherwise SetThreadDesktop will fail. | 84 // Release GDI resources otherwise SetThreadDesktop will fail. |
| 96 if (desktop_dc_) { | 85 if (desktop_dc_) { |
| 97 ReleaseDC(NULL, desktop_dc_); | 86 ReleaseDC(NULL, desktop_dc_); |
| 98 desktop_dc_ = NULL; | 87 desktop_dc_ = NULL; |
| 99 } | 88 } |
| 100 // If SetThreadDesktop() fails, the thread is still assigned a desktop. | 89 // If SetThreadDesktop() fails, the thread is still assigned a desktop. |
| 101 // So we can continue capture screen bits, just from the wrong desktop. | 90 // So we can continue capture screen bits, just from the wrong desktop. |
| 102 desktop_.SetThreadDesktop(input_desktop.release()); | 91 desktop_.SetThreadDesktop(input_desktop.release()); |
| 103 } | 92 } |
| 104 | 93 |
| 105 DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_); | 94 DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_); |
| 106 queue_.MoveToNextFrame(); | 95 queue_.MoveToNextFrame(); |
| 107 CreateCurrentFrameIfNecessary(rect.size()); | 96 CreateCurrentFrameIfNecessary(rect.size()); |
| 108 // CaptureImage may fail in some situations, e.g. windows8 metro mode. So | 97 // CaptureImage may fail in some situations, e.g. windows8 metro mode. So |
| 109 // defer to the fallback capturer if magnifier capturer did not work. | 98 // defer to the fallback capturer if magnifier capturer did not work. |
| 110 if (!CaptureImage(rect)) { | 99 if (!CaptureImage(rect)) { |
| 111 LOG_F(LS_WARNING) << "Switching to the fallback screen capturer because " | 100 LOG_F(LS_WARNING) << "Magnifier capturer failed to capture a frame."; |
| 112 "last capture attempt failed."; | 101 callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr); |
| 113 StartFallbackCapturer(); | |
| 114 fallback_capturer_->CaptureFrame(); | |
| 115 return; | 102 return; |
| 116 } | 103 } |
| 117 | 104 |
| 118 // Emit the current frame. | 105 // Emit the current frame. |
| 119 std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share(); | 106 std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share(); |
| 120 frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX), | 107 frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX), |
| 121 GetDeviceCaps(desktop_dc_, LOGPIXELSY))); | 108 GetDeviceCaps(desktop_dc_, LOGPIXELSY))); |
| 122 frame->mutable_updated_region()->SetRect( | 109 frame->mutable_updated_region()->SetRect( |
| 123 DesktopRect::MakeSize(frame->size())); | 110 DesktopRect::MakeSize(frame->size())); |
| 124 frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / | 111 frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) / |
| 125 rtc::kNumNanosecsPerMillisec); | 112 rtc::kNumNanosecsPerMillisec); |
| 126 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); | 113 callback_->OnCaptureResult(Result::SUCCESS, std::move(frame)); |
| 127 } | 114 } |
| 128 | 115 |
| 129 bool ScreenCapturerWinMagnifier::GetSourceList(SourceList* sources) { | 116 bool ScreenCapturerWinMagnifier::GetSourceList(SourceList* sources) { |
| 130 return webrtc::GetScreenList(sources); | 117 return webrtc::GetScreenList(sources); |
| 131 } | 118 } |
| 132 | 119 |
| 133 bool ScreenCapturerWinMagnifier::SelectSource(SourceId id) { | 120 bool ScreenCapturerWinMagnifier::SelectSource(SourceId id) { |
| 134 bool valid = IsScreenValid(id, ¤t_device_key_); | 121 if (IsScreenValid(id, ¤t_device_key_)) { |
| 122 current_screen_id_ = id; | |
| 123 return true; | |
| 124 } | |
| 135 | 125 |
| 136 // Set current_screen_id_ even if the fallback capturer is being used, so we | 126 return false; |
| 137 // can switch back to the magnifier when possible. | |
| 138 if (valid) | |
| 139 current_screen_id_ = id; | |
| 140 | |
| 141 if (fallback_capturer_started_) | |
| 142 fallback_capturer_->SelectSource(id); | |
| 143 | |
| 144 return valid; | |
| 145 } | 127 } |
| 146 | 128 |
| 147 void ScreenCapturerWinMagnifier::SetExcludedWindow(WindowId excluded_window) { | 129 void ScreenCapturerWinMagnifier::SetExcludedWindow(WindowId excluded_window) { |
| 148 excluded_window_ = (HWND)excluded_window; | 130 excluded_window_ = (HWND)excluded_window; |
| 149 if (excluded_window_ && magnifier_initialized_) { | 131 if (excluded_window_ && magnifier_initialized_) { |
| 150 set_window_filter_list_func_( | 132 set_window_filter_list_func_( |
| 151 magnifier_window_, MW_FILTERMODE_EXCLUDE, 1, &excluded_window_); | 133 magnifier_window_, MW_FILTERMODE_EXCLUDE, 1, &excluded_window_); |
| 152 } | 134 } |
| 153 } | 135 } |
| 154 | 136 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 owner->OnCaptured(srcdata, srcheader); | 185 owner->OnCaptured(srcdata, srcheader); |
| 204 | 186 |
| 205 return TRUE; | 187 return TRUE; |
| 206 } | 188 } |
| 207 | 189 |
| 208 // TODO(zijiehe): These functions are available on Windows Vista or upper, so we | 190 // TODO(zijiehe): These functions are available on Windows Vista or upper, so we |
| 209 // do not need to use LoadLibrary and GetProcAddress anymore. Use regular | 191 // do not need to use LoadLibrary and GetProcAddress anymore. Use regular |
| 210 // include and function calls instead of a dynamical loaded library. | 192 // include and function calls instead of a dynamical loaded library. |
| 211 bool ScreenCapturerWinMagnifier::InitializeMagnifier() { | 193 bool ScreenCapturerWinMagnifier::InitializeMagnifier() { |
| 212 RTC_DCHECK(!magnifier_initialized_); | 194 RTC_DCHECK(!magnifier_initialized_); |
| 195 | |
| 196 if (GetSystemMetrics(SM_CMONITORS) != 1) { | |
| 197 // Do not try to use the magnifier if it failed before and in multi-screen | |
| 198 // setup (where the API crashes sometimes). | |
| 199 LOG_F(LS_WARNING) << "Magnifier capturer cannot work on multi-screen " | |
| 200 "system."; | |
| 201 return false; | |
| 202 } | |
| 203 | |
| 213 desktop_dc_ = GetDC(nullptr); | 204 desktop_dc_ = GetDC(nullptr); |
| 214 | 205 |
| 215 mag_lib_handle_ = LoadLibrary(L"Magnification.dll"); | 206 mag_lib_handle_ = LoadLibrary(L"Magnification.dll"); |
| 216 if (!mag_lib_handle_) | 207 if (!mag_lib_handle_) |
| 217 return false; | 208 return false; |
| 218 | 209 |
| 219 // Initialize Magnification API function pointers. | 210 // Initialize Magnification API function pointers. |
| 220 mag_initialize_func_ = reinterpret_cast<MagInitializeFunc>( | 211 mag_initialize_func_ = reinterpret_cast<MagInitializeFunc>( |
| 221 GetProcAddress(mag_lib_handle_, "MagInitialize")); | 212 GetProcAddress(mag_lib_handle_, "MagInitialize")); |
| 222 mag_uninitialize_func_ = reinterpret_cast<MagUninitializeFunc>( | 213 mag_uninitialize_func_ = reinterpret_cast<MagUninitializeFunc>( |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 if (!queue_.current_frame() || !queue_.current_frame()->size().equals(size)) { | 360 if (!queue_.current_frame() || !queue_.current_frame()->size().equals(size)) { |
| 370 std::unique_ptr<DesktopFrame> frame = | 361 std::unique_ptr<DesktopFrame> frame = |
| 371 shared_memory_factory_ | 362 shared_memory_factory_ |
| 372 ? SharedMemoryDesktopFrame::Create(size, | 363 ? SharedMemoryDesktopFrame::Create(size, |
| 373 shared_memory_factory_.get()) | 364 shared_memory_factory_.get()) |
| 374 : std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(size)); | 365 : std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(size)); |
| 375 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); | 366 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); |
| 376 } | 367 } |
| 377 } | 368 } |
| 378 | 369 |
| 379 void ScreenCapturerWinMagnifier::StartFallbackCapturer() { | |
| 380 RTC_DCHECK(fallback_capturer_); | |
| 381 if (!fallback_capturer_started_) { | |
| 382 fallback_capturer_started_ = true; | |
| 383 | |
| 384 fallback_capturer_->Start(callback_); | |
| 385 fallback_capturer_->SelectSource(current_screen_id_); | |
| 386 } | |
| 387 } | |
| 388 | |
| 389 } // namespace webrtc | 370 } // namespace webrtc |
| OLD | NEW |