mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-23 00:36:51 +00:00
d3d11screencapturesrc: Use DirectXMath struct and C++ mutex
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5572>
This commit is contained in:
parent
63bb0b8de7
commit
e13612162b
1 changed files with 40 additions and 82 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue