WinGui: Fix another instance of the Caliburn vs Json.net sillyness where objects...
[HandBrake.git] / libhb / vadxva2.c
blob1d74856e2349308aed2a396719c7b1fc9ee34c4b
1 /* vadxva2.c
3 Copyright (c) 2003-2015 HandBrake Team
4 This file is part of the HandBrake source code
5 Homepage: <http://handbrake.fr/>.
6 It may be used under the terms of the GNU General Public License v2.
7 For full terms see the file COPYING file or visit http://www.gnu.org/licenses/gpl-2.0.html
9 Authors: Peng Gao <peng@multicorewareinc.com> <http://www.multicorewareinc.com/>
10 Li Cao <li@multicorewareinc.com> <http://www.multicorewareinc.com/>
14 #ifdef USE_HWD
16 #include "vadxva2.h"
17 #include "extras/cl.h"
18 #include "oclnv12toyuv.h"
20 static int hb_va_setup( hb_va_dxva2_t *dxva2, void **hw, int width, int height );
21 static int hb_va_get( hb_va_dxva2_t *dxva2, AVFrame *frame );
22 static int hb_d3d_create_device( hb_va_dxva2_t *dxva2 );
23 static void hb_d3d_destroy_device( hb_va_dxva2_t *dxvva2 );
24 static int hb_d3d_create_device_manager( hb_va_dxva2_t *dxva2 );
25 static void hb_d3d_destroy_device_manager( hb_va_dxva2_t *dxva2 );
26 static int hb_dx_create_video_service( hb_va_dxva2_t *dxva2 );
27 static void hb_dx_destroy_video_service( hb_va_dxva2_t *dxva2 );
28 static int hb_dx_find_video_service_conversion( hb_va_dxva2_t *dxva2, GUID *input, D3DFORMAT *output );
29 static int hb_dx_create_video_decoder( hb_va_dxva2_t *dxva2, int codec_id, const hb_title_t* fmt );
30 static void hb_dx_create_video_conversion( hb_va_dxva2_t *dxva2 );
31 static const hb_d3d_format_t *hb_d3d_find_format( D3DFORMAT format );
32 static const hb_dx_mode_t *hb_dx_find_mode( const GUID *guid );
33 static void hb_dx_destroy_video_decoder( hb_va_dxva2_t *dxva2 );
34 /**
35 * It destroys a Direct3D device manager
37 static void hb_d3d_destroy_device_manager( hb_va_dxva2_t *dxva2 )
39 if( dxva2->devmng )
40 IDirect3DDeviceManager9_Release( dxva2->devmng );
42 /**
43 * It releases a Direct3D device and its resources.
45 static void hb_d3d_destroy_device( hb_va_dxva2_t *dxva2 )
47 if( dxva2->d3ddev )
48 IDirect3DDevice9_Release( dxva2->d3ddev );
49 if( dxva2->d3dobj )
50 IDirect3D9_Release( dxva2->d3dobj );
52 /**
53 * It destroys a DirectX video service
55 static void hb_dx_destroy_video_service( hb_va_dxva2_t *dxva2 )
57 if( dxva2->device )
58 IDirect3DDeviceManager9_CloseDeviceHandle( dxva2->devmng, dxva2->device );
60 if( dxva2->vs )
61 IDirectXVideoDecoderService_Release( dxva2->vs );
64 static const hb_d3d_format_t *hb_d3d_find_format( D3DFORMAT format )
66 unsigned i;
67 for( i = 0; d3d_formats[i].name; i++ )
69 if( d3d_formats[i].format == format )
70 return &d3d_formats[i];
72 return NULL;
75 static void hb_dx_create_video_conversion( hb_va_dxva2_t *dxva2 )
77 switch( dxva2->render )
79 case MAKEFOURCC( 'N', 'V', '1', '2' ):
80 dxva2->output = MAKEFOURCC( 'Y', 'V', '1', '2' );
81 break;
82 default:
83 dxva2->output = dxva2->render;
84 break;
88 void hb_va_release( hb_va_dxva2_t *dxva2, AVFrame *frame )
90 LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3];
91 unsigned i;
92 for( i = 0; i < dxva2->surface_count; i++ )
94 hb_va_surface_t *surface = &dxva2->surface[i];
95 if( surface->d3d == d3d )
96 surface->refcount--;
101 void hb_va_close( hb_va_dxva2_t *dxva2 )
103 hb_dx_destroy_video_decoder( dxva2 );
104 hb_dx_destroy_video_service( dxva2 );
105 hb_d3d_destroy_device_manager( dxva2 );
106 hb_d3d_destroy_device( dxva2 );
108 if( dxva2->hdxva2_dll )
109 FreeLibrary( dxva2->hdxva2_dll );
110 if( dxva2->hd3d9_dll )
111 FreeLibrary( dxva2->hd3d9_dll );
113 if ( dxva2->nv12toyuv_tmp_in )
114 free( dxva2->nv12toyuv_tmp_in );
115 if ( dxva2->nv12toyuv_tmp_out )
116 free( dxva2->nv12toyuv_tmp_out );
118 dxva2->description = NULL;
119 free( dxva2 );
123 * It creates a DXVA2 decoder using the given video format
125 static int hb_dx_create_video_decoder( hb_va_dxva2_t *dxva2, int codec_id, const hb_title_t* fmt )
127 int surface_alignment;
128 dxva2->width = fmt->geometry.width;
129 dxva2->height = fmt->geometry.height;
131 switch( codec_id )
133 case AV_CODEC_ID_H264:
134 dxva2->surface_count = 16 + 1;
135 surface_alignment = 16;
136 break;
137 case AV_CODEC_ID_HEVC:
138 dxva2->surface_count = 16 + 1;
139 surface_alignment = 128;
140 break;
141 case AV_CODEC_ID_MPEG2VIDEO:
142 dxva2->surface_count = 2 + 1;
143 surface_alignment = 32;
144 break;
145 default:
146 dxva2->surface_count = 2 + 1;
147 surface_alignment = 16;
148 break;
151 dxva2->surface_width = HB_ALIGN(fmt->geometry.width, surface_alignment);
152 dxva2->surface_height = HB_ALIGN(fmt->geometry.height, surface_alignment);
154 LPDIRECT3DSURFACE9 surface_list[VA_DXVA2_MAX_SURFACE_COUNT];
155 if( FAILED( IDirectXVideoDecoderService_CreateSurface( dxva2->vs,
156 dxva2->surface_width,
157 dxva2->surface_height,
158 dxva2->surface_count - 1,
159 dxva2->render,
160 D3DPOOL_DEFAULT,
162 DXVA2_VideoDecoderRenderTarget,
163 surface_list, NULL )))
165 hb_log( "dxva2:IDirectXVideoAccelerationService_CreateSurface failed" );
166 dxva2->surface_count = 0;
167 return HB_WORK_ERROR;
170 unsigned i;
171 for( i = 0; i<dxva2->surface_count; i++ )
173 hb_va_surface_t *surface = &dxva2->surface[i];
174 surface->d3d = surface_list[i];
175 surface->refcount = 0;
176 surface->order = 0;
178 hb_log( "dxva2:CreateSurface succeed with %d, fmt (%dx%d) surfaces (%dx%d)", dxva2->surface_count,
179 fmt->geometry.width, fmt->geometry.height, dxva2->surface_width, dxva2->surface_height );
180 DXVA2_VideoDesc dsc;
181 memset( &dsc, 0, sizeof(dsc));
182 dsc.SampleWidth = fmt->geometry.width;
183 dsc.SampleHeight = fmt->geometry.height;
184 dsc.Format = dxva2->render;
186 if( fmt->vrate.num > 0 && fmt->vrate.den > 0 )
188 dsc.InputSampleFreq.Numerator = fmt->vrate.num;
189 dsc.InputSampleFreq.Denominator = fmt->vrate.den;
191 else
193 dsc.InputSampleFreq.Numerator = 0;
194 dsc.InputSampleFreq.Denominator = 0;
197 dsc.OutputFrameFreq = dsc.InputSampleFreq;
198 dsc.UABProtectionLevel = FALSE;
199 dsc.Reserved = 0;
201 /* FIXME I am unsure we can let unknown everywhere */
202 DXVA2_ExtendedFormat *ext = &dsc.SampleFormat;
203 ext->SampleFormat = 0; //DXVA2_SampleUnknown;
204 ext->VideoChromaSubsampling = 0; //DXVA2_VideoChromaSubsampling_Unknown;
205 ext->NominalRange = 0; //DXVA2_NominalRange_Unknown;
206 ext->VideoTransferMatrix = 0; //DXVA2_VideoTransferMatrix_Unknown;
207 ext->VideoLighting = 0; //DXVA2_VideoLighting_Unknown;
208 ext->VideoPrimaries = 0; //DXVA2_VideoPrimaries_Unknown;
209 ext->VideoTransferFunction = 0; //DXVA2_VideoTransFunc_Unknown;
211 /* List all configurations available for the decoder */
212 UINT cfg_count = 0;
213 DXVA2_ConfigPictureDecode *cfg_list = NULL;
214 if( FAILED( IDirectXVideoDecoderService_GetDecoderConfigurations( dxva2->vs, &dxva2->input, &dsc, NULL, &cfg_count, &cfg_list )))
216 hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderConfigurations failed" );
217 return HB_WORK_ERROR;
219 hb_log( "dxva2:we got %d decoder configurations", cfg_count );
221 /* Select the best decoder configuration */
222 int cfg_score = 0;
223 for( i = 0; i < cfg_count; i++ )
225 const DXVA2_ConfigPictureDecode *cfg = &cfg_list[i];
226 hb_log( "dxva2:configuration[%d] ConfigBitstreamRaw %d", i, cfg->ConfigBitstreamRaw );
227 int score;
228 if( cfg->ConfigBitstreamRaw == 1 )
229 score = 1;
230 else if( codec_id == AV_CODEC_ID_H264 && cfg->ConfigBitstreamRaw == 2 )
231 score = 2;
232 else
233 continue;
234 if( IsEqualGUID( &cfg->guidConfigBitstreamEncryption, &DXVA_NoEncrypt ))
235 score += 16;
236 if( cfg_score < score )
238 dxva2->cfg = *cfg;
239 cfg_score = score;
242 //my_release(cfg_list);
243 if( cfg_score <= 0 )
245 hb_log( "dxva2:Failed to find a supported decoder configuration" );
246 return HB_WORK_ERROR;
249 /* Create the decoder */
250 IDirectXVideoDecoder *decoder;
251 if( FAILED( IDirectXVideoDecoderService_CreateVideoDecoder( dxva2->vs, &dxva2->input, &dsc, &dxva2->cfg, surface_list, dxva2->surface_count, &decoder )))
253 hb_log( "dxva2:IDirectXVideoDecoderService_CreateVideoDecoder failed" );
254 return HB_WORK_ERROR;
256 dxva2->decoder = decoder;
257 hb_log( "dxva2:IDirectXVideoDecoderService_CreateVideoDecoder succeed" );
258 return HB_WORK_OK;
261 typedef HWND (WINAPI *PROCGETSHELLWND)();
263 * It creates a DirectX video service
265 static int hb_d3d_create_device( hb_va_dxva2_t *dxva2 )
267 LPDIRECT3D9 (WINAPI *Create9)( UINT SDKVersion );
268 Create9 = (void*)GetProcAddress( dxva2->hd3d9_dll, TEXT( "Direct3DCreate9" ));
269 if( !Create9 )
271 hb_log( "dxva2:Cannot locate reference to Direct3DCreate9 ABI in DLL" );
272 return HB_WORK_ERROR;
274 LPDIRECT3D9 d3dobj;
275 d3dobj = Create9( D3D_SDK_VERSION );
276 if( !d3dobj )
278 hb_log( "dxva2:Direct3DCreate9 failed" );
279 return HB_WORK_ERROR;
281 dxva2->d3dobj = d3dobj;
282 D3DADAPTER_IDENTIFIER9 *d3dai = &dxva2->d3dai;
283 if( FAILED( IDirect3D9_GetAdapterIdentifier( dxva2->d3dobj, D3DADAPTER_DEFAULT, 0, d3dai )))
285 hb_log( "dxva2:IDirect3D9_GetAdapterIdentifier failed" );
286 memset( d3dai, 0, sizeof(*d3dai));
289 PROCGETSHELLWND GetShellWindow;
290 HMODULE hUser32 = GetModuleHandle( "user32" );
291 GetShellWindow = (PROCGETSHELLWND)
292 GetProcAddress( hUser32, "GetShellWindow" );
294 D3DPRESENT_PARAMETERS *d3dpp = &dxva2->d3dpp;
295 memset( d3dpp, 0, sizeof(*d3dpp));
296 d3dpp->Flags = D3DPRESENTFLAG_VIDEO;
297 d3dpp->Windowed = TRUE;
298 d3dpp->hDeviceWindow = NULL;
299 d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD;
300 d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE;
301 d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;
302 d3dpp->BackBufferCount = 0; /* FIXME what to put here */
303 d3dpp->BackBufferFormat = D3DFMT_X8R8G8B8; /* FIXME what to put here */
304 d3dpp->BackBufferWidth = 0;
305 d3dpp->BackBufferHeight = 0;
306 d3dpp->EnableAutoDepthStencil = FALSE;
308 LPDIRECT3DDEVICE9 d3ddev;
309 //if (FAILED(IDirect3D9_CreateDevice(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetShellWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED, d3dpp, &d3ddev)))
310 if( FAILED( IDirect3D9_CreateDevice( d3dobj,
311 D3DADAPTER_DEFAULT,
312 D3DDEVTYPE_HAL,
313 GetShellWindow(),
314 D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,
315 d3dpp,
316 &d3ddev )))
318 hb_log( "dxva2:IDirect3D9_CreateDevice failed" );
319 return HB_WORK_ERROR;
321 dxva2->d3ddev = d3ddev;
323 return HB_WORK_OK;
326 * It creates a Direct3D device manager
328 static int hb_d3d_create_device_manager( hb_va_dxva2_t *dxva2 )
330 HRESULT(WINAPI *CreateDeviceManager9)( UINT *pResetToken, IDirect3DDeviceManager9 ** );
331 CreateDeviceManager9 = (void*)GetProcAddress( dxva2->hdxva2_dll, TEXT( "DXVA2CreateDirect3DDeviceManager9" ));
333 if( !CreateDeviceManager9 )
335 hb_log( "dxva2:cannot load function" );
336 return HB_WORK_ERROR;
339 UINT token;
340 IDirect3DDeviceManager9 *devmng;
341 if( FAILED( CreateDeviceManager9( &token, &devmng )))
343 hb_log( "dxva2:OurDirect3DCreateDeviceManager9 failed" );
344 return HB_WORK_ERROR;
346 dxva2->token = token;
347 dxva2->devmng = devmng;
349 long hr = IDirect3DDeviceManager9_ResetDevice( devmng, dxva2->d3ddev, token );
350 if( FAILED( hr ))
352 hb_log( "dxva2:IDirect3DDeviceManager9_ResetDevice failed: %08x", (unsigned)hr );
353 return HB_WORK_ERROR;
355 return HB_WORK_OK;
358 * It creates a DirectX video service
360 static int hb_dx_create_video_service( hb_va_dxva2_t *dxva2 )
362 HRESULT (WINAPI *CreateVideoService)( IDirect3DDevice9 *, REFIID riid, void **ppService );
363 CreateVideoService = (void*)GetProcAddress( dxva2->hdxva2_dll, TEXT( "DXVA2CreateVideoService" ));
365 if( !CreateVideoService )
367 hb_log( "dxva2:cannot load function" );
368 return HB_WORK_ERROR;
371 HRESULT hr;
373 HANDLE device;
374 hr = IDirect3DDeviceManager9_OpenDeviceHandle( dxva2->devmng, &device );
375 if( FAILED( hr ))
377 hb_log( "dxva2:OpenDeviceHandle failed" );
378 return HB_WORK_ERROR;
380 dxva2->device = device;
382 IDirectXVideoDecoderService *vs;
383 hr = IDirect3DDeviceManager9_GetVideoService( dxva2->devmng, device, &IID_IDirectXVideoDecoderService, (void*)&vs );
384 if( FAILED( hr ))
386 hb_log( "dxva2:GetVideoService failed" );
387 return HB_WORK_ERROR;
389 dxva2->vs = vs;
391 return HB_WORK_OK;
394 * Find the best suited decoder mode GUID and render format.
396 static int hb_dx_find_video_service_conversion( hb_va_dxva2_t *dxva2, GUID *input, D3DFORMAT *output )
398 unsigned int input_count = 0;
399 GUID *input_list = NULL;
400 if( FAILED( IDirectXVideoDecoderService_GetDecoderDeviceGuids( dxva2->vs, &input_count, &input_list )))
402 hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderDeviceGuids failed" );
403 return HB_WORK_ERROR;
405 unsigned i, j;
406 for( i = 0; i < input_count; i++ )
408 const GUID *g = &input_list[i];
409 const hb_dx_mode_t *mode = hb_dx_find_mode( g );
412 for( i = 0; dxva2_modes[i].name; i++ )
414 const hb_dx_mode_t *mode = &dxva2_modes[i];
415 if( !mode->codec || mode->codec != dxva2->codec_id )
416 continue;
418 int is_suported = 0;
419 const GUID *g;
420 for( g = &input_list[0]; !is_suported && g < &input_list[input_count]; g++ )
422 is_suported = IsEqualGUID( mode->guid, g );
424 if( !is_suported )
425 continue;
427 unsigned int output_count = 0;
428 D3DFORMAT *output_list = NULL;
429 if( FAILED( IDirectXVideoDecoderService_GetDecoderRenderTargets( dxva2->vs, mode->guid, &output_count, &output_list )))
431 hb_log( "dxva2:IDirectXVideoDecoderService_GetDecoderRenderTargets failed" );
432 continue;
434 for( j = 0; j < output_count; j++ )
436 const D3DFORMAT f = output_list[j];
437 const hb_d3d_format_t *format = hb_d3d_find_format( f );
438 if( format )
440 //hb_log( "dxva2:%s is supported for output", format->name );
442 else
444 hb_log( "dxvar2:%d is supported for output (%4.4s)", f, (const char*)&f );
448 for( j = 0; d3d_formats[j].name; j++ )
450 const hb_d3d_format_t *format = &d3d_formats[j];
451 int is_suported = 0;
452 unsigned k;
453 for( k = 0; !is_suported && k < output_count; k++ )
455 is_suported = format->format == output_list[k];
457 if( !is_suported )
458 continue;
459 *input = *mode->guid;
460 *output = format->format;
461 return HB_WORK_OK;
464 return HB_WORK_ERROR;
466 static const hb_dx_mode_t *hb_dx_find_mode( const GUID *guid )
468 unsigned i;
469 for( i = 0; dxva2_modes[i].name; i++ )
471 if( IsEqualGUID( dxva2_modes[i].guid, guid ))
472 return &dxva2_modes[i];
474 return NULL;
478 static void hb_dx_destroy_video_decoder( hb_va_dxva2_t *dxva2 )
480 if( dxva2->decoder )
481 IDirectXVideoDecoder_Release( dxva2->decoder );
482 dxva2->decoder = NULL;
484 unsigned i;
485 for( i = 0; i<dxva2->surface_count; i++ )
486 IDirect3DSurface9_Release( dxva2->surface[i].d3d );
487 dxva2->surface_count = 0;
490 * setup dxva2
492 static int hb_va_setup( hb_va_dxva2_t *dxva2, void **hw, int width, int height )
494 if( dxva2->width == width && dxva2->height == height && dxva2->decoder )
495 goto ok;
497 hb_dx_destroy_video_decoder( dxva2 );
498 *hw = NULL;
499 dxva2->i_chroma = 0;
501 if( width <= 0 || height <= 0 )
502 return HB_WORK_ERROR;
504 hb_title_t fmt;
505 memset( &fmt, 0, sizeof(fmt));
506 fmt.geometry.width = width;
507 fmt.geometry.height = height;
509 if( hb_dx_create_video_decoder( dxva2, dxva2->codec_id, &fmt ) == HB_WORK_ERROR )
510 return HB_WORK_ERROR;
511 dxva2->hw.decoder = dxva2->decoder;
512 dxva2->hw.cfg = &dxva2->cfg;
513 dxva2->hw.surface_count = dxva2->surface_count;
514 dxva2->hw.surface = dxva2->hw_surface;
516 unsigned i;
517 for( i = 0; i < dxva2->surface_count; i++ )
518 dxva2->hw.surface[i] = dxva2->surface[i].d3d;
520 hb_dx_create_video_conversion( dxva2 );
523 *hw = &dxva2->hw;
524 const hb_d3d_format_t *output = hb_d3d_find_format( dxva2->output );
525 dxva2->i_chroma = output->codec;
526 return HB_WORK_OK;
530 static int hb_va_get( hb_va_dxva2_t *dxva2, AVFrame *frame )
532 unsigned i, old;
533 for( i = 0, old = 0; i < dxva2->surface_count; i++ )
535 hb_va_surface_t *surface = &dxva2->surface[i];
536 if( !surface->refcount )
537 break;
538 if( surface->order < dxva2->surface[old].order )
539 old = i;
541 if( i >= dxva2->surface_count )
542 i = old;
544 hb_va_surface_t *surface = &dxva2->surface[i];
546 surface->refcount = 1;
547 surface->order = dxva2->surface_order++;
549 for( i = 0; i < 4; i++ )
551 frame->data[i] = NULL;
552 frame->linesize[i] = 0;
553 if( i == 0 || i == 3 )
554 frame->data[i] = (void*)surface->d3d;
556 return HB_WORK_OK;
559 * nv12 to yuv of c reference
561 static void hb_copy_from_nv12( uint8_t *dst, uint8_t *src[2], size_t src_pitch[2], unsigned width, unsigned height )
563 unsigned int i, j;
564 uint8_t *dstU, *dstV;
565 dstU = dst + width*height;
566 dstV = dstU + width*height/4;
567 unsigned int heithtUV, widthUV;
568 heithtUV = height/2;
569 widthUV = width/2;
571 for( i = 0; i < height; i++ ) //Y
573 memcpy( dst + i * width, src[0] + i * src_pitch[0], width );
575 for( i = 0; i < heithtUV; i++ )
577 for( j = 0; j < widthUV; j++ )
579 dstU[i * widthUV + j] = *(src[1] + i * src_pitch[1] + 2 * j);
580 dstV[i *widthUV + j] = *(src[1] + i * src_pitch[1] + 2 * j + 1);
586 * lock frame data form surface.
587 * nv12 to yuv with opencl and with C reference
588 * scale with opencl
590 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 )
593 LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3];
594 D3DLOCKED_RECT lock;
595 if( FAILED( IDirect3DSurface9_LockRect( d3d, &lock, NULL, D3DLOCK_READONLY )))
597 hb_log( "dxva2:Failed to lock surface" );
598 return HB_WORK_ERROR;
601 if( dxva2->render == MAKEFOURCC( 'N', 'V', '1', '2' ))
603 uint8_t *plane[2] =
605 lock.pBits,
606 (uint8_t*)lock.pBits + lock.Pitch * dxva2->surface_height
608 size_t pitch[2] =
610 lock.Pitch,
611 lock.Pitch,
614 hb_copy_from_nv12( dst, plane, pitch, dxva2->width, dxva2->height );
616 IDirect3DSurface9_UnlockRect( d3d );
617 return HB_WORK_OK;
621 * create dxva2 service
622 * load library D3D9.dll
624 hb_va_dxva2_t * hb_va_create_dxva2( hb_va_dxva2_t *dxva2, int codec_id )
626 if( dxva2 )
628 hb_va_close( dxva2 );
629 dxva2 = NULL;
632 hb_va_dxva2_t *dxva = calloc( 1, sizeof(*dxva) );
633 if( !dxva ) return NULL;
634 dxva->codec_id = codec_id;
636 dxva->hd3d9_dll = LoadLibrary( TEXT( "D3D9.DLL" ) );
637 if( !dxva->hd3d9_dll )
639 hb_deep_log(2, "dxva2:cannot load d3d9.dll");
640 goto error;
642 dxva->hdxva2_dll = LoadLibrary( TEXT( "DXVA2.DLL" ) );
643 if( !dxva->hdxva2_dll )
645 hb_deep_log(2, "dxva2:cannot load DXVA2.dll");
646 goto error;
649 if( hb_d3d_create_device( dxva ) == HB_WORK_ERROR )
651 hb_deep_log(2, "dxva2:Failed to create Direct3D device");
652 goto error;
655 if( hb_d3d_create_device_manager( dxva ) == HB_WORK_ERROR )
657 hb_deep_log(2, "dxva2:D3dCreateDeviceManager failed");
658 goto error;
662 if( hb_dx_create_video_service( dxva ) == HB_WORK_ERROR )
664 hb_deep_log(2, "dxva2:DxCreateVideoService failed");
665 goto error;
668 if( hb_dx_find_video_service_conversion( dxva, &dxva->input, &dxva->render ) == HB_WORK_ERROR )
670 hb_deep_log(2, "dxva2:DxFindVideoServiceConversion failed");
671 goto error;
675 * We may get a valid DXVA2 decoder later on, but we won't be able to
676 * use it if libavcodec is built without support for the appropriate
677 * AVHWaccel, so we need to check for it before declaring victory.
679 AVHWAccel *hwaccel = NULL;
680 for (hwaccel = av_hwaccel_next(NULL);
681 hwaccel != NULL;
682 hwaccel = av_hwaccel_next(hwaccel))
684 if (hwaccel->id == codec_id && hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
686 dxva->do_job = HB_WORK_OK;
687 dxva->description = "DXVA2";
688 return dxva;
691 hb_deep_log(2, "dxva2:compatible AVHWAccel not found");
693 error:
694 hb_va_close( dxva );
695 return NULL;
698 void hb_va_new_dxva2( hb_va_dxva2_t *dxva2, AVCodecContext *p_context )
700 if( p_context->width > 0 && p_context->height > 0 )
702 if( hb_va_setup( dxva2, &p_context->hwaccel_context, p_context->width, p_context->height ) == HB_WORK_ERROR )
704 hb_log( "dxva2:hb_va_Setup failed" );
705 hb_va_close( dxva2 );
706 dxva2 = NULL;
709 if( dxva2 )
711 dxva2->input_pts[0] = 0;
712 dxva2->input_pts[1] = 0;
713 if( dxva2->description )
714 hb_log( "dxva2:Using %s for hardware decoding", dxva2->description );
715 p_context->draw_horiz_band = NULL;
720 char* hb_get_pix_fmt_name( int pix_fmt )
722 static const char *ppsz_name[AV_PIX_FMT_NB] =
724 [AV_PIX_FMT_VDPAU_H264] = "AV_PIX_FMT_VDPAU_H264",
725 [AV_PIX_FMT_VAAPI_IDCT] = "AV_PIX_FMT_VAAPI_IDCT",
726 [AV_PIX_FMT_VAAPI_VLD] = "AV_PIX_FMT_VAAPI_VLD",
727 [AV_PIX_FMT_VAAPI_MOCO] = "AV_PIX_FMT_VAAPI_MOCO",
728 [AV_PIX_FMT_DXVA2_VLD] = "AV_PIX_FMT_DXVA2_VLD",
729 [AV_PIX_FMT_YUYV422] = "AV_PIX_FMT_YUYV422",
730 [AV_PIX_FMT_YUV420P] = "AV_PIX_FMT_YUV420P",
733 return ppsz_name[pix_fmt];
736 enum PixelFormat hb_ffmpeg_get_format( AVCodecContext *p_context, const enum PixelFormat *pi_fmt )
738 int i;
739 for( i = 0; pi_fmt[i] != AV_PIX_FMT_NONE; i++ )
741 hb_log( "dxva2:Available decoder output format %d (%s)", pi_fmt[i], hb_get_pix_fmt_name(pi_fmt[i]) ? : "Unknown" );
742 if( pi_fmt[i] == AV_PIX_FMT_DXVA2_VLD )
744 return pi_fmt[i];
747 return avcodec_default_get_format( p_context, pi_fmt );
750 int hb_va_get_frame_buf( hb_va_dxva2_t *dxva2, AVCodecContext *p_context, AVFrame *frame )
752 frame->type = FF_BUFFER_TYPE_USER;
753 if( hb_va_get( dxva2, frame ) == HB_WORK_ERROR )
755 hb_log( "VaGrabSurface failed" );
756 return HB_WORK_ERROR;
758 return HB_WORK_OK;
762 int hb_check_hwd_fmt( int fmt )
764 int result = 1;
765 switch ( fmt )
767 case AV_PIX_FMT_YUV420P16LE:
768 case AV_PIX_FMT_YUV420P16BE:
769 case AV_PIX_FMT_YUV422P16LE:
770 case AV_PIX_FMT_YUV422P16BE:
771 case AV_PIX_FMT_YUV444P16LE:
772 case AV_PIX_FMT_YUV444P16BE:
773 case AV_PIX_FMT_YUV420P9BE:
774 case AV_PIX_FMT_YUV420P9LE:
775 case AV_PIX_FMT_YUV420P10BE:
776 case AV_PIX_FMT_YUV420P10LE:
777 case AV_PIX_FMT_YUV422P10BE:
778 case AV_PIX_FMT_YUV422P10LE:
779 case AV_PIX_FMT_YUV444P9BE:
780 case AV_PIX_FMT_YUV444P9LE:
781 case AV_PIX_FMT_YUV444P10BE:
782 case AV_PIX_FMT_YUV444P10LE:
783 case AV_PIX_FMT_YUV422P9BE:
784 case AV_PIX_FMT_YUV422P9LE:
785 case AV_PIX_FMT_GBRP9BE:
786 case AV_PIX_FMT_GBRP9LE:
787 case AV_PIX_FMT_GBRP10BE:
788 case AV_PIX_FMT_GBRP10LE:
789 case AV_PIX_FMT_GBRP16BE:
790 case AV_PIX_FMT_GBRP16LE:
791 case AV_PIX_FMT_YUVA420P9BE:
792 case AV_PIX_FMT_YUVA420P9LE:
793 case AV_PIX_FMT_YUVA422P9BE:
794 case AV_PIX_FMT_YUVA422P9LE:
795 case AV_PIX_FMT_YUVA444P9BE:
796 case AV_PIX_FMT_YUVA444P9LE:
797 case AV_PIX_FMT_YUVA420P10BE:
798 case AV_PIX_FMT_YUVA420P10LE:
799 result = 0;
801 return result;
804 #endif // USE_HWD