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

Side by Side Diff: webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc

Issue 2268093002: [WebRTC] A real ScreenCapturer test (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Resolve review comments Created 4 years, 3 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
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (error.Error() != S_OK) { 111 if (error.Error() != S_OK) {
112 LOG(LS_ERROR) << "Failed to release frame from IDXGIOutputDuplication, " 112 LOG(LS_ERROR) << "Failed to release frame from IDXGIOutputDuplication, "
113 "error" 113 "error"
114 << error.ErrorMessage() << ", code " << error.Error(); 114 << error.ErrorMessage() << ", code " << error.Error();
115 return false; 115 return false;
116 } 116 }
117 return true; 117 return true;
118 } 118 }
119 119
120 bool DxgiOutputDuplicator::Duplicate(Context* context, 120 bool DxgiOutputDuplicator::Duplicate(Context* context,
121 const DesktopFrame* last_frame,
122 const DesktopVector offset, 121 const DesktopVector offset,
123 DesktopFrame* target) { 122 SharedDesktopFrame* target) {
124 RTC_DCHECK(duplication_); 123 RTC_DCHECK(duplication_);
125 RTC_DCHECK(texture_); 124 RTC_DCHECK(texture_);
126 RTC_DCHECK(target); 125 RTC_DCHECK(target);
126 if (!DesktopRect::MakeSize(target->size())
127 .ContainsRect(TranslatedDesktopRect(offset))) {
128 // target size is not large enough to cover current output region.
129 return false;
130 }
131
127 DXGI_OUTDUPL_FRAME_INFO frame_info; 132 DXGI_OUTDUPL_FRAME_INFO frame_info;
128 memset(&frame_info, 0, sizeof(frame_info)); 133 memset(&frame_info, 0, sizeof(frame_info));
129 ComPtr<IDXGIResource> resource; 134 ComPtr<IDXGIResource> resource;
130 _com_error error = duplication_->AcquireNextFrame( 135 _com_error error = duplication_->AcquireNextFrame(
131 kAcquireTimeoutMs, &frame_info, resource.GetAddressOf()); 136 kAcquireTimeoutMs, &frame_info, resource.GetAddressOf());
132 if (error.Error() != S_OK && error.Error() != DXGI_ERROR_WAIT_TIMEOUT) { 137 if (error.Error() != S_OK && error.Error() != DXGI_ERROR_WAIT_TIMEOUT) {
133 LOG(LS_ERROR) << "Failed to capture frame, error " << error.ErrorMessage() 138 LOG(LS_ERROR) << "Failed to capture frame, error " << error.ErrorMessage()
134 << ", code " << error.Error(); 139 << ", code " << error.Error();
135 return false; 140 return false;
136 } 141 }
137 142
138 // We need to merge updated region with the one from last frame, since current 143 // We need to merge updated region with the one from last frame, since current
139 // frame contains the content one frame before. Note, this is for double 144 // frame contains the content one frame before. Note, this is for double
140 // buffering implementation, as what we have in ScreenCapturerWinDirectx. If 145 // buffering implementation, as what we have in ScreenCapturerWinDirectx. If
141 // a consumer uses single buffering, we should clear context->updated_region 146 // a consumer uses single buffering, we should clear context->updated_region
142 // after it has been merged to updated_region. 147 // after it has been merged to updated_region.
143 DesktopRegion updated_region = context->updated_region; 148 DesktopRegion updated_region;
149 updated_region.Swap(&context->updated_region);
144 if (error.Error() == S_OK && frame_info.AccumulatedFrames > 0) { 150 if (error.Error() == S_OK && frame_info.AccumulatedFrames > 0) {
145 DetectUpdatedRegion(frame_info, offset, &context->updated_region); 151 DetectUpdatedRegion(frame_info, offset, &context->updated_region);
152 if (!texture_->CopyFrom(frame_info, resource.Get(),
153 context->updated_region)) {
154 return false;
155 }
146 SpreadContextChange(context); 156 SpreadContextChange(context);
147 updated_region.AddRegion(context->updated_region); 157 updated_region.AddRegion(context->updated_region);
148 if (!texture_->CopyFrom(frame_info, resource.Get(), updated_region)) {
149 return false;
150 }
151
152 const DesktopFrame& source = texture_->AsDesktopFrame(); 158 const DesktopFrame& source = texture_->AsDesktopFrame();
153 DesktopRect target_rect(DesktopRect::MakeSize(target->size()));
154 for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd(); 159 for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
155 it.Advance()) { 160 it.Advance()) {
156 if (!target_rect.ContainsRect(it.rect())) {
157 // target size is not large enough to copy the pixel from texture.
158 return false;
159 }
160 target->CopyPixelsFrom(source, it.rect().top_left().subtract(offset), 161 target->CopyPixelsFrom(source, it.rect().top_left().subtract(offset),
161 it.rect()); 162 it.rect());
162 } 163 }
164 last_frame_ = target->Share();
165 last_frame_offset_ = offset;
163 target->mutable_updated_region()->AddRegion(updated_region); 166 target->mutable_updated_region()->AddRegion(updated_region);
164 return texture_->Release() && ReleaseFrame(); 167 return texture_->Release() && ReleaseFrame();
165 } 168 }
166 169
167 if (last_frame != nullptr) { 170 if (last_frame_) {
168 // DxgiOutputDuplicatorContainer::Duplicate() makes sure target size and
169 // last frame size are consistent.
170 RTC_DCHECK(target->size().equals(last_frame->size()));
171 // No change since last frame or AcquireNextFrame() timed out, we will 171 // No change since last frame or AcquireNextFrame() timed out, we will
172 // export last frame to the target. 172 // export last frame to the target.
173 context->updated_region.Clear(); 173 context->updated_region.Clear();
174 for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd(); 174 for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
175 it.Advance()) { 175 it.Advance()) {
176 target->CopyPixelsFrom(*last_frame, it.rect().top_left(), it.rect()); 176 target->CopyPixelsFrom(*last_frame_, last_frame_offset_, it.rect());
177 } 177 }
178 target->mutable_updated_region()->AddRegion(updated_region); 178 target->mutable_updated_region()->AddRegion(updated_region);
179 } 179 }
180 // If AcquireNextFrame() failed with timeout error, we do not need to release 180 // If AcquireNextFrame() failed with timeout error, we do not need to release
181 // the frame. 181 // the frame.
182 return error.Error() == DXGI_ERROR_WAIT_TIMEOUT || ReleaseFrame(); 182 return error.Error() == DXGI_ERROR_WAIT_TIMEOUT || ReleaseFrame();
183 } 183 }
184 184
185 DesktopRect DxgiOutputDuplicator::TranslatedDesktopRect( 185 DesktopRect DxgiOutputDuplicator::TranslatedDesktopRect(
186 const DesktopVector offset) { 186 const DesktopVector offset) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 295
296 void DxgiOutputDuplicator::SpreadContextChange(const Context* const source) { 296 void DxgiOutputDuplicator::SpreadContextChange(const Context* const source) {
297 for (Context* dest : contexts_) { 297 for (Context* dest : contexts_) {
298 if (dest != source) { 298 if (dest != source) {
299 dest->updated_region.AddRegion(source->updated_region); 299 dest->updated_region.AddRegion(source->updated_region);
300 } 300 }
301 } 301 }
302 } 302 }
303 303
304 } // namespace webrtc 304 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698