d3d12: Add testsrc element

Adding testsrc element with d2d interop support via d3d11on12

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5875>
This commit is contained in:
Seungha Yang 2023-12-30 00:08:27 +09:00 committed by GStreamer Marge Bot
parent e5b3f090fc
commit 7c701058ed
14 changed files with 2854 additions and 6 deletions

View file

@ -11614,6 +11614,81 @@
},
"rank": "none"
},
"d3d12testsrc": {
"author": "Seungha Yang <seungha@centricular.com>",
"description": "Creates a test video stream",
"hierarchy": [
"GstD3D12TestSrc",
"GstBaseSrc",
"GstElement",
"GstObject",
"GInitiallyUnowned",
"GObject"
],
"klass": "Source/Video",
"pad-templates": {
"src": {
"caps": "video/x-raw(memory:D3D12Memory):\n format: { RGBA64_LE, RGB10A2_LE, Y410, VUYA, RGBA, BGRA, RBGA, P016_LE, P012_LE, P010_10LE, RGBx, BGRx, NV12, AYUV64, GBRA_12LE, GBRA_10LE, AYUV, ABGR, ARGB, GBRA, Y444_16LE, GBR_16LE, Y444_12LE, GBR_12LE, I422_12LE, I420_12LE, Y444_10LE, GBR_10LE, I422_10LE, I420_10LE, Y444, BGRP, GBR, RGBP, xBGR, xRGB, Y42B, NV21, I420, YV12, GRAY16_LE, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\nvideo/x-raw:\n format: { RGBA64_LE, RGB10A2_LE, Y410, VUYA, RGBA, BGRA, RBGA, P016_LE, P012_LE, P010_10LE, RGBx, BGRx, NV12, AYUV64, GBRA_12LE, GBRA_10LE, AYUV, ABGR, ARGB, GBRA, Y444_16LE, GBR_16LE, Y444_12LE, GBR_12LE, I422_12LE, I420_12LE, Y444_10LE, GBR_10LE, I422_10LE, I420_10LE, Y444, BGRP, GBR, RGBP, xBGR, xRGB, Y42B, NV21, I420, YV12, GRAY16_LE, GRAY8 }\n width: [ 1, 2147483647 ]\n height: [ 1, 2147483647 ]\n framerate: [ 0/1, 2147483647/1 ]\n",
"direction": "src",
"presence": "always"
}
},
"properties": {
"adapter": {
"blurb": "DXGI Adapter index (-1 for any device)",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "-1",
"max": "2147483647",
"min": "-1",
"mutable": "ready",
"readable": true,
"type": "gint",
"writable": true
},
"alpha": {
"blurb": "Global alpha value to use",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "1",
"max": "1",
"min": "0",
"mutable": "ready",
"readable": true,
"type": "gfloat",
"writable": true
},
"is-live": {
"blurb": "Whether to act as a live source",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"pattern": {
"blurb": "Type of test pattern to generate",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "smpte (0)",
"mutable": "ready",
"readable": true,
"type": "GstD3D12TestSrcPattern",
"writable": true
}
},
"rank": "none"
},
"d3d12upload": {
"author": "Seungha Yang <seungha@centricular.com>",
"description": "Uploads system memory into Direct3D12 texture memory",
@ -11830,6 +11905,81 @@
"value": "3"
}
]
},
"GstD3D12TestSrcPattern": {
"kind": "enum",
"values": [
{
"desc": "SMPTE 100%% color bars",
"name": "smpte",
"value": "0"
},
{
"desc": "Random (television snow)",
"name": "snow",
"value": "1"
},
{
"desc": "100%% Black",
"name": "black",
"value": "2"
},
{
"desc": "100%% White",
"name": "white",
"value": "3"
},
{
"desc": "Red",
"name": "red",
"value": "4"
},
{
"desc": "Green",
"name": "green",
"value": "5"
},
{
"desc": "Blue",
"name": "blue",
"value": "6"
},
{
"desc": "Checkers 1px",
"name": "checkers-1",
"value": "7"
},
{
"desc": "Checkers 2px",
"name": "checkers-2",
"value": "8"
},
{
"desc": "Checkers 4px",
"name": "checkers-4",
"value": "9"
},
{
"desc": "Checkers 8px",
"name": "checkers-8",
"value": "10"
},
{
"desc": "Circular",
"name": "circular",
"value": "11"
},
{
"desc": "Blink",
"name": "blink",
"value": "12"
},
{
"desc": "Moving ball",
"name": "ball",
"value": "18"
}
]
}
},
"package": "GStreamer Bad Plug-ins",

View file

@ -0,0 +1,129 @@
/* 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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "gstd3d11on12.h"
#include <d3d11on12.h>
#include <wrl.h>
/* *INDENT-OFF* */
using namespace Microsoft::WRL;
/* *INDENT-ON* */
HRESULT
GstD3D11On12CreateDevice (IUnknown * device, IUnknown * command_queue,
IUnknown ** d3d11on12)
{
static const D3D_FEATURE_LEVEL feature_levels[] = {
D3D_FEATURE_LEVEL_12_1,
D3D_FEATURE_LEVEL_12_0,
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
};
g_return_val_if_fail (device, E_INVALIDARG);
g_return_val_if_fail (command_queue, E_INVALIDARG);
g_return_val_if_fail (d3d11on12, E_INVALIDARG);
IUnknown *cq[] = { command_queue };
ComPtr < ID3D11Device > d3d11device;
auto hr = D3D11On12CreateDevice (device, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
feature_levels, G_N_ELEMENTS (feature_levels), cq, 1, 0, &d3d11device,
nullptr, nullptr);
if (FAILED (hr))
return hr;
ComPtr < ID3D11On12Device > d3d11on12device;
hr = d3d11device.As (&d3d11on12device);
if (FAILED (hr))
return hr;
*d3d11on12 = d3d11on12device.Detach ();
return S_OK;
}
HRESULT
GstD3D11On12CreateWrappedResource (IUnknown * d3d11on12, IUnknown * resource12,
UINT bind_flags, UINT misc_flags, UINT cpu_access_flags,
UINT structure_byte_stride, UINT in_state, UINT out_state,
ID3D11Resource ** resource11)
{
g_return_val_if_fail (d3d11on12, E_INVALIDARG);
g_return_val_if_fail (resource12, E_INVALIDARG);
g_return_val_if_fail (resource11, E_INVALIDARG);
ComPtr < ID3D11On12Device > device;
auto hr = d3d11on12->QueryInterface (IID_PPV_ARGS (&device));
if (FAILED (hr))
return hr;
D3D11_RESOURCE_FLAGS flags = { };
flags.BindFlags = bind_flags;
flags.MiscFlags = misc_flags;
flags.CPUAccessFlags = cpu_access_flags;
flags.StructureByteStride = structure_byte_stride;
ComPtr < ID3D11Resource > resource;
hr = device->CreateWrappedResource (resource12, &flags,
(D3D12_RESOURCE_STATES) in_state, (D3D12_RESOURCE_STATES) out_state,
IID_PPV_ARGS (&resource));
if (FAILED (hr))
return hr;
*resource11 = resource.Detach ();
return S_OK;
}
HRESULT
GstD3D11On12ReleaseWrappedResource (IUnknown * d3d11on12,
ID3D11Resource ** resources, guint num_resources)
{
g_return_val_if_fail (d3d11on12, E_INVALIDARG);
ComPtr < ID3D11On12Device > device;
auto hr = d3d11on12->QueryInterface (IID_PPV_ARGS (&device));
if (FAILED (hr))
return hr;
device->ReleaseWrappedResources (resources, num_resources);
return S_OK;
}
HRESULT
GstD3D11On12AcquireWrappedResource (IUnknown * d3d11on12,
ID3D11Resource ** resources, guint num_resources)
{
g_return_val_if_fail (d3d11on12, E_INVALIDARG);
ComPtr < ID3D11On12Device > device;
auto hr = d3d11on12->QueryInterface (IID_PPV_ARGS (&device));
if (FAILED (hr))
return hr;
device->AcquireWrappedResources (resources, num_resources);
return S_OK;
}

View file

@ -0,0 +1,50 @@
/* 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 <windows.h>
#include <d3d11.h>
G_BEGIN_DECLS
HRESULT GstD3D11On12CreateDevice (IUnknown * device,
IUnknown * command_queue,
IUnknown ** d3d11on12);
HRESULT GstD3D11On12CreateWrappedResource (IUnknown * d3d11on12,
IUnknown * resource12,
UINT bind_flags,
UINT misc_flags,
UINT cpu_access_flags,
UINT structure_byte_stride,
UINT in_state,
UINT out_state,
ID3D11Resource ** resource11);
HRESULT GstD3D11On12ReleaseWrappedResource (IUnknown * d3d11on12,
ID3D11Resource ** resources,
guint num_resources);
HRESULT GstD3D11On12AcquireWrappedResource (IUnknown * d3d11on12,
ID3D11Resource ** resources,
guint num_resources);
G_END_DECLS

View file

@ -23,6 +23,7 @@
#include "gstd3d12.h"
#include "gstd3d12-private.h"
#include "gstd3d11on12.h"
#include <wrl.h>
#include <vector>
#include <string.h>
@ -89,9 +90,12 @@ struct _GstD3D12DevicePrivate
ComPtr<IDXGIFactory2> factory;
std::unordered_map<GstVideoFormat, GstD3D12Format> format_table;
std::recursive_mutex extern_lock;
std::mutex lock;
ComPtr<ID3D12InfoQueue> info_queue;
ComPtr<IUnknown> d3d11on12;
GstD3D12CommandQueue *direct_queue = nullptr;
GstD3D12CommandQueue *copy_queue = nullptr;
@ -724,6 +728,51 @@ gst_d3d12_device_get_factory_handle (GstD3D12Device * device)
return device->priv->factory.Get ();
}
gboolean
gst_d3d12_device_get_d3d11on12_device (GstD3D12Device * device,
IUnknown ** d3d11on12)
{
g_return_val_if_fail (GST_IS_D3D12_DEVICE (device), FALSE);
g_return_val_if_fail (d3d11on12, FALSE);
auto priv = device->priv;
std::lock_guard < std::mutex > lk (priv->lock);
if (!priv->d3d11on12) {
ComPtr < ID3D12CommandQueue > cq;
gst_d3d12_command_queue_get_handle (priv->direct_queue, &cq);
auto hr = GstD3D11On12CreateDevice (priv->device.Get (), cq.Get (),
&priv->d3d11on12);
if (!gst_d3d12_result (hr, device)) {
GST_ERROR_OBJECT (device, "Couldn't create d3d11on12 device");
return FALSE;
}
}
*d3d11on12 = priv->d3d11on12.Get ();
(*d3d11on12)->AddRef ();
return TRUE;
}
void
gst_d3d12_device_lock (GstD3D12Device * device)
{
g_return_if_fail (GST_IS_D3D12_DEVICE (device));
auto priv = device->priv;
priv->extern_lock.lock ();
}
void
gst_d3d12_device_unlock (GstD3D12Device * device)
{
g_return_if_fail (GST_IS_D3D12_DEVICE (device));
auto priv = device->priv;
priv->extern_lock.unlock ();
}
gboolean
gst_d3d12_device_get_format (GstD3D12Device * device,
GstVideoFormat format, GstD3D12Format * device_format)

View file

@ -75,6 +75,13 @@ IDXGIAdapter1 * gst_d3d12_device_get_adapter_handle (GstD3D12Devic
IDXGIFactory2 * gst_d3d12_device_get_factory_handle (GstD3D12Device * device);
gboolean gst_d3d12_device_get_d3d11on12_device (GstD3D12Device * device,
IUnknown ** d3d11on12);
void gst_d3d12_device_lock (GstD3D12Device * device);
void gst_d3d12_device_unlock (GstD3D12Device * device);
gboolean gst_d3d12_device_get_format (GstD3D12Device * device,
GstVideoFormat format,
GstD3D12Format * device_format);

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,34 @@
/* 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/base/gstbasesrc.h>
#include "gstd3d12.h"
G_BEGIN_DECLS
#define GST_TYPE_D3D12_TEST_SRC (gst_d3d12_test_src_get_type())
G_DECLARE_FINAL_TYPE (GstD3D12TestSrc, gst_d3d12_test_src,
GST, D3D12_TEST_SRC, GstBaseSrc);
G_END_DECLS

View file

@ -0,0 +1,44 @@
/* 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.
*/
cbuffer CheckerConstBuffer : register(b0)
{
float width;
float height;
float checker_size;
float alpha;
};
struct PS_INPUT
{
float4 Position: SV_POSITION;
float2 Texture: TEXCOORD;
};
float4 PSMain_checker (PS_INPUT input) : SV_Target
{
float4 output;
float2 xy_mod = floor (0.5 * input.Texture * float2 (width, height) / checker_size);
float result = fmod (xy_mod.x + xy_mod.y, 2.0);
output.r = step (result, 0.5);
output.g = 1.0 - output.r;
output.b = 0;
output.a = alpha;
return output;
}

View file

@ -0,0 +1,29 @@
/* 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.
*/
struct PS_INPUT
{
float4 Position: SV_POSITION;
float4 Color: COLOR;
};
float4 PSMain_color (PS_INPUT input) : SV_TARGET
{
return input.Color;
}

View file

@ -0,0 +1,45 @@
/* 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.
*/
cbuffer SnowConstBuffer : register(b0)
{
float time;
float alpha;
};
struct PS_INPUT
{
float4 Position : SV_POSITION;
float2 Texture : TEXCOORD;
};
float get_rand (float2 uv)
{
return frac (sin (dot (uv, float2 (12.9898,78.233))) * 43758.5453);
}
float4 PSMain_snow (PS_INPUT input) : SV_Target
{
float4 output;
float val = get_rand (time * input.Texture);
output.rgb = float3(val, val, val);
output.a = alpha;
return output;
}

View file

@ -0,0 +1,35 @@
/* 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.
*/
struct VS_INPUT
{
float4 Position : POSITION;
float4 Color : COLOR;
};
struct VS_OUTPUT
{
float4 Position : SV_POSITION;
float4 Color : COLOR;
};
VS_OUTPUT VSMain_color (VS_INPUT input)
{
return input;
}

View file

@ -144,6 +144,10 @@ hlsl_sources = [
['PSMain_sample', 'ps_6_0'],
['PSMain_sample_premul', 'ps_6_0'],
['VSMain_coord', 'vs_6_0'],
['PSMain_color', 'ps_6_0'],
['VSMain_color', 'vs_6_0'],
['PSMain_snow', 'ps_6_0'],
['PSMain_checker', 'ps_6_0'],
]
foreach shader : hlsl_sources

View file

@ -1,4 +1,5 @@
d3d12_sources = [
'gstd3d11on12.cpp',
'gstd3d12av1dec.cpp',
'gstd3d12basefilter.cpp',
'gstd3d12bufferpool.cpp',
@ -19,6 +20,7 @@ d3d12_sources = [
'gstd3d12memory.cpp',
'gstd3d12overlaycompositor.cpp',
'gstd3d12pluginutils.cpp',
'gstd3d12testsrc.cpp',
'gstd3d12upload.cpp',
'gstd3d12utils.cpp',
'gstd3d12videosink.cpp',
@ -48,8 +50,9 @@ if cc.get_id() != 'msvc'
endif
d3d12_lib = cc.find_library('d3d12', required : d3d12_option)
d3d11_lib = cc.find_library('d3d11', required : d3d12_option)
d2d_dep = cc.find_library('d2d1', required: d3d12_option)
dxgi_lib = cc.find_library('dxgi', required : d3d12_option)
d3dcompiler_lib = cc.find_library('d3dcompiler', required : d3d12_option)
dx_headers_dep = dependency('DirectX-Headers',
version: '>= 1.611',
allow_fallback: true,
@ -57,17 +60,18 @@ dx_headers_dep = dependency('DirectX-Headers',
dxc = find_program('dxc', required : d3d12_option)
if not gstdxva_dep.found() or not d3d12_lib.found() or not dxgi_lib.found() \
or not dx_headers_dep.found() or not d3dcompiler_lib.found() \
or not dxc.found()
or not dx_headers_dep.found() or not dxc.found() or not d2d_dep.found()
if d3d12_option.enabled()
error('The d3d12 was enabled explicitly, but required GstD3D11 dependencies were not found.')
error('The d3d12 was enabled explicitly, but required dependencies were not found.')
endif
subdir_done()
endif
d3d12_headers = [
'dxgi1_6.h',
'd3dcompiler.h',
'd3d11.h',
'd3d11on12.h',
'd2d1.h',
'DirectXMath.h',
]
@ -100,7 +104,7 @@ gstd3d12 = library('gstd3d12',
cpp_args: gst_plugins_bad_args + extra_args,
include_directories : [configinc],
dependencies : [gstbase_dep, gstvideo_dep, gstcodecs_dep,
gstdxva_dep, d3d12_lib, dxgi_lib, d3dcompiler_lib,
gstdxva_dep, d3d12_lib, d3d11_lib, d2d_dep, dxgi_lib,
dx_headers_dep],
install : true,
install_dir : plugins_install_dir,

View file

@ -33,6 +33,7 @@
#include "gstd3d12download.h"
#include "gstd3d12upload.h"
#include "gstd3d12videosink.h"
#include "gstd3d12testsrc.h"
#include "gstd3d12h264dec.h"
#include "gstd3d12h265dec.h"
#include "gstd3d12vp9dec.h"
@ -113,6 +114,8 @@ plugin_init (GstPlugin * plugin)
"d3d12upload", GST_RANK_NONE, GST_TYPE_D3D12_UPLOAD);
gst_element_register (plugin,
"d3d12videosink", GST_RANK_NONE, GST_TYPE_D3D12_VIDEO_SINK);
gst_element_register (plugin,
"d3d12testsrc", GST_RANK_NONE, GST_TYPE_D3D12_TEST_SRC);
return TRUE;
}