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 |
11 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h" | 11 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h" |
12 | 12 |
13 #include <utility> | 13 #include <utility> |
14 | 14 |
15 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
16 #include "webrtc/base/timeutils.h" | 16 #include "webrtc/base/timeutils.h" |
17 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 17 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
18 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 18 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
19 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" | 19 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" |
20 #include "webrtc/modules/desktop_capture/desktop_region.h" | 20 #include "webrtc/modules/desktop_capture/desktop_region.h" |
21 #include "webrtc/modules/desktop_capture/mouse_cursor.h" | 21 #include "webrtc/modules/desktop_capture/mouse_cursor.h" |
22 #include "webrtc/modules/desktop_capture/win/cursor.h" | 22 #include "webrtc/modules/desktop_capture/win/cursor.h" |
23 #include "webrtc/modules/desktop_capture/win/desktop.h" | 23 #include "webrtc/modules/desktop_capture/win/desktop.h" |
24 #include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" | 24 #include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" |
25 #include "webrtc/system_wrappers/include/logging.h" | |
26 | 25 |
27 namespace webrtc { | 26 namespace webrtc { |
28 | 27 |
29 // kMagnifierWindowClass has to be "Magnifier" according to the Magnification | 28 // kMagnifierWindowClass has to be "Magnifier" according to the Magnification |
30 // API. The other strings can be anything. | 29 // API. The other strings can be anything. |
31 static LPCTSTR kMagnifierHostClass = L"ScreenCapturerWinMagnifierHost"; | 30 static LPCTSTR kMagnifierHostClass = L"ScreenCapturerWinMagnifierHost"; |
32 static LPCTSTR kHostWindowName = L"MagnifierHost"; | 31 static LPCTSTR kHostWindowName = L"MagnifierHost"; |
33 static LPCTSTR kMagnifierWindowClass = L"Magnifier"; | 32 static LPCTSTR kMagnifierWindowClass = L"Magnifier"; |
34 static LPCTSTR kMagnifierWindowName = L"MagnifierWindow"; | 33 static LPCTSTR kMagnifierWindowName = L"MagnifierWindow"; |
35 | 34 |
(...skipping 15 matching lines...) Expand all Loading... |
51 if (desktop_dc_) | 50 if (desktop_dc_) |
52 ReleaseDC(NULL, desktop_dc_); | 51 ReleaseDC(NULL, desktop_dc_); |
53 } | 52 } |
54 | 53 |
55 void ScreenCapturerWinMagnifier::Start(Callback* callback) { | 54 void ScreenCapturerWinMagnifier::Start(Callback* callback) { |
56 RTC_DCHECK(!callback_); | 55 RTC_DCHECK(!callback_); |
57 RTC_DCHECK(callback); | 56 RTC_DCHECK(callback); |
58 callback_ = callback; | 57 callback_ = callback; |
59 | 58 |
60 if (!InitializeMagnifier()) { | 59 if (!InitializeMagnifier()) { |
61 LOG_F(LS_WARNING) << "Magnifier initialization failed."; | |
62 } | 60 } |
63 } | 61 } |
64 | 62 |
65 void ScreenCapturerWinMagnifier::SetSharedMemoryFactory( | 63 void ScreenCapturerWinMagnifier::SetSharedMemoryFactory( |
66 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { | 64 std::unique_ptr<SharedMemoryFactory> shared_memory_factory) { |
67 shared_memory_factory_ = std::move(shared_memory_factory); | 65 shared_memory_factory_ = std::move(shared_memory_factory); |
68 } | 66 } |
69 | 67 |
70 void ScreenCapturerWinMagnifier::CaptureFrame() { | 68 void ScreenCapturerWinMagnifier::CaptureFrame() { |
71 RTC_DCHECK(callback_); | 69 RTC_DCHECK(callback_); |
72 if (!magnifier_initialized_) { | 70 if (!magnifier_initialized_) { |
73 LOG_F(LS_WARNING) << "Magnifier initialization failed."; | |
74 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 71 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); |
75 return; | 72 return; |
76 } | 73 } |
77 | 74 |
78 int64_t capture_start_time_nanos = rtc::TimeNanos(); | 75 int64_t capture_start_time_nanos = rtc::TimeNanos(); |
79 | 76 |
80 // Switch to the desktop receiving user input if different from the current | 77 // Switch to the desktop receiving user input if different from the current |
81 // one. | 78 // one. |
82 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop()); | 79 std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop()); |
83 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { | 80 if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) { |
84 // Release GDI resources otherwise SetThreadDesktop will fail. | 81 // Release GDI resources otherwise SetThreadDesktop will fail. |
85 if (desktop_dc_) { | 82 if (desktop_dc_) { |
86 ReleaseDC(NULL, desktop_dc_); | 83 ReleaseDC(NULL, desktop_dc_); |
87 desktop_dc_ = NULL; | 84 desktop_dc_ = NULL; |
88 } | 85 } |
89 // If SetThreadDesktop() fails, the thread is still assigned a desktop. | 86 // If SetThreadDesktop() fails, the thread is still assigned a desktop. |
90 // So we can continue capture screen bits, just from the wrong desktop. | 87 // So we can continue capture screen bits, just from the wrong desktop. |
91 desktop_.SetThreadDesktop(input_desktop.release()); | 88 desktop_.SetThreadDesktop(input_desktop.release()); |
92 } | 89 } |
93 | 90 |
94 DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_); | 91 DesktopRect rect = GetScreenRect(current_screen_id_, current_device_key_); |
95 queue_.MoveToNextFrame(); | 92 queue_.MoveToNextFrame(); |
96 CreateCurrentFrameIfNecessary(rect.size()); | 93 CreateCurrentFrameIfNecessary(rect.size()); |
97 // CaptureImage may fail in some situations, e.g. windows8 metro mode. So | 94 // CaptureImage may fail in some situations, e.g. windows8 metro mode. So |
98 // defer to the fallback capturer if magnifier capturer did not work. | 95 // defer to the fallback capturer if magnifier capturer did not work. |
99 if (!CaptureImage(rect)) { | 96 if (!CaptureImage(rect)) { |
100 LOG_F(LS_WARNING) << "Magnifier capturer failed to capture a frame."; | |
101 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); | 97 callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr); |
102 return; | 98 return; |
103 } | 99 } |
104 | 100 |
105 // Emit the current frame. | 101 // Emit the current frame. |
106 std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share(); | 102 std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share(); |
107 frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX), | 103 frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX), |
108 GetDeviceCaps(desktop_dc_, LOGPIXELSY))); | 104 GetDeviceCaps(desktop_dc_, LOGPIXELSY))); |
109 frame->mutable_updated_region()->SetRect( | 105 frame->mutable_updated_region()->SetRect( |
110 DesktopRect::MakeSize(frame->size())); | 106 DesktopRect::MakeSize(frame->size())); |
(...skipping 24 matching lines...) Expand all Loading... |
135 } | 131 } |
136 | 132 |
137 bool ScreenCapturerWinMagnifier::CaptureImage(const DesktopRect& rect) { | 133 bool ScreenCapturerWinMagnifier::CaptureImage(const DesktopRect& rect) { |
138 RTC_DCHECK(magnifier_initialized_); | 134 RTC_DCHECK(magnifier_initialized_); |
139 | 135 |
140 // Set the magnifier control to cover the captured rect. The content of the | 136 // Set the magnifier control to cover the captured rect. The content of the |
141 // magnifier control will be the captured image. | 137 // magnifier control will be the captured image. |
142 BOOL result = SetWindowPos(magnifier_window_, NULL, rect.left(), rect.top(), | 138 BOOL result = SetWindowPos(magnifier_window_, NULL, rect.left(), rect.top(), |
143 rect.width(), rect.height(), 0); | 139 rect.width(), rect.height(), 0); |
144 if (!result) { | 140 if (!result) { |
145 LOG_F(LS_WARNING) << "Failed to call SetWindowPos: " << GetLastError() | |
146 << ". Rect = {" << rect.left() << ", " << rect.top() | |
147 << ", " << rect.right() << ", " << rect.bottom() << "}"; | |
148 return false; | 141 return false; |
149 } | 142 } |
150 | 143 |
151 magnifier_capture_succeeded_ = false; | 144 magnifier_capture_succeeded_ = false; |
152 | 145 |
153 RECT native_rect = {rect.left(), rect.top(), rect.right(), rect.bottom()}; | 146 RECT native_rect = {rect.left(), rect.top(), rect.right(), rect.bottom()}; |
154 | 147 |
155 RTC_DCHECK(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES)); | 148 RTC_DCHECK(tls_index_.Value() != static_cast<int32_t>(TLS_OUT_OF_INDEXES)); |
156 TlsSetValue(tls_index_.Value(), this); | 149 TlsSetValue(tls_index_.Value(), this); |
157 // OnCaptured will be called via OnMagImageScalingCallback and fill in the | 150 // OnCaptured will be called via OnMagImageScalingCallback and fill in the |
158 // frame before set_window_source_func_ returns. | 151 // frame before set_window_source_func_ returns. |
159 result = set_window_source_func_(magnifier_window_, native_rect); | 152 result = set_window_source_func_(magnifier_window_, native_rect); |
160 | 153 |
161 if (!result) { | 154 if (!result) { |
162 LOG_F(LS_WARNING) << "Failed to call MagSetWindowSource: " << GetLastError() | |
163 << ". Rect = {" << rect.left() << ", " << rect.top() | |
164 << ", " << rect.right() << ", " << rect.bottom() << "}"; | |
165 return false; | 155 return false; |
166 } | 156 } |
167 | 157 |
168 return magnifier_capture_succeeded_; | 158 return magnifier_capture_succeeded_; |
169 } | 159 } |
170 | 160 |
171 BOOL ScreenCapturerWinMagnifier::OnMagImageScalingCallback( | 161 BOOL ScreenCapturerWinMagnifier::OnMagImageScalingCallback( |
172 HWND hwnd, | 162 HWND hwnd, |
173 void* srcdata, | 163 void* srcdata, |
174 MAGIMAGEHEADER srcheader, | 164 MAGIMAGEHEADER srcheader, |
(...skipping 14 matching lines...) Expand all Loading... |
189 | 179 |
190 // TODO(zijiehe): These functions are available on Windows Vista or upper, so we | 180 // TODO(zijiehe): These functions are available on Windows Vista or upper, so we |
191 // do not need to use LoadLibrary and GetProcAddress anymore. Use regular | 181 // do not need to use LoadLibrary and GetProcAddress anymore. Use regular |
192 // include and function calls instead of a dynamical loaded library. | 182 // include and function calls instead of a dynamical loaded library. |
193 bool ScreenCapturerWinMagnifier::InitializeMagnifier() { | 183 bool ScreenCapturerWinMagnifier::InitializeMagnifier() { |
194 RTC_DCHECK(!magnifier_initialized_); | 184 RTC_DCHECK(!magnifier_initialized_); |
195 | 185 |
196 if (GetSystemMetrics(SM_CMONITORS) != 1) { | 186 if (GetSystemMetrics(SM_CMONITORS) != 1) { |
197 // Do not try to use the magnifier in multi-screen setup (where the API | 187 // Do not try to use the magnifier in multi-screen setup (where the API |
198 // crashes sometimes). | 188 // crashes sometimes). |
199 LOG_F(LS_WARNING) << "Magnifier capturer cannot work on multi-screen " | |
200 "system."; | |
201 return false; | 189 return false; |
202 } | 190 } |
203 | 191 |
204 desktop_dc_ = GetDC(nullptr); | 192 desktop_dc_ = GetDC(nullptr); |
205 | 193 |
206 mag_lib_handle_ = LoadLibrary(L"Magnification.dll"); | 194 mag_lib_handle_ = LoadLibrary(L"Magnification.dll"); |
207 if (!mag_lib_handle_) | 195 if (!mag_lib_handle_) |
208 return false; | 196 return false; |
209 | 197 |
210 // Initialize Magnification API function pointers. | 198 // Initialize Magnification API function pointers. |
211 mag_initialize_func_ = reinterpret_cast<MagInitializeFunc>( | 199 mag_initialize_func_ = reinterpret_cast<MagInitializeFunc>( |
212 GetProcAddress(mag_lib_handle_, "MagInitialize")); | 200 GetProcAddress(mag_lib_handle_, "MagInitialize")); |
213 mag_uninitialize_func_ = reinterpret_cast<MagUninitializeFunc>( | 201 mag_uninitialize_func_ = reinterpret_cast<MagUninitializeFunc>( |
214 GetProcAddress(mag_lib_handle_, "MagUninitialize")); | 202 GetProcAddress(mag_lib_handle_, "MagUninitialize")); |
215 set_window_source_func_ = reinterpret_cast<MagSetWindowSourceFunc>( | 203 set_window_source_func_ = reinterpret_cast<MagSetWindowSourceFunc>( |
216 GetProcAddress(mag_lib_handle_, "MagSetWindowSource")); | 204 GetProcAddress(mag_lib_handle_, "MagSetWindowSource")); |
217 set_window_filter_list_func_ = reinterpret_cast<MagSetWindowFilterListFunc>( | 205 set_window_filter_list_func_ = reinterpret_cast<MagSetWindowFilterListFunc>( |
218 GetProcAddress(mag_lib_handle_, "MagSetWindowFilterList")); | 206 GetProcAddress(mag_lib_handle_, "MagSetWindowFilterList")); |
219 set_image_scaling_callback_func_ = | 207 set_image_scaling_callback_func_ = |
220 reinterpret_cast<MagSetImageScalingCallbackFunc>( | 208 reinterpret_cast<MagSetImageScalingCallbackFunc>( |
221 GetProcAddress(mag_lib_handle_, "MagSetImageScalingCallback")); | 209 GetProcAddress(mag_lib_handle_, "MagSetImageScalingCallback")); |
222 | 210 |
223 if (!mag_initialize_func_ || !mag_uninitialize_func_ || | 211 if (!mag_initialize_func_ || !mag_uninitialize_func_ || |
224 !set_window_source_func_ || !set_window_filter_list_func_ || | 212 !set_window_source_func_ || !set_window_filter_list_func_ || |
225 !set_image_scaling_callback_func_) { | 213 !set_image_scaling_callback_func_) { |
226 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | |
227 << "library functions missing."; | |
228 return false; | 214 return false; |
229 } | 215 } |
230 | 216 |
231 BOOL result = mag_initialize_func_(); | 217 BOOL result = mag_initialize_func_(); |
232 if (!result) { | 218 if (!result) { |
233 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | |
234 << "error from MagInitialize " << GetLastError(); | |
235 return false; | 219 return false; |
236 } | 220 } |
237 | 221 |
238 HMODULE hInstance = nullptr; | 222 HMODULE hInstance = nullptr; |
239 result = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | | 223 result = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | |
240 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | 224 GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, |
241 reinterpret_cast<char*>(&DefWindowProc), | 225 reinterpret_cast<char*>(&DefWindowProc), |
242 &hInstance); | 226 &hInstance); |
243 if (!result) { | 227 if (!result) { |
244 mag_uninitialize_func_(); | 228 mag_uninitialize_func_(); |
245 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | 229 |
246 << "error from GetModulehandleExA " << GetLastError(); | |
247 return false; | 230 return false; |
248 } | 231 } |
249 | 232 |
250 // Register the host window class. See the MSDN documentation of the | 233 // Register the host window class. See the MSDN documentation of the |
251 // Magnification API for more infomation. | 234 // Magnification API for more infomation. |
252 WNDCLASSEX wcex = {}; | 235 WNDCLASSEX wcex = {}; |
253 wcex.cbSize = sizeof(WNDCLASSEX); | 236 wcex.cbSize = sizeof(WNDCLASSEX); |
254 wcex.lpfnWndProc = &DefWindowProc; | 237 wcex.lpfnWndProc = &DefWindowProc; |
255 wcex.hInstance = hInstance; | 238 wcex.hInstance = hInstance; |
256 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); | 239 wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); |
257 wcex.lpszClassName = kMagnifierHostClass; | 240 wcex.lpszClassName = kMagnifierHostClass; |
258 | 241 |
259 // Ignore the error which may happen when the class is already registered. | 242 // Ignore the error which may happen when the class is already registered. |
260 RegisterClassEx(&wcex); | 243 RegisterClassEx(&wcex); |
261 | 244 |
262 // Create the host window. | 245 // Create the host window. |
263 host_window_ = | 246 host_window_ = |
264 CreateWindowEx(WS_EX_LAYERED, kMagnifierHostClass, kHostWindowName, 0, 0, | 247 CreateWindowEx(WS_EX_LAYERED, kMagnifierHostClass, kHostWindowName, 0, 0, |
265 0, 0, 0, nullptr, nullptr, hInstance, nullptr); | 248 0, 0, 0, nullptr, nullptr, hInstance, nullptr); |
266 if (!host_window_) { | 249 if (!host_window_) { |
267 mag_uninitialize_func_(); | 250 mag_uninitialize_func_(); |
268 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | 251 |
269 << "error from creating host window " << GetLastError(); | |
270 return false; | 252 return false; |
271 } | 253 } |
272 | 254 |
273 // Create the magnifier control. | 255 // Create the magnifier control. |
274 magnifier_window_ = CreateWindow(kMagnifierWindowClass, kMagnifierWindowName, | 256 magnifier_window_ = CreateWindow(kMagnifierWindowClass, kMagnifierWindowName, |
275 WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, | 257 WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, |
276 host_window_, nullptr, hInstance, nullptr); | 258 host_window_, nullptr, hInstance, nullptr); |
277 if (!magnifier_window_) { | 259 if (!magnifier_window_) { |
278 mag_uninitialize_func_(); | 260 mag_uninitialize_func_(); |
279 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | 261 |
280 << "error from creating magnifier window " | |
281 << GetLastError(); | |
282 return false; | 262 return false; |
283 } | 263 } |
284 | 264 |
285 // Hide the host window. | 265 // Hide the host window. |
286 ShowWindow(host_window_, SW_HIDE); | 266 ShowWindow(host_window_, SW_HIDE); |
287 | 267 |
288 // Set the scaling callback to receive captured image. | 268 // Set the scaling callback to receive captured image. |
289 result = set_image_scaling_callback_func_( | 269 result = set_image_scaling_callback_func_( |
290 magnifier_window_, | 270 magnifier_window_, |
291 &ScreenCapturerWinMagnifier::OnMagImageScalingCallback); | 271 &ScreenCapturerWinMagnifier::OnMagImageScalingCallback); |
292 if (!result) { | 272 if (!result) { |
293 mag_uninitialize_func_(); | 273 mag_uninitialize_func_(); |
294 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | 274 |
295 << "error from MagSetImageScalingCallback " | |
296 << GetLastError(); | |
297 return false; | 275 return false; |
298 } | 276 } |
299 | 277 |
300 if (excluded_window_) { | 278 if (excluded_window_) { |
301 result = set_window_filter_list_func_( | 279 result = set_window_filter_list_func_( |
302 magnifier_window_, MW_FILTERMODE_EXCLUDE, 1, &excluded_window_); | 280 magnifier_window_, MW_FILTERMODE_EXCLUDE, 1, &excluded_window_); |
303 if (!result) { | 281 if (!result) { |
304 mag_uninitialize_func_(); | 282 mag_uninitialize_func_(); |
305 LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: " | 283 |
306 << "error from MagSetWindowFilterList " | |
307 << GetLastError(); | |
308 return false; | 284 return false; |
309 } | 285 } |
310 } | 286 } |
311 | 287 |
312 if (tls_index_.Value() == static_cast<int32_t>(TLS_OUT_OF_INDEXES)) { | 288 if (tls_index_.Value() == static_cast<int32_t>(TLS_OUT_OF_INDEXES)) { |
313 // More than one threads may get here at the same time, but only one will | 289 // More than one threads may get here at the same time, but only one will |
314 // write to tls_index_ using CompareExchange. | 290 // write to tls_index_ using CompareExchange. |
315 DWORD new_tls_index = TlsAlloc(); | 291 DWORD new_tls_index = TlsAlloc(); |
316 if (!tls_index_.CompareExchange(new_tls_index, TLS_OUT_OF_INDEXES)) | 292 if (!tls_index_.CompareExchange(new_tls_index, TLS_OUT_OF_INDEXES)) |
317 TlsFree(new_tls_index); | 293 TlsFree(new_tls_index); |
318 } | 294 } |
319 | 295 |
320 magnifier_initialized_ = true; | 296 magnifier_initialized_ = true; |
321 return true; | 297 return true; |
322 } | 298 } |
323 | 299 |
324 void ScreenCapturerWinMagnifier::OnCaptured(void* data, | 300 void ScreenCapturerWinMagnifier::OnCaptured(void* data, |
325 const MAGIMAGEHEADER& header) { | 301 const MAGIMAGEHEADER& header) { |
326 DesktopFrame* current_frame = queue_.current_frame(); | 302 DesktopFrame* current_frame = queue_.current_frame(); |
327 | 303 |
328 // Verify the format. | 304 // Verify the format. |
329 // TODO(jiayl): support capturing sources with pixel formats other than RGBA. | 305 // TODO(jiayl): support capturing sources with pixel formats other than RGBA. |
330 int captured_bytes_per_pixel = header.cbSize / header.width / header.height; | 306 int captured_bytes_per_pixel = header.cbSize / header.width / header.height; |
331 if (header.format != GUID_WICPixelFormat32bppRGBA || | 307 if (header.format != GUID_WICPixelFormat32bppRGBA || |
332 header.width != static_cast<UINT>(current_frame->size().width()) || | 308 header.width != static_cast<UINT>(current_frame->size().width()) || |
333 header.height != static_cast<UINT>(current_frame->size().height()) || | 309 header.height != static_cast<UINT>(current_frame->size().height()) || |
334 header.stride != static_cast<UINT>(current_frame->stride()) || | 310 header.stride != static_cast<UINT>(current_frame->stride()) || |
335 captured_bytes_per_pixel != DesktopFrame::kBytesPerPixel) { | 311 captured_bytes_per_pixel != DesktopFrame::kBytesPerPixel) { |
336 LOG_F(LS_WARNING) << "Output format does not match the captured format: " | 312 |
337 << "width = " << header.width << ", " | |
338 << "height = " << header.height << ", " | |
339 << "stride = " << header.stride << ", " | |
340 << "bpp = " << captured_bytes_per_pixel << ", " | |
341 << "pixel format RGBA ? " | |
342 << (header.format == GUID_WICPixelFormat32bppRGBA) << "."; | |
343 return; | 313 return; |
344 } | 314 } |
345 | 315 |
346 // Copy the data into the frame. | 316 // Copy the data into the frame. |
347 current_frame->CopyPixelsFrom( | 317 current_frame->CopyPixelsFrom( |
348 reinterpret_cast<uint8_t*>(data), | 318 reinterpret_cast<uint8_t*>(data), |
349 header.stride, | 319 header.stride, |
350 DesktopRect::MakeXYWH(0, 0, header.width, header.height)); | 320 DesktopRect::MakeXYWH(0, 0, header.width, header.height)); |
351 | 321 |
352 magnifier_capture_succeeded_ = true; | 322 magnifier_capture_succeeded_ = true; |
353 } | 323 } |
354 | 324 |
355 void ScreenCapturerWinMagnifier::CreateCurrentFrameIfNecessary( | 325 void ScreenCapturerWinMagnifier::CreateCurrentFrameIfNecessary( |
356 const DesktopSize& size) { | 326 const DesktopSize& size) { |
357 // If the current buffer is from an older generation then allocate a new one. | 327 // If the current buffer is from an older generation then allocate a new one. |
358 // Note that we can't reallocate other buffers at this point, since the caller | 328 // Note that we can't reallocate other buffers at this point, since the caller |
359 // may still be reading from them. | 329 // may still be reading from them. |
360 if (!queue_.current_frame() || !queue_.current_frame()->size().equals(size)) { | 330 if (!queue_.current_frame() || !queue_.current_frame()->size().equals(size)) { |
361 std::unique_ptr<DesktopFrame> frame = | 331 std::unique_ptr<DesktopFrame> frame = |
362 shared_memory_factory_ | 332 shared_memory_factory_ |
363 ? SharedMemoryDesktopFrame::Create(size, | 333 ? SharedMemoryDesktopFrame::Create(size, |
364 shared_memory_factory_.get()) | 334 shared_memory_factory_.get()) |
365 : std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(size)); | 335 : std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(size)); |
366 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); | 336 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame))); |
367 } | 337 } |
368 } | 338 } |
369 | 339 |
370 } // namespace webrtc | 340 } // namespace webrtc |
OLD | NEW |