10#include <private/qvideotexturehelper_p.h>
11#include <private/qcomptr_p.h>
18#include <libavutil/hwcontext_d3d11va.h>
26class D3D11TextureSet :
public TextureSet
29 D3D11TextureSet(ComPtr<ID3D11Texture2D> &&tex)
33 qint64 textureHandle(
int )
override
35 return qint64(m_tex.Get());
39 ComPtr<ID3D11Texture2D> m_tex;
43D3D11TextureConverter::D3D11TextureConverter(
QRhi *rhi)
44 : TextureConverterBackend(rhi)
48static ComPtr<ID3D11Texture2D> getSharedTextureForDevice(ID3D11Device *dev, ID3D11Texture2D *tex)
50 ComPtr<IDXGIResource> dxgiResource;
51 HRESULT hr = tex->QueryInterface(__uuidof(IDXGIResource),
reinterpret_cast<void **
>(dxgiResource.GetAddressOf()));
53 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to obtain resource handle from FFMpeg texture" << hr;
56 HANDLE shared =
nullptr;
57 hr = dxgiResource->GetSharedHandle(&shared);
59 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to obtain shared handle for FFmpeg texture" << hr;
63 ComPtr<ID3D11Texture2D> sharedTex;
64 hr = dev->OpenSharedResource(shared, __uuidof(ID3D11Texture2D),
reinterpret_cast<void **
>(sharedTex.GetAddressOf()));
66 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to share FFmpeg texture" << hr;
70static ComPtr<ID3D11Texture2D> copyTextureFromArray(ID3D11Device *dev, ID3D11Texture2D *
array,
int index)
72 D3D11_TEXTURE2D_DESC arrayDesc = {};
73 array->GetDesc(&arrayDesc);
75 D3D11_TEXTURE2D_DESC texDesc = {};
76 texDesc.Width = arrayDesc.Width;
77 texDesc.Height = arrayDesc.Height;
78 texDesc.Format = arrayDesc.Format;
79 texDesc.ArraySize = 1;
80 texDesc.MipLevels = 1;
81 texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
82 texDesc.MiscFlags = 0;
83 texDesc.SampleDesc = { 1, 0};
85 ComPtr<ID3D11Texture2D> texCopy;
86 HRESULT hr = dev->CreateTexture2D(&texDesc,
nullptr, texCopy.GetAddressOf());
88 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to create texture" << hr;
92 ComPtr<ID3D11DeviceContext>
ctx;
93 dev->GetImmediateContext(
ctx.GetAddressOf());
94 ctx->CopySubresourceRegion(texCopy.Get(), 0, 0, 0, 0,
array,
index,
nullptr);
99TextureSet *D3D11TextureConverter::getTextures(AVFrame *
frame)
101 if (!
frame || !
frame->hw_frames_ctx ||
frame->format != AV_PIX_FMT_D3D11)
104 auto *fCtx = (AVHWFramesContext *)
frame->hw_frames_ctx->data;
105 auto *
ctx = fCtx->device_ctx;
106 if (!
ctx ||
ctx->type != AV_HWDEVICE_TYPE_D3D11VA)
113 auto ffmpegTex = (ID3D11Texture2D *)
frame->data[0];
117 auto dev =
reinterpret_cast<ID3D11Device *
>(nh->dev);
120 auto sharedTex = getSharedTextureForDevice(dev, ffmpegTex);
122 auto tex = copyTextureFromArray(dev, sharedTex.Get(),
index);
124 return new D3D11TextureSet(std::move(tex));
132void D3D11TextureConverter::SetupDecoderTextures(AVCodecContext *
s)
134 int ret = avcodec_get_hw_frames_parameters(
s,
139 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to allocate HW frames context" <<
ret;
143 auto *frames_ctx = (AVHWFramesContext *)
s->hw_frames_ctx->data;
144 auto *hwctx = (AVD3D11VAFramesContext *)frames_ctx->hwctx;
145 hwctx->MiscFlags = D3D11_RESOURCE_MISC_SHARED;
146 hwctx->BindFlags = D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE;
147 ret = av_hwframe_ctx_init(
s->hw_frames_ctx);
149 qCDebug(qLcMediaFFmpegHWAccel) <<
"Failed to initialize HW frames context" <<
ret;
150 av_buffer_unref(&
s->hw_frames_ctx);
\variable QRhiD3D11InitParams::enableDebugLayer
Implementation backend() const
const QRhiNativeHandles * nativeHandles()
Combined button and popup list for selecting options.
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)