@ -24,6 +24,10 @@
# if CONFIG_D3D11VA
# include "libavutil/hwcontext_d3d11va.h"
# endif
# if CONFIG_DXVA2
# define COBJMACROS
# include "libavutil/hwcontext_dxva2.h"
# endif
# include "libavutil/mem.h"
# include "libavutil/pixdesc.h"
# include "libavutil/time.h"
@ -50,6 +54,9 @@ const enum AVPixelFormat ff_amf_pix_fmts[] = {
AV_PIX_FMT_YUV420P ,
# if CONFIG_D3D11VA
AV_PIX_FMT_D3D11 ,
# endif
# if CONFIG_DXVA2
AV_PIX_FMT_DXVA2_VLD ,
# endif
AV_PIX_FMT_NONE
} ;
@ -162,6 +169,52 @@ static int amf_init_from_d3d11_device(AVCodecContext *avctx, AVD3D11VADeviceCont
}
# endif
# if CONFIG_DXVA2
static int amf_init_from_dxva2_device ( AVCodecContext * avctx , AVDXVA2DeviceContext * hwctx )
{
AmfContext * ctx = avctx - > priv_data ;
HANDLE device_handle ;
IDirect3DDevice9 * device ;
HRESULT hr ;
AMF_RESULT res ;
int ret ;
hr = IDirect3DDeviceManager9_OpenDeviceHandle ( hwctx - > devmgr , & device_handle ) ;
if ( FAILED ( hr ) ) {
av_log ( avctx , AV_LOG_ERROR , " Failed to open device handle for Direct3D9 device: %lx. \n " , ( unsigned long ) hr ) ;
return AVERROR_EXTERNAL ;
}
hr = IDirect3DDeviceManager9_LockDevice ( hwctx - > devmgr , device_handle , & device , FALSE ) ;
if ( SUCCEEDED ( hr ) ) {
IDirect3DDeviceManager9_UnlockDevice ( hwctx - > devmgr , device_handle , FALSE ) ;
ret = 0 ;
} else {
av_log ( avctx , AV_LOG_ERROR , " Failed to lock device handle for Direct3D9 device: %lx. \n " , ( unsigned long ) hr ) ;
ret = AVERROR_EXTERNAL ;
}
IDirect3DDeviceManager9_CloseDeviceHandle ( hwctx - > devmgr , device_handle ) ;
if ( ret < 0 )
return ret ;
res = ctx - > context - > pVtbl - > InitDX9 ( ctx - > context , device ) ;
IDirect3DDevice9_Release ( device ) ;
if ( res ! = AMF_OK ) {
if ( res = = AMF_NOT_SUPPORTED )
av_log ( avctx , AV_LOG_ERROR , " AMF via D3D9 is not supported on the given device. \n " ) ;
else
av_log ( avctx , AV_LOG_ERROR , " AMF failed to initialise on given D3D9 device: %d. \n " , res ) ;
return AVERROR ( ENODEV ) ;
}
return 0 ;
}
# endif
static int amf_init_context ( AVCodecContext * avctx )
{
AmfContext * ctx = avctx - > priv_data ;
@ -205,6 +258,13 @@ static int amf_init_context(AVCodecContext *avctx)
if ( ret < 0 )
return ret ;
break ;
# endif
# if CONFIG_DXVA2
case AV_HWDEVICE_TYPE_DXVA2 :
ret = amf_init_from_dxva2_device ( avctx , frames_ctx - > device_ctx - > hwctx ) ;
if ( ret < 0 )
return ret ;
break ;
# endif
default :
av_log ( avctx , AV_LOG_ERROR , " AMF initialisation from a %s frames context is not supported. \n " ,
@ -229,6 +289,13 @@ static int amf_init_context(AVCodecContext *avctx)
if ( ret < 0 )
return ret ;
break ;
# endif
# if CONFIG_DXVA2
case AV_HWDEVICE_TYPE_DXVA2 :
ret = amf_init_from_dxva2_device ( avctx , device_ctx - > hwctx ) ;
if ( ret < 0 )
return ret ;
break ;
# endif
default :
av_log ( avctx , AV_LOG_ERROR , " AMF initialisation from a %s device is not supported. \n " ,
@ -580,6 +647,18 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame)
hw_surface = 1 ;
}
break ;
# endif
# if CONFIG_DXVA2
case AV_PIX_FMT_DXVA2_VLD :
{
IDirect3DSurface9 * texture = ( IDirect3DSurface9 * ) frame - > data [ 3 ] ; // actual texture
res = ctx - > context - > pVtbl - > CreateSurfaceFromDX9Native ( ctx - > context , texture , & surface , NULL ) ; // wrap to AMF surface
AMF_RETURN_IF_FALSE ( ctx , res = = AMF_OK , AVERROR ( ENOMEM ) , " CreateSurfaceFromDX9Native() failed with error %d \n " , res ) ;
hw_surface = 1 ;
}
break ;
# endif
default :
{