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);
128 IDirect3DSurface9_Release(ctx->
surfaces[i]);
137 IDirectXVideoDecoder_Release(ctx->
decoder);
161 IDirect3DDeviceManager9_Release(ctx->
d3d9devmgr);
167 IDirect3D9_Release(ctx->
d3d9);
193 IDirect3DSurface9_Release(w->
surface);
194 IDirectXVideoDecoder_Release(w->
decoder);
202 int i, old_unused = -1;
203 LPDIRECT3DSURFACE9 surface;
213 if (old_unused == -1) {
228 if (!frame->
buf[0]) {
235 IDirect3DSurface9_AddRef(w->
surface);
237 IDirectXVideoDecoder_AddRef(w->
decoder);
249 LPDIRECT3DSURFACE9 surface = (LPDIRECT3DSURFACE9)frame->
data[3];
252 D3DSURFACE_DESC surfaceDesc;
253 D3DLOCKED_RECT LockedRect;
257 IDirect3DSurface9_GetDesc(surface, &surfaceDesc);
260 ctx->tmp_frame->height = frame->
height;
267 hr = IDirect3DSurface9_LockRect(surface, &LockedRect,
NULL, D3DLOCK_READONLY);
278 (
uint8_t*)LockedRect.pBits + LockedRect.Pitch * surfaceDesc.Height,
279 LockedRect.Pitch, frame->
width, frame->
height / 2);
281 IDirect3DSurface9_UnlockRect(surface);
304 D3DPRESENT_PARAMETERS d3dpp = {0};
305 D3DDISPLAYMODE d3ddm;
306 unsigned resetToken = 0;
307 UINT adapter = D3DADAPTER_DEFAULT;
322 av_log(
NULL, loglevel,
"Failed to load D3D9 library\n");
327 av_log(
NULL, loglevel,
"Failed to load DXVA2 library\n");
333 av_log(
NULL, loglevel,
"Failed to locate Direct3DCreate9\n");
337 if (!createDeviceManager) {
338 av_log(
NULL, loglevel,
"Failed to locate DXVA2CreateDirect3DDeviceManager9\n");
342 ctx->
d3d9 = createD3D(D3D_SDK_VERSION);
344 av_log(
NULL, loglevel,
"Failed to create IDirect3D object\n");
353 IDirect3D9_GetAdapterDisplayMode(ctx->
d3d9, adapter, &d3ddm);
354 d3dpp.Windowed = TRUE;
355 d3dpp.BackBufferWidth = 640;
356 d3dpp.BackBufferHeight = 480;
357 d3dpp.BackBufferCount = 0;
358 d3dpp.BackBufferFormat = d3ddm.Format;
359 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
360 d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
362 hr = IDirect3D9_CreateDevice(ctx->
d3d9, adapter, D3DDEVTYPE_HAL, GetShellWindow(),
363 D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED | D3DCREATE_FPU_PRESERVE,
366 av_log(
NULL, loglevel,
"Failed to create Direct3D device\n");
370 hr = createDeviceManager(&resetToken, &ctx->
d3d9devmgr);
372 av_log(
NULL, loglevel,
"Failed to create Direct3D device manager\n");
378 av_log(
NULL, loglevel,
"Failed to bind Direct3D device to device manager\n");
384 av_log(
NULL, loglevel,
"Failed to open device handle\n");
390 av_log(
NULL, loglevel,
"Failed to create IDirectXVideoDecoderService\n");
409 const DXVA2_VideoDesc *desc,
410 DXVA2_ConfigPictureDecode *config)
415 unsigned cfg_count = 0, best_score = 0;
416 DXVA2_ConfigPictureDecode *cfg_list =
NULL;
417 DXVA2_ConfigPictureDecode best_cfg = {{0}};
421 hr = IDirectXVideoDecoderService_GetDecoderConfigurations(ctx->
decoder_service, device_guid, desc,
NULL, &cfg_count, &cfg_list);
423 av_log(
NULL, loglevel,
"Unable to retrieve decoder configurations\n");
427 for (i = 0; i < cfg_count; i++) {
428 DXVA2_ConfigPictureDecode *cfg = &cfg_list[i];
431 if (cfg->ConfigBitstreamRaw == 1)
437 if (IsEqualGUID(&cfg->guidConfigBitstreamEncryption, &DXVA2_NoEncrypt))
439 if (score > best_score) {
444 CoTaskMemFree(cfg_list);
447 av_log(
NULL, loglevel,
"No valid decoder configuration available\n");
461 GUID *guid_list =
NULL;
462 unsigned guid_count = 0, i, j;
463 GUID device_guid = GUID_NULL;
464 D3DFORMAT target_format = 0;
465 DXVA2_VideoDesc desc = { 0 };
466 DXVA2_ConfigPictureDecode config;
468 int surface_alignment;
471 hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->
decoder_service, &guid_count, &guid_list);
473 av_log(
NULL, loglevel,
"Failed to retrieve decoder device GUIDs\n");
477 for (i = 0; dxva2_modes[i].
guid; i++) {
478 D3DFORMAT *target_list =
NULL;
479 unsigned target_count = 0;
484 for (j = 0; j < guid_count; j++) {
485 if (IsEqualGUID(mode->
guid, &guid_list[j]))
491 hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->
decoder_service, mode->
guid, &target_count, &target_list);
495 for (j = 0; j < target_count; j++) {
496 const D3DFORMAT format = target_list[j];
497 if (format ==
MKTAG(
'N',
'V',
'1',
'2')) {
498 target_format = format;
502 CoTaskMemFree(target_list);
504 device_guid = *mode->
guid;
508 CoTaskMemFree(guid_list);
510 if (IsEqualGUID(&device_guid, &GUID_NULL)) {
511 av_log(
NULL, loglevel,
"No decoder device for codec found\n");
517 desc.Format = target_format;
527 surface_alignment = 32;
529 surface_alignment = 16;
548 av_log(
NULL, loglevel,
"Unable to allocate surface arrays\n");
556 target_format, D3DPOOL_DEFAULT, 0,
557 DXVA2_VideoDecoderRenderTarget,
564 hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->
decoder_service, &device_guid,
568 av_log(
NULL, loglevel,
"Failed to create DXVA2 video decoder\n");
580 if (IsEqualGUID(&ctx->
decoder_guid, &DXVADDI_Intel_ModeH264_E))
605 av_log(
NULL, loglevel,
"Unsupported H.264 profile for DXVA2 HWAccel: %d\n", s->
profile);
614 av_log(
NULL, loglevel,
"Error creating the DXVA2 decoder\n");
This structure describes decoded (raw) audio or video data.
static void dxva2_release_buffer(void *opaque, uint8_t *data)
int coded_width
Bitstream width / height, may be different from width/height e.g.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
Work around for DXVA2 and old Intel GPUs with ClearVideo interface.
static int dxva2_get_decoder_configuration(AVCodecContext *s, const GUID *device_guid, const DXVA2_VideoDesc *desc, DXVA2_ConfigPictureDecode *config)
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everythnig contained in src to dst and reset src.
LPDIRECT3DSURFACE9 * surface
The array of Direct3D surfaces used to create the decoder.
static const dxva2_mode dxva2_modes[]
const DXVA2_ConfigPictureDecode * cfg
DXVA2 configuration used to create the decoder.
IDirect3DDeviceManager9 * d3d9devmgr
unsigned surface_count
The number of surface in the surface array.
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
#define av_assert0(cond)
assert() equivalent, that is always enabled.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
void * hwaccel_context
Hardware accelerator context.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
uint64_t workaround
A bit field configuring the workarounds needed for using the decoder.
AVCodecID
Identify the syntax and semantics of the bitstream.
int width
width and height of the video frame
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
int dxva2_init(AVCodecContext *s)
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int active_thread_type
Which multithreading methods are in use by the codec.
#define FF_PROFILE_H264_HIGH
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
simple assert() macros that are a bit more flexible than ISO C assert().
void av_log(void *avcl, int level, const char *fmt,...)
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
reference-counted frame API
static void dxva2_uninit(AVCodecContext *s)
static int dxva2_create_decoder(AVCodecContext *s)
DXVA2_ConfigPictureDecode decoder_config
#define FF_THREAD_FRAME
Decode more than one frame at once.
static int dxva2_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
IDirectXVideoDecoder * decoder
preferred ID for MPEG-1/2 video decoding
int thread_count
thread count is used to decide how many independent tasks should be passed to execute() ...
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
LPDIRECT3DSURFACE9 * surfaces
#define AV_LOG_INFO
Standard information.
Public libavcodec DXVA2 header.
main external API structure.
static int dxva2_alloc(AVCodecContext *s)
static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
refcounted data buffer API
IDirectXVideoDecoder * decoder
IDirect3D9 *WINAPI pDirect3DCreate9(UINT)
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
surface_info * surface_infos
DEFINE_GUID(IID_IDirectXVideoDecoderService, 0xfc51a551, 0xd5e7, 0x11d9, 0xaf, 0x55, 0x00, 0x05, 0x4e, 0x43, 0xff, 0x02)
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
IDirectXVideoDecoderService * decoder_service
HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **)
LPDIRECT3DSURFACE9 surface
static void dxva2_destroy_decoder(AVCodecContext *s)
IDirectXVideoDecoder * decoder
DXVA2 decoder object.
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
#define FF_PROFILE_H264_CONSTRAINED
#define MKTAG(a, b, c, d)
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
void * opaque
Private data of the user, can be used to carry app specific stuff.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
This structure is used to provides the necessary configurations and data to the DXVA2 Libav HWAccel i...
IDirect3DDevice9 * d3d9device