d3d11: Enable DirectXMath SIMD

* Enable SIMD except for x86 target
* Use aligned matrix struct
* Remove unnecessary matrix copy operations

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5602>
This commit is contained in:
Seungha Yang 2023-11-04 21:23:31 +09:00 committed by GStreamer Marge Bot
parent 4c5aaa742f
commit 0bcddfc894
9 changed files with 245 additions and 237 deletions

View File

@ -0,0 +1,41 @@
/* GStreamer
* Copyright (C) 2023 Seungha Yang <seungha@centricular.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#pragma once
#include <gst/gst.h>
#include <gst/video/video.h>
#include <gst/d3d11/gstd3d11_fwd.h>
G_BEGIN_DECLS
GST_D3D11_API
gboolean gst_d3d11_converter_apply_transform (GstD3D11Converter * converter,
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);
G_END_DECLS

View File

@ -25,6 +25,7 @@
#include "gstd3d11-private.h" #include "gstd3d11-private.h"
#include "gstd3d11device-private.h" #include "gstd3d11device-private.h"
#include "gstd3d11converter-private.h"
#include "gstd3d11converter.h" #include "gstd3d11converter.h"
#include "gstd3d11device.h" #include "gstd3d11device.h"
#include "gstd3d11utils.h" #include "gstd3d11utils.h"
@ -38,6 +39,11 @@
#include <map> #include <map>
#include <memory> #include <memory>
#ifndef HAVE_DIRECTX_MATH_SIMD
#define _XM_NO_INTRINSICS_
#endif
#include <DirectXMath.h>
/** /**
* SECTION:gstd3d11converter * SECTION:gstd3d11converter
* @title: GstD3D11Converter * @title: GstD3D11Converter
@ -119,6 +125,7 @@ gst_d3d11_converter_alpha_mode_get_type (void)
/* *INDENT-OFF* */ /* *INDENT-OFF* */
using namespace Microsoft::WRL; using namespace Microsoft::WRL;
using namespace DirectX;
/* *INDENT-ON* */ /* *INDENT-ON* */
#define CONVERTER_MAX_QUADS 2 #define CONVERTER_MAX_QUADS 2
@ -175,61 +182,53 @@ struct GammaLut
/* *INDENT-OFF* */ /* *INDENT-OFF* */
typedef std::shared_ptr<GammaLut> GammaLutPtr; typedef std::shared_ptr<GammaLut> GammaLutPtr;
static const FLOAT g_matrix_identity[] = { static const XMFLOAT4X4A g_matrix_identity = XMFLOAT4X4A (
1.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, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.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, 1.0f);
};
static const FLOAT g_matrix_90r[] = { static const XMFLOAT4X4A g_matrix_90r = XMFLOAT4X4A (
0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
1.0f, 0.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, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
};
static const FLOAT g_matrix_180[] = { static const XMFLOAT4X4A g_matrix_180 = XMFLOAT4X4A (
-1.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, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.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, 1.0f);
};
static const FLOAT g_matrix_90l[] = { static const XMFLOAT4X4A g_matrix_90l = XMFLOAT4X4A (
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.0f, 0.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, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
};
static const FLOAT g_matrix_horiz[] = { static const XMFLOAT4X4A g_matrix_horiz = XMFLOAT4X4A (
-1.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, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.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, 1.0f);
};
static const FLOAT g_matrix_vert[] = { static const XMFLOAT4X4A g_matrix_vert = XMFLOAT4X4A (
1.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, -1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.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, 1.0f);
};
static const FLOAT g_matrix_ul_lr[] = { static const XMFLOAT4X4A g_matrix_ul_lr = XMFLOAT4X4A (
0.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
-1.0f, 0.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, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
};
static const FLOAT g_matrix_ur_ll[] = { static const XMFLOAT4X4A g_matrix_ur_ll = XMFLOAT4X4A (
0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
1.0f, 0.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, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
};
/* *INDENT-ON* */ /* *INDENT-ON* */
enum enum
@ -263,8 +262,7 @@ struct _GstD3D11ConverterPrivate
{ {
_GstD3D11ConverterPrivate () _GstD3D11ConverterPrivate ()
{ {
G_STATIC_ASSERT (sizeof (custom_transform) == sizeof (g_matrix_identity)); custom_transform = g_matrix_identity;
memcpy (custom_transform, g_matrix_identity, sizeof (g_matrix_identity));
} }
~_GstD3D11ConverterPrivate () ~_GstD3D11ConverterPrivate ()
@ -320,7 +318,7 @@ struct _GstD3D11ConverterPrivate
gboolean update_dest_rect = FALSE; gboolean update_dest_rect = FALSE;
gboolean update_alpha = FALSE; gboolean update_alpha = FALSE;
gboolean update_transform = FALSE; gboolean update_transform = FALSE;
FLOAT custom_transform[16]; XMFLOAT4X4A custom_transform;
PSConstBuffer const_data; PSConstBuffer const_data;
@ -863,14 +861,13 @@ gst_d3d11_color_convert_setup_shader (GstD3D11Converter * self,
} }
} }
G_STATIC_ASSERT (sizeof (g_matrix_identity) % 16 == 0);
buffer_desc.Usage = D3D11_USAGE_DYNAMIC; buffer_desc.Usage = D3D11_USAGE_DYNAMIC;
buffer_desc.ByteWidth = sizeof (g_matrix_identity); buffer_desc.ByteWidth = sizeof (g_matrix_identity);
buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; buffer_desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
subresource.pSysMem = g_matrix_identity; subresource.pSysMem = g_matrix_identity.m;
subresource.SysMemPitch = sizeof (g_matrix_identity); subresource.SysMemPitch = sizeof (FLOAT) * 16;
hr = device_handle->CreateBuffer (&buffer_desc, &subresource, hr = device_handle->CreateBuffer (&buffer_desc, &subresource,
&vs_const_buffer); &vs_const_buffer);
@ -982,7 +979,7 @@ gst_d3d11_converter_apply_orientation (GstD3D11Converter * self)
{ {
GstD3D11ConverterPrivate *priv = self->priv; GstD3D11ConverterPrivate *priv = self->priv;
ID3D11DeviceContext *context_handle; ID3D11DeviceContext *context_handle;
const FLOAT *matrix = nullptr; const XMFLOAT4X4A *matrix = &g_matrix_identity;
D3D11_MAPPED_SUBRESOURCE map; D3D11_MAPPED_SUBRESOURCE map;
HRESULT hr; HRESULT hr;
@ -990,31 +987,30 @@ gst_d3d11_converter_apply_orientation (GstD3D11Converter * self)
case GST_VIDEO_ORIENTATION_IDENTITY: case GST_VIDEO_ORIENTATION_IDENTITY:
case GST_VIDEO_ORIENTATION_AUTO: case GST_VIDEO_ORIENTATION_AUTO:
default: default:
matrix = g_matrix_identity;
break; break;
case GST_VIDEO_ORIENTATION_CUSTOM: case GST_VIDEO_ORIENTATION_CUSTOM:
matrix = priv->custom_transform; matrix = &priv->custom_transform;
break; break;
case GST_VIDEO_ORIENTATION_90R: case GST_VIDEO_ORIENTATION_90R:
matrix = g_matrix_90r; matrix = &g_matrix_90r;
break; break;
case GST_VIDEO_ORIENTATION_180: case GST_VIDEO_ORIENTATION_180:
matrix = g_matrix_180; matrix = &g_matrix_180;
break; break;
case GST_VIDEO_ORIENTATION_90L: case GST_VIDEO_ORIENTATION_90L:
matrix = g_matrix_90l; matrix = &g_matrix_90l;
break; break;
case GST_VIDEO_ORIENTATION_HORIZ: case GST_VIDEO_ORIENTATION_HORIZ:
matrix = g_matrix_horiz; matrix = &g_matrix_horiz;
break; break;
case GST_VIDEO_ORIENTATION_VERT: case GST_VIDEO_ORIENTATION_VERT:
matrix = g_matrix_vert; matrix = &g_matrix_vert;
break; break;
case GST_VIDEO_ORIENTATION_UL_LR: case GST_VIDEO_ORIENTATION_UL_LR:
matrix = g_matrix_ul_lr; matrix = &g_matrix_ul_lr;
break; break;
case GST_VIDEO_ORIENTATION_UR_LL: case GST_VIDEO_ORIENTATION_UR_LL:
matrix = g_matrix_ur_ll; matrix = &g_matrix_ur_ll;
break; break;
} }
@ -1025,7 +1021,7 @@ gst_d3d11_converter_apply_orientation (GstD3D11Converter * self)
if (!gst_d3d11_result (hr, self->device)) if (!gst_d3d11_result (hr, self->device))
return FALSE; return FALSE;
memcpy (map.pData, matrix, sizeof (FLOAT) * 16); memcpy (map.pData, matrix->m, sizeof (FLOAT) * 16);
context_handle->Unmap (priv->vs_const_buffer.Get (), 0); context_handle->Unmap (priv->vs_const_buffer.Get (), 0);
@ -3212,7 +3208,7 @@ gst_d3d11_converter_convert_buffer_unlocked (GstD3D11Converter * converter,
*/ */
gboolean gboolean
gst_d3d11_converter_set_transform_matrix (GstD3D11Converter * converter, gst_d3d11_converter_set_transform_matrix (GstD3D11Converter * converter,
gfloat matrix[16]) const gfloat matrix[16])
{ {
GstD3D11ConverterPrivate *priv; GstD3D11ConverterPrivate *priv;
@ -3226,7 +3222,95 @@ gst_d3d11_converter_set_transform_matrix (GstD3D11Converter * converter,
} }
std::lock_guard < std::mutex > lk (priv->prop_lock); std::lock_guard < std::mutex > lk (priv->prop_lock);
memcpy (priv->custom_transform, matrix, sizeof (priv->custom_transform)); priv->custom_transform = XMFLOAT4X4A (matrix);
priv->update_transform = TRUE; priv->update_transform = TRUE;
return TRUE;
}
gboolean
gst_d3d11_converter_apply_transform (GstD3D11Converter * converter,
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)
{
GstD3D11ConverterPrivate *priv;
g_return_val_if_fail (GST_IS_D3D11_CONVERTER (converter), FALSE);
priv = converter->priv;
if ((priv->supported_backend & GST_D3D11_CONVERTER_BACKEND_SHADER) == 0) {
GST_ERROR_OBJECT (converter, "Shader backend is disabled");
return FALSE;
}
std::lock_guard < std::mutex > lk (priv->prop_lock);
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 = XMLoadFloat4x4A (&g_matrix_90r);
rotated = TRUE;
break;
case GST_VIDEO_ORIENTATION_180:
rotate_matrix = XMLoadFloat4x4A (&g_matrix_180);
break;
case GST_VIDEO_ORIENTATION_90L:
rotate_matrix = XMLoadFloat4x4A (&g_matrix_90l);
rotated = TRUE;
break;
case GST_VIDEO_ORIENTATION_HORIZ:
rotate_matrix = XMLoadFloat4x4A (&g_matrix_horiz);
break;
case GST_VIDEO_ORIENTATION_VERT:
rotate_matrix = XMLoadFloat4x4A (&g_matrix_vert);
break;
case GST_VIDEO_ORIENTATION_UL_LR:
rotate_matrix = XMLoadFloat4x4A (&g_matrix_ul_lr);
rotated = TRUE;
break;
case GST_VIDEO_ORIENTATION_UR_LL:
rotate_matrix = XMLoadFloat4x4A (&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;
XMStoreFloat4x4A (&priv->custom_transform, mvp);
priv->update_transform = TRUE;
priv->video_direction = GST_VIDEO_ORIENTATION_CUSTOM;
return TRUE; return TRUE;
} }

View File

@ -197,6 +197,6 @@ gboolean gst_d3d11_converter_convert_buffer_unlocked (GstD3D11Convert
GST_D3D11_API GST_D3D11_API
gboolean gst_d3d11_converter_set_transform_matrix (GstD3D11Converter * converter, gboolean gst_d3d11_converter_set_transform_matrix (GstD3D11Converter * converter,
gfloat matrix[16]); const gfloat matrix[16]);
G_END_DECLS G_END_DECLS

View File

@ -24,6 +24,7 @@ d3d11_headers = [
] ]
gstd3d11_dep = dependency('', required : false) gstd3d11_dep = dependency('', required : false)
directxmath_dep = dependency('', required : false)
if host_system != 'windows' if host_system != 'windows'
subdir_done() subdir_done()
@ -175,6 +176,51 @@ if cc.get_id() == 'msvc' and fxc.found()
extra_comm_args += ['-DHLSL_PRECOMPILED'] extra_comm_args += ['-DHLSL_PRECOMPILED']
endif endif
have_dx_math = cxx.compiles('''
#include <windows.h>
#include <DirectXMath.h>
using namespace DirectX;
int main(int argc, char ** argv) {
XMMATRIX matrix;
XMFLOAT4X4 dump;
matrix = XMMatrixIdentity ();
XMStoreFloat4x4 (&dump, matrix);
return 0;
}
''',
name: 'DirectXMath suupport in Windows SDK')
if not have_dx_math
directxmath_dep = dependency('directxmath',
fallback: ['directxmath', 'directxmath_dep'],
required: false)
if not directxmath_dep.found()
subdir_done ()
endif
extra_deps += [directxmath_dep]
endif
# https://learn.microsoft.com/en-us/windows/win32/dxmath/pg-xnamath-internals#windows-sse-versus-sse2
# x86 with Windows 7 or older may not support SSE2
if host_machine.cpu_family() != 'x86'
# XXX: __cpuid() mismatch in case of some mingw toolchain
have_dx_math_simd = cxx.compiles('''
#include <windows.h>
#include <DirectXMath.h>
using namespace DirectX;
int main(int argc, char ** argv) {
XMVerifyCPUSupport ();
return 0;
}
''',
name: 'DirectXMath SIMD suupport',
dependencies: directxmath_dep)
if have_dx_math_simd
extra_comm_args += ['-DHAVE_DIRECTX_MATH_SIMD']
endif
endif
configure_file( configure_file(
input : 'gstd3d11config.h.meson', input : 'gstd3d11config.h.meson',
output : 'gstd3d11config.h', output : 'gstd3d11config.h',

View File

@ -1848,18 +1848,12 @@ gst_d3d11_base_convert_set_info (GstD3D11BaseFilter * filter,
"dest-width", out_width, "dest-height", out_height, nullptr); "dest-width", out_width, "dest-height", out_height, nullptr);
if (need_transform) { if (need_transform) {
gfloat transform_matrix[16];
GST_DEBUG_OBJECT (self, "Applying custom transform"); GST_DEBUG_OBJECT (self, "Applying custom transform");
gst_d3d11_calculate_transform_matrix (self->active_method, gst_d3d11_converter_apply_transform (self->converter, self->active_method,
(gfloat) out_width, (gfloat) out_height, self->fov, (gfloat) out_width, (gfloat) out_height, self->fov,
self->ortho, self->rotation_x, self->rotation_y, self->ortho, self->rotation_x, self->rotation_y,
self->rotation_z, self->scale_x, self->scale_y, transform_matrix); self->rotation_z, self->scale_x, self->scale_y);
g_object_set (self->converter,
"video-direction", GST_VIDEO_ORIENTATION_CUSTOM, nullptr);
gst_d3d11_converter_set_transform_matrix (self->converter,
transform_matrix);
} else { } else {
g_object_set (self->converter, g_object_set (self->converter,
"video-direction", self->active_method, nullptr); "video-direction", self->active_method, nullptr);

View File

@ -1016,121 +1016,6 @@ gst_d3d11_need_transform (gfloat rotation_x, gfloat rotation_y,
return FALSE; 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];
}
}
}
struct SamplingMethodMap struct SamplingMethodMap
{ {
GstD3D11SamplingMethod method; GstD3D11SamplingMethod method;

View File

@ -26,6 +26,7 @@
#include <gst/d3d11/gstd3d11.h> #include <gst/d3d11/gstd3d11.h>
#include <gst/d3d11/gstd3d11-private.h> #include <gst/d3d11/gstd3d11-private.h>
#include <gst/d3d11/gstd3d11device-private.h> #include <gst/d3d11/gstd3d11device-private.h>
#include <gst/d3d11/gstd3d11converter-private.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -165,18 +166,6 @@ gboolean gst_d3d11_need_transform (gfloat rotation_x,
gfloat scale_x, gfloat scale_x,
gfloat scale_y); 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]);
D3D11_FILTER gst_d3d11_sampling_method_to_native (GstD3D11SamplingMethod method); D3D11_FILTER gst_d3d11_sampling_method_to_native (GstD3D11SamplingMethod method);
G_END_DECLS G_END_DECLS

View File

@ -996,18 +996,12 @@ gst_d3d11_window_present (GstD3D11Window * self, GstBuffer * buffer,
self->rotation_z, self->scale_x, self->scale_y)) { self->rotation_z, self->scale_x, self->scale_y)) {
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];
GST_DEBUG_OBJECT (self, "Applying custom transform"); GST_DEBUG_OBJECT (self, "Applying custom transform");
gst_d3d11_calculate_transform_matrix (self->method, gst_d3d11_converter_apply_transform (self->converter, self->method,
viewport.Width, viewport.Height, self->fov, self->ortho, viewport.Width, viewport.Height, self->fov, self->ortho,
self->rotation_x, self->rotation_y, self->rotation_z, self->rotation_x, self->rotation_y, self->rotation_z,
self->scale_x, self->scale_y, transform_matrix); self->scale_x, self->scale_y);
g_object_set (self->converter,
"video-direction", GST_VIDEO_ORIENTATION_CUSTOM, nullptr);
gst_d3d11_converter_set_transform_matrix (self->converter,
transform_matrix);
} }
gst_d3d11_overlay_compositor_update_viewport (self->compositor, &viewport); gst_d3d11_overlay_compositor_update_viewport (self->compositor, &viewport);

View File

@ -130,38 +130,13 @@ if cc.get_id() == 'msvc' and fxc.found()
extra_args += ['-DHLSL_PRECOMPILED'] extra_args += ['-DHLSL_PRECOMPILED']
endif endif
have_dx_math = cxx.compiles('''
#include <windows.h>
#include <DirectXMath.h>
using namespace DirectX;
int main(int argc, char ** argv) {
XMMATRIX matrix;
XMFLOAT4X4 dump;
matrix = XMMatrixIdentity ();
XMStoreFloat4x4 (&dump, matrix);
return 0;
}
''',
name: 'DirectXMath suupport in Windows SDK')
if not have_dx_math
directxmath_dep = dependency('directxmath',
fallback: ['directxmath', 'directxmath_dep'],
required: d3d11_option)
if not directxmath_dep.found()
subdir_done ()
endif
extra_dep += [directxmath_dep]
endif
gstd3d11 = library('gstd3d11', gstd3d11 = library('gstd3d11',
d3d11_sources + hlsl_precompiled, d3d11_sources + hlsl_precompiled,
c_args : gst_plugins_bad_args + extra_c_args + extra_args, c_args : gst_plugins_bad_args + extra_c_args + extra_args,
cpp_args: gst_plugins_bad_args + extra_args, cpp_args: gst_plugins_bad_args + extra_args,
include_directories : [configinc], include_directories : [configinc],
dependencies : [gstbase_dep, gstvideo_dep, gmodule_dep, gstcontroller_dep, dependencies : [gstbase_dep, gstvideo_dep, gmodule_dep, gstcontroller_dep,
gstd3d11_dep, gstdxva_dep, d2d_dep] + extra_dep, gstd3d11_dep, gstdxva_dep, d2d_dep, directxmath_dep] + extra_dep,
install : true, install : true,
install_dir : plugins_install_dir, install_dir : plugins_install_dir,
) )