1 /*****************************************************************************
2 * dxva2.c: Video Acceleration helpers
3 *****************************************************************************
4 * Copyright (C) 2009 Geoffroy Couprie
5 * Copyright (C) 2009 Laurent Aimar
8 * Authors: Geoffroy Couprie <geal@videolan.org>
9 * Laurent Aimar <fenrir _AT_ videolan _DOT_ org>
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License as published by
13 * the Free Software Foundation; either version 2.1 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public License
22 * along with this program; if not, write to the Free Software Foundation,
23 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_picture.h>
34 #include <vlc_plugin.h>
36 #define DXVA2API_USE_BITFIELDS
38 #include <libavcodec/dxva2.h>
39 #include "../../video_chroma/d3d9_fmt.h"
41 #define D3D_Device IDirect3DDevice9
42 #define D3D_DecoderType IDirectXVideoDecoder
43 #define D3D_DecoderDevice IDirectXVideoDecoderService
44 #define D3D_DecoderSurface IDirect3DSurface9
45 #include "directx_va.h"
47 static int Open(vlc_va_t
*, AVCodecContext
*, enum PixelFormat
,
48 const es_format_t
*, picture_sys_t
*p_sys
);
49 static void Close(vlc_va_t
*, void **);
52 set_description(N_("DirectX Video Acceleration (DXVA) 2.0"))
53 set_capability("hw decoder", 100)
54 set_category(CAT_INPUT
)
55 set_subcategory(SUBCAT_INPUT_VCODEC
)
56 set_callbacks(Open
, Close
)
59 #include <initguid.h> /* must be last included to not redefine existing GUIDs */
61 /* dxva2api.h GUIDs: http://msdn.microsoft.com/en-us/library/windows/desktop/ms697067(v=vs100).aspx
62 * assume that they are declared in dxva2api.h */
63 #define MS_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)
68 # if !defined(__MINGW64_VERSION_MAJOR)
70 # define MS_GUID DEFINE_GUID /* dxva2api.h fails to declare those, redefine as static */
71 # define DXVA2_E_NEW_VIDEO_DEVICE MAKE_HRESULT(1, 4, 4097)
76 #endif /* __MINGW32__ */
78 MS_GUID(IID_IDirectXVideoDecoderService
, 0xfc51a551, 0xd5e7, 0x11d9, 0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
79 MS_GUID(IID_IDirectXVideoAccelerationService
, 0xfc51a550, 0xd5e7, 0x11d9, 0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
81 DEFINE_GUID(DXVA2_NoEncrypt
, 0x1b81bed0, 0xa0c7, 0x11d3, 0xb9, 0x84, 0x00, 0xc0, 0x4f, 0x2e, 0x73, 0xc5);
83 DEFINE_GUID(DXVA_Intel_H264_NoFGT_ClearVideo
, 0x604F8E68, 0x4951, 0x4c54, 0x88, 0xFE, 0xAB, 0xD2, 0x5C, 0x15, 0xB3, 0xD6);
92 /* XXX Prefered format must come first */
93 static const d3d_format_t d3d_formats
[] = {
94 { "YV12", MAKEFOURCC('Y','V','1','2'), VLC_CODEC_YV12
},
95 { "NV12", MAKEFOURCC('N','V','1','2'), VLC_CODEC_NV12
},
96 { "IMC3", MAKEFOURCC('I','M','C','3'), VLC_CODEC_YV12
},
97 { "P010", MAKEFOURCC('P','0','1','0'), VLC_CODEC_P010
},
102 static const d3d_format_t
*D3dFindFormat(D3DFORMAT format
)
104 for (unsigned i
= 0; d3d_formats
[i
].name
; i
++) {
105 if (d3d_formats
[i
].format
== format
)
106 return &d3d_formats
[i
];
113 directx_sys_t dx_sys
;
120 D3DADAPTER_IDENTIFIER9 d3dai
;
123 IDirect3DDeviceManager9
*devmng
;
130 DXVA2_ConfigPictureDecode cfg
;
132 /* avcodec internals */
133 struct dxva_context hw
;
138 static int D3dCreateDevice(vlc_va_t
*);
139 static void D3dDestroyDevice(vlc_va_t
*);
140 static char *DxDescribe(vlc_va_sys_t
*);
142 static int D3dCreateDeviceManager(vlc_va_t
*);
143 static void D3dDestroyDeviceManager(vlc_va_t
*);
145 static int DxCreateVideoService(vlc_va_t
*);
146 static void DxDestroyVideoService(vlc_va_t
*);
147 static int DxGetInputList(vlc_va_t
*, input_list_t
*);
148 static int DxSetupOutput(vlc_va_t
*, const GUID
*, const video_format_t
*);
150 static int DxCreateVideoDecoder(vlc_va_t
*, int codec_id
,
151 const video_format_t
*, unsigned surface_count
);
152 static void DxDestroyVideoDecoder(vlc_va_t
*);
153 static int DxResetVideoDecoder(vlc_va_t
*);
154 static void SetupAVCodecContext(vlc_va_t
*);
156 void SetupAVCodecContext(vlc_va_t
*va
)
158 vlc_va_sys_t
*sys
= va
->sys
;
159 directx_sys_t
*dx_sys
= &sys
->dx_sys
;
161 sys
->hw
.decoder
= dx_sys
->decoder
;
162 sys
->hw
.cfg
= &sys
->cfg
;
163 sys
->hw
.surface_count
= dx_sys
->va_pool
.surface_count
;
164 sys
->hw
.surface
= dx_sys
->hw_surface
;
166 if (IsEqualGUID(&dx_sys
->input
, &DXVA_Intel_H264_NoFGT_ClearVideo
))
167 sys
->hw
.workaround
|= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
;
170 static void d3d9_pic_context_destroy(struct picture_context_t
*opaque
)
172 struct va_pic_context
*pic_ctx
= (struct va_pic_context
*)opaque
;
173 if (pic_ctx
->va_surface
)
175 ReleasePictureSys(&pic_ctx
->picsys
);
176 va_surface_Release(pic_ctx
->va_surface
);
181 static struct va_pic_context
*CreatePicContext(IDirect3DSurface9
*);
183 static struct picture_context_t
*d3d9_pic_context_copy(struct picture_context_t
*ctx
)
185 struct va_pic_context
*src_ctx
= (struct va_pic_context
*)ctx
;
186 struct va_pic_context
*pic_ctx
= CreatePicContext(src_ctx
->picsys
.surface
);
187 if (unlikely(pic_ctx
==NULL
))
189 pic_ctx
->va_surface
= src_ctx
->va_surface
;
190 va_surface_AddRef(pic_ctx
->va_surface
);
194 static struct va_pic_context
*CreatePicContext(IDirect3DSurface9
*surface
)
196 struct va_pic_context
*pic_ctx
= calloc(1, sizeof(*pic_ctx
));
197 if (unlikely(pic_ctx
==NULL
))
199 pic_ctx
->s
.destroy
= d3d9_pic_context_destroy
;
200 pic_ctx
->s
.copy
= d3d9_pic_context_copy
;
201 pic_ctx
->picsys
.surface
= surface
;
202 AcquirePictureSys(&pic_ctx
->picsys
);
206 static struct va_pic_context
* NewSurfacePicContext(vlc_va_t
*va
, int surface_index
)
208 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
209 struct va_pic_context
*pic_ctx
= CreatePicContext(dx_sys
->hw_surface
[surface_index
]);
210 if (unlikely(pic_ctx
==NULL
))
212 /* all the resources are acquired during surfaces init, and a second time in
213 * CreatePicContext(), undo one of them otherwise we need an extra release
214 * when the pool is emptied */
215 ReleasePictureSys(&pic_ctx
->picsys
);
219 static int Get(vlc_va_t
*va
, picture_t
*pic
, uint8_t **data
)
221 vlc_va_sys_t
*sys
= va
->sys
;
223 /* Check the device */
224 HRESULT hr
= IDirect3DDeviceManager9_TestDevice(sys
->devmng
, sys
->device
);
225 if (hr
== DXVA2_E_NEW_VIDEO_DEVICE
) {
226 if (DxResetVideoDecoder(va
))
228 } else if (FAILED(hr
)) {
229 msg_Err(va
, "IDirect3DDeviceManager9_TestDevice %u", (unsigned)hr
);
233 int res
= va_pool_Get(&sys
->dx_sys
.va_pool
, pic
);
234 if (likely(res
==VLC_SUCCESS
))
235 *data
= (uint8_t*)((struct va_pic_context
*)pic
->context
)->picsys
.surface
;
239 static void Close(vlc_va_t
*va
, void **ctx
)
241 vlc_va_sys_t
*sys
= va
->sys
;
245 directx_va_Close(va
, &sys
->dx_sys
);
248 FreeLibrary(sys
->hd3d9_dll
);
250 free((char *)va
->description
);
254 static int Open(vlc_va_t
*va
, AVCodecContext
*ctx
, enum PixelFormat pix_fmt
,
255 const es_format_t
*fmt
, picture_sys_t
*p_sys
)
257 int err
= VLC_EGENERIC
;
258 directx_sys_t
*dx_sys
;
260 if (pix_fmt
!= AV_PIX_FMT_DXVA2_VLD
)
263 ctx
->hwaccel_context
= NULL
;
265 vlc_va_sys_t
*sys
= calloc(1, sizeof (*sys
));
266 if (unlikely(sys
== NULL
))
270 sys
->hd3d9_dll
= LoadLibrary(TEXT("D3D9.DLL"));
271 if (!sys
->hd3d9_dll
) {
272 msg_Warn(va
, "cannot load d3d9.dll");
276 dx_sys
= &sys
->dx_sys
;
278 dx_sys
->va_pool
.pf_create_device
= D3dCreateDevice
;
279 dx_sys
->va_pool
.pf_destroy_device
= D3dDestroyDevice
;
280 dx_sys
->va_pool
.pf_create_device_manager
= D3dCreateDeviceManager
;
281 dx_sys
->va_pool
.pf_destroy_device_manager
= D3dDestroyDeviceManager
;
282 dx_sys
->va_pool
.pf_create_video_service
= DxCreateVideoService
;
283 dx_sys
->va_pool
.pf_destroy_video_service
= DxDestroyVideoService
;
284 dx_sys
->va_pool
.pf_create_decoder_surfaces
= DxCreateVideoDecoder
;
285 dx_sys
->va_pool
.pf_destroy_surfaces
= DxDestroyVideoDecoder
;
286 dx_sys
->va_pool
.pf_setup_avcodec_ctx
= SetupAVCodecContext
;
287 dx_sys
->va_pool
.pf_new_surface_context
= NewSurfacePicContext
;
288 dx_sys
->pf_get_input_list
= DxGetInputList
;
289 dx_sys
->pf_setup_output
= DxSetupOutput
;
290 dx_sys
->psz_decoder_dll
= TEXT("DXVA2.DLL");
294 dx_sys
->d3ddev
= NULL
;
298 if (SUCCEEDED(IDirect3DSurface9_GetDesc(p_sys
->surface
, &src
)))
299 sys
->render
= src
.Format
;
300 IDirect3DSurface9_GetDevice(p_sys
->surface
, &dx_sys
->d3ddev
);
303 err
= directx_va_Open(va
, &sys
->dx_sys
, true);
304 if (err
!=VLC_SUCCESS
)
307 err
= directx_va_Setup(va
, &sys
->dx_sys
, ctx
, fmt
);
308 if (err
!= VLC_SUCCESS
)
311 ctx
->hwaccel_context
= &sys
->hw
;
313 /* TODO print the hardware name/vendor for debugging purposes */
314 va
->description
= DxDescribe(sys
);
325 * It creates a Direct3D device usable for DXVA 2
327 static int D3dCreateDevice(vlc_va_t
*va
)
329 vlc_va_sys_t
*sys
= va
->sys
;
331 if (sys
->dx_sys
.d3ddev
) {
332 msg_Dbg(va
, "Reusing Direct3D9 device");
337 LPDIRECT3D9 (WINAPI
*Create9
)(UINT SDKVersion
);
338 Create9
= (void *)GetProcAddress(sys
->hd3d9_dll
, "Direct3DCreate9");
340 msg_Err(va
, "Cannot locate reference to Direct3DCreate9 ABI in DLL");
346 d3dobj
= Create9(D3D_SDK_VERSION
);
348 msg_Err(va
, "Direct3DCreate9 failed");
351 sys
->d3dobj
= d3dobj
;
354 D3DADAPTER_IDENTIFIER9
*d3dai
= &sys
->d3dai
;
355 if (FAILED(IDirect3D9_GetAdapterIdentifier(sys
->d3dobj
,
356 D3DADAPTER_DEFAULT
, 0, d3dai
))) {
357 msg_Warn(va
, "IDirect3D9_GetAdapterIdentifier failed");
358 ZeroMemory(d3dai
, sizeof(*d3dai
));
362 D3DPRESENT_PARAMETERS d3dpp
;
363 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
364 d3dpp
.Flags
= D3DPRESENTFLAG_VIDEO
;
365 d3dpp
.Windowed
= TRUE
;
366 d3dpp
.hDeviceWindow
= NULL
;
367 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
368 d3dpp
.MultiSampleType
= D3DMULTISAMPLE_NONE
;
369 d3dpp
.PresentationInterval
= D3DPRESENT_INTERVAL_DEFAULT
;
370 d3dpp
.BackBufferCount
= 0; /* FIXME what to put here */
371 d3dpp
.BackBufferFormat
= D3DFMT_X8R8G8B8
; /* FIXME what to put here */
372 d3dpp
.BackBufferWidth
= 0;
373 d3dpp
.BackBufferHeight
= 0;
374 d3dpp
.EnableAutoDepthStencil
= FALSE
;
376 /* Direct3D needs a HWND to create a device, even without using ::Present
377 this HWND is used to alert Direct3D when there's a change of focus window.
378 For now, use GetDesktopWindow, as it looks harmless */
379 LPDIRECT3DDEVICE9 d3ddev
;
380 if (FAILED(IDirect3D9_CreateDevice(d3dobj
, D3DADAPTER_DEFAULT
,
381 D3DDEVTYPE_HAL
, GetDesktopWindow(),
382 D3DCREATE_SOFTWARE_VERTEXPROCESSING
|
383 D3DCREATE_MULTITHREADED
,
385 msg_Err(va
, "IDirect3D9_CreateDevice failed");
388 sys
->dx_sys
.d3ddev
= d3ddev
;
394 * It releases a Direct3D device and its resources.
396 static void D3dDestroyDevice(vlc_va_t
*va
)
398 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
400 IDirect3D9_Release(va
->sys
->d3dobj
);
402 IDirect3DDevice9_Release(dx_sys
->d3ddev
);
405 * It describes our Direct3D object
407 static char *DxDescribe(vlc_va_sys_t
*va
)
409 static const struct {
414 { 0x10DE, "NVIDIA" },
417 { 0x5333, "S3 Graphics" },
420 D3DADAPTER_IDENTIFIER9
*id
= &va
->d3dai
;
422 const char *vendor
= "Unknown";
423 for (int i
= 0; vendors
[i
].id
!= 0; i
++) {
424 if (vendors
[i
].id
== id
->VendorId
) {
425 vendor
= vendors
[i
].name
;
431 if (asprintf(&description
, "DXVA2 (%.*s, vendor %lu(%s), device %lu, revision %lu)",
432 (int)sizeof(id
->Description
), id
->Description
,
433 id
->VendorId
, vendor
, id
->DeviceId
, id
->Revision
) < 0)
439 * It creates a Direct3D device manager
441 static int D3dCreateDeviceManager(vlc_va_t
*va
)
443 vlc_va_sys_t
*sys
= va
->sys
;
444 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
446 HRESULT (WINAPI
*CreateDeviceManager9
)(UINT
*pResetToken
,
447 IDirect3DDeviceManager9
**);
448 CreateDeviceManager9
=
449 (void *)GetProcAddress(dx_sys
->hdecoder_dll
,
450 "DXVA2CreateDirect3DDeviceManager9");
452 if (!CreateDeviceManager9
) {
453 msg_Err(va
, "cannot load function");
456 msg_Dbg(va
, "OurDirect3DCreateDeviceManager9 Success!");
459 IDirect3DDeviceManager9
*devmng
;
460 if (FAILED(CreateDeviceManager9(&token
, &devmng
))) {
461 msg_Err(va
, " OurDirect3DCreateDeviceManager9 failed");
464 sys
->devmng
= devmng
;
465 msg_Info(va
, "obtained IDirect3DDeviceManager9");
467 HRESULT hr
= IDirect3DDeviceManager9_ResetDevice(devmng
, dx_sys
->d3ddev
, token
);
469 msg_Err(va
, "IDirect3DDeviceManager9_ResetDevice failed: %08x", (unsigned)hr
);
475 * It destroys a Direct3D device manager
477 static void D3dDestroyDeviceManager(vlc_va_t
*va
)
480 IDirect3DDeviceManager9_Release(va
->sys
->devmng
);
484 * It creates a DirectX video service
486 static int DxCreateVideoService(vlc_va_t
*va
)
488 vlc_va_sys_t
*sys
= va
->sys
;
489 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
493 hr
= IDirect3DDeviceManager9_OpenDeviceHandle(sys
->devmng
, &device
);
495 msg_Err(va
, "OpenDeviceHandle failed");
498 sys
->device
= device
;
501 hr
= IDirect3DDeviceManager9_GetVideoService(sys
->devmng
, device
,
502 &IID_IDirectXVideoDecoderService
, &pv
);
504 msg_Err(va
, "GetVideoService failed");
513 * It destroys a DirectX video service
515 static void DxDestroyVideoService(vlc_va_t
*va
)
517 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
520 HRESULT hr
= IDirect3DDeviceManager9_CloseDeviceHandle(va
->sys
->devmng
, va
->sys
->device
);
522 msg_Warn(va
, "Failed to release device handle %x. (hr=0x%lX)", va
->sys
->device
, hr
);
525 IDirectXVideoDecoderService_Release(dx_sys
->d3ddec
);
528 static void ReleaseInputList(input_list_t
*p_list
)
530 CoTaskMemFree(p_list
->list
);
533 static int DxGetInputList(vlc_va_t
*va
, input_list_t
*p_list
)
535 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
536 UINT input_count
= 0;
537 GUID
*input_list
= NULL
;
538 if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(dx_sys
->d3ddec
,
541 msg_Err(va
, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
545 p_list
->count
= input_count
;
546 p_list
->list
= input_list
;
547 p_list
->pf_release
= ReleaseInputList
;
551 static int DxSetupOutput(vlc_va_t
*va
, const GUID
*input
, const video_format_t
*fmt
)
554 int err
= VLC_EGENERIC
;
555 UINT output_count
= 0;
556 D3DFORMAT
*output_list
= NULL
;
557 if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va
->sys
->dx_sys
.d3ddec
,
561 msg_Err(va
, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
565 for (unsigned j
= 0; j
< output_count
; j
++) {
566 const D3DFORMAT f
= output_list
[j
];
567 const d3d_format_t
*format
= D3dFindFormat(f
);
569 msg_Dbg(va
, "%s is supported for output", format
->name
);
571 msg_Dbg(va
, "%d is supported for output (%4.4s)", f
, (const char*)&f
);
576 for (unsigned pass
= 0; pass
< 2 && err
!= VLC_SUCCESS
; ++pass
)
578 for (unsigned j
= 0; d3d_formats
[j
].name
; j
++) {
579 const d3d_format_t
*format
= &d3d_formats
[j
];
582 bool is_supported
= false;
583 for (unsigned k
= 0; !is_supported
&& k
< output_count
; k
++) {
584 is_supported
= format
->format
== output_list
[k
];
588 if (pass
== 0 && format
->format
!= va
->sys
->render
)
591 /* We have our solution */
592 msg_Dbg(va
, "Using decoder output '%s'", format
->name
);
593 va
->sys
->render
= format
->format
;
598 CoTaskMemFree(output_list
);
603 * It creates a DXVA2 decoder using the given video format
605 static int DxCreateVideoDecoder(vlc_va_t
*va
, int codec_id
,
606 const video_format_t
*fmt
, unsigned surface_count
)
608 vlc_va_sys_t
*p_sys
= va
->sys
;
609 directx_sys_t
*sys
= &va
->sys
->dx_sys
;
612 hr
= IDirectXVideoDecoderService_CreateSurface(sys
->d3ddec
,
619 DXVA2_VideoDecoderRenderTarget
,
623 msg_Err(va
, "IDirectXVideoAccelerationService_CreateSurface %d failed (hr=0x%0lx)", surface_count
- 1, hr
);
626 msg_Dbg(va
, "IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)",
627 surface_count
, fmt
->i_width
, fmt
->i_height
);
629 IDirect3DSurface9
*tstCrash
;
630 hr
= IDirectXVideoDecoderService_CreateSurface(sys
->d3ddec
,
637 DXVA2_VideoDecoderRenderTarget
,
641 msg_Err(va
, "extra buffer impossible, avoid a crash (hr=0x%0lx)", hr
);
642 for (unsigned i
= 0; i
< surface_count
; i
++)
643 IDirect3DSurface9_Release( sys
->hw_surface
[i
] );
646 IDirect3DSurface9_Release(tstCrash
);
650 ZeroMemory(&dsc
, sizeof(dsc
));
651 dsc
.SampleWidth
= fmt
->i_width
;
652 dsc
.SampleHeight
= fmt
->i_height
;
653 dsc
.Format
= p_sys
->render
;
654 if (fmt
->i_frame_rate
> 0 && fmt
->i_frame_rate_base
> 0) {
655 dsc
.InputSampleFreq
.Numerator
= fmt
->i_frame_rate
;
656 dsc
.InputSampleFreq
.Denominator
= fmt
->i_frame_rate_base
;
658 dsc
.InputSampleFreq
.Numerator
= 0;
659 dsc
.InputSampleFreq
.Denominator
= 0;
661 dsc
.OutputFrameFreq
= dsc
.InputSampleFreq
;
662 dsc
.UABProtectionLevel
= FALSE
;
665 /* FIXME I am unsure we can let unknown everywhere */
666 DXVA2_ExtendedFormat
*ext
= &dsc
.SampleFormat
;
667 ext
->SampleFormat
= 0;//DXVA2_SampleUnknown;
668 ext
->VideoChromaSubsampling
= 0;//DXVA2_VideoChromaSubsampling_Unknown;
669 ext
->NominalRange
= 0;//DXVA2_NominalRange_Unknown;
670 ext
->VideoTransferMatrix
= 0;//DXVA2_VideoTransferMatrix_Unknown;
671 ext
->VideoLighting
= 0;//DXVA2_VideoLighting_Unknown;
672 ext
->VideoPrimaries
= 0;//DXVA2_VideoPrimaries_Unknown;
673 ext
->VideoTransferFunction
= 0;//DXVA2_VideoTransFunc_Unknown;
675 /* List all configurations available for the decoder */
677 DXVA2_ConfigPictureDecode
*cfg_list
= NULL
;
678 if (FAILED(IDirectXVideoDecoderService_GetDecoderConfigurations(sys
->d3ddec
,
684 msg_Err(va
, "IDirectXVideoDecoderService_GetDecoderConfigurations failed");
685 for (unsigned i
= 0; i
< surface_count
; i
++)
686 IDirect3DSurface9_Release( sys
->hw_surface
[i
] );
689 msg_Dbg(va
, "we got %d decoder configurations", cfg_count
);
691 /* Select the best decoder configuration */
693 for (unsigned i
= 0; i
< cfg_count
; i
++) {
694 const DXVA2_ConfigPictureDecode
*cfg
= &cfg_list
[i
];
697 msg_Dbg(va
, "configuration[%d] ConfigBitstreamRaw %d",
698 i
, cfg
->ConfigBitstreamRaw
);
702 if (cfg
->ConfigBitstreamRaw
== 1)
704 else if (codec_id
== AV_CODEC_ID_H264
&& cfg
->ConfigBitstreamRaw
== 2)
708 if (IsEqualGUID(&cfg
->guidConfigBitstreamEncryption
, &DXVA2_NoEncrypt
))
711 if (cfg_score
< score
) {
716 CoTaskMemFree(cfg_list
);
717 if (cfg_score
<= 0) {
718 msg_Err(va
, "Failed to find a supported decoder configuration");
722 /* Create the decoder */
723 IDirectXVideoDecoder
*decoder
;
724 if (FAILED(IDirectXVideoDecoderService_CreateVideoDecoder(sys
->d3ddec
,
731 msg_Err(va
, "IDirectXVideoDecoderService_CreateVideoDecoder failed");
732 for (unsigned i
= 0; i
< surface_count
; i
++)
733 IDirect3DSurface9_Release( sys
->hw_surface
[i
] );
736 sys
->decoder
= decoder
;
738 msg_Dbg(va
, "IDirectXVideoDecoderService_CreateVideoDecoder succeed");
742 static void DxDestroyVideoDecoder(vlc_va_t
*va
)
744 directx_sys_t
*dx_sys
= &va
->sys
->dx_sys
;
747 IDirectXVideoDecoder_Release(dx_sys
->decoder
);
748 dx_sys
->decoder
= NULL
;
749 for (unsigned i
= 0; i
< dx_sys
->va_pool
.surface_count
; i
++)
750 IDirect3DSurface9_Release(dx_sys
->hw_surface
[i
]);
754 static int DxResetVideoDecoder(vlc_va_t
*va
)
756 msg_Err(va
, "DxResetVideoDecoder unimplemented");