[vlc-commits] d3d11_player: use a different ID3D11Device between the app and VLC
Steve Lhomme
git at videolan.org
Fri Oct 4 12:28:17 CEST 2019
vlc | branch: master | Steve Lhomme <robux4 at ycbcr.xyz> | Thu Oct 3 13:18:08 2019 +0200| [a882a3a8861f6be982c5a3ebc6232f6738b9be5e] | committer: Steve Lhomme
d3d11_player: use a different ID3D11Device between the app and VLC
The texture we render to is shared between the 2 devices and locked internally
by the driver when needed.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a882a3a8861f6be982c5a3ebc6232f6738b9be5e
---
doc/libvlc/d3d11_player.cpp | 65 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 52 insertions(+), 13 deletions(-)
diff --git a/doc/libvlc/d3d11_player.cpp b/doc/libvlc/d3d11_player.cpp
index a94fe793f3..ce9de70467 100644
--- a/doc/libvlc/d3d11_player.cpp
+++ b/doc/libvlc/d3d11_player.cpp
@@ -1,9 +1,22 @@
/* compile: g++ d3d11_player.cpp -o d3d11_player.exe -L<path/libvlc> -lvlc -ld3d11 -ld3dcompiler_47 -luuid */
+/* This is the most extreme use case where libvlc is given its own ID3D11DeviceContext
+ and draws in a texture shared with the ID3D11DeviceContext of the app.
+
+ It's possible to share the ID3D11DeviceContext as long as the proper PixelShader
+ calls are overridden in the app after each libvlc drawing (see libvlc D3D11 doc).
+
+ It's also possible to use the SwapChain directly with libvlc and let it draw on its
+ entire area instead of drawing in a texture.
+*/
+
#include <windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
+#include <d3d11_1.h>
+#include <dxgi1_2.h>
+
#include <vlc/vlc.h>
#define SCREEN_WIDTH 1500
@@ -15,6 +28,13 @@
struct render_context
{
+ /* resources shared by VLC */
+ ID3D11Device *d3deviceVLC;
+ ID3D11DeviceContext *d3dctxVLC;
+ ID3D11Texture2D *textureVLC; // shared between VLC and the app
+ HANDLE sharedHandled; // handle of the texture used by VLC and the app
+ ID3D11RenderTargetView *textureRenderTarget;
+
/* Direct3D11 device/context */
ID3D11Device *d3device;
ID3D11DeviceContext *d3dctx;
@@ -38,7 +58,6 @@ struct render_context
/* texture VLC renders into */
ID3D11Texture2D *texture;
ID3D11ShaderResourceView *textureShaderInput;
- ID3D11RenderTargetView *textureRenderTarget;
CRITICAL_SECTION sizeLock; // the ReportSize callback cannot be called during/after the Cleanup_cb is called
unsigned width, height;
@@ -59,6 +78,11 @@ static bool UpdateOutput_cb( void *opaque, const libvlc_video_direct3d_cfg_t *cf
ctx->texture->Release();
ctx->texture = NULL;
}
+ if (ctx->textureVLC)
+ {
+ ctx->textureVLC->Release();
+ ctx->textureVLC = NULL;
+ }
if (ctx->textureShaderInput)
{
ctx->textureShaderInput->Release();
@@ -82,10 +106,21 @@ static bool UpdateOutput_cb( void *opaque, const libvlc_video_direct3d_cfg_t *cf
texDesc.Format = renderFormat;
texDesc.Height = cfg->height;
texDesc.Width = cfg->width;
+ texDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
hr = ctx->d3device->CreateTexture2D( &texDesc, NULL, &ctx->texture );
if (FAILED(hr)) return false;
+ IDXGIResource1* sharedResource = NULL;
+ ctx->texture->QueryInterface(__uuidof(IDXGIResource1), (LPVOID*) &sharedResource);
+ hr = sharedResource->CreateSharedHandle(NULL, DXGI_SHARED_RESOURCE_READ, NULL, &ctx->sharedHandled);
+ sharedResource->Release();
+
+ ID3D11Device1* d3d11VLC1;
+ ctx->d3deviceVLC->QueryInterface(__uuidof(ID3D11Device1), (LPVOID*) &d3d11VLC1);
+ hr = d3d11VLC1->OpenSharedResource1(ctx->sharedHandled, __uuidof(ID3D11Texture2D), (void**)&ctx->textureVLC);
+ d3d11VLC1->Release();
+
D3D11_SHADER_RESOURCE_VIEW_DESC resviewDesc;
ZeroMemory(&resviewDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC));
resviewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
@@ -98,7 +133,7 @@ static bool UpdateOutput_cb( void *opaque, const libvlc_video_direct3d_cfg_t *cf
.Format = texDesc.Format,
.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D,
};
- hr = ctx->d3device->CreateRenderTargetView(ctx->texture, &renderTargetViewDesc, &ctx->textureRenderTarget);
+ hr = ctx->d3deviceVLC->CreateRenderTargetView(ctx->textureVLC, &renderTargetViewDesc, &ctx->textureRenderTarget);
if (FAILED(hr)) return false;
@@ -162,14 +197,7 @@ static bool StartRendering_cb( void *opaque, bool enter, const libvlc_video_dire
if ( enter )
{
static const FLOAT blackRGBA[4] = {0.5f, 0.5f, 0.0f, 1.0f};
-
- /* force unbinding the input texture, otherwise we get:
- * OMSetRenderTargets: Resource being set to OM RenderTarget slot 0 is still bound on input! */
- ID3D11ShaderResourceView *reset = NULL;
- ctx->d3dctx->PSSetShaderResources(0, 1, &reset);
- //ctx->d3dctx->Flush();
-
- ctx->d3dctx->ClearRenderTargetView( ctx->textureRenderTarget, blackRGBA);
+ ctx->d3dctxVLC->ClearRenderTargetView( ctx->textureRenderTarget, blackRGBA);
return true;
}
@@ -182,14 +210,14 @@ static bool SelectPlane_cb( void *opaque, size_t plane )
struct render_context *ctx = static_cast<struct render_context *>( opaque );
if ( plane != 0 ) // we only support one packed RGBA plane (DXGI_FORMAT_R8G8B8A8_UNORM)
return false;
- ctx->d3dctx->OMSetRenderTargets( 1, &ctx->textureRenderTarget, NULL );
+ ctx->d3dctxVLC->OMSetRenderTargets( 1, &ctx->textureRenderTarget, NULL );
return true;
}
static bool Setup_cb( void **opaque, const libvlc_video_direct3d_device_cfg_t *cfg, libvlc_video_direct3d_device_setup_t *out )
{
struct render_context *ctx = static_cast<struct render_context *>(*opaque);
- out->device_context = ctx->d3dctx;
+ out->device_context = ctx->d3dctxVLC;
return true;
}
@@ -275,7 +303,7 @@ static void init_direct3d(struct render_context *ctx, HWND hWnd)
scd.Windowed = TRUE;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
- UINT creationFlags = D3D11_CREATE_DEVICE_VIDEO_SUPPORT; /* needed for hardware decoding */
+ UINT creationFlags = 0;
#ifndef NDEBUG
creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
@@ -301,6 +329,14 @@ static void init_direct3d(struct render_context *ctx, HWND hWnd)
pMultithread->Release();
}
+ D3D11CreateDevice(NULL,
+ D3D_DRIVER_TYPE_HARDWARE,
+ NULL,
+ creationFlags | D3D11_CREATE_DEVICE_VIDEO_SUPPORT, /* needed for hardware decoding */
+ NULL, 0,
+ D3D11_SDK_VERSION,
+ &ctx->d3deviceVLC, NULL, &ctx->d3dctxVLC);
+
ID3D11Texture2D *pBackBuffer;
ctx->swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
@@ -384,6 +420,9 @@ static void init_direct3d(struct render_context *ctx, HWND hWnd)
static void release_direct3d(struct render_context *ctx)
{
+ ctx->d3deviceVLC->Release();
+ ctx->d3dctxVLC->Release();
+
ctx->samplerState->Release();
ctx->textureRenderTarget->Release();
ctx->textureShaderInput->Release();
More information about the vlc-commits
mailing list