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_gdi.h" | 11 #include "webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h" |
12 | 12 |
13 #include <assert.h> | |
14 | |
15 #include <utility> | 13 #include <utility> |
16 | 14 |
17 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
| 16 #include "webrtc/base/logging.h" |
18 #include "webrtc/base/timeutils.h" | 17 #include "webrtc/base/timeutils.h" |
19 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" | 18 #include "webrtc/modules/desktop_capture/desktop_capture_options.h" |
20 #include "webrtc/modules/desktop_capture/desktop_frame.h" | 19 #include "webrtc/modules/desktop_capture/desktop_frame.h" |
21 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" | 20 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" |
22 #include "webrtc/modules/desktop_capture/desktop_region.h" | 21 #include "webrtc/modules/desktop_capture/desktop_region.h" |
23 #include "webrtc/modules/desktop_capture/mouse_cursor.h" | 22 #include "webrtc/modules/desktop_capture/mouse_cursor.h" |
24 #include "webrtc/modules/desktop_capture/win/cursor.h" | 23 #include "webrtc/modules/desktop_capture/win/cursor.h" |
25 #include "webrtc/modules/desktop_capture/win/desktop.h" | 24 #include "webrtc/modules/desktop_capture/win/desktop.h" |
26 #include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" | 25 #include "webrtc/modules/desktop_capture/win/screen_capture_utils.h" |
27 #include "webrtc/system_wrappers/include/logging.h" | 26 #include "webrtc/system_wrappers/include/logging.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 } | 102 } |
104 | 103 |
105 bool ScreenCapturerWinGdi::SelectSource(SourceId id) { | 104 bool ScreenCapturerWinGdi::SelectSource(SourceId id) { |
106 bool valid = IsScreenValid(id, ¤t_device_key_); | 105 bool valid = IsScreenValid(id, ¤t_device_key_); |
107 if (valid) | 106 if (valid) |
108 current_screen_id_ = id; | 107 current_screen_id_ = id; |
109 return valid; | 108 return valid; |
110 } | 109 } |
111 | 110 |
112 void ScreenCapturerWinGdi::Start(Callback* callback) { | 111 void ScreenCapturerWinGdi::Start(Callback* callback) { |
113 assert(!callback_); | 112 RTC_DCHECK(!callback_); |
114 assert(callback); | 113 RTC_DCHECK(callback); |
115 | 114 |
116 callback_ = callback; | 115 callback_ = callback; |
117 | 116 |
118 // Vote to disable Aero composited desktop effects while capturing. Windows | 117 // Vote to disable Aero composited desktop effects while capturing. Windows |
119 // will restore Aero automatically if the process exits. This has no effect | 118 // will restore Aero automatically if the process exits. This has no effect |
120 // under Windows 8 or higher. See crbug.com/124018. | 119 // under Windows 8 or higher. See crbug.com/124018. |
121 if (composition_func_) | 120 if (composition_func_) |
122 (*composition_func_)(DWM_EC_DISABLECOMPOSITION); | 121 (*composition_func_)(DWM_EC_DISABLECOMPOSITION); |
123 } | 122 } |
124 | 123 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 desktop_dc_ = nullptr; | 161 desktop_dc_ = nullptr; |
163 } | 162 } |
164 if (memory_dc_) { | 163 if (memory_dc_) { |
165 DeleteDC(memory_dc_); | 164 DeleteDC(memory_dc_); |
166 memory_dc_ = nullptr; | 165 memory_dc_ = nullptr; |
167 } | 166 } |
168 desktop_dc_rect_ = DesktopRect(); | 167 desktop_dc_rect_ = DesktopRect(); |
169 } | 168 } |
170 | 169 |
171 if (!desktop_dc_) { | 170 if (!desktop_dc_) { |
172 assert(!memory_dc_); | 171 RTC_DCHECK(!memory_dc_); |
173 | 172 |
174 // Create GDI device contexts to capture from the desktop into memory. | 173 // Create GDI device contexts to capture from the desktop into memory. |
175 desktop_dc_ = GetDC(nullptr); | 174 desktop_dc_ = GetDC(nullptr); |
176 if (!desktop_dc_) | 175 RTC_CHECK(desktop_dc_); |
177 abort(); | |
178 memory_dc_ = CreateCompatibleDC(desktop_dc_); | 176 memory_dc_ = CreateCompatibleDC(desktop_dc_); |
179 if (!memory_dc_) | 177 RTC_CHECK(memory_dc_); |
180 abort(); | |
181 | 178 |
182 desktop_dc_rect_ = screen_rect; | 179 desktop_dc_rect_ = screen_rect; |
183 | 180 |
184 // Make sure the frame buffers will be reallocated. | 181 // Make sure the frame buffers will be reallocated. |
185 queue_.Reset(); | 182 queue_.Reset(); |
186 } | 183 } |
187 } | 184 } |
188 | 185 |
189 bool ScreenCapturerWinGdi::CaptureImage() { | 186 bool ScreenCapturerWinGdi::CaptureImage() { |
190 DesktopRect screen_rect = | 187 DesktopRect screen_rect = |
191 GetScreenRect(current_screen_id_, current_device_key_); | 188 GetScreenRect(current_screen_id_, current_device_key_); |
192 if (screen_rect.is_empty()) | 189 if (screen_rect.is_empty()) |
193 return false; | 190 return false; |
194 | 191 |
195 DesktopSize size = screen_rect.size(); | 192 DesktopSize size = screen_rect.size(); |
196 // If the current buffer is from an older generation then allocate a new one. | 193 // If the current buffer is from an older generation then allocate a new one. |
197 // Note that we can't reallocate other buffers at this point, since the caller | 194 // Note that we can't reallocate other buffers at this point, since the caller |
198 // may still be reading from them. | 195 // may still be reading from them. |
199 if (!queue_.current_frame() || | 196 if (!queue_.current_frame() || |
200 !queue_.current_frame()->size().equals(screen_rect.size())) { | 197 !queue_.current_frame()->size().equals(screen_rect.size())) { |
201 assert(desktop_dc_); | 198 RTC_DCHECK(desktop_dc_); |
202 assert(memory_dc_); | 199 RTC_DCHECK(memory_dc_); |
203 | 200 |
204 std::unique_ptr<DesktopFrame> buffer = DesktopFrameWin::Create( | 201 std::unique_ptr<DesktopFrame> buffer = DesktopFrameWin::Create( |
205 size, shared_memory_factory_.get(), desktop_dc_); | 202 size, shared_memory_factory_.get(), desktop_dc_); |
206 if (!buffer) | 203 if (!buffer) |
207 return false; | 204 return false; |
208 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(buffer))); | 205 queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(buffer))); |
209 } | 206 } |
210 | 207 |
211 // Select the target bitmap into the memory dc and copy the rect from desktop | 208 // Select the target bitmap into the memory dc and copy the rect from desktop |
212 // to memory. | 209 // to memory. |
213 DesktopFrameWin* current = static_cast<DesktopFrameWin*>( | 210 DesktopFrameWin* current = static_cast<DesktopFrameWin*>( |
214 queue_.current_frame()->GetUnderlyingFrame()); | 211 queue_.current_frame()->GetUnderlyingFrame()); |
215 HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap()); | 212 HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap()); |
216 if (previous_object) { | 213 if (!previous_object || previous_object == HGDI_ERROR) { |
217 BitBlt(memory_dc_, 0, 0, screen_rect.width(), screen_rect.height(), | 214 return false; |
218 desktop_dc_, screen_rect.left(), screen_rect.top(), | 215 } |
219 SRCCOPY | CAPTUREBLT); | |
220 | 216 |
221 // Select back the previously selected object to that the device contect | 217 bool result = (BitBlt(memory_dc_, 0, 0, screen_rect.width(), |
222 // could be destroyed independently of the bitmap if needed. | 218 screen_rect.height(), desktop_dc_, screen_rect.left(), screen_rect.top(), |
223 SelectObject(memory_dc_, previous_object); | 219 SRCCOPY | CAPTUREBLT) != FALSE); |
| 220 if (!result) { |
| 221 LOG_GLE(LS_WARNING) << "BitBlt failed"; |
224 } | 222 } |
225 return true; | 223 |
| 224 // Select back the previously selected object to that the device contect |
| 225 // could be destroyed independently of the bitmap if needed. |
| 226 SelectObject(memory_dc_, previous_object); |
| 227 |
| 228 return result; |
226 } | 229 } |
227 | 230 |
228 } // namespace webrtc | 231 } // namespace webrtc |
OLD | NEW |