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

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

Issue 2530303002: Use RotateDesktopFrame in DirectX capturer (Closed)
Patch Set: Sync latest changes Created 4 years, 1 month 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 9c0f14c43d2a8a1552d9c0c619a81a0ef7c2b218..9e35b6cdc5df5cbfcbafbff3f04ccaa56df33d1e 100644
--- a/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
+++ b/webrtc/modules/desktop_capture/win/dxgi_output_duplicator.cc
@@ -13,6 +13,7 @@
#include <string.h>
#include <unknwn.h>
+#include <DXGI.h>
#include <DXGIFormat.h>
#include <Windows.h>
@@ -36,6 +37,29 @@ DesktopRect RECTToDesktopRect(const RECT& rect) {
return DesktopRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom);
}
+Rotation DxgiRotationToRotation(DXGI_MODE_ROTATION rotation) {
+ switch (rotation) {
+ case DXGI_MODE_ROTATION_IDENTITY:
+ case DXGI_MODE_ROTATION_UNSPECIFIED:
+ return Rotation::CLOCK_WISE_0;
+ case DXGI_MODE_ROTATION_ROTATE90:
+ return Rotation::CLOCK_WISE_90;
+ case DXGI_MODE_ROTATION_ROTATE180:
+ return Rotation::CLOCK_WISE_180;
+ case DXGI_MODE_ROTATION_ROTATE270:
+ return Rotation::CLOCK_WISE_270;
+ }
+
+ RTC_NOTREACHED();
+ return Rotation::CLOCK_WISE_0;
+}
+
+// Translates |rect| with the reverse of |offset|
+DesktopRect ReverseTranslate(DesktopRect rect, DesktopVector offset) {
+ rect.Translate(-offset.x(), -offset.y());
+ return rect;
+}
+
} // namespace
DxgiOutputDuplicator::DxgiOutputDuplicator(const D3dDevice& device,
@@ -61,10 +85,13 @@ DxgiOutputDuplicator::~DxgiOutputDuplicator() {
bool DxgiOutputDuplicator::Initialize() {
if (DuplicateOutput()) {
+ DesktopSize unrotated_size =
+ RotateSize(desktop_rect().size(), ReverseRotation(rotation_));
if (desc_.DesktopImageInSystemMemory) {
- texture_.reset(new DxgiTextureMapping(desktop_rect_, duplication_.Get()));
+ texture_.reset(
+ new DxgiTextureMapping(unrotated_size, duplication_.Get()));
} else {
- texture_.reset(new DxgiTextureStaging(desktop_rect_, device_));
+ texture_.reset(new DxgiTextureStaging(unrotated_size, device_));
}
return true;
} else {
@@ -104,6 +131,10 @@ bool DxgiOutputDuplicator::DuplicateOutput() {
return false;
}
+ rotation_ = DxgiRotationToRotation(desc_.Rotation);
+ unrotated_size_ =
+ RotateSize(desktop_rect_.size(), ReverseRotation(rotation_));
+
return true;
}
@@ -142,29 +173,36 @@ bool DxgiOutputDuplicator::Duplicate(Context* context,
return false;
}
- // We need to merge updated region with the one from last frame, since current
- // frame contains the content one frame before. Note, this is for double
- // 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.
+ // We need to merge updated region with the one from context, but only spread
+ // updated region from current frame. So keeps a copy of updated region from
+ // context here.
DesktopRegion updated_region;
updated_region.Swap(&context->updated_region);
if (error.Error() == S_OK &&
frame_info.AccumulatedFrames > 0 &&
resource) {
DetectUpdatedRegion(frame_info, offset, &context->updated_region);
- if (!texture_->CopyFrom(frame_info, resource.Get(),
- context->updated_region)) {
+ if (!texture_->CopyFrom(frame_info, resource.Get())) {
return false;
}
SpreadContextChange(context);
updated_region.AddRegion(context->updated_region);
const DesktopFrame& source = texture_->AsDesktopFrame();
- for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
- it.Advance()) {
- target->CopyPixelsFrom(
- source, SourceRect(it.rect()).top_left(), it.rect());
+ if (rotation_ != Rotation::CLOCK_WISE_0) {
+ for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
+ it.Advance()) {
+ const DesktopRect source_rect =
+ RotateRect(ReverseTranslate(it.rect(), offset),
+ desktop_rect().size(), ReverseRotation(rotation_));
+ RotateDesktopFrame(source, source_rect, rotation_, offset, target);
+ }
+ } else {
+ for (DesktopRegion::Iterator it(updated_region); !it.IsAtEnd();
+ it.Advance()) {
+ target->CopyPixelsFrom(
+ source, ReverseTranslate(it.rect(), offset).top_left(), it.rect());
+ }
}
last_frame_ = target->Share();
last_frame_offset_ = offset;
@@ -218,17 +256,17 @@ bool DxgiOutputDuplicator::DoDetectUpdatedRegion(
return false;
}
- if (metadata.capacity() < frame_info.TotalMetadataBufferSize) {
- metadata.clear(); // Avoid data copy
- metadata.reserve(frame_info.TotalMetadataBufferSize);
+ if (metadata_.capacity() < frame_info.TotalMetadataBufferSize) {
+ metadata_.clear(); // Avoid data copy
+ metadata_.reserve(frame_info.TotalMetadataBufferSize);
}
UINT buff_size = 0;
DXGI_OUTDUPL_MOVE_RECT* move_rects =
- reinterpret_cast<DXGI_OUTDUPL_MOVE_RECT*>(metadata.data());
+ reinterpret_cast<DXGI_OUTDUPL_MOVE_RECT*>(metadata_.data());
size_t move_rects_count = 0;
_com_error error = duplication_->GetFrameMoveRects(
- static_cast<UINT>(metadata.capacity()), move_rects, &buff_size);
+ static_cast<UINT>(metadata_.capacity()), move_rects, &buff_size);
if (error.Error() != S_OK) {
LOG(LS_ERROR) << "Failed to get move rectangles, error "
<< error.ErrorMessage() << ", code " << error.Error();
@@ -236,10 +274,10 @@ bool DxgiOutputDuplicator::DoDetectUpdatedRegion(
}
move_rects_count = buff_size / sizeof(DXGI_OUTDUPL_MOVE_RECT);
- RECT* dirty_rects = reinterpret_cast<RECT*>(metadata.data() + buff_size);
+ RECT* dirty_rects = reinterpret_cast<RECT*>(metadata_.data() + buff_size);
size_t dirty_rects_count = 0;
error = duplication_->GetFrameDirtyRects(
- static_cast<UINT>(metadata.capacity()) - buff_size, dirty_rects,
+ static_cast<UINT>(metadata_.capacity()) - buff_size, dirty_rects,
&buff_size);
if (error.Error() != S_OK) {
LOG(LS_ERROR) << "Failed to get dirty rectangles, error "
@@ -249,21 +287,29 @@ bool DxgiOutputDuplicator::DoDetectUpdatedRegion(
dirty_rects_count = buff_size / sizeof(RECT);
while (move_rects_count > 0) {
- updated_region->AddRect(DesktopRect::MakeXYWH(
- move_rects->SourcePoint.x, move_rects->SourcePoint.y,
- move_rects->DestinationRect.right - move_rects->DestinationRect.left,
- move_rects->DestinationRect.bottom - move_rects->DestinationRect.top));
- updated_region->AddRect(DesktopRect::MakeLTRB(
- move_rects->DestinationRect.left, move_rects->DestinationRect.top,
- move_rects->DestinationRect.right, move_rects->DestinationRect.bottom));
+ updated_region->AddRect(
+ RotateRect(DesktopRect::MakeXYWH(move_rects->SourcePoint.x,
+ move_rects->SourcePoint.y,
+ move_rects->DestinationRect.right -
+ move_rects->DestinationRect.left,
+ move_rects->DestinationRect.bottom -
+ move_rects->DestinationRect.top),
+ unrotated_size_, rotation_));
+ updated_region->AddRect(
+ RotateRect(DesktopRect::MakeLTRB(move_rects->DestinationRect.left,
+ move_rects->DestinationRect.top,
+ move_rects->DestinationRect.right,
+ move_rects->DestinationRect.bottom),
+ unrotated_size_, rotation_));
move_rects++;
move_rects_count--;
}
while (dirty_rects_count > 0) {
- updated_region->AddRect(
+ updated_region->AddRect(RotateRect(
DesktopRect::MakeLTRB(dirty_rects->left, dirty_rects->top,
- dirty_rects->right, dirty_rects->bottom));
+ dirty_rects->right, dirty_rects->bottom),
+ unrotated_size_, rotation_));
dirty_rects++;
dirty_rects_count--;
}
@@ -295,10 +341,4 @@ 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;
-}
-
} // namespace webrtc
« no previous file with comments | « webrtc/modules/desktop_capture/win/dxgi_output_duplicator.h ('k') | webrtc/modules/desktop_capture/win/dxgi_texture.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698