| 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..00d326768a5395c6cbcf9ff5c642c8647e935e4d 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) {
|
| + 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,35 @@ 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());
|
| }
|
| + 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_, last_frame_offset_, it.rect());
|
| }
|
| target->mutable_updated_region()->AddRegion(updated_region);
|
| }
|
|
|