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