d3d11screencapturesrc: Use DirectXMath struct and C++ mutex

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5572>
This commit is contained in:
Seungha Yang 2023-10-27 22:23:46 +09:00
parent 63bb0b8de7
commit e13612162b

View file

@ -49,69 +49,36 @@
#include "gstd3d11dxgicapture.h"
#include "gstd3d11pluginutils.h"
#include <string.h>
#include <mutex>
#include <wrl.h>
#define _XM_NO_INTRINSICS_
#include <DirectXMath.h>
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_screen_capture_debug);
#define GST_CAT_DEFAULT gst_d3d11_screen_capture_debug
/* *INDENT-OFF* */
using namespace Microsoft::WRL;
using namespace DirectX;
/* List of GstD3D11DxgiCapture weakref */
G_LOCK_DEFINE_STATIC (dupl_list_lock);
static std::mutex dupl_list_lock;
static GList *dupl_list = nullptr;
/* Below implemenation were taken from Microsoft sample
/* Below implementation were taken from Microsoft sample
* https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/DXGIDesktopDuplication
*/
#define NUMVERTICES 6
#define BPP 4
/* Define our own MyFLOAT3 and MyFLOAT2 struct, since MinGW doesn't support
* DirectXMath.h
*/
struct MyFLOAT3
struct VERTEX
{
float x;
float y;
float z;
MyFLOAT3() = default;
MyFLOAT3(const MyFLOAT3&) = default;
MyFLOAT3& operator=(const MyFLOAT3&) = default;
MyFLOAT3(MyFLOAT3&&) = default;
MyFLOAT3& operator=(MyFLOAT3&&) = default;
constexpr MyFLOAT3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}
explicit MyFLOAT3(const float *pArray) : x(pArray[0]), y(pArray[1]), z(pArray[2]) {}
XMFLOAT3 Pos;
XMFLOAT2 TexCoord;
};
struct MyFLOAT2
{
float x;
float y;
MyFLOAT2() = default;
MyFLOAT2(const MyFLOAT2&) = default;
MyFLOAT2& operator=(const MyFLOAT2&) = default;
MyFLOAT2(MyFLOAT2&&) = default;
MyFLOAT2& operator=(MyFLOAT2&&) = default;
constexpr MyFLOAT2(float _x, float _y) : x(_x), y(_y) {}
explicit MyFLOAT2(const float *pArray) : x(pArray[0]), y(pArray[1]) {}
};
typedef struct
{
MyFLOAT3 Pos;
MyFLOAT2 TexCoord;
} VERTEX;
/* List of expected error cases */
/* These are the errors we expect from general Dxgi API due to a transition */
HRESULT SystemTransitionsExpectedErrors[] = {
@ -387,12 +354,12 @@ public:
VERTEX Vertices[NUMVERTICES] =
{
{MyFLOAT3(-1.0f, -1.0f, 0), MyFLOAT2(0.0f, 1.0f)},
{MyFLOAT3(-1.0f, 1.0f, 0), MyFLOAT2(0.0f, 0.0f)},
{MyFLOAT3(1.0f, -1.0f, 0), MyFLOAT2(1.0f, 1.0f)},
{MyFLOAT3(1.0f, -1.0f, 0), MyFLOAT2(1.0f, 1.0f)},
{MyFLOAT3(-1.0f, 1.0f, 0), MyFLOAT2(0.0f, 0.0f)},
{MyFLOAT3(1.0f, 1.0f, 0), MyFLOAT2(1.0f, 0.0f)},
{XMFLOAT3(-1.0f, -1.0f, 0), XMFLOAT2(0.0f, 1.0f)},
{XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)},
{XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)},
{XMFLOAT3(1.0f, -1.0f, 0), XMFLOAT2(1.0f, 1.0f)},
{XMFLOAT3(-1.0f, 1.0f, 0), XMFLOAT2(0.0f, 0.0f)},
{XMFLOAT3(1.0f, 1.0f, 0), XMFLOAT2(1.0f, 0.0f)},
};
D3D11_TEXTURE2D_DESC FullDesc;
@ -1030,16 +997,16 @@ private:
DestDirty.bottom = Dirty->right;
Vertices[0].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[1].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[2].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[5].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
break;
case DXGI_MODE_ROTATION_ROTATE180:
@ -1049,16 +1016,16 @@ private:
DestDirty.bottom = Height - Dirty->top;
Vertices[0].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[1].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[2].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[5].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
break;
case DXGI_MODE_ROTATION_ROTATE270:
@ -1068,56 +1035,56 @@ private:
DestDirty.bottom = Height - Dirty->left;
Vertices[0].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[1].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[2].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[5].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
break;
case DXGI_MODE_ROTATION_UNSPECIFIED:
case DXGI_MODE_ROTATION_IDENTITY:
default:
Vertices[0].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[1].TexCoord =
MyFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->left / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
Vertices[2].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->bottom / static_cast<FLOAT>(ThisDesc->Height));
Vertices[5].TexCoord =
MyFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
XMFLOAT2(Dirty->right / static_cast<FLOAT>(ThisDesc->Width),
Dirty->top / static_cast<FLOAT>(ThisDesc->Height));
break;
}
/* Set positions */
Vertices[0].Pos =
MyFLOAT3(
XMFLOAT3(
(DestDirty.left - CenterX) / static_cast<FLOAT>(CenterX),
-1 * (DestDirty.bottom - CenterY) / static_cast<FLOAT>(CenterY),
0.0f);
Vertices[1].Pos =
MyFLOAT3(
XMFLOAT3(
(DestDirty.left - CenterX) / static_cast<FLOAT>(CenterX),
-1 * (DestDirty.top - CenterY) / static_cast<FLOAT>(CenterY),
0.0f);
Vertices[2].Pos =
MyFLOAT3(
XMFLOAT3(
(DestDirty.right - CenterX) / static_cast<FLOAT>(CenterX),
-1 * (DestDirty.bottom - CenterY) / static_cast<FLOAT>(CenterY),
0.0f);
Vertices[3].Pos = Vertices[2].Pos;
Vertices[4].Pos = Vertices[1].Pos;
Vertices[5].Pos =
MyFLOAT3(
XMFLOAT3(
(DestDirty.right - CenterX) / static_cast<FLOAT>(CenterX),
-1 * (DestDirty.top - CenterY) / static_cast<FLOAT>(CenterY),
0.0f);
@ -1707,9 +1674,8 @@ static void
gst_d3d11_dxgi_capture_weak_ref_notify (gpointer data,
GstD3D11DxgiCapture * dupl)
{
G_LOCK (dupl_list_lock);
std::lock_guard < std::mutex > lk (dupl_list_lock);
dupl_list = g_list_remove (dupl_list, dupl);
G_UNLOCK (dupl_list_lock);
}
GstD3D11ScreenCapture *
@ -1727,30 +1693,24 @@ gst_d3d11_dxgi_capture_new (GstD3D11Device * device, HMONITOR monitor_handle)
* See also
* https://docs.microsoft.com/en-us/windows/win32/api/dxgi1_2/nf-dxgi1_2-idxgioutput1-duplicateoutput#remarks
*/
G_LOCK (dupl_list_lock);
std::lock_guard < std::mutex > lk (dupl_list_lock);
for (iter = dupl_list; iter; iter = g_list_next (iter)) {
GstD3D11DxgiCapture *dupl = (GstD3D11DxgiCapture *) iter->data;
if (dupl->monitor_handle == monitor_handle) {
GST_DEBUG ("Found configured desktop dup object for monitor handle %p",
monitor_handle);
self = (GstD3D11DxgiCapture *) gst_object_ref (dupl);
break;
gst_object_ref (dupl);
return GST_D3D11_SCREEN_CAPTURE_CAST (dupl);
}
}
if (self) {
G_UNLOCK (dupl_list_lock);
return GST_D3D11_SCREEN_CAPTURE_CAST (self);
}
self = (GstD3D11DxgiCapture *) g_object_new (GST_TYPE_D3D11_DXGI_CAPTURE,
"d3d11device", device, "monitor-handle", monitor_handle, nullptr);
if (!self->device) {
GST_WARNING_OBJECT (self, "Couldn't configure desktop dup object");
gst_object_unref (self);
G_UNLOCK (dupl_list_lock);
return nullptr;
}
@ -1759,8 +1719,6 @@ gst_d3d11_dxgi_capture_new (GstD3D11Device * device, HMONITOR monitor_handle)
(GWeakNotify) gst_d3d11_dxgi_capture_weak_ref_notify, nullptr);
dupl_list = g_list_append (dupl_list, self);
G_UNLOCK (dupl_list_lock);
return GST_D3D11_SCREEN_CAPTURE_CAST (self);
}