@ -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 ) ;