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

Unified Diff: webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc

Issue 2299663003: [WebRTC] Two DirectX capturers cannot work concurrently (Closed)
Patch Set: Sync latest changes 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
diff --git a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
index 7ce17c66a464e739537fb01202b97e1b92e894b8..d7eb335fc3cf1e193da07b977424a38920b2fe6f 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
@@ -118,12 +118,17 @@ bool DxgiOutputDuplicator::ReleaseFrame() {
}
bool DxgiOutputDuplicator::Duplicate(Context* context,
- const DesktopFrame* last_frame,
- const DesktopVector offset,
- DesktopFrame* target) {
+ DesktopVector offset,
+ SharedDesktopFrame* target) {
RTC_DCHECK(duplication_);
RTC_DCHECK(texture_);
RTC_DCHECK(target);
+ if (!DesktopRect::MakeSize(target->size())
+ .ContainsRect(TranslatedDesktopRect(offset))) {
+ // target size is not large enough to cover current output region.
+ return false;
+ }
+
DXGI_OUTDUPL_FRAME_INFO frame_info;
memset(&frame_info, 0, sizeof(frame_info));
ComPtr<IDXGIResource> resource;
@@ -140,40 +145,36 @@ bool DxgiOutputDuplicator::Duplicate(Context* context,
// buffering implementation, as what we have in ScreenCapturerWinDirectx. If
// a consumer uses single buffering, we should clear context->updated_region
// after it has been merged to updated_region.
- DesktopRegion updated_region = context->updated_region;
+ DesktopRegion updated_region;
+ updated_region.Swap(&context->updated_region);
if (error.Error() == S_OK && frame_info.AccumulatedFrames > 0) {
DetectUpdatedRegion(frame_info, offset, &context->updated_region);
- SpreadContextChange(context);
- updated_region.AddRegion(context->updated_region);
- if (!texture_->CopyFrom(frame_info, resource.Get(), updated_region)) {
+ if (!texture_->CopyFrom(frame_info, resource.Get(),
+ context->updated_region)) {
return false;
}
+ SpreadContextChange(context);
+ updated_region.AddRegion(context->updated_region);
const DesktopFrame& source = texture_->AsDesktopFrame();
- DesktopRect target_rect(DesktopRect::MakeSize(target->size()));
for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
it.Advance()) {
- if (!target_rect.ContainsRect(it.rect())) {
- // target size is not large enough to copy the pixel from texture.
- return false;
- }
- target->CopyPixelsFrom(source, it.rect().top_left().subtract(offset),
- it.rect());
+ target->CopyPixelsFrom(source, SourceRect(it.rect()).top_left(),
+ TargetRect(it.rect(), offset));
}
+ last_frame_ = target->Share();
+ last_frame_offset_ = offset;
target->mutable_updated_region()->AddRegion(updated_region);
return texture_->Release() && ReleaseFrame();
}
- if (last_frame != nullptr) {
- // DxgiOutputDuplicatorContainer::Duplicate() makes sure target size and
- // last frame size are consistent.
- RTC_DCHECK(target->size().equals(last_frame->size()));
+ if (last_frame_) {
// No change since last frame or AcquireNextFrame() timed out, we will
// export last frame to the target.
- context->updated_region.Clear();
for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
it.Advance()) {
- target->CopyPixelsFrom(*last_frame, it.rect().top_left(), it.rect());
+ target->CopyPixelsFrom(*last_frame_, SourceRect(it.rect()).top_left(),
+ TargetRect(it.rect(), offset));
}
target->mutable_updated_region()->AddRegion(updated_region);
}
@@ -182,8 +183,7 @@ bool DxgiOutputDuplicator::Duplicate(Context* context,
return error.Error() == DXGI_ERROR_WAIT_TIMEOUT || ReleaseFrame();
}
-DesktopRect DxgiOutputDuplicator::TranslatedDesktopRect(
- const DesktopVector offset) {
+DesktopRect DxgiOutputDuplicator::TranslatedDesktopRect(DesktopVector offset) {
DesktopRect result(DesktopRect::MakeSize(desktop_rect_.size()));
result.Translate(offset);
return result;
@@ -191,7 +191,7 @@ DesktopRect DxgiOutputDuplicator::TranslatedDesktopRect(
void DxgiOutputDuplicator::DetectUpdatedRegion(
const DXGI_OUTDUPL_FRAME_INFO& frame_info,
- const DesktopVector offset,
+ DesktopVector offset,
DesktopRegion* updated_region) {
if (DoDetectUpdatedRegion(frame_info, updated_region)) {
updated_region->Translate(offset.x(), offset.y());
@@ -301,4 +301,17 @@ void DxgiOutputDuplicator::SpreadContextChange(const Context* const source) {
}
}
+DesktopRect DxgiOutputDuplicator::SourceRect(DesktopRect rect) {
+ // |texture_|->AsDesktopFrame() starts from (0, 0).
+ rect.Translate(-desktop_rect_.left(), -desktop_rect_.top());
+ return rect;
+}
+
+DesktopRect DxgiOutputDuplicator::TargetRect(DesktopRect rect,
+ DesktopVector offset) {
+ rect = SourceRect(rect);
+ rect.Translate(offset);
+ return rect;
+}
+
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698