/* vadxva2.c Copyright (c) 2003-2015 HandBrake Team This file is part of the HandBrake source code Homepage: . It may be used under the terms of the GNU General Public License v2. For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html Authors: Peng Gao Li Cao */ #ifdef USE_HWD #include "vadxva2.h" #include "extras/cl.h" #include "oclnv12toyuv.h" static int hb_va_setup( hb_va_dxva2_t *dxva2, void **hw, int width, int height ); static int hb_va_get( hb_va_dxva2_t *dxva2, AVFrame *frame ); static int hb_d3d_create_device( hb_va_dxva2_t *dxva2 ); static void hb_d3d_destroy_device( hb_va_dxva2_t *dxvva2 ); static int hb_d3d_create_device_manager( hb_va_dxva2_t *dxva2 ); static void hb_d3d_destroy_device_manager( hb_va_dxva2_t *dxva2 ); static int hb_dx_create_video_service( hb_va_dxva2_t *dxva2 ); static void hb_dx_destroy_video_service( hb_va_dxva2_t *dxva2 ); static int hb_dx_find_video_service_conversion( hb_va_dxva2_t *dxva2, GUID *input, D3DFORMAT *output ); static int hb_dx_create_video_decoder( hb_va_dxva2_t *dxva2, int codec_id, const hb_title_t* fmt ); static void hb_dx_create_video_conversion( hb_va_dxva2_t *dxva2 ); static const hb_d3d_format_t *hb_d3d_find_format( D3DFORMAT format ); static const hb_dx_mode_t *hb_dx_find_mode( const GUID *guid ); static void hb_dx_destroy_video_decoder( hb_va_dxva2_t *dxva2 ); /** * It destroys a Direct3D device manager */ static void hb_d3d_destroy_device_manager( hb_va_dxva2_t *dxva2 ) { if( dxva2->devmng ) IDirect3DDeviceManager9_Release( dxva2->devmng ); } /** * It releases a Direct3D device and its resources. */ static void hb_d3d_destroy_device( hb_va_dxva2_t *dxva2 ) { if( dxva2->d3ddev ) IDirect3DDevice9_Release( dxva2->d3ddev ); if( dxva2->d3dobj ) IDirect3D9_Release( dxva2->d3dobj ); } /** * It destroys a DirectX video service */ static void hb_dx_destroy_video_service( hb_va_dxva2_t *dxva2 ) { if( dxva2->device ) IDirect3DDeviceManager9_CloseDeviceHandle( dxva2->devmng, dxva2->device ); if( dxva2->vs ) IDirectXVideoDecoderService_Release( dxva2->vs ); } static const hb_d3d_format_t *hb_d3d_find_format( D3DFORMAT format ) { unsigned i; for( i = 0; d3d_formats[i].name; i++ ) { if( d3d_formats[i].format == format ) return &d3d_formats[i]; } return NULL; } static void hb_dx_create_video_conversion( hb_va_dxva2_t *dxva2 ) { switch( dxva2->render ) { case MAKEFOURCC( 'N', 'V', '1', '2' ): dxva2->output = MAKEFOURCC( 'Y', 'V', '1', '2' ); break; default: dxva2->output = dxva2->render; break; } } void hb_va_release( hb_va_dxva2_t *dxva2, AVFrame *frame ) { LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3]; unsigned i; for( i = 0; i < dxva2->surface_count; i++ ) { hb_va_surface_t *surface = &dxva2->surface[i]; if( surface->d3d == d3d ) surface->refcount--; } } void hb_va_close( hb_va_dxva2_t *dxva2 ) { hb_dx_destroy_video_decoder( dxva2 ); hb_dx_destroy_video_service( dxva2 ); hb_d3d_destroy_device_manager( dxva2 ); hb_d3d_destroy_device( dxva2 ); if( dxva2->hdxva2_dll ) FreeLibrary( dxva2->hdxva2_dll ); if( dxva2->hd3d9_dll ) FreeLibrary( dxva2->hd3d9_dll ); if ( dxva2->nv12toyuv_tmp_in ) free( dxva2->nv12toyuv_tmp_in ); if ( dxva2->nv12toyuv_tmp_out ) free( dxva2->nv12toyuv_tmp_out ); dxva2->description = NULL; free( dxva2 ); } /** * It creates a DXVA2 decoder using the given video format */ static int hb_dx_create_video_decoder( hb_va_dxva2_t *dxva2, int codec_id, const hb_title_t* fmt ) { int surface_alignment; dxva2->width = fmt->geometry.width; dxva2->height = fmt->geometry.height; switch( codec_id ) { case AV_CODEC_ID_H264: dxva2->surface_count = 16 + 1; surface_alignment = 16; break; case AV_CODEC_ID_HEVC: dxva2->surface_count = 16 + 1; surface_alignment = 128; break; case AV_CODEC_ID_MPEG2VIDEO: dxva2->surface_count = 2 + 1; surface_alignment = 32; break; default: dxva2->surface_count = 2 + 1; surface_alignment = 16; break; } dxva2->surface_width = HB_ALIGN(fmt->geometry.width, surface_alignment); dxva2->surface_height = HB_ALIGN(fmt->geometry.height, surface_alignment); LPDIRECT3DSURFACE9 surface_list[VA_DXVA2_MAX_SURFACE_COUNT]; if( FAILED( IDirectXVideoDecoderService_CreateSurface( dxva2->vs, dxva2->surface_width, dxva2->surface_height, dxva2->surface_count - 1, dxva2->render, D3DPOOL_DEFAULT, 0, DXVA2_VideoDecoderRenderTarget, surface_list, NULL ))) { hb_log( "dxva2:IDirectXVideoAccelerationService_CreateSurface failed" ); dxva2->surface_count = 0; return HB_WORK_ERROR; } unsigned i; for( i = 0; isurface_count; i++ ) { hb_va_surface_t *surface = &dxva2->surface[i]; surface->d3d = surface_list[i]; surface->refcount = 0; surface->order = 0; } hb_log( "dxva2:CreateSurface succeed with %d, fmt (%dx%d) surfaces (%dx%d)", dxva2->surface_count, fmt->geometry.width, fmt->geometry.height, dxva2->surface_width, dxva2->surface_height ); DXVA2_VideoDesc dsc; memset( &dsc, 0, sizeof(dsc)); dsc.SampleWidth = fmt->geometry.width; dsc.SampleHeight = fmt->geometry.height; dsc.Format = dxva2->render; if( fmt->vrate.num > 0 && fmt->vrate.den > 0 ) { dsc.InputSampleFreq.Numerator = fmt->vrate.num; dsc.InputSampleFreq.Denominator = fmt->vrate.den; } else { dsc.InputSampleFreq.Numerator = 0; dsc.InputSampleFreq.Denominator = 0; } dsc.OutputFrameFreq = dsc.InputSampleFreq; dsc.UABProtectionLevel = FALSE; dsc.Reserved = 0; /* FIXME I am unsure we can let unknown everywhere */ DXVA2_ExtendedFormat *ext = &dsc.SampleFormat; ext->SampleFormat = 0; //DXVA2_SampleUnknown; ext->VideoChromaSubsampling = 0; //DXVA2_VideoChromaSubsampling_Unknown; ext->NominalRange = 0; //DXVA2_NominalRange_Unknown; ext->VideoTransferMatrix = 0; //DXVA2_VideoTransferMatrix_Unknown; ext->VideoLighting = 0; //DXVA2_VideoLighting_Unknown; ext->VideoPrimaries = 0; //DXVA2_VideoPrimaries_Unknown; ext->VideoTransferFunction = 0; //DXVA2_VideoTransFunc_Unknown; /* List all configurations available for the decoder */ UINT cfg_count = 0; DXVA2_ConfigPictureDecode *cfg_list = NULL; if( FAILED( IDirectXVideoDecoderService_GetDecoderConfigurations( dxva2->vs, &dxva2->input, &dsc, NULL, &cfg_count, &cfg_list ))) { hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderConfigurations failed" ); return HB_WORK_ERROR; } hb_log( "dxva2:we got %d decoder configurations", cfg_count ); /* Select the best decoder configuration */ int cfg_score = 0; for( i = 0; i < cfg_count; i++ ) { const DXVA2_ConfigPictureDecode *cfg = &cfg_list[i]; hb_log( "dxva2:configuration[%d] ConfigBitstreamRaw %d", i, cfg->ConfigBitstreamRaw ); int score; if( cfg->ConfigBitstreamRaw == 1 ) score = 1; else if( codec_id == AV_CODEC_ID_H264 && cfg->ConfigBitstreamRaw == 2 ) score = 2; else continue; if( IsEqualGUID( &cfg->guidConfigBitstreamEncryption, &DXVA_NoEncrypt )) score += 16; if( cfg_score < score ) { dxva2->cfg = *cfg; cfg_score = score; } } //my_release(cfg_list); if( cfg_score <= 0 ) { hb_log( "dxva2:Failed to find a supported decoder configuration" ); return HB_WORK_ERROR; } /* Create the decoder */ IDirectXVideoDecoder *decoder; if( FAILED( IDirectXVideoDecoderService_CreateVideoDecoder( dxva2->vs, &dxva2->input, &dsc, &dxva2->cfg, surface_list, dxva2->surface_count, &decoder ))) { hb_log( "dxva2:IDirectXVideoDecoderService_CreateVideoDecoder failed" ); return HB_WORK_ERROR; } dxva2->decoder = decoder; hb_log( "dxva2:IDirectXVideoDecoderService_CreateVideoDecoder succeed" ); return HB_WORK_OK; } typedef HWND (WINAPI *PROCGETSHELLWND)(); /** * It creates a DirectX video service */ static int hb_d3d_create_device( hb_va_dxva2_t *dxva2 ) { LPDIRECT3D9 (WINAPI *Create9)( UINT SDKVersion ); Create9 = (void*)GetProcAddress( dxva2->hd3d9_dll, TEXT( "Direct3DCreate9" )); if( !Create9 ) { hb_log( "dxva2:Cannot locate reference to Direct3DCreate9 ABI in DLL" ); return HB_WORK_ERROR; } LPDIRECT3D9 d3dobj; d3dobj = Create9( D3D_SDK_VERSION ); if( !d3dobj ) { hb_log( "dxva2:Direct3DCreate9 failed" ); return HB_WORK_ERROR; } dxva2->d3dobj = d3dobj; D3DADAPTER_IDENTIFIER9 *d3dai = &dxva2->d3dai; if( FAILED( IDirect3D9_GetAdapterIdentifier( dxva2->d3dobj, D3DADAPTER_DEFAULT, 0, d3dai ))) { hb_log( "dxva2:IDirect3D9_GetAdapterIdentifier failed" ); memset( d3dai, 0, sizeof(*d3dai)); } PROCGETSHELLWND GetShellWindow; HMODULE hUser32 = GetModuleHandle( "user32" ); GetShellWindow = (PROCGETSHELLWND) GetProcAddress( hUser32, "GetShellWindow" ); D3DPRESENT_PARAMETERS *d3dpp = &dxva2->d3dpp; memset( d3dpp, 0, sizeof(*d3dpp)); d3dpp->Flags = D3DPRESENTFLAG_VIDEO; d3dpp->Windowed = TRUE; d3dpp->hDeviceWindow = NULL; d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; d3dpp->BackBufferCount = 0; /* FIXME what to put here */ d3dpp->BackBufferFormat = D3DFMT_X8R8G8B8; /* FIXME what to put here */ d3dpp->BackBufferWidth = 0; d3dpp->BackBufferHeight = 0; d3dpp->EnableAutoDepthStencil = FALSE; LPDIRECT3DDEVICE9 d3ddev; //if (FAILED(IDirect3D9_CreateDevice(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetShellWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, d3dpp, &d3ddev))) if( FAILED( IDirect3D9_CreateDevice( d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetShellWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, d3dpp, &d3ddev ))) { hb_log( "dxva2:IDirect3D9_CreateDevice failed" ); return HB_WORK_ERROR; } dxva2->d3ddev = d3ddev; return HB_WORK_OK; } /** * It creates a Direct3D device manager */ static int hb_d3d_create_device_manager( hb_va_dxva2_t *dxva2 ) { HRESULT(WINAPI *CreateDeviceManager9)( UINT *pResetToken, IDirect3DDeviceManager9 ** ); CreateDeviceManager9 = (void*)GetProcAddress( dxva2->hdxva2_dll, TEXT( "DXVA2CreateDirect3DDeviceManager9" )); if( !CreateDeviceManager9 ) { hb_log( "dxva2:cannot load function" ); return HB_WORK_ERROR; } UINT token; IDirect3DDeviceManager9 *devmng; if( FAILED( CreateDeviceManager9( &token, &devmng ))) { hb_log( "dxva2:OurDirect3DCreateDeviceManager9 failed" ); return HB_WORK_ERROR; } dxva2->token = token; dxva2->devmng = devmng; long hr = IDirect3DDeviceManager9_ResetDevice( devmng, dxva2->d3ddev, token ); if( FAILED( hr )) { hb_log( "dxva2:IDirect3DDeviceManager9_ResetDevice failed: %08x", (unsigned)hr ); return HB_WORK_ERROR; } return HB_WORK_OK; } /** * It creates a DirectX video service */ static int hb_dx_create_video_service( hb_va_dxva2_t *dxva2 ) { HRESULT (WINAPI *CreateVideoService)( IDirect3DDevice9 *, REFIID riid, void **ppService ); CreateVideoService = (void*)GetProcAddress( dxva2->hdxva2_dll, TEXT( "DXVA2CreateVideoService" )); if( !CreateVideoService ) { hb_log( "dxva2:cannot load function" ); return HB_WORK_ERROR; } HRESULT hr; HANDLE device; hr = IDirect3DDeviceManager9_OpenDeviceHandle( dxva2->devmng, &device ); if( FAILED( hr )) { hb_log( "dxva2:OpenDeviceHandle failed" ); return HB_WORK_ERROR; } dxva2->device = device; IDirectXVideoDecoderService *vs; hr = IDirect3DDeviceManager9_GetVideoService( dxva2->devmng, device, &IID_IDirectXVideoDecoderService, (void*)&vs ); if( FAILED( hr )) { hb_log( "dxva2:GetVideoService failed" ); return HB_WORK_ERROR; } dxva2->vs = vs; return HB_WORK_OK; } /** * Find the best suited decoder mode GUID and render format. */ static int hb_dx_find_video_service_conversion( hb_va_dxva2_t *dxva2, GUID *input, D3DFORMAT *output ) { unsigned int input_count = 0; GUID *input_list = NULL; if( FAILED( IDirectXVideoDecoderService_GetDecoderDeviceGuids( dxva2->vs, &input_count, &input_list ))) { hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderDeviceGuids failed" ); return HB_WORK_ERROR; } unsigned i, j; for( i = 0; i < input_count; i++ ) { const GUID *g = &input_list[i]; const hb_dx_mode_t *mode = hb_dx_find_mode( g ); } for( i = 0; dxva2_modes[i].name; i++ ) { const hb_dx_mode_t *mode = &dxva2_modes[i]; if( !mode->codec || mode->codec != dxva2->codec_id ) continue; int is_suported = 0; const GUID *g; for( g = &input_list[0]; !is_suported && g < &input_list[input_count]; g++ ) { is_suported = IsEqualGUID( mode->guid, g ); } if( !is_suported ) continue; unsigned int output_count = 0; D3DFORMAT *output_list = NULL; if( FAILED( IDirectXVideoDecoderService_GetDecoderRenderTargets( dxva2->vs, mode->guid, &output_count, &output_list ))) { hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderRenderTargets failed" ); continue; } for( j = 0; j < output_count; j++ ) { const D3DFORMAT f = output_list[j]; const hb_d3d_format_t *format = hb_d3d_find_format( f ); if( format ) { //hb_log( "dxva2:%s is supported for output", format->name ); } else { hb_log( "dxvar2:%d is supported for output (%4.4s)", f, (const char*)&f ); } } for( j = 0; d3d_formats[j].name; j++ ) { const hb_d3d_format_t *format = &d3d_formats[j]; int is_suported = 0; unsigned k; for( k = 0; !is_suported && k < output_count; k++ ) { is_suported = format->format == output_list[k]; } if( !is_suported ) continue; *input = *mode->guid; *output = format->format; return HB_WORK_OK; } } return HB_WORK_ERROR; } static const hb_dx_mode_t *hb_dx_find_mode( const GUID *guid ) { unsigned i; for( i = 0; dxva2_modes[i].name; i++ ) { if( IsEqualGUID( dxva2_modes[i].guid, guid )) return &dxva2_modes[i]; } return NULL; } static void hb_dx_destroy_video_decoder( hb_va_dxva2_t *dxva2 ) { if( dxva2->decoder ) IDirectXVideoDecoder_Release( dxva2->decoder ); dxva2->decoder = NULL; unsigned i; for( i = 0; isurface_count; i++ ) IDirect3DSurface9_Release( dxva2->surface[i].d3d ); dxva2->surface_count = 0; } /** * setup dxva2 */ static int hb_va_setup( hb_va_dxva2_t *dxva2, void **hw, int width, int height ) { if( dxva2->width == width && dxva2->height == height && dxva2->decoder ) goto ok; hb_dx_destroy_video_decoder( dxva2 ); *hw = NULL; dxva2->i_chroma = 0; if( width <= 0 || height <= 0 ) return HB_WORK_ERROR; hb_title_t fmt; memset( &fmt, 0, sizeof(fmt)); fmt.geometry.width = width; fmt.geometry.height = height; if( hb_dx_create_video_decoder( dxva2, dxva2->codec_id, &fmt ) == HB_WORK_ERROR ) return HB_WORK_ERROR; dxva2->hw.decoder = dxva2->decoder; dxva2->hw.cfg = &dxva2->cfg; dxva2->hw.surface_count = dxva2->surface_count; dxva2->hw.surface = dxva2->hw_surface; unsigned i; for( i = 0; i < dxva2->surface_count; i++ ) dxva2->hw.surface[i] = dxva2->surface[i].d3d; hb_dx_create_video_conversion( dxva2 ); ok: *hw = &dxva2->hw; const hb_d3d_format_t *output = hb_d3d_find_format( dxva2->output ); dxva2->i_chroma = output->codec; return HB_WORK_OK; } static int hb_va_get( hb_va_dxva2_t *dxva2, AVFrame *frame ) { unsigned i, old; for( i = 0, old = 0; i < dxva2->surface_count; i++ ) { hb_va_surface_t *surface = &dxva2->surface[i]; if( !surface->refcount ) break; if( surface->order < dxva2->surface[old].order ) old = i; } if( i >= dxva2->surface_count ) i = old; hb_va_surface_t *surface = &dxva2->surface[i]; surface->refcount = 1; surface->order = dxva2->surface_order++; for( i = 0; i < 4; i++ ) { frame->data[i] = NULL; frame->linesize[i] = 0; if( i == 0 || i == 3 ) frame->data[i] = (void*)surface->d3d; } return HB_WORK_OK; } /** * nv12 to yuv of c reference */ static void hb_copy_from_nv12( uint8_t *dst, uint8_t *src[2], size_t src_pitch[2], unsigned width, unsigned height ) { unsigned int i, j; uint8_t *dstU, *dstV; dstU = dst + width*height; dstV = dstU + width*height/4; unsigned int heithtUV, widthUV; heithtUV = height/2; widthUV = width/2; for( i = 0; i < height; i++ ) //Y { memcpy( dst + i * width, src[0] + i * src_pitch[0], width ); } for( i = 0; i < heithtUV; i++ ) { for( j = 0; j < widthUV; j++ ) { dstU[i * widthUV + j] = *(src[1] + i * src_pitch[1] + 2 * j); dstV[i *widthUV + j] = *(src[1] + i * src_pitch[1] + 2 * j + 1); } } } /** * lock frame data form surface. * nv12 to yuv with opencl and with C reference * scale with opencl */ int hb_va_extract( hb_va_dxva2_t *dxva2, uint8_t *dst, AVFrame *frame, int job_w, int job_h, int *crop, hb_oclscale_t *os, int use_opencl, int use_decomb, int use_detelecine ) { LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3]; D3DLOCKED_RECT lock; if( FAILED( IDirect3DSurface9_LockRect( d3d, &lock, NULL, D3DLOCK_READONLY ))) { hb_log( "dxva2:Failed to lock surface" ); return HB_WORK_ERROR; } if( dxva2->render == MAKEFOURCC( 'N', 'V', '1', '2' )) { uint8_t *plane[2] = { lock.pBits, (uint8_t*)lock.pBits + lock.Pitch * dxva2->surface_height }; size_t pitch[2] = { lock.Pitch, lock.Pitch, }; hb_copy_from_nv12( dst, plane, pitch, dxva2->width, dxva2->height ); } IDirect3DSurface9_UnlockRect( d3d ); return HB_WORK_OK; } /** * create dxva2 service * load library D3D9.dll */ hb_va_dxva2_t * hb_va_create_dxva2( hb_va_dxva2_t *dxva2, int codec_id ) { if( dxva2 ) { hb_va_close( dxva2 ); dxva2 = NULL; } hb_va_dxva2_t *dxva = calloc( 1, sizeof(*dxva) ); if( !dxva ) return NULL; dxva->codec_id = codec_id; dxva->hd3d9_dll = LoadLibrary( TEXT( "D3D9.DLL" ) ); if( !dxva->hd3d9_dll ) { hb_log( "dxva2:cannot load d3d9.dll" ); goto error; } dxva->hdxva2_dll = LoadLibrary( TEXT( "DXVA2.DLL" ) ); if( !dxva->hdxva2_dll ) { hb_log( "dxva2:cannot load DXVA2.dll" ); goto error; } if( hb_d3d_create_device( dxva ) == HB_WORK_ERROR ) { hb_log( "dxva2:Failed to create Direct3D device" ); goto error; } if( hb_d3d_create_device_manager( dxva ) == HB_WORK_ERROR ) { hb_log( "dxva2:D3dCreateDeviceManager failed" ); goto error; } if( hb_dx_create_video_service( dxva ) == HB_WORK_ERROR ) { hb_log( "dxva2:DxCreateVideoService failed" ); goto error; } if( hb_dx_find_video_service_conversion( dxva, &dxva->input, &dxva->render ) == HB_WORK_ERROR ) { hb_log( "dxva2:DxFindVideoServiceConversion failed" ); goto error; } dxva->do_job = HB_WORK_OK; dxva->description = "DXVA2"; return dxva; error: hb_va_close( dxva ); return NULL; } void hb_va_new_dxva2( hb_va_dxva2_t *dxva2, AVCodecContext *p_context ) { if( p_context->width > 0 && p_context->height > 0 ) { if( hb_va_setup( dxva2, &p_context->hwaccel_context, p_context->width, p_context->height ) == HB_WORK_ERROR ) { hb_log( "dxva2:hb_va_Setup failed" ); hb_va_close( dxva2 ); dxva2 = NULL; } } if( dxva2 ) { dxva2->input_pts[0] = 0; dxva2->input_pts[1] = 0; if( dxva2->description ) hb_log( "dxva2:Using %s for hardware decoding", dxva2->description ); p_context->draw_horiz_band = NULL; } } char* hb_get_pix_fmt_name( int pix_fmt ) { static const char *ppsz_name[AV_PIX_FMT_NB] = { [AV_PIX_FMT_VDPAU_H264] = "AV_PIX_FMT_VDPAU_H264", [AV_PIX_FMT_VAAPI_IDCT] = "AV_PIX_FMT_VAAPI_IDCT", [AV_PIX_FMT_VAAPI_VLD] = "AV_PIX_FMT_VAAPI_VLD", [AV_PIX_FMT_VAAPI_MOCO] = "AV_PIX_FMT_VAAPI_MOCO", [AV_PIX_FMT_DXVA2_VLD] = "AV_PIX_FMT_DXVA2_VLD", [AV_PIX_FMT_YUYV422] = "AV_PIX_FMT_YUYV422", [AV_PIX_FMT_YUV420P] = "AV_PIX_FMT_YUV420P", }; return ppsz_name[pix_fmt]; } enum PixelFormat hb_ffmpeg_get_format( AVCodecContext *p_context, const enum PixelFormat *pi_fmt ) { int i; for( i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++ ) { hb_log( "dxva2:Available decoder output format %d (%s)", pi_fmt[i], hb_get_pix_fmt_name(pi_fmt[i]) ? : "Unknown" ); if( pi_fmt[i] == AV_PIX_FMT_DXVA2_VLD ) { return pi_fmt[i]; } } return avcodec_default_get_format( p_context, pi_fmt ); } int hb_va_get_frame_buf( hb_va_dxva2_t *dxva2, AVCodecContext *p_context, AVFrame *frame ) { frame->type = FF_BUFFER_TYPE_USER; if( hb_va_get( dxva2, frame ) == HB_WORK_ERROR ) { hb_log( "VaGrabSurface failed" ); return HB_WORK_ERROR; } return HB_WORK_OK; } int hb_check_hwd_fmt( int fmt ) { int result = 1; switch ( fmt ) { case AV_PIX_FMT_YUV420P16LE: case AV_PIX_FMT_YUV420P16BE: case AV_PIX_FMT_YUV422P16LE: case AV_PIX_FMT_YUV422P16BE: case AV_PIX_FMT_YUV444P16LE: case AV_PIX_FMT_YUV444P16BE: case AV_PIX_FMT_YUV420P9BE: case AV_PIX_FMT_YUV420P9LE: case AV_PIX_FMT_YUV420P10BE: case AV_PIX_FMT_YUV420P10LE: case AV_PIX_FMT_YUV422P10BE: case AV_PIX_FMT_YUV422P10LE: case AV_PIX_FMT_YUV444P9BE: case AV_PIX_FMT_YUV444P9LE: case AV_PIX_FMT_YUV444P10BE: case AV_PIX_FMT_YUV444P10LE: case AV_PIX_FMT_YUV422P9BE: case AV_PIX_FMT_YUV422P9LE: case AV_PIX_FMT_GBRP9BE: case AV_PIX_FMT_GBRP9LE: case AV_PIX_FMT_GBRP10BE: case AV_PIX_FMT_GBRP10LE: case AV_PIX_FMT_GBRP16BE: case AV_PIX_FMT_GBRP16LE: case AV_PIX_FMT_YUVA420P9BE: case AV_PIX_FMT_YUVA420P9LE: case AV_PIX_FMT_YUVA422P9BE: case AV_PIX_FMT_YUVA422P9LE: case AV_PIX_FMT_YUVA444P9BE: case AV_PIX_FMT_YUVA444P9LE: case AV_PIX_FMT_YUVA420P10BE: case AV_PIX_FMT_YUVA420P10LE: result = 0; } return result; } #endif // USE_HWD