24 #define _WIN32_WINNT 0x0600
25 #define DXVA2API_USE_BITFIELDS
46 DEFINE_GUID(IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
48 DEFINE_GUID(DXVA2_ModeMPEG2_VLD, 0xee27417f, 0x5e28,0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
49 DEFINE_GUID(DXVA2_ModeMPEG2and1_VLD, 0x86695f12, 0x340e,0x4f04,0x9f,0xd3,0x92,0x53,0xdd,0x32,0x74,0x60);
50 DEFINE_GUID(DXVA2_ModeH264_E, 0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
51 DEFINE_GUID(DXVA2_ModeH264_F, 0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
52 DEFINE_GUID(DXVADDI_Intel_ModeH264_E, 0x604F8E68, 0x4951,0x4C54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
53 DEFINE_GUID(DXVA2_ModeVC1_D, 0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
54 DEFINE_GUID(DXVA2_ModeVC1_D2010, 0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
55 DEFINE_GUID(DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
56 DEFINE_GUID(GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
129 IDirect3DSurface9_Release(ctx->
surfaces[i]);
138 IDirectXVideoDecoder_Release(ctx->
decoder);
162 IDirect3DDeviceManager9_Release(ctx->
d3d9devmgr);
168 IDirect3D9_Release(ctx->
d3d9);
194 IDirect3DSurface9_Release(w->
surface);
195 IDirectXVideoDecoder_Release(w->
decoder);
203 int i, old_unused = -1;
204 LPDIRECT3DSURFACE9 surface;
214 if (old_unused == -1) {
229 if (!frame->
buf[0]) {
236 IDirect3DSurface9_AddRef(w->
surface);
238 IDirectXVideoDecoder_AddRef(w->
decoder);
250 LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->
data[3];
253 D3DSURFACE_DESC surfaceDesc;
254 D3DLOCKED_RECT LockedRect;
258 IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
260 ctx->tmp_frame->width = frame->
width;
261 ctx->tmp_frame->height = frame->
height;
268 hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, D3DLOCK_READONLY);
279 (
uint8_t*)LockedRect.pBits + LockedRect.Pitch * surfaceDesc.Height,
280 LockedRect.Pitch, frame->
width, frame->
height / 2);
282 IDirect3DSurface9_UnlockRect(surface);
305 D3DPRESENT_PARAMETERS d3dpp = {0};
306 D3DDISPLAYMODE d3ddm;
307 unsigned resetToken = 0;
308 UINT adapter = D3DADAPTER_DEFAULT;
323 av_log(NULL, loglevel,
"Failed to load D3D9 library\n");
328 av_log(NULL, loglevel,
"Failed to load DXVA2 library\n");
334 av_log(NULL, loglevel,
"Failed to locate Direct3DCreate9\n");
338 if (!createDeviceManager) {
339 av_log(NULL, loglevel,
"Failed to locate DXVA2CreateDirect3DDeviceManager9\n");
343 ctx->
d3d9 = createD3D(D3D_SDK_VERSION);
345 av_log(NULL, loglevel,
"Failed to create IDirect3D object\n");
354 IDirect3D9_GetAdapterDisplayMode(ctx->
d3d9, adapter, &d3ddm);
355 d3dpp.Windowed =
TRUE;
356 d3dpp.BackBufferWidth = 640;
357 d3dpp.BackBufferHeight = 480;
358 d3dpp.BackBufferCount = 0;
359 d3dpp.BackBufferFormat = d3ddm.Format;
360 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
361 d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
363 hr = IDirect3D9_CreateDevice(ctx->
d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(),
364 D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
367 av_log(NULL, loglevel,
"Failed to create Direct3D device\n");
371 hr = createDeviceManager(&resetToken, &ctx->
d3d9devmgr);
373 av_log(NULL, loglevel,
"Failed to create Direct3D device manager\n");
379 av_log(NULL, loglevel,
"Failed to bind Direct3D device to device manager\n");
385 av_log(NULL, loglevel,
"Failed to open device handle\n");
391 av_log(NULL, loglevel,
"Failed to create IDirectXVideoDecoderService\n");
410 const DXVA2_VideoDesc *desc,
411 DXVA2_ConfigPictureDecode *
config)
416 unsigned cfg_count = 0, best_score = 0;
417 DXVA2_ConfigPictureDecode *cfg_list = NULL;
418 DXVA2_ConfigPictureDecode best_cfg = {{0}};
422 hr = IDirectXVideoDecoderService_GetDecoderConfigurations(ctx->
decoder_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
424 av_log(NULL, loglevel,
"Unable to retrieve decoder configurations\n");
428 for (i = 0; i < cfg_count; i++) {
429 DXVA2_ConfigPictureDecode *cfg = &cfg_list[i];
432 if (cfg->ConfigBitstreamRaw == 1)
438 if (IsEqualGUID(&cfg->guidConfigBitstreamEncryption, &DXVA2_NoEncrypt))
440 if (score > best_score) {
445 CoTaskMemFree(cfg_list);
448 av_log(NULL, loglevel,
"No valid decoder configuration available\n");
462 GUID *guid_list = NULL;
463 unsigned guid_count = 0, i, j;
464 GUID device_guid = GUID_NULL;
465 D3DFORMAT target_format = 0;
466 DXVA2_VideoDesc desc = { 0 };
467 DXVA2_ConfigPictureDecode
config;
469 int surface_alignment;
472 hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->
decoder_service, &guid_count, &guid_list);
474 av_log(NULL, loglevel,
"Failed to retrieve decoder device GUIDs\n");
478 for (i = 0; dxva2_modes[i].
guid; i++) {
479 D3DFORMAT *target_list = NULL;
480 unsigned target_count = 0;
485 for (j = 0; j < guid_count; j++) {
486 if (IsEqualGUID(mode->
guid, &guid_list[j]))
492 hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->
decoder_service, mode->
guid, &target_count, &target_list);
496 for (j = 0; j < target_count; j++) {
497 const D3DFORMAT format = target_list[j];
498 if (format ==
MKTAG(
'N',
'V',
'1',
'2')) {
499 target_format = format;
503 CoTaskMemFree(target_list);
505 device_guid = *mode->
guid;
509 CoTaskMemFree(guid_list);
511 if (IsEqualGUID(&device_guid, &GUID_NULL)) {
512 av_log(NULL, loglevel,
"No decoder device for codec found\n");
518 desc.Format = target_format;
528 surface_alignment = 32;
530 surface_alignment = 16;
549 av_log(NULL, loglevel,
"Unable to allocate surface arrays\n");
557 target_format, D3DPOOL_DEFAULT, 0,
558 DXVA2_VideoDecoderRenderTarget,
565 hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->
decoder_service, &device_guid,
569 av_log(NULL, loglevel,
"Failed to create DXVA2 video decoder\n");
581 if (IsEqualGUID(&ctx->
decoder_guid, &DXVADDI_Intel_ModeH264_E))
606 av_log(NULL, loglevel,
"Unsupported H.264 profile for DXVA2 HWAccel: %d\n", s->
profile);
615 av_log(NULL, loglevel,
"Error creating the DXVA2 decoder\n");