d3d12screencapturesrc: Fix capturing rotated monitor
Acquired and reconstructed frames will have different resolution if monitor is rotated. Use the copying logic of d3d11 implementation Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/8444>
This commit is contained in:
parent
8cfbdd7cf6
commit
1902b5ca1b
@ -617,12 +617,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
copyMoveRects (ID3D11Texture2D * src, DXGI_OUTDUPL_MOVE_RECT * rects,
|
copyMoveRects (DXGI_OUTDUPL_MOVE_RECT * rects, UINT move_count)
|
||||||
UINT move_count)
|
|
||||||
{
|
{
|
||||||
if (!move_texture_) {
|
if (!move_texture_) {
|
||||||
D3D11_TEXTURE2D_DESC desc;
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
src->GetDesc (&desc);
|
texture_->GetDesc (&desc);
|
||||||
desc.BindFlags = 0;
|
desc.BindFlags = 0;
|
||||||
desc.MiscFlags = 0;
|
desc.MiscFlags = 0;
|
||||||
auto hr = device_->CreateTexture2D (&desc, nullptr, &move_texture_);
|
auto hr = device_->CreateTexture2D (&desc, nullptr, &move_texture_);
|
||||||
@ -658,115 +657,123 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setDirtyVert (RECT * dirty, DXGI_MODE_ROTATION rotation,
|
setDirtyVert (VERTEX* Vertices, RECT* Dirty,
|
||||||
INT width, INT height, VERTEX * vert)
|
DXGI_OUTDUPL_DESC* DeskDesc, D3D11_TEXTURE2D_DESC* FullDesc,
|
||||||
|
D3D11_TEXTURE2D_DESC* ThisDesc)
|
||||||
{
|
{
|
||||||
FLOAT center_x = width / 2.0;
|
INT CenterX = FullDesc->Width / 2;
|
||||||
FLOAT center_y = height / 2.0;
|
INT CenterY = FullDesc->Height / 2;
|
||||||
|
|
||||||
RECT dst = *dirty;
|
INT Width = FullDesc->Width;
|
||||||
|
INT Height = FullDesc->Height;
|
||||||
|
|
||||||
switch (rotation) {
|
/* Rotation compensated destination rect */
|
||||||
|
RECT DestDirty = *Dirty;
|
||||||
|
|
||||||
|
/* Set appropriate coordinates compensated for rotation */
|
||||||
|
switch (DeskDesc->Rotation)
|
||||||
|
{
|
||||||
case DXGI_MODE_ROTATION_ROTATE90:
|
case DXGI_MODE_ROTATION_ROTATE90:
|
||||||
dst.left = width - dirty->bottom;
|
DestDirty.left = Width - Dirty->bottom;
|
||||||
dst.top = dirty->left;
|
DestDirty.top = Dirty->left;
|
||||||
dst.right = width - dirty->top;
|
DestDirty.right = Width - Dirty->top;
|
||||||
dst.bottom = dirty->right;
|
DestDirty.bottom = Dirty->right;
|
||||||
|
|
||||||
vert[0].TexCoord =
|
Vertices[0].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[1].TexCoord =
|
Vertices[1].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[2].TexCoord =
|
Vertices[2].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[5].TexCoord =
|
Vertices[5].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
break;
|
break;
|
||||||
case DXGI_MODE_ROTATION_ROTATE180:
|
case DXGI_MODE_ROTATION_ROTATE180:
|
||||||
dst.left = width - dirty->right;
|
DestDirty.left = Width - Dirty->right;
|
||||||
dst.top = height - dirty->bottom;
|
DestDirty.top = Height - Dirty->bottom;
|
||||||
dst.right = width - dirty->left;
|
DestDirty.right = Width - Dirty->left;
|
||||||
dst.bottom = height - dirty->top;
|
DestDirty.bottom = Height - Dirty->top;
|
||||||
|
|
||||||
vert[0].TexCoord =
|
Vertices[0].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[1].TexCoord =
|
Vertices[1].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[2].TexCoord =
|
Vertices[2].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[5].TexCoord =
|
Vertices[5].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
break;
|
break;
|
||||||
case DXGI_MODE_ROTATION_ROTATE270:
|
case DXGI_MODE_ROTATION_ROTATE270:
|
||||||
dst.left = dirty->top;
|
DestDirty.left = Dirty->top;
|
||||||
dst.top = height - dirty->right;
|
DestDirty.top = Height - Dirty->right;
|
||||||
dst.right = dirty->bottom;
|
DestDirty.right = Dirty->bottom;
|
||||||
dst.bottom = height - dirty->left;
|
DestDirty.bottom = Height - Dirty->left;
|
||||||
|
|
||||||
vert[0].TexCoord =
|
Vertices[0].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[1].TexCoord =
|
Vertices[1].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[2].TexCoord =
|
Vertices[2].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[5].TexCoord =
|
Vertices[5].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
break;
|
break;
|
||||||
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
case DXGI_MODE_ROTATION_UNSPECIFIED:
|
||||||
case DXGI_MODE_ROTATION_IDENTITY:
|
case DXGI_MODE_ROTATION_IDENTITY:
|
||||||
default:
|
default:
|
||||||
vert[0].TexCoord =
|
Vertices[0].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[1].TexCoord =
|
Vertices[1].TexCoord =
|
||||||
XMFLOAT2(dirty->left / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[2].TexCoord =
|
Vertices[2].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->bottom / static_cast<FLOAT>(height));
|
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
vert[5].TexCoord =
|
Vertices[5].TexCoord =
|
||||||
XMFLOAT2(dirty->right / static_cast<FLOAT>(width),
|
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
|
||||||
dirty->top / static_cast<FLOAT>(height));
|
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vert[0].Pos =
|
/* Set positions */
|
||||||
|
Vertices[0].Pos =
|
||||||
XMFLOAT3(
|
XMFLOAT3(
|
||||||
(dst.left - center_x) / center_x,
|
(DestDirty.left - CenterX) / static_cast<FLOAT>(CenterX),
|
||||||
-1 * (dst.bottom - center_y) / center_y,
|
-1 * (DestDirty.bottom - CenterY) / static_cast<FLOAT>(CenterY),
|
||||||
0.0f);
|
0.0f);
|
||||||
vert[1].Pos =
|
Vertices[1].Pos =
|
||||||
XMFLOAT3(
|
XMFLOAT3(
|
||||||
(dst.left - center_x) / center_x,
|
(DestDirty.left - CenterX) / static_cast<FLOAT>(CenterX),
|
||||||
-1 * (dst.top - center_y) / center_y,
|
-1 * (DestDirty.top - CenterY) / static_cast<FLOAT>(CenterY),
|
||||||
0.0f);
|
0.0f);
|
||||||
vert[2].Pos =
|
Vertices[2].Pos =
|
||||||
XMFLOAT3(
|
XMFLOAT3(
|
||||||
(dst.right - center_x) / center_x,
|
(DestDirty.right - CenterX) / static_cast<FLOAT>(CenterX),
|
||||||
-1 * (dst.bottom - center_y) / center_y,
|
-1 * (DestDirty.bottom - CenterY) / static_cast<FLOAT>(CenterY),
|
||||||
0.0f);
|
0.0f);
|
||||||
vert[3].Pos = vert[2].Pos;
|
Vertices[3].Pos = Vertices[2].Pos;
|
||||||
vert[4].Pos = vert[1].Pos;
|
Vertices[4].Pos = Vertices[1].Pos;
|
||||||
vert[5].Pos =
|
Vertices[5].Pos =
|
||||||
XMFLOAT3(
|
XMFLOAT3(
|
||||||
(dst.right - center_x) / center_x,
|
(DestDirty.right - CenterX) / static_cast<FLOAT>(CenterX),
|
||||||
-1 * (dst.top - center_y) / center_y,
|
-1 * (DestDirty.top - CenterY) / static_cast<FLOAT>(CenterY),
|
||||||
0.0f);
|
0.0f);
|
||||||
|
|
||||||
vert[3].TexCoord = vert[2].TexCoord;
|
Vertices[3].TexCoord = Vertices[2].TexCoord;
|
||||||
vert[4].TexCoord = vert[1].TexCoord;
|
Vertices[4].TexCoord = Vertices[1].TexCoord;
|
||||||
}
|
}
|
||||||
|
|
||||||
GstFlowReturn
|
GstFlowReturn
|
||||||
@ -785,11 +792,15 @@ public:
|
|||||||
auto byte_needed = sizeof (VERTEX) * 6 * dirty_count;
|
auto byte_needed = sizeof (VERTEX) * 6 * dirty_count;
|
||||||
dirty_vertex_.resize (dirty_count * 6);
|
dirty_vertex_.resize (dirty_count * 6);
|
||||||
VERTEX *vert_data = dirty_vertex_.data ();
|
VERTEX *vert_data = dirty_vertex_.data ();
|
||||||
|
D3D11_TEXTURE2D_DESC FullDesc;
|
||||||
|
D3D11_TEXTURE2D_DESC ThisDesc;
|
||||||
|
|
||||||
|
texture_->GetDesc (&FullDesc);
|
||||||
|
src->GetDesc (&ThisDesc);
|
||||||
|
|
||||||
for (guint i = 0; i < dirty_count; i++, vert_data += 6) {
|
for (guint i = 0; i < dirty_count; i++, vert_data += 6) {
|
||||||
setDirtyVert (&dirty_rects[i], output_desc_.Rotation,
|
setDirtyVert (vert_data, &dirty_rects[i], &output_desc_, &FullDesc,
|
||||||
output_desc_.ModeDesc.Width, output_desc_.ModeDesc.Height,
|
&ThisDesc);
|
||||||
vert_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (byte_needed > vertext_buf_size_)
|
if (byte_needed > vertext_buf_size_)
|
||||||
@ -883,7 +894,7 @@ public:
|
|||||||
|
|
||||||
auto move_count = buf_size / sizeof (DXGI_OUTDUPL_MOVE_RECT);
|
auto move_count = buf_size / sizeof (DXGI_OUTDUPL_MOVE_RECT);
|
||||||
if (move_count > 0) {
|
if (move_count > 0) {
|
||||||
auto ret = copyMoveRects (cur_texture.Get (),
|
auto ret = copyMoveRects (
|
||||||
(DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), move_count);
|
(DXGI_OUTDUPL_MOVE_RECT *) metadata_buffer_.data (), move_count);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user