]> git.sesse.net Git - ffmpeg/blob - libavcodec/dxva2.c
Merge commit 'b200a2c8da403b5a5c8b50f8cb4a75fd4f0131b1'
[ffmpeg] / libavcodec / dxva2.c
1 /*
2  * DXVA2 HW acceleration.
3  *
4  * copyright (c) 2010 Laurent Aimar
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include <assert.h>
24 #include <string.h>
25 #include <initguid.h>
26
27 #include "libavutil/common.h"
28 #include "libavutil/log.h"
29 #include "libavutil/time.h"
30
31 #include "avcodec.h"
32 #include "dxva2_internal.h"
33
34 /* define all the GUIDs used directly here,
35  to avoid problems with inconsistent dxva2api.h versions in mingw-w64 and different MSVC version */
36 DEFINE_GUID(ff_DXVA2_ModeMPEG2_VLD,      0xee27417f, 0x5e28,0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
37 DEFINE_GUID(ff_DXVA2_ModeMPEG2and1_VLD,  0x86695f12, 0x340e,0x4f04,0x9f,0xd3,0x92,0x53,0xdd,0x32,0x74,0x60);
38 DEFINE_GUID(ff_DXVA2_ModeH264_E,         0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
39 DEFINE_GUID(ff_DXVA2_ModeH264_F,         0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
40 DEFINE_GUID(ff_DXVADDI_Intel_ModeH264_E, 0x604F8E68, 0x4951,0x4C54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
41 DEFINE_GUID(ff_DXVA2_ModeVC1_D,          0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
42 DEFINE_GUID(ff_DXVA2_ModeVC1_D2010,      0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
43 DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main,  0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
44 DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
45 DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_Profile0,0x463707f8,0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e);
46 DEFINE_GUID(ff_DXVA2_NoEncrypt,          0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
47 DEFINE_GUID(ff_GUID_NULL,                0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
48 DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
49
50 typedef struct dxva_mode {
51     const GUID     *guid;
52     enum AVCodecID codec;
53     // List of supported profiles, terminated by a FF_PROFILE_UNKNOWN entry.
54     // If NULL, don't check profile.
55     const int      *profiles;
56 } dxva_mode;
57
58 static const int prof_mpeg2_main[]   = {FF_PROFILE_MPEG2_SIMPLE,
59                                         FF_PROFILE_MPEG2_MAIN,
60                                         FF_PROFILE_UNKNOWN};
61 static const int prof_h264_high[]    = {FF_PROFILE_H264_CONSTRAINED_BASELINE,
62                                         FF_PROFILE_H264_MAIN,
63                                         FF_PROFILE_H264_HIGH,
64                                         FF_PROFILE_UNKNOWN};
65 static const int prof_hevc_main[]    = {FF_PROFILE_HEVC_MAIN,
66                                         FF_PROFILE_UNKNOWN};
67 static const int prof_hevc_main10[]  = {FF_PROFILE_HEVC_MAIN_10,
68                                         FF_PROFILE_UNKNOWN};
69
70 static const dxva_mode dxva_modes[] = {
71     /* MPEG-2 */
72     { &ff_DXVA2_ModeMPEG2_VLD,       AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
73     { &ff_DXVA2_ModeMPEG2and1_VLD,   AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
74
75     /* H.264 */
76     { &ff_DXVA2_ModeH264_F,          AV_CODEC_ID_H264, prof_h264_high },
77     { &ff_DXVA2_ModeH264_E,          AV_CODEC_ID_H264, prof_h264_high },
78     /* Intel specific H.264 mode */
79     { &ff_DXVADDI_Intel_ModeH264_E,  AV_CODEC_ID_H264, prof_h264_high },
80
81     /* VC-1 / WMV3 */
82     { &ff_DXVA2_ModeVC1_D2010,       AV_CODEC_ID_VC1 },
83     { &ff_DXVA2_ModeVC1_D2010,       AV_CODEC_ID_WMV3 },
84     { &ff_DXVA2_ModeVC1_D,           AV_CODEC_ID_VC1 },
85     { &ff_DXVA2_ModeVC1_D,           AV_CODEC_ID_WMV3 },
86
87     /* HEVC/H.265 */
88     { &ff_DXVA2_ModeHEVC_VLD_Main10, AV_CODEC_ID_HEVC, prof_hevc_main10 },
89     { &ff_DXVA2_ModeHEVC_VLD_Main,   AV_CODEC_ID_HEVC, prof_hevc_main },
90
91     /* VP8/9 */
92     { &ff_DXVA2_ModeVP9_VLD_Profile0,AV_CODEC_ID_VP9 },
93
94     { NULL,                          0 },
95 };
96
97 static int dxva_get_decoder_configuration(AVCodecContext *avctx,
98                                           const void *cfg_list,
99                                           unsigned cfg_count)
100 {
101     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
102     unsigned i, best_score = 0;
103     int best_cfg = -1;
104
105     for (i = 0; i < cfg_count; i++) {
106         unsigned score;
107         UINT ConfigBitstreamRaw;
108         GUID guidConfigBitstreamEncryption;
109
110 #if CONFIG_D3D11VA
111         if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
112             D3D11_VIDEO_DECODER_CONFIG *cfg = &((D3D11_VIDEO_DECODER_CONFIG *)cfg_list)[i];
113             ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
114             guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
115         }
116 #endif
117 #if CONFIG_DXVA2
118         if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
119             DXVA2_ConfigPictureDecode *cfg = &((DXVA2_ConfigPictureDecode *)cfg_list)[i];
120             ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
121             guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
122         }
123 #endif
124
125         if (ConfigBitstreamRaw == 1)
126             score = 1;
127         else if (avctx->codec_id == AV_CODEC_ID_H264 && ConfigBitstreamRaw == 2)
128             score = 2;
129         else
130             continue;
131         if (IsEqualGUID(&guidConfigBitstreamEncryption, &ff_DXVA2_NoEncrypt))
132             score += 16;
133         if (score > best_score) {
134             best_score = score;
135             best_cfg = i;
136         }
137     }
138
139     if (!best_score) {
140         av_log(avctx, AV_LOG_VERBOSE, "No valid decoder configuration available\n");
141         return AVERROR(EINVAL);
142     }
143
144     return best_cfg;
145 }
146
147 #if CONFIG_D3D11VA
148 static int d3d11va_validate_output(void *service, GUID guid, const void *surface_format)
149 {
150     HRESULT hr;
151     BOOL is_supported = FALSE;
152     hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice *)service,
153                                                    &guid,
154                                                    *(DXGI_FORMAT *)surface_format,
155                                                    &is_supported);
156     return SUCCEEDED(hr) && is_supported;
157 }
158 #endif
159
160 #if CONFIG_DXVA2
161 static int dxva2_validate_output(void *decoder_service, GUID guid, const void *surface_format)
162 {
163     HRESULT hr;
164     int ret = 0;
165     unsigned j, target_count;
166     D3DFORMAT *target_list;
167     hr = IDirectXVideoDecoderService_GetDecoderRenderTargets((IDirectXVideoDecoderService *)decoder_service, &guid, &target_count, &target_list);
168     if (SUCCEEDED(hr)) {
169         for (j = 0; j < target_count; j++) {
170             const D3DFORMAT format = target_list[j];
171             if (format == *(D3DFORMAT *)surface_format) {
172                 ret = 1;
173                 break;
174             }
175         }
176         CoTaskMemFree(target_list);
177     }
178     return ret;
179 }
180 #endif
181
182 static int dxva_check_codec_compatibility(AVCodecContext *avctx, const dxva_mode *mode)
183 {
184     if (mode->codec != avctx->codec_id)
185             return 0;
186
187     if (mode->profiles && !(avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) {
188         int i, found = 0;
189         for (i = 0; mode->profiles[i] != FF_PROFILE_UNKNOWN; i++) {
190             if (avctx->profile == mode->profiles[i]) {
191                 found = 1;
192                 break;
193             }
194         }
195         if (!found)
196             return 0;
197     }
198
199     return 1;
200 }
201
202 static void dxva_list_guids_debug(AVCodecContext *avctx, void *service,
203                                  unsigned guid_count, const GUID *guid_list)
204 {
205     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
206     int i;
207
208     av_log(avctx, AV_LOG_VERBOSE, "Decoder GUIDs reported as supported:\n");
209
210     for (i = 0; i < guid_count; i++) {
211         const GUID *guid = &guid_list[i];
212
213         av_log(avctx, AV_LOG_VERBOSE,
214              "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
215              (unsigned) guid->Data1, guid->Data2, guid->Data3,
216              guid->Data4[0], guid->Data4[1],
217              guid->Data4[2], guid->Data4[3],
218              guid->Data4[4], guid->Data4[5],
219              guid->Data4[6], guid->Data4[7]);
220
221 #if CONFIG_D3D11VA
222         if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
223             DXGI_FORMAT format;
224             // We don't know the maximum valid DXGI_FORMAT, so use 200 as
225             // arbitrary upper bound (that could become outdated).
226             for (format = 0; format < 200; format++) {
227                 if (d3d11va_validate_output(service, *guid, &format))
228                     av_log(avctx, AV_LOG_VERBOSE, " %d", (int)format);
229             }
230         }
231 #endif
232 #if CONFIG_DXVA2
233         if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
234             const D3DFORMAT formats[] = {MKTAG('N', 'V', '1', '2'),
235                                          MKTAG('P', '0', '1', '0')};
236             int i;
237             for (i = 0; i < FF_ARRAY_ELEMS(formats); i++) {
238                 if (dxva2_validate_output(service, *guid, &formats[i]))
239                     av_log(avctx, AV_LOG_VERBOSE, " %d", i);
240             }
241         }
242 #endif
243         av_log(avctx, AV_LOG_VERBOSE, "\n");
244     }
245 }
246
247 static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *surface_format,
248                                  unsigned guid_count, const GUID *guid_list, GUID *decoder_guid)
249 {
250     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
251     unsigned i, j;
252
253     dxva_list_guids_debug(avctx, service, guid_count, guid_list);
254
255     *decoder_guid = ff_GUID_NULL;
256     for (i = 0; dxva_modes[i].guid; i++) {
257         const dxva_mode *mode = &dxva_modes[i];
258         int validate;
259         if (!dxva_check_codec_compatibility(avctx, mode))
260             continue;
261
262         for (j = 0; j < guid_count; j++) {
263             if (IsEqualGUID(mode->guid, &guid_list[j]))
264                 break;
265         }
266         if (j == guid_count)
267             continue;
268
269 #if CONFIG_D3D11VA
270         if (sctx->pix_fmt == AV_PIX_FMT_D3D11)
271             validate = d3d11va_validate_output(service, *mode->guid, surface_format);
272 #endif
273 #if CONFIG_DXVA2
274         if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
275             validate = dxva2_validate_output(service, *mode->guid, surface_format);
276 #endif
277         if (validate) {
278             *decoder_guid = *mode->guid;
279             break;
280         }
281     }
282
283     if (IsEqualGUID(decoder_guid, &ff_GUID_NULL)) {
284         av_log(avctx, AV_LOG_VERBOSE, "No decoder device for codec found\n");
285         return AVERROR(EINVAL);
286     }
287
288     if (IsEqualGUID(decoder_guid, &ff_DXVADDI_Intel_ModeH264_E))
289         sctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
290
291     return 0;
292 }
293
294 static void bufref_free_interface(void *opaque, uint8_t *data)
295 {
296     IUnknown_Release((IUnknown *)opaque);
297 }
298
299 static AVBufferRef *bufref_wrap_interface(IUnknown *iface)
300 {
301     return av_buffer_create((uint8_t*)iface, 1, bufref_free_interface, iface, 0);
302 }
303
304 #if CONFIG_DXVA2
305
306 static int dxva2_get_decoder_configuration(AVCodecContext *avctx, const GUID *device_guid,
307                                            const DXVA2_VideoDesc *desc,
308                                            DXVA2_ConfigPictureDecode *config)
309 {
310     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
311     unsigned cfg_count;
312     DXVA2_ConfigPictureDecode *cfg_list;
313     HRESULT hr;
314     int ret;
315
316     hr = IDirectXVideoDecoderService_GetDecoderConfigurations(sctx->dxva2_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
317     if (FAILED(hr)) {
318         av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
319         return AVERROR(EINVAL);
320     }
321
322     ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
323     if (ret >= 0)
324         *config = cfg_list[ret];
325     CoTaskMemFree(cfg_list);
326     return ret;
327 }
328
329 static int dxva2_create_decoder(AVCodecContext *avctx)
330 {
331     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
332     GUID *guid_list;
333     unsigned guid_count;
334     GUID device_guid;
335     D3DFORMAT surface_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
336                                MKTAG('P', '0', '1', '0') : MKTAG('N', 'V', '1', '2');
337     DXVA2_VideoDesc desc = { 0 };
338     DXVA2_ConfigPictureDecode config;
339     HRESULT hr;
340     int ret;
341     HANDLE device_handle;
342     AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
343     AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
344     AVDXVA2DeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
345
346     hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
347                                                   &device_handle);
348     if (FAILED(hr)) {
349         av_log(avctx, AV_LOG_ERROR, "Failed to open a device handle\n");
350         goto fail;
351     }
352
353     hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle,
354                                                  &ff_IID_IDirectXVideoDecoderService,
355                                                  (void **)&sctx->dxva2_service);
356     IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle);
357     if (FAILED(hr)) {
358         av_log(avctx, AV_LOG_ERROR, "Failed to create IDirectXVideoDecoderService\n");
359         goto fail;
360     }
361
362     hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(sctx->dxva2_service, &guid_count, &guid_list);
363     if (FAILED(hr)) {
364         av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder device GUIDs\n");
365         goto fail;
366     }
367
368     ret = dxva_get_decoder_guid(avctx, sctx->dxva2_service, &surface_format,
369                                 guid_count, guid_list, &device_guid);
370     CoTaskMemFree(guid_list);
371     if (ret < 0) {
372         goto fail;
373     }
374
375     desc.SampleWidth  = avctx->coded_width;
376     desc.SampleHeight = avctx->coded_height;
377     desc.Format       = surface_format;
378
379     ret = dxva2_get_decoder_configuration(avctx, &device_guid, &desc, &config);
380     if (ret < 0) {
381         goto fail;
382     }
383
384     hr = IDirectXVideoDecoderService_CreateVideoDecoder(sctx->dxva2_service, &device_guid,
385                                                         &desc, &config, frames_hwctx->surfaces,
386                                                         frames_hwctx->nb_surfaces, &sctx->dxva2_decoder);
387     if (FAILED(hr)) {
388         av_log(avctx, AV_LOG_ERROR, "Failed to create DXVA2 video decoder\n");
389         goto fail;
390     }
391
392     sctx->dxva2_config = config;
393
394     sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->dxva2_decoder);
395     if (!sctx->decoder_ref)
396         return AVERROR(ENOMEM);
397
398     return 0;
399 fail:
400     return AVERROR(EINVAL);
401 }
402
403 #endif
404
405 #if CONFIG_D3D11VA
406
407 static int d3d11va_get_decoder_configuration(AVCodecContext *avctx,
408                                              ID3D11VideoDevice *video_device,
409                                              const D3D11_VIDEO_DECODER_DESC *desc,
410                                              D3D11_VIDEO_DECODER_CONFIG *config)
411 {
412     unsigned cfg_count = 0;
413     D3D11_VIDEO_DECODER_CONFIG *cfg_list = NULL;
414     HRESULT hr;
415     int i, ret;
416
417     hr = ID3D11VideoDevice_GetVideoDecoderConfigCount(video_device, desc, &cfg_count);
418     if (FAILED(hr)) {
419         av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
420         return AVERROR(EINVAL);
421     }
422
423     cfg_list = av_malloc_array(cfg_count, sizeof(D3D11_VIDEO_DECODER_CONFIG));
424     if (cfg_list == NULL)
425         return AVERROR(ENOMEM);
426     for (i = 0; i < cfg_count; i++) {
427         hr = ID3D11VideoDevice_GetVideoDecoderConfig(video_device, desc, i, &cfg_list[i]);
428         if (FAILED(hr)) {
429             av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations. (hr=0x%lX)\n", hr);
430             av_free(cfg_list);
431             return AVERROR(EINVAL);
432         }
433     }
434
435     ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
436     if (ret >= 0)
437         *config = cfg_list[ret];
438     av_free(cfg_list);
439     return ret;
440 }
441
442 static DXGI_FORMAT d3d11va_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)
443 {
444     switch (pix_fmt) {
445     case AV_PIX_FMT_NV12:       return DXGI_FORMAT_NV12;
446     case AV_PIX_FMT_P010:       return DXGI_FORMAT_P010;
447     case AV_PIX_FMT_YUV420P:    return DXGI_FORMAT_420_OPAQUE;
448     default:                    return DXGI_FORMAT_UNKNOWN;
449     }
450 }
451
452 static int d3d11va_create_decoder(AVCodecContext *avctx)
453 {
454     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
455     GUID *guid_list;
456     unsigned guid_count, i;
457     GUID decoder_guid;
458     D3D11_VIDEO_DECODER_DESC desc = { 0 };
459     D3D11_VIDEO_DECODER_CONFIG config;
460     AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
461     AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
462     AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
463     DXGI_FORMAT surface_format = d3d11va_map_sw_to_hw_format(frames_ctx->sw_format);
464     D3D11_TEXTURE2D_DESC texdesc;
465     HRESULT hr;
466     int ret;
467
468     if (!frames_hwctx->texture) {
469         av_log(avctx, AV_LOG_ERROR, "AVD3D11VAFramesContext.texture not set.\n");
470         return AVERROR(EINVAL);
471     }
472     ID3D11Texture2D_GetDesc(frames_hwctx->texture, &texdesc);
473
474     guid_count = ID3D11VideoDevice_GetVideoDecoderProfileCount(device_hwctx->video_device);
475     guid_list = av_malloc_array(guid_count, sizeof(*guid_list));
476     if (guid_list == NULL || guid_count == 0) {
477         av_log(avctx, AV_LOG_ERROR, "Failed to get the decoder GUIDs\n");
478         av_free(guid_list);
479         return AVERROR(EINVAL);
480     }
481     for (i = 0; i < guid_count; i++) {
482         hr = ID3D11VideoDevice_GetVideoDecoderProfile(device_hwctx->video_device, i, &guid_list[i]);
483         if (FAILED(hr)) {
484             av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder GUID %d\n", i);
485             av_free(guid_list);
486             return AVERROR(EINVAL);
487         }
488     }
489
490     ret = dxva_get_decoder_guid(avctx, device_hwctx->video_device, &surface_format,
491                                 guid_count, guid_list, &decoder_guid);
492     av_free(guid_list);
493     if (ret < 0)
494         return AVERROR(EINVAL);
495
496     desc.SampleWidth  = avctx->coded_width;
497     desc.SampleHeight = avctx->coded_height;
498     desc.OutputFormat = surface_format;
499     desc.Guid         = decoder_guid;
500
501     ret = d3d11va_get_decoder_configuration(avctx, device_hwctx->video_device, &desc, &config);
502     if (ret < 0)
503         return AVERROR(EINVAL);
504
505     sctx->d3d11_views = av_mallocz_array(texdesc.ArraySize, sizeof(sctx->d3d11_views[0]));
506     if (!sctx->d3d11_views)
507         return AVERROR(ENOMEM);
508     sctx->nb_d3d11_views = texdesc.ArraySize;
509
510     for (i = 0; i < sctx->nb_d3d11_views; i++) {
511         D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc = {
512             .DecodeProfile = decoder_guid,
513             .ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D,
514             .Texture2D = {
515                 .ArraySlice = i,
516             }
517         };
518         hr = ID3D11VideoDevice_CreateVideoDecoderOutputView(device_hwctx->video_device,
519                                                             (ID3D11Resource*) frames_hwctx->texture,
520                                                             &viewDesc,
521                                                             (ID3D11VideoDecoderOutputView**) &sctx->d3d11_views[i]);
522         if (FAILED(hr)) {
523             av_log(avctx, AV_LOG_ERROR, "Could not create the decoder output view %d\n", i);
524             return AVERROR_UNKNOWN;
525         }
526     }
527
528     hr = ID3D11VideoDevice_CreateVideoDecoder(device_hwctx->video_device, &desc,
529                                               &config, &sctx->d3d11_decoder);
530     if (FAILED(hr)) {
531         av_log(avctx, AV_LOG_ERROR, "Failed to create D3D11VA video decoder\n");
532         return AVERROR(EINVAL);
533     }
534
535     sctx->d3d11_config = config;
536     sctx->d3d11_texture = frames_hwctx->texture;
537
538     sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->d3d11_decoder);
539     if (!sctx->decoder_ref)
540         return AVERROR(ENOMEM);
541
542     return 0;
543 }
544
545 #endif
546
547 static void ff_dxva2_lock(AVCodecContext *avctx)
548 {
549 #if CONFIG_D3D11VA
550     if (ff_dxva2_is_d3d11(avctx)) {
551         FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
552         AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
553         if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
554             WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, FALSE);
555         if (sctx->device_ctx) {
556             AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
557             hwctx->lock(hwctx->lock_ctx);
558         }
559     }
560 #endif
561 }
562
563 static void ff_dxva2_unlock(AVCodecContext *avctx)
564 {
565 #if CONFIG_D3D11VA
566     if (ff_dxva2_is_d3d11(avctx)) {
567         FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
568         AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
569         if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
570             ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
571         if (sctx->device_ctx) {
572             AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
573             hwctx->unlock(hwctx->lock_ctx);
574         }
575     }
576 #endif
577 }
578
579 // This must work before the decoder is created.
580 // This somehow needs to be exported to the user.
581 static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frames_ctx)
582 {
583     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
584     int surface_alignment, num_surfaces;
585
586     frames_ctx->format = sctx->pix_fmt;
587
588     /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
589     but it causes issues for H.264 on certain AMD GPUs..... */
590     if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)
591         surface_alignment = 32;
592     /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
593     all coding features have enough room to work with */
594     else if (avctx->codec_id == AV_CODEC_ID_HEVC)
595         surface_alignment = 128;
596     else
597         surface_alignment = 16;
598
599     /* 4 base work surfaces */
600     num_surfaces = 4;
601
602     /* add surfaces based on number of possible refs */
603     if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
604         num_surfaces += 16;
605     else if (avctx->codec_id == AV_CODEC_ID_VP9)
606         num_surfaces += 8;
607     else
608         num_surfaces += 2;
609
610     /* add extra surfaces for frame threading */
611     if (avctx->active_thread_type & FF_THREAD_FRAME)
612         num_surfaces += avctx->thread_count;
613
614     frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
615                             AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
616     frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);
617     frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);
618     frames_ctx->initial_pool_size = num_surfaces;
619
620
621 #if CONFIG_DXVA2
622     if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) {
623         AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
624
625         frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
626     }
627 #endif
628
629 #if CONFIG_D3D11VA
630     if (frames_ctx->format == AV_PIX_FMT_D3D11) {
631         AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
632
633         frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
634     }
635 #endif
636 }
637
638 int ff_dxva2_decode_init(AVCodecContext *avctx)
639 {
640     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
641     AVHWFramesContext *frames_ctx = NULL;
642     int ret = 0;
643
644     // Old API.
645     if (avctx->hwaccel_context)
646         return 0;
647
648     // (avctx->pix_fmt is not updated yet at this point)
649     sctx->pix_fmt = avctx->hwaccel->pix_fmt;
650
651     if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {
652         av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a hw_device_ctx needs to be set for hardware decoding.\n");
653         return AVERROR(EINVAL);
654     }
655
656     if (avctx->hw_frames_ctx) {
657         frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
658     } else {
659         avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
660         if (!avctx->hw_frames_ctx)
661             return AVERROR(ENOMEM);
662
663         frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
664
665         dxva_adjust_hwframes(avctx, frames_ctx);
666
667         ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
668         if (ret < 0)
669             goto fail;
670     }
671
672     sctx->device_ctx = frames_ctx->device_ctx;
673
674     if (frames_ctx->format != sctx->pix_fmt ||
675         !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) ||
676           (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) {
677         av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
678         ret = AVERROR(EINVAL);
679         goto fail;
680     }
681
682 #if CONFIG_D3D11VA
683     if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
684         AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
685         AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va;
686
687         ff_dxva2_lock(avctx);
688         ret = d3d11va_create_decoder(avctx);
689         ff_dxva2_unlock(avctx);
690         if (ret < 0)
691             goto fail;
692
693         d3d11_ctx->decoder       = sctx->d3d11_decoder;
694         d3d11_ctx->video_context = device_hwctx->video_context;
695         d3d11_ctx->cfg           = &sctx->d3d11_config;
696         d3d11_ctx->surface_count = sctx->nb_d3d11_views;
697         d3d11_ctx->surface       = sctx->d3d11_views;
698         d3d11_ctx->workaround    = sctx->workaround;
699         d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;
700     }
701 #endif
702
703 #if CONFIG_DXVA2
704     if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
705         AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
706         struct dxva_context *dxva_ctx = &sctx->ctx.dxva2;
707
708         ff_dxva2_lock(avctx);
709         ret = dxva2_create_decoder(avctx);
710         ff_dxva2_unlock(avctx);
711         if (ret < 0)
712             goto fail;
713
714         dxva_ctx->decoder       = sctx->dxva2_decoder;
715         dxva_ctx->cfg           = &sctx->dxva2_config;
716         dxva_ctx->surface       = frames_hwctx->surfaces;
717         dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
718         dxva_ctx->workaround    = sctx->workaround;
719     }
720 #endif
721
722     return 0;
723
724 fail:
725     ff_dxva2_decode_uninit(avctx);
726     return ret;
727 }
728
729 int ff_dxva2_decode_uninit(AVCodecContext *avctx)
730 {
731     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
732     int i;
733
734     av_buffer_unref(&sctx->decoder_ref);
735
736 #if CONFIG_D3D11VA
737     for (i = 0; i < sctx->nb_d3d11_views; i++) {
738         if (sctx->d3d11_views[i])
739             ID3D11VideoDecoderOutputView_Release(sctx->d3d11_views[i]);
740     }
741     av_freep(&sctx->d3d11_views);
742 #endif
743
744 #if CONFIG_DXVA2
745     if (sctx->dxva2_service)
746         IDirectXVideoDecoderService_Release(sctx->dxva2_service);
747 #endif
748
749     return 0;
750 }
751
752 static void *get_surface(const AVCodecContext *avctx, const AVFrame *frame)
753 {
754 #if CONFIG_D3D11VA
755     if (frame->format == AV_PIX_FMT_D3D11) {
756         FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
757         intptr_t index = (intptr_t)frame->data[1];
758         if (index < 0 || index >= sctx->nb_d3d11_views ||
759             sctx->d3d11_texture != (ID3D11Texture2D *)frame->data[0]) {
760             av_log((void *)avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
761             return NULL;
762         }
763         return sctx->d3d11_views[index];
764     }
765 #endif
766     return frame->data[3];
767 }
768
769 unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
770                                     const AVDXVAContext *ctx,
771                                     const AVFrame *frame)
772 {
773     void *surface = get_surface(avctx, frame);
774     unsigned i;
775
776 #if CONFIG_D3D11VA
777     if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
778         return (intptr_t)frame->data[1];
779     if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
780         D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
781         ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
782         return viewDesc.Texture2D.ArraySlice;
783     }
784 #endif
785 #if CONFIG_DXVA2
786     for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
787         if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
788             return i;
789     }
790 #endif
791
792     assert(0);
793     return 0;
794 }
795
796 int ff_dxva2_commit_buffer(AVCodecContext *avctx,
797                            AVDXVAContext *ctx,
798                            DECODER_BUFFER_DESC *dsc,
799                            unsigned type, const void *data, unsigned size,
800                            unsigned mb_count)
801 {
802     void     *dxva_data;
803     unsigned dxva_size;
804     int      result;
805     HRESULT hr = 0;
806
807 #if CONFIG_D3D11VA
808     if (ff_dxva2_is_d3d11(avctx))
809         hr = ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
810                                                  D3D11VA_CONTEXT(ctx)->decoder,
811                                                  type,
812                                                  &dxva_size, &dxva_data);
813 #endif
814 #if CONFIG_DXVA2
815     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
816         hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, type,
817                                             &dxva_data, &dxva_size);
818 #endif
819     if (FAILED(hr)) {
820         av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%x\n",
821                type, (unsigned)hr);
822         return -1;
823     }
824     if (size <= dxva_size) {
825         memcpy(dxva_data, data, size);
826
827 #if CONFIG_D3D11VA
828         if (ff_dxva2_is_d3d11(avctx)) {
829             D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
830             memset(dsc11, 0, sizeof(*dsc11));
831             dsc11->BufferType           = type;
832             dsc11->DataSize             = size;
833             dsc11->NumMBsInBuffer       = mb_count;
834         }
835 #endif
836 #if CONFIG_DXVA2
837         if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
838             DXVA2_DecodeBufferDesc *dsc2 = dsc;
839             memset(dsc2, 0, sizeof(*dsc2));
840             dsc2->CompressedBufferType = type;
841             dsc2->DataSize             = size;
842             dsc2->NumMBsInBuffer       = mb_count;
843         }
844 #endif
845
846         result = 0;
847     } else {
848         av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", type);
849         result = -1;
850     }
851
852 #if CONFIG_D3D11VA
853     if (ff_dxva2_is_d3d11(avctx))
854         hr = ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type);
855 #endif
856 #if CONFIG_DXVA2
857     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
858         hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type);
859 #endif
860     if (FAILED(hr)) {
861         av_log(avctx, AV_LOG_ERROR,
862                "Failed to release buffer type %u: 0x%x\n",
863                type, (unsigned)hr);
864         result = -1;
865     }
866     return result;
867 }
868
869 static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
870 {
871     int i;
872
873     for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
874         if (!frame->buf[i]) {
875             frame->buf[i] = av_buffer_ref(ref);
876             return frame->buf[i] ? 0 : AVERROR(ENOMEM);
877         }
878     }
879
880     // For now we expect that the caller does not use more than
881     // AV_NUM_DATA_POINTERS-1 buffers if the user uses a custom pool.
882     return AVERROR(EINVAL);
883 }
884
885 int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
886                               const void *pp, unsigned pp_size,
887                               const void *qm, unsigned qm_size,
888                               int (*commit_bs_si)(AVCodecContext *,
889                                                   DECODER_BUFFER_DESC *bs,
890                                                   DECODER_BUFFER_DESC *slice))
891 {
892     AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
893     unsigned               buffer_count = 0;
894 #if CONFIG_D3D11VA
895     D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
896 #endif
897 #if CONFIG_DXVA2
898     DXVA2_DecodeBufferDesc          buffer2[4];
899 #endif
900     DECODER_BUFFER_DESC             *buffer = NULL, *buffer_slice = NULL;
901     int result, runs = 0;
902     HRESULT hr;
903     unsigned type;
904     FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
905
906     if (sctx->decoder_ref) {
907         result = frame_add_buf(frame, sctx->decoder_ref);
908         if (result < 0)
909             return result;
910     }
911
912     do {
913         ff_dxva2_lock(avctx);
914 #if CONFIG_D3D11VA
915         if (ff_dxva2_is_d3d11(avctx))
916             hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder,
917                                                       get_surface(avctx, frame),
918                                                       0, NULL);
919 #endif
920 #if CONFIG_DXVA2
921         if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
922             hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
923                                                  get_surface(avctx, frame),
924                                                  NULL);
925 #endif
926         if (hr != E_PENDING || ++runs > 50)
927             break;
928         ff_dxva2_unlock(avctx);
929         av_usleep(2000);
930     } while(1);
931
932     if (FAILED(hr)) {
933         av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%x\n", (unsigned)hr);
934         ff_dxva2_unlock(avctx);
935         return -1;
936     }
937
938 #if CONFIG_D3D11VA
939     if (ff_dxva2_is_d3d11(avctx)) {
940         buffer = &buffer11[buffer_count];
941         type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
942     }
943 #endif
944 #if CONFIG_DXVA2
945     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
946         buffer = &buffer2[buffer_count];
947         type = DXVA2_PictureParametersBufferType;
948     }
949 #endif
950     result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
951                                     type,
952                                     pp, pp_size, 0);
953     if (result) {
954         av_log(avctx, AV_LOG_ERROR,
955                "Failed to add picture parameter buffer\n");
956         goto end;
957     }
958     buffer_count++;
959
960     if (qm_size > 0) {
961 #if CONFIG_D3D11VA
962         if (ff_dxva2_is_d3d11(avctx)) {
963             buffer = &buffer11[buffer_count];
964             type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
965         }
966 #endif
967 #if CONFIG_DXVA2
968         if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
969             buffer = &buffer2[buffer_count];
970             type = DXVA2_InverseQuantizationMatrixBufferType;
971         }
972 #endif
973         result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
974                                         type,
975                                         qm, qm_size, 0);
976         if (result) {
977             av_log(avctx, AV_LOG_ERROR,
978                    "Failed to add inverse quantization matrix buffer\n");
979             goto end;
980         }
981         buffer_count++;
982     }
983
984 #if CONFIG_D3D11VA
985     if (ff_dxva2_is_d3d11(avctx)) {
986         buffer       = &buffer11[buffer_count + 0];
987         buffer_slice = &buffer11[buffer_count + 1];
988     }
989 #endif
990 #if CONFIG_DXVA2
991     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
992         buffer       = &buffer2[buffer_count + 0];
993         buffer_slice = &buffer2[buffer_count + 1];
994     }
995 #endif
996
997     result = commit_bs_si(avctx,
998                           buffer,
999                           buffer_slice);
1000     if (result) {
1001         av_log(avctx, AV_LOG_ERROR,
1002                "Failed to add bitstream or slice control buffer\n");
1003         goto end;
1004     }
1005     buffer_count += 2;
1006
1007     /* TODO Film Grain when possible */
1008
1009     assert(buffer_count == 1 + (qm_size > 0) + 2);
1010
1011 #if CONFIG_D3D11VA
1012     if (ff_dxva2_is_d3d11(avctx))
1013         hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
1014                                                      D3D11VA_CONTEXT(ctx)->decoder,
1015                                                      buffer_count, buffer11);
1016 #endif
1017 #if CONFIG_DXVA2
1018     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1019         DXVA2_DecodeExecuteParams exec = {
1020             .NumCompBuffers     = buffer_count,
1021             .pCompressedBuffers = buffer2,
1022             .pExtensionData     = NULL,
1023         };
1024         hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, &exec);
1025     }
1026 #endif
1027     if (FAILED(hr)) {
1028         av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%x\n", (unsigned)hr);
1029         result = -1;
1030     }
1031
1032 end:
1033 #if CONFIG_D3D11VA
1034     if (ff_dxva2_is_d3d11(avctx))
1035         hr = ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder);
1036 #endif
1037 #if CONFIG_DXVA2
1038     if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
1039         hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, NULL);
1040 #endif
1041     ff_dxva2_unlock(avctx);
1042     if (FAILED(hr)) {
1043         av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%x\n", (unsigned)hr);
1044         result = -1;
1045     }
1046
1047     return result;
1048 }
1049
1050 int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
1051 {
1052     if (CONFIG_D3D11VA)
1053         return avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ||
1054                avctx->pix_fmt == AV_PIX_FMT_D3D11;
1055     else
1056         return 0;
1057 }