mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-18 12:15:19 +00:00
d3d11: Move transform matrix related method to utils
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5572>
This commit is contained in:
parent
3a2a31d18b
commit
1813b4e3d9
3 changed files with 161 additions and 127 deletions
|
@ -30,11 +30,16 @@
|
||||||
|
|
||||||
#include "hlsl/gstd3d11plugin-hlsl.h"
|
#include "hlsl/gstd3d11plugin-hlsl.h"
|
||||||
|
|
||||||
|
/* Disable platform-specific intrinsics */
|
||||||
|
#define _XM_NO_INTRINSICS_
|
||||||
|
#include <DirectXMath.h>
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_plugin_utils_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_plugin_utils_debug);
|
||||||
#define GST_CAT_DEFAULT gst_d3d11_plugin_utils_debug
|
#define GST_CAT_DEFAULT gst_d3d11_plugin_utils_debug
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
|
using namespace DirectX;
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -941,3 +946,135 @@ gst_d3d11_get_vertex_shader_pos (GstD3D11Device * device,
|
||||||
g_VSMain_pos_str, sizeof (g_VSMain_pos_str), "VSMain_pos", &input_desc, 1,
|
g_VSMain_pos_str, sizeof (g_VSMain_pos_str), "VSMain_pos", &input_desc, 1,
|
||||||
vs, layout);
|
vs, layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gst_d3d11_need_transform (gfloat rotation_x, gfloat rotation_y,
|
||||||
|
gfloat rotation_z, gfloat scale_x, gfloat scale_y)
|
||||||
|
{
|
||||||
|
const gfloat min_diff = 0.00001f;
|
||||||
|
|
||||||
|
if (!XMScalarNearEqual (rotation_x, 0.0f, min_diff) ||
|
||||||
|
!XMScalarNearEqual (rotation_y, 0.0f, min_diff) ||
|
||||||
|
!XMScalarNearEqual (rotation_z, 0.0f, min_diff) ||
|
||||||
|
!XMScalarNearEqual (scale_x, 1.0f, min_diff) ||
|
||||||
|
!XMScalarNearEqual (scale_y, 1.0f, min_diff)) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_90r = XMFLOAT4X4 (0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_180 = XMFLOAT4X4 (-1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_90l = XMFLOAT4X4 (0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_horiz = XMFLOAT4X4 (-1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_vert = XMFLOAT4X4 (1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_ul_lr = XMFLOAT4X4 (0.0f, -1.0f, 0.0f, 0.0f,
|
||||||
|
-1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
static const XMFLOAT4X4 g_matrix_ur_ll = XMFLOAT4X4 (0.0f, 1.0f, 0.0f, 0.0f,
|
||||||
|
1.0f, 0.0f, 0.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 1.0f, 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
void
|
||||||
|
gst_d3d11_calculate_transform_matrix (GstVideoOrientationMethod method,
|
||||||
|
gfloat viewport_width, gfloat viewport_height, gfloat fov, gboolean ortho,
|
||||||
|
gfloat rotation_x, gfloat rotation_y, gfloat rotation_z,
|
||||||
|
gfloat scale_x, gfloat scale_y, gfloat transform_matrix[16])
|
||||||
|
{
|
||||||
|
gfloat aspect_ratio;
|
||||||
|
gboolean rotated = FALSE;
|
||||||
|
XMMATRIX rotate_matrix = XMMatrixIdentity ();
|
||||||
|
|
||||||
|
switch (method) {
|
||||||
|
case GST_VIDEO_ORIENTATION_IDENTITY:
|
||||||
|
case GST_VIDEO_ORIENTATION_AUTO:
|
||||||
|
case GST_VIDEO_ORIENTATION_CUSTOM:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_90R:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_90r);
|
||||||
|
rotated = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_180:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_180);
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_90L:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_90l);
|
||||||
|
rotated = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_HORIZ:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_horiz);
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_VERT:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_vert);
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_UL_LR:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_ul_lr);
|
||||||
|
rotated = TRUE;
|
||||||
|
break;
|
||||||
|
case GST_VIDEO_ORIENTATION_UR_LL:
|
||||||
|
rotate_matrix = XMLoadFloat4x4 (&g_matrix_ur_ll);
|
||||||
|
rotated = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rotated)
|
||||||
|
aspect_ratio = viewport_height / viewport_width;
|
||||||
|
else
|
||||||
|
aspect_ratio = viewport_width / viewport_height;
|
||||||
|
|
||||||
|
/* Apply user specified transform matrix first, then rotate-method */
|
||||||
|
XMMATRIX scale = XMMatrixScaling (scale_x * aspect_ratio, scale_y, 1.0);
|
||||||
|
|
||||||
|
XMMATRIX rotate =
|
||||||
|
XMMatrixRotationX (XMConvertToRadians (rotation_x)) *
|
||||||
|
XMMatrixRotationY (XMConvertToRadians (-rotation_y)) *
|
||||||
|
XMMatrixRotationZ (XMConvertToRadians (-rotation_z));
|
||||||
|
|
||||||
|
XMMATRIX view = XMMatrixLookAtLH (XMVectorSet (0.0, 0.0, -1.0, 0.0),
|
||||||
|
XMVectorSet (0.0, 0.0, 0.0, 0.0), XMVectorSet (0.0, 1.0, 0.0, 0.0));
|
||||||
|
|
||||||
|
XMMATRIX proj;
|
||||||
|
if (ortho) {
|
||||||
|
proj = XMMatrixOrthographicOffCenterLH (-aspect_ratio,
|
||||||
|
aspect_ratio, -1.0, 1.0, 0.1, 100.0);
|
||||||
|
} else {
|
||||||
|
proj = XMMatrixPerspectiveFovLH (XMConvertToRadians (fov),
|
||||||
|
aspect_ratio, 0.1, 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
XMMATRIX mvp = scale * rotate * view * proj * rotate_matrix;
|
||||||
|
|
||||||
|
XMFLOAT4X4 matrix;
|
||||||
|
XMStoreFloat4x4 (&matrix, mvp);
|
||||||
|
|
||||||
|
for (guint i = 0; i < 4; i++) {
|
||||||
|
for (guint j = 0; j < 4; j++) {
|
||||||
|
transform_matrix[i * 4 + j] = matrix.m[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -148,6 +148,24 @@ HRESULT gst_d3d11_get_vertex_shader_pos (GstD3D11Device * device,
|
||||||
ID3D11VertexShader ** vs,
|
ID3D11VertexShader ** vs,
|
||||||
ID3D11InputLayout ** layout);
|
ID3D11InputLayout ** layout);
|
||||||
|
|
||||||
|
gboolean gst_d3d11_need_transform (gfloat rotation_x,
|
||||||
|
gfloat rotation_y,
|
||||||
|
gfloat rotation_z,
|
||||||
|
gfloat scale_x,
|
||||||
|
gfloat scale_y);
|
||||||
|
|
||||||
|
void gst_d3d11_calculate_transform_matrix (GstVideoOrientationMethod method,
|
||||||
|
gfloat viewport_width,
|
||||||
|
gfloat viewport_height,
|
||||||
|
gfloat fov,
|
||||||
|
gboolean ortho,
|
||||||
|
gfloat rotation_x,
|
||||||
|
gfloat rotation_y,
|
||||||
|
gfloat rotation_z,
|
||||||
|
gfloat scale_x,
|
||||||
|
gfloat scale_y,
|
||||||
|
gfloat transform_matrix[16]);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GST_D3D11_PLUGIN_UTILS_H__ */
|
#endif /* __GST_D3D11_PLUGIN_UTILS_H__ */
|
||||||
|
|
|
@ -36,13 +36,8 @@
|
||||||
|
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
|
|
||||||
/* Disable platform-specific intrinsics */
|
|
||||||
#define _XM_NO_INTRINSICS_
|
|
||||||
#include <DirectXMath.h>
|
|
||||||
|
|
||||||
/* *INDENT-OFF* */
|
/* *INDENT-OFF* */
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
using namespace DirectX;
|
|
||||||
/* *INDENT-ON* */
|
/* *INDENT-ON* */
|
||||||
|
|
||||||
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_window_debug);
|
GST_DEBUG_CATEGORY_EXTERN (gst_d3d11_window_debug);
|
||||||
|
@ -912,120 +907,6 @@ gst_d3d11_window_set_title (GstD3D11Window * window, const gchar * title)
|
||||||
klass->set_title (window, title);
|
klass->set_title (window, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_90r = XMFLOAT4X4 (0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_180 = XMFLOAT4X4 (-1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_90l = XMFLOAT4X4 (0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_horiz = XMFLOAT4X4 (-1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_vert = XMFLOAT4X4 (1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_ul_lr = XMFLOAT4X4 (0.0f, -1.0f, 0.0f, 0.0f,
|
|
||||||
-1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static const XMFLOAT4X4 g_matrix_ur_ll = XMFLOAT4X4 (0.0f, 1.0f, 0.0f, 0.0f,
|
|
||||||
1.0f, 0.0f, 0.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 1.0f, 0.0f,
|
|
||||||
0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_d3d11_window_calculate_matrix (GstD3D11Window * self,
|
|
||||||
gfloat viewport_width, gfloat viewport_height, gfloat transform_matrix[16])
|
|
||||||
{
|
|
||||||
gfloat aspect_ratio;
|
|
||||||
gboolean rotated = FALSE;
|
|
||||||
XMMATRIX rotate_matrix = XMMatrixIdentity ();
|
|
||||||
|
|
||||||
switch (self->method) {
|
|
||||||
case GST_VIDEO_ORIENTATION_IDENTITY:
|
|
||||||
case GST_VIDEO_ORIENTATION_AUTO:
|
|
||||||
case GST_VIDEO_ORIENTATION_CUSTOM:
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_90R:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_90r);
|
|
||||||
rotated = TRUE;
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_180:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_180);
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_90L:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_90l);
|
|
||||||
rotated = TRUE;
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_HORIZ:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_horiz);
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_VERT:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_vert);
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_UL_LR:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_ul_lr);
|
|
||||||
rotated = TRUE;
|
|
||||||
break;
|
|
||||||
case GST_VIDEO_ORIENTATION_UR_LL:
|
|
||||||
rotate_matrix = XMLoadFloat4x4 (&g_matrix_ur_ll);
|
|
||||||
rotated = TRUE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rotated)
|
|
||||||
aspect_ratio = viewport_height / viewport_width;
|
|
||||||
else
|
|
||||||
aspect_ratio = viewport_width / viewport_height;
|
|
||||||
|
|
||||||
/* Apply user specified transform matrix first, then rotate-method */
|
|
||||||
XMMATRIX scale =
|
|
||||||
XMMatrixScaling (self->scale_x * aspect_ratio, self->scale_y, 1.0);
|
|
||||||
|
|
||||||
XMMATRIX rotate =
|
|
||||||
XMMatrixRotationX (XMConvertToRadians (self->rotation_x)) *
|
|
||||||
XMMatrixRotationY (XMConvertToRadians (-self->rotation_y)) *
|
|
||||||
XMMatrixRotationZ (XMConvertToRadians (-self->rotation_z));
|
|
||||||
|
|
||||||
XMMATRIX view = XMMatrixLookAtLH (XMVectorSet (0.0, 0.0, -1.0, 0.0),
|
|
||||||
XMVectorSet (0.0, 0.0, 0.0, 0.0), XMVectorSet (0.0, 1.0, 0.0, 0.0));
|
|
||||||
|
|
||||||
XMMATRIX proj;
|
|
||||||
if (self->ortho) {
|
|
||||||
proj = XMMatrixOrthographicOffCenterLH (-aspect_ratio,
|
|
||||||
aspect_ratio, -1.0, 1.0, 0.1, 100.0);
|
|
||||||
} else {
|
|
||||||
proj = XMMatrixPerspectiveFovLH (XMConvertToRadians (self->fov),
|
|
||||||
aspect_ratio, 0.1, 100.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
XMMATRIX mvp = scale * rotate * view * proj * rotate_matrix;
|
|
||||||
|
|
||||||
XMFLOAT4X4 matrix;
|
|
||||||
XMStoreFloat4x4 (&matrix, mvp);
|
|
||||||
|
|
||||||
for (guint i = 0; i < 4; i++) {
|
|
||||||
for (guint j = 0; j < 4; j++) {
|
|
||||||
transform_matrix[i * 4 + j] = matrix.m[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
GstBuffer * backbuffer, GstBuffer * multisample)
|
GstBuffer * backbuffer, GstBuffer * multisample)
|
||||||
|
@ -1098,7 +979,6 @@ gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
|
|
||||||
if (self->first_present) {
|
if (self->first_present) {
|
||||||
D3D11_VIEWPORT viewport;
|
D3D11_VIEWPORT viewport;
|
||||||
const gfloat min_diff = 0.00001f;
|
|
||||||
|
|
||||||
viewport.TopLeftX = self->render_rect.left;
|
viewport.TopLeftX = self->render_rect.left;
|
||||||
viewport.TopLeftY = self->render_rect.top;
|
viewport.TopLeftY = self->render_rect.top;
|
||||||
|
@ -1114,19 +994,18 @@ gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
|
||||||
"dest-height",
|
"dest-height",
|
||||||
(gint) (self->render_rect.bottom - self->render_rect.top), nullptr);
|
(gint) (self->render_rect.bottom - self->render_rect.top), nullptr);
|
||||||
|
|
||||||
if (!XMScalarNearEqual (self->rotation_x, 0.0f, min_diff) &&
|
if (!gst_d3d11_need_transform (self->rotation_x, self->rotation_y,
|
||||||
!XMScalarNearEqual (self->rotation_y, 0.0f, min_diff) &&
|
self->rotation_z, self->scale_x, self->scale_y)) {
|
||||||
!XMScalarNearEqual (self->rotation_z, 0.0f, min_diff) &&
|
|
||||||
!XMScalarNearEqual (self->scale_x, 1.0f, min_diff) &&
|
|
||||||
!XMScalarNearEqual (self->scale_y, 1.0f, min_diff)) {
|
|
||||||
g_object_set (self->converter, "video-direction", self->method, nullptr);
|
g_object_set (self->converter, "video-direction", self->method, nullptr);
|
||||||
} else {
|
} else {
|
||||||
gfloat transform_matrix[16];
|
gfloat transform_matrix[16];
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "Applying custom transform");
|
GST_DEBUG_OBJECT (self, "Applying custom transform");
|
||||||
|
|
||||||
gst_d3d11_window_calculate_matrix (self,
|
gst_d3d11_calculate_transform_matrix (self->method,
|
||||||
viewport.Width, viewport.Height, transform_matrix);
|
viewport.Width, viewport.Height, self->fov, self->ortho,
|
||||||
|
self->rotation_x, self->rotation_y, self->rotation_z,
|
||||||
|
self->scale_x, self->scale_y, transform_matrix);
|
||||||
g_object_set (self->converter,
|
g_object_set (self->converter,
|
||||||
"video-direction", GST_VIDEO_ORIENTATION_CUSTOM, nullptr);
|
"video-direction", GST_VIDEO_ORIENTATION_CUSTOM, nullptr);
|
||||||
gst_d3d11_converter_set_transform_matrix (self->converter,
|
gst_d3d11_converter_set_transform_matrix (self->converter,
|
||||||
|
|
Loading…
Reference in a new issue