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

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

Issue 1705183002: Fix screen flickering for Windows platform… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
11 #include "webrtc/modules/desktop_capture/window_capturer.h" 11 #include "webrtc/modules/desktop_capture/window_capturer.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <set>
14 15
15 #include "webrtc/base/scoped_ptr.h" 16 #include "webrtc/base/scoped_ptr.h"
16 #include "webrtc/base/checks.h" 17 #include "webrtc/base/checks.h"
17 #include "webrtc/base/win32.h" 18 #include "webrtc/base/win32.h"
18 #include "webrtc/modules/desktop_capture/desktop_frame_win.h" 19 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
19 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h" 20 #include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
20 #include "webrtc/system_wrappers/include/logging.h" 21 #include "webrtc/system_wrappers/include/logging.h"
21 22
22 namespace webrtc { 23 namespace webrtc {
23 24
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 Callback* callback_; 97 Callback* callback_;
97 98
98 // HWND and HDC for the currently selected window or NULL if window is not 99 // HWND and HDC for the currently selected window or NULL if window is not
99 // selected. 100 // selected.
100 HWND window_; 101 HWND window_;
101 102
102 DesktopSize previous_size_; 103 DesktopSize previous_size_;
103 104
104 AeroChecker aero_checker_; 105 AeroChecker aero_checker_;
105 106
107 // JavaScript fucntion ChooseDesktopMedia() leads SelectWindow() and Capture()
Sergey Ulanov 2016/02/20 18:47:49 nit: no need mention JavaScript here. Just say tha
GeorgeZ 2016/02/22 17:08:45 Done.
108 // to be called in interleaved sequence. The size of each window need to be
109 // tracked so that when there is no size change, capture will use BitBlt()
110 // instead of PrintWindow() when aero is enabled. keep using PrintWindow() for
111 // each frame capture will lead to screen flickering.
112 std::map<HWND, DesktopSize> window_size_map_;
113
106 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin); 114 RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
107 }; 115 };
108 116
109 WindowCapturerWin::WindowCapturerWin() 117 WindowCapturerWin::WindowCapturerWin()
110 : callback_(NULL), 118 : callback_(NULL),
111 window_(NULL) { 119 window_(NULL) {
112 } 120 }
113 121
114 WindowCapturerWin::~WindowCapturerWin() { 122 WindowCapturerWin::~WindowCapturerWin() {
115 } 123 }
116 124
117 bool WindowCapturerWin::GetWindowList(WindowList* windows) { 125 bool WindowCapturerWin::GetWindowList(WindowList* windows) {
118 WindowList result; 126 WindowList result;
119 LPARAM param = reinterpret_cast<LPARAM>(&result); 127 LPARAM param = reinterpret_cast<LPARAM>(&result);
120 if (!EnumWindows(&WindowsEnumerationHandler, param)) 128 if (!EnumWindows(&WindowsEnumerationHandler, param))
121 return false; 129 return false;
122 windows->swap(result); 130 windows->swap(result);
131
132 // Remove windows not in the list.
133 std::set<HWND> ids;
Sergey Ulanov 2016/02/20 18:47:49 I think it would be better to just build a new map
GeorgeZ 2016/02/22 17:08:45 Good idea.
134 for (const auto& item : *windows) {
135 ids.insert(reinterpret_cast<HWND>(item.id));
136 }
137 auto itr = window_size_map_.begin();
138 while (itr != window_size_map_.end()) {
139 if (!ids.count(itr->first)) {
140 itr = window_size_map_.erase(itr);
141 } else {
142 ++itr;
143 }
144 }
145
123 return true; 146 return true;
124 } 147 }
125 148
126 bool WindowCapturerWin::SelectWindow(WindowId id) { 149 bool WindowCapturerWin::SelectWindow(WindowId id) {
127 HWND window = reinterpret_cast<HWND>(id); 150 HWND window = reinterpret_cast<HWND>(id);
128 if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window)) 151 if (!IsWindow(window) || !IsWindowVisible(window) || IsIconic(window))
129 return false; 152 return false;
130 window_ = window; 153 window_ = window;
131 previous_size_.set(0, 0); 154 if (window_size_map_.count(window)) {
155 previous_size_ = window_size_map_[window];
156 } else {
157 previous_size_.set(0, 0);
158 }
132 return true; 159 return true;
133 } 160 }
134 161
135 bool WindowCapturerWin::BringSelectedWindowToFront() { 162 bool WindowCapturerWin::BringSelectedWindowToFront() {
136 if (!window_) 163 if (!window_)
137 return false; 164 return false;
138 165
139 if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_)) 166 if (!IsWindow(window_) || !IsWindowVisible(window_) || IsIconic(window_))
140 return false; 167 return false;
141 168
(...skipping 21 matching lines...) Expand all
163 } 190 }
164 191
165 // Return a 1x1 black frame if the window is minimized or invisible, to match 192 // Return a 1x1 black frame if the window is minimized or invisible, to match
166 // behavior on mace. Window can be temporarily invisible during the 193 // behavior on mace. Window can be temporarily invisible during the
167 // transition of full screen mode on/off. 194 // transition of full screen mode on/off.
168 if (IsIconic(window_) || !IsWindowVisible(window_)) { 195 if (IsIconic(window_) || !IsWindowVisible(window_)) {
169 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1)); 196 BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1));
170 memset(frame->data(), 0, frame->stride() * frame->size().height()); 197 memset(frame->data(), 0, frame->stride() * frame->size().height());
171 198
172 previous_size_ = frame->size(); 199 previous_size_ = frame->size();
200 window_size_map_[window_] = previous_size_;
173 callback_->OnCaptureCompleted(frame); 201 callback_->OnCaptureCompleted(frame);
174 return; 202 return;
175 } 203 }
176 204
177 DesktopRect original_rect; 205 DesktopRect original_rect;
178 DesktopRect cropped_rect; 206 DesktopRect cropped_rect;
179 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) { 207 if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) {
180 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError(); 208 LOG(LS_WARNING) << "Failed to get window info: " << GetLastError();
181 callback_->OnCaptureCompleted(NULL); 209 callback_->OnCaptureCompleted(NULL);
182 return; 210 return;
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 cropped_rect.left() - original_rect.left(), 257 cropped_rect.left() - original_rect.left(),
230 cropped_rect.top() - original_rect.top(), 258 cropped_rect.top() - original_rect.top(),
231 SRCCOPY); 259 SRCCOPY);
232 } 260 }
233 261
234 SelectObject(mem_dc, previous_object); 262 SelectObject(mem_dc, previous_object);
235 DeleteDC(mem_dc); 263 DeleteDC(mem_dc);
236 ReleaseDC(window_, window_dc); 264 ReleaseDC(window_, window_dc);
237 265
238 previous_size_ = frame->size(); 266 previous_size_ = frame->size();
267 window_size_map_[window_] = previous_size_;
239 268
240 frame->mutable_updated_region()->SetRect( 269 frame->mutable_updated_region()->SetRect(
241 DesktopRect::MakeSize(frame->size())); 270 DesktopRect::MakeSize(frame->size()));
242 271
243 if (!result) { 272 if (!result) {
244 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed."; 273 LOG(LS_ERROR) << "Both PrintWindow() and BitBlt() failed.";
245 frame.reset(); 274 frame.reset();
246 } 275 }
247 276
248 callback_->OnCaptureCompleted(frame.release()); 277 callback_->OnCaptureCompleted(frame.release());
249 } 278 }
250 279
251 } // namespace 280 } // namespace
252 281
253 // static 282 // static
254 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) { 283 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) {
255 return new WindowCapturerWin(); 284 return new WindowCapturerWin();
256 } 285 }
257 286
258 } // namespace webrtc 287 } // namespace webrtc
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698