|
|
@@ -38,8 +38,22 @@ |
|
|
|
#include "pixfmt.h" |
|
|
|
|
|
|
|
typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT); |
|
|
|
typedef HRESULT WINAPI pDirect3DCreate9Ex(UINT, IDirect3D9Ex **); |
|
|
|
typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **); |
|
|
|
|
|
|
|
#define FF_D3DCREATE_FLAGS (D3DCREATE_SOFTWARE_VERTEXPROCESSING | \ |
|
|
|
D3DCREATE_MULTITHREADED | \ |
|
|
|
D3DCREATE_FPU_PRESERVE) |
|
|
|
|
|
|
|
static const D3DPRESENT_PARAMETERS dxva2_present_params = { |
|
|
|
.Windowed = TRUE, |
|
|
|
.BackBufferWidth = 640, |
|
|
|
.BackBufferHeight = 480, |
|
|
|
.BackBufferCount = 0, |
|
|
|
.SwapEffect = D3DSWAPEFFECT_DISCARD, |
|
|
|
.Flags = D3DPRESENTFLAG_VIDEO, |
|
|
|
}; |
|
|
|
|
|
|
|
typedef struct DXVA2Mapping { |
|
|
|
uint32_t palette_dummy[256]; |
|
|
|
} DXVA2Mapping; |
|
|
@@ -411,19 +425,83 @@ static void dxva2_device_free(AVHWDeviceContext *ctx) |
|
|
|
av_freep(&ctx->user_opaque); |
|
|
|
} |
|
|
|
|
|
|
|
static int dxva2_device_create9(AVHWDeviceContext *ctx, UINT adapter) |
|
|
|
{ |
|
|
|
DXVA2DevicePriv *priv = ctx->user_opaque; |
|
|
|
D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; |
|
|
|
D3DDISPLAYMODE d3ddm; |
|
|
|
HRESULT hr; |
|
|
|
pDirect3DCreate9 *createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9"); |
|
|
|
if (!createD3D) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
priv->d3d9 = createD3D(D3D_SDK_VERSION); |
|
|
|
if (!priv->d3d9) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); |
|
|
|
|
|
|
|
d3dpp.BackBufferFormat = d3ddm.Format; |
|
|
|
|
|
|
|
hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), |
|
|
|
FF_D3DCREATE_FLAGS, |
|
|
|
&d3dpp, &priv->d3d9device); |
|
|
|
if (FAILED(hr)) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int dxva2_device_create9ex(AVHWDeviceContext *ctx, UINT adapter) |
|
|
|
{ |
|
|
|
DXVA2DevicePriv *priv = ctx->user_opaque; |
|
|
|
D3DPRESENT_PARAMETERS d3dpp = dxva2_present_params; |
|
|
|
D3DDISPLAYMODEEX modeex = {0}; |
|
|
|
IDirect3D9Ex *d3d9ex = NULL; |
|
|
|
IDirect3DDevice9Ex *exdev = NULL; |
|
|
|
HRESULT hr; |
|
|
|
pDirect3DCreate9Ex *createD3DEx = (pDirect3DCreate9Ex *)GetProcAddress(priv->d3dlib, "Direct3DCreate9Ex"); |
|
|
|
if (!createD3DEx) |
|
|
|
return AVERROR(ENOSYS); |
|
|
|
|
|
|
|
hr = createD3DEx(D3D_SDK_VERSION, &d3d9ex); |
|
|
|
if (FAILED(hr)) |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
|
|
|
|
IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, adapter, &modeex, NULL); |
|
|
|
|
|
|
|
d3dpp.BackBufferFormat = modeex.Format; |
|
|
|
|
|
|
|
hr = IDirect3D9Ex_CreateDeviceEx(d3d9ex, adapter, D3DDEVTYPE_HAL, GetShellWindow(), |
|
|
|
FF_D3DCREATE_FLAGS, |
|
|
|
&d3dpp, NULL, &exdev); |
|
|
|
if (FAILED(hr)) { |
|
|
|
IDirect3D9Ex_Release(d3d9ex); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
av_log(ctx, AV_LOG_VERBOSE, "Using D3D9Ex device.\n"); |
|
|
|
priv->d3d9 = (IDirect3D9 *)d3d9ex; |
|
|
|
priv->d3d9device = (IDirect3DDevice9 *)exdev; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, |
|
|
|
AVDictionary *opts, int flags) |
|
|
|
{ |
|
|
|
AVDXVA2DeviceContext *hwctx = ctx->hwctx; |
|
|
|
DXVA2DevicePriv *priv; |
|
|
|
|
|
|
|
pDirect3DCreate9 *createD3D = NULL; |
|
|
|
pCreateDeviceManager9 *createDeviceManager = NULL; |
|
|
|
D3DPRESENT_PARAMETERS d3dpp = {0}; |
|
|
|
D3DDISPLAYMODE d3ddm; |
|
|
|
unsigned resetToken = 0; |
|
|
|
UINT adapter = D3DADAPTER_DEFAULT; |
|
|
|
HRESULT hr; |
|
|
|
int err; |
|
|
|
|
|
|
|
if (device) |
|
|
|
adapter = atoi(device); |
|
|
@@ -448,11 +526,6 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9"); |
|
|
|
if (!createD3D) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(priv->dxva2lib, |
|
|
|
"DXVA2CreateDirect3DDeviceManager9"); |
|
|
|
if (!createDeviceManager) { |
|
|
@@ -460,27 +533,11 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device, |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
priv->d3d9 = createD3D(D3D_SDK_VERSION); |
|
|
|
if (!priv->d3d9) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to create IDirect3D object\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
} |
|
|
|
|
|
|
|
IDirect3D9_GetAdapterDisplayMode(priv->d3d9, adapter, &d3ddm); |
|
|
|
d3dpp.Windowed = TRUE; |
|
|
|
d3dpp.BackBufferWidth = 640; |
|
|
|
d3dpp.BackBufferHeight = 480; |
|
|
|
d3dpp.BackBufferCount = 0; |
|
|
|
d3dpp.BackBufferFormat = d3ddm.Format; |
|
|
|
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; |
|
|
|
d3dpp.Flags = D3DPRESENTFLAG_VIDEO; |
|
|
|
|
|
|
|
hr = IDirect3D9_CreateDevice(priv->d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(), |
|
|
|
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE, |
|
|
|
&d3dpp, &priv->d3d9device); |
|
|
|
if (FAILED(hr)) { |
|
|
|
av_log(ctx, AV_LOG_ERROR, "Failed to create Direct3D device\n"); |
|
|
|
return AVERROR_UNKNOWN; |
|
|
|
if (dxva2_device_create9ex(ctx, adapter) < 0) { |
|
|
|
// Retry with "classic" d3d9 |
|
|
|
err = dxva2_device_create9(ctx, adapter); |
|
|
|
if (err < 0) |
|
|
|
return err; |
|
|
|
} |
|
|
|
|
|
|
|
hr = createDeviceManager(&resetToken, &hwctx->devmgr); |
|
|
|