FFmpeg
Loading...
Searching...
No Matches
dxva2.c
Go to the documentation of this file.
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 <string.h>
24#include <initguid.h>
25
26#include "libavutil/avassert.h"
27#include "libavutil/common.h"
28#include "libavutil/log.h"
29#include "libavutil/mem.h"
30#include "libavutil/time.h"
31
32#include "avcodec.h"
33#include "decode.h"
34#include "dxva2_internal.h"
35
36/* define all the GUIDs used directly here,
37 to avoid problems with inconsistent dxva2api.h versions in mingw-w64 and different MSVC version */
38DEFINE_GUID(ff_DXVA2_ModeMPEG2_VLD, 0xee27417f, 0x5e28,0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
39DEFINE_GUID(ff_DXVA2_ModeMPEG2and1_VLD, 0x86695f12, 0x340e,0x4f04,0x9f,0xd3,0x92,0x53,0xdd,0x32,0x74,0x60);
40DEFINE_GUID(ff_DXVA2_ModeH264_E, 0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
41DEFINE_GUID(ff_DXVA2_ModeH264_F, 0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
42DEFINE_GUID(ff_DXVADDI_Intel_ModeH264_E, 0x604F8E68, 0x4951,0x4C54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
43DEFINE_GUID(ff_DXVA2_ModeVC1_D, 0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
44DEFINE_GUID(ff_DXVA2_ModeVC1_D2010, 0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
45DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main, 0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
46DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
47DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_Profile0,0x463707f8,0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e);
48DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_10bit_Profile2,0xa4c749ef,0x6ecf,0x48aa,0x84,0x48,0x50,0xa7,0xa1,0x16,0x5f,0xf7);
49DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_Profile0,0xb8be4ccb,0xcf53,0x46ba,0x8d,0x59,0xd6,0xb8,0xa6,0xda,0x5d,0x2a);
50DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_Profile1,0x6936ff0f,0x45b1,0x4163,0x9c,0xc1,0x64,0x6e,0xf6,0x94,0x61,0x08);
51DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_Profile2,0x0c5f2aa1,0xe541,0x4089,0xbb,0x7b,0x98,0x11,0x0a,0x19,0xd7,0xc8);
52DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2,0x17127009,0xa00f,0x4ce1,0x99,0x4e,0xbf,0x40,0x81,0xf6,0xf3,0xf0);
53DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2_420,0x2d80bed6,0x9cac,0x4835,0x9e,0x91,0x32,0x7b,0xbc,0x4f,0x9e,0xe8);
54DEFINE_GUID(ff_DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
55DEFINE_GUID(ff_GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
56DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
57
58typedef struct dxva_mode {
59 const GUID *guid;
61 // List of supported profiles, terminated by a AV_PROFILE_UNKNOWN entry.
62 // If NULL, don't check profile.
63 const int *profiles;
64} dxva_mode;
65
87
88static const dxva_mode dxva_modes[] = {
89 /* MPEG-2 */
90 { &ff_DXVA2_ModeMPEG2_VLD, AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
91 { &ff_DXVA2_ModeMPEG2and1_VLD, AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
92
93 /* H.264 */
94 { &ff_DXVA2_ModeH264_F, AV_CODEC_ID_H264, prof_h264_high },
95 { &ff_DXVA2_ModeH264_E, AV_CODEC_ID_H264, prof_h264_high },
96 /* Intel specific H.264 mode */
97 { &ff_DXVADDI_Intel_ModeH264_E, AV_CODEC_ID_H264, prof_h264_high },
98
99 /* VC-1 / WMV3 */
100 { &ff_DXVA2_ModeVC1_D2010, AV_CODEC_ID_VC1 },
101 { &ff_DXVA2_ModeVC1_D2010, AV_CODEC_ID_WMV3 },
102 { &ff_DXVA2_ModeVC1_D, AV_CODEC_ID_VC1 },
103 { &ff_DXVA2_ModeVC1_D, AV_CODEC_ID_WMV3 },
104
105 /* HEVC/H.265 */
106 { &ff_DXVA2_ModeHEVC_VLD_Main10, AV_CODEC_ID_HEVC, prof_hevc_main10 },
107 { &ff_DXVA2_ModeHEVC_VLD_Main, AV_CODEC_ID_HEVC, prof_hevc_main },
108
109 /* VP8/9 */
110 { &ff_DXVA2_ModeVP9_VLD_Profile0, AV_CODEC_ID_VP9, prof_vp9_profile0 },
111 { &ff_DXVA2_ModeVP9_VLD_10bit_Profile2, AV_CODEC_ID_VP9, prof_vp9_profile2 },
112
113 /* AV1 */
114 { &ff_DXVA2_ModeAV1_VLD_Profile0, AV_CODEC_ID_AV1, prof_av1_profile0 },
115 { &ff_DXVA2_ModeAV1_VLD_Profile1, AV_CODEC_ID_AV1, prof_av1_profile1 },
116 { &ff_DXVA2_ModeAV1_VLD_12bit_Profile2_420, AV_CODEC_ID_AV1, prof_av1_profile2 },
117 { &ff_DXVA2_ModeAV1_VLD_12bit_Profile2, AV_CODEC_ID_AV1, prof_av1_profile2 },
118 { &ff_DXVA2_ModeAV1_VLD_Profile2, AV_CODEC_ID_AV1, prof_av1_profile2 },
119
120 { NULL, 0 },
121};
122
124 const void *cfg_list,
125 unsigned cfg_count)
126{
128 unsigned i, best_score = 0;
129 int best_cfg = -1;
130
131 for (i = 0; i < cfg_count; i++) {
132 unsigned score;
133 UINT ConfigBitstreamRaw = 0;
134 GUID guidConfigBitstreamEncryption;
135
136#if CONFIG_D3D11VA
137 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
138 D3D11_VIDEO_DECODER_CONFIG *cfg = &((D3D11_VIDEO_DECODER_CONFIG *)cfg_list)[i];
139 ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
140 guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
141 }
142#endif
143#if CONFIG_DXVA2
144 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
145 DXVA2_ConfigPictureDecode *cfg = &((DXVA2_ConfigPictureDecode *)cfg_list)[i];
146 ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
147 guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
148 }
149#endif
150
151 if (ConfigBitstreamRaw == 1)
152 score = 1;
153 else if (avctx->codec_id == AV_CODEC_ID_H264 && ConfigBitstreamRaw == 2)
154 score = 2;
155 else
156 continue;
157 if (IsEqualGUID(&guidConfigBitstreamEncryption, &ff_DXVA2_NoEncrypt))
158 score += 16;
159 if (score > best_score) {
160 best_score = score;
161 best_cfg = i;
162 }
163 }
164
165 if (!best_score) {
166 av_log(avctx, AV_LOG_VERBOSE, "No valid decoder configuration available\n");
167 return AVERROR(EINVAL);
168 }
169
170 return best_cfg;
171}
172
173#if CONFIG_D3D11VA
174static int d3d11va_validate_output(void *service, GUID guid, const void *surface_format)
175{
176 HRESULT hr;
177 BOOL is_supported = FALSE;
178 hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice *)service,
179 &guid,
180 *(DXGI_FORMAT *)surface_format,
181 &is_supported);
182 return SUCCEEDED(hr) && is_supported;
183}
184#endif
185
186#if CONFIG_DXVA2
187static int dxva2_validate_output(void *decoder_service, GUID guid, const void *surface_format)
188{
189 HRESULT hr;
190 int ret = 0;
191 unsigned j, target_count;
192 D3DFORMAT *target_list;
193 hr = IDirectXVideoDecoderService_GetDecoderRenderTargets((IDirectXVideoDecoderService *)decoder_service, &guid, &target_count, &target_list);
194 if (SUCCEEDED(hr)) {
195 for (j = 0; j < target_count; j++) {
196 const D3DFORMAT format = target_list[j];
197 if (format == *(D3DFORMAT *)surface_format) {
198 ret = 1;
199 break;
200 }
201 }
202 CoTaskMemFree(target_list);
203 }
204 return ret;
205}
206#endif
207
209{
210 if (mode->codec != avctx->codec_id)
211 return 0;
212
213 if (mode->profiles && !(avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) {
214 int i, found = 0;
215 for (i = 0; mode->profiles[i] != AV_PROFILE_UNKNOWN; i++) {
216 if (avctx->profile == mode->profiles[i]) {
217 found = 1;
218 break;
219 }
220 }
221 if (!found)
222 return 0;
223 }
224
225 return 1;
226}
227
228static void dxva_list_guids_debug(AVCodecContext *avctx, void *service,
229 unsigned guid_count, const GUID *guid_list)
230{
232 int i;
233
234 av_log(avctx, AV_LOG_VERBOSE, "Decoder GUIDs reported as supported:\n");
235
236 for (i = 0; i < guid_count; i++) {
237 const GUID *guid = &guid_list[i];
238
239 av_log(avctx, AV_LOG_VERBOSE,
240 "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
241 (unsigned) guid->Data1, guid->Data2, guid->Data3,
242 guid->Data4[0], guid->Data4[1],
243 guid->Data4[2], guid->Data4[3],
244 guid->Data4[4], guid->Data4[5],
245 guid->Data4[6], guid->Data4[7]);
246
247#if CONFIG_D3D11VA
248 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
249 DXGI_FORMAT format;
250 // We don't know the maximum valid DXGI_FORMAT, so use 200 as
251 // arbitrary upper bound (that could become outdated).
252 for (format = 0; format < 200; format++) {
253 if (d3d11va_validate_output(service, *guid, &format))
254 av_log(avctx, AV_LOG_VERBOSE, " %d", (int)format);
255 }
256 }
257#endif
258#if CONFIG_DXVA2
259 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
260 const D3DFORMAT formats[] = {MKTAG('N', 'V', '1', '2'),
261 MKTAG('P', '0', '1', '0')};
262 int i;
263 for (i = 0; i < FF_ARRAY_ELEMS(formats); i++) {
264 if (dxva2_validate_output(service, *guid, &formats[i]))
265 av_log(avctx, AV_LOG_VERBOSE, " %d", i);
266 }
267 }
268#endif
269 av_log(avctx, AV_LOG_VERBOSE, "\n");
270 }
271}
272
273static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *surface_format,
274 unsigned guid_count, const GUID *guid_list, GUID *decoder_guid)
275{
277 unsigned i, j;
278
279 dxva_list_guids_debug(avctx, service, guid_count, guid_list);
280
281 *decoder_guid = ff_GUID_NULL;
282 for (i = 0; dxva_modes[i].guid; i++) {
283 const dxva_mode *mode = &dxva_modes[i];
284 int validate = 0;
286 continue;
287
288 for (j = 0; j < guid_count; j++) {
289 if (IsEqualGUID(mode->guid, &guid_list[j]))
290 break;
291 }
292 if (j == guid_count)
293 continue;
294
295#if CONFIG_D3D11VA
296 if (sctx->pix_fmt == AV_PIX_FMT_D3D11)
297 validate = d3d11va_validate_output(service, *mode->guid, surface_format);
298#endif
299#if CONFIG_DXVA2
300 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
301 validate = dxva2_validate_output(service, *mode->guid, surface_format);
302#endif
303 if (validate) {
304 *decoder_guid = *mode->guid;
305 break;
306 }
307 }
308
309 if (IsEqualGUID(decoder_guid, &ff_GUID_NULL)) {
310 av_log(avctx, AV_LOG_VERBOSE, "No decoder device for codec found\n");
311 return AVERROR(EINVAL);
312 }
313
314 if (IsEqualGUID(decoder_guid, &ff_DXVADDI_Intel_ModeH264_E))
316
317 return 0;
318}
319
320static void bufref_free_interface(void *opaque, uint8_t *data)
321{
322 IUnknown_Release((IUnknown *)opaque);
323}
324
325static AVBufferRef *bufref_wrap_interface(IUnknown *iface)
326{
327 return av_buffer_create((uint8_t*)iface, 1, bufref_free_interface, iface, 0);
328}
329
330#if CONFIG_DXVA2
331
332static int dxva2_get_decoder_configuration(AVCodecContext *avctx, const GUID *device_guid,
333 const DXVA2_VideoDesc *desc,
334 DXVA2_ConfigPictureDecode *config)
335{
337 unsigned cfg_count;
338 DXVA2_ConfigPictureDecode *cfg_list;
339 HRESULT hr;
340 int ret;
341
342 hr = IDirectXVideoDecoderService_GetDecoderConfigurations(sctx->dxva2_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
343 if (FAILED(hr)) {
344 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
345 return AVERROR(EINVAL);
346 }
347
348 ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
349 if (ret >= 0)
350 *config = cfg_list[ret];
351 CoTaskMemFree(cfg_list);
352 return ret;
353}
354
355static D3DFORMAT dxva2_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)
356{
357 switch (pix_fmt) {
358 case AV_PIX_FMT_NV12: return MKTAG('N', 'V', '1', '2');
359 case AV_PIX_FMT_P010: return MKTAG('P', '0', '1', '0');
360 default: return D3DFMT_UNKNOWN;
361 }
362}
363
364static int dxva2_create_decoder(AVCodecContext *avctx)
365{
367 GUID *guid_list;
368 unsigned guid_count;
369 GUID device_guid;
371 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
372 AVDXVA2DeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
373 D3DFORMAT surface_format = dxva2_map_sw_to_hw_format(frames_ctx->sw_format);
374 DXVA2_VideoDesc desc = { 0 };
375 DXVA2_ConfigPictureDecode config;
376 HRESULT hr;
377 int ret;
378 HANDLE device_handle;
379
380 hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
381 &device_handle);
382 if (FAILED(hr)) {
383 av_log(avctx, AV_LOG_ERROR, "Failed to open a device handle\n");
384 goto fail;
385 }
386
387 hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle,
388 &ff_IID_IDirectXVideoDecoderService,
389 (void **)&sctx->dxva2_service);
390 IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle);
391 if (FAILED(hr)) {
392 av_log(avctx, AV_LOG_ERROR, "Failed to create IDirectXVideoDecoderService\n");
393 goto fail;
394 }
395
396 hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(sctx->dxva2_service, &guid_count, &guid_list);
397 if (FAILED(hr)) {
398 av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder device GUIDs\n");
399 goto fail;
400 }
401
402 ret = dxva_get_decoder_guid(avctx, sctx->dxva2_service, &surface_format,
403 guid_count, guid_list, &device_guid);
404 CoTaskMemFree(guid_list);
405 if (ret < 0) {
406 goto fail;
407 }
408
409 desc.SampleWidth = avctx->coded_width;
410 desc.SampleHeight = avctx->coded_height;
411 desc.Format = surface_format;
412
413 ret = dxva2_get_decoder_configuration(avctx, &device_guid, &desc, &config);
414 if (ret < 0) {
415 goto fail;
416 }
417
418 hr = IDirectXVideoDecoderService_CreateVideoDecoder(sctx->dxva2_service, &device_guid,
419 &desc, &config, frames_hwctx->surfaces,
420 frames_hwctx->nb_surfaces, &sctx->dxva2_decoder);
421 if (FAILED(hr)) {
422 av_log(avctx, AV_LOG_ERROR, "Failed to create DXVA2 video decoder\n");
423 goto fail;
424 }
425
426 sctx->dxva2_config = config;
427
428 sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->dxva2_decoder);
429 if (!sctx->decoder_ref)
430 return AVERROR(ENOMEM);
431
432 return 0;
433fail:
434 return AVERROR(EINVAL);
435}
436
437#endif
438
439#if CONFIG_D3D11VA
440
441static int d3d11va_get_decoder_configuration(AVCodecContext *avctx,
442 ID3D11VideoDevice *video_device,
443 const D3D11_VIDEO_DECODER_DESC *desc,
444 D3D11_VIDEO_DECODER_CONFIG *config)
445{
446 unsigned cfg_count = 0;
447 D3D11_VIDEO_DECODER_CONFIG *cfg_list = NULL;
448 HRESULT hr;
449 int i, ret;
450
451 hr = ID3D11VideoDevice_GetVideoDecoderConfigCount(video_device, desc, &cfg_count);
452 if (FAILED(hr)) {
453 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
454 return AVERROR(EINVAL);
455 }
456
457 cfg_list = av_malloc_array(cfg_count, sizeof(D3D11_VIDEO_DECODER_CONFIG));
458 if (cfg_list == NULL)
459 return AVERROR(ENOMEM);
460 for (i = 0; i < cfg_count; i++) {
461 hr = ID3D11VideoDevice_GetVideoDecoderConfig(video_device, desc, i, &cfg_list[i]);
462 if (FAILED(hr)) {
463 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations. (hr=0x%lX)\n", hr);
464 av_free(cfg_list);
465 return AVERROR(EINVAL);
466 }
467 }
468
469 ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
470 if (ret >= 0)
471 *config = cfg_list[ret];
472 av_free(cfg_list);
473 return ret;
474}
475
476static DXGI_FORMAT d3d11va_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)
477{
478 switch (pix_fmt) {
479 case AV_PIX_FMT_NV12: return DXGI_FORMAT_NV12;
480 case AV_PIX_FMT_P010: return DXGI_FORMAT_P010;
481 case AV_PIX_FMT_P012:
482 case AV_PIX_FMT_P016: return DXGI_FORMAT_P016;
483 case AV_PIX_FMT_YUYV422: return DXGI_FORMAT_YUY2;
484 case AV_PIX_FMT_Y210: return DXGI_FORMAT_Y210;
485 case AV_PIX_FMT_Y212:
486 case AV_PIX_FMT_Y216: return DXGI_FORMAT_Y216;
487 case AV_PIX_FMT_VUYX: return DXGI_FORMAT_AYUV;
488 case AV_PIX_FMT_XV30: return DXGI_FORMAT_Y410;
489 case AV_PIX_FMT_XV36:
490 case AV_PIX_FMT_XV48: return DXGI_FORMAT_Y416;
491 case AV_PIX_FMT_YUV420P: return DXGI_FORMAT_420_OPAQUE;
492 default: return DXGI_FORMAT_UNKNOWN;
493 }
494}
495
496static int d3d11va_create_decoder(AVCodecContext *avctx)
497{
499 GUID *guid_list;
500 unsigned guid_count, i;
501 GUID decoder_guid;
502 D3D11_VIDEO_DECODER_DESC desc = { 0 };
503 D3D11_VIDEO_DECODER_CONFIG config;
504 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
505 AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
506 AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
507 DXGI_FORMAT surface_format = d3d11va_map_sw_to_hw_format(frames_ctx->sw_format);
508 D3D11_TEXTURE2D_DESC texdesc;
509 HRESULT hr;
510 int ret;
511
512 if (!frames_hwctx->texture) {
513 av_log(avctx, AV_LOG_ERROR, "AVD3D11VAFramesContext.texture not set.\n");
514 return AVERROR(EINVAL);
515 }
516 ID3D11Texture2D_GetDesc(frames_hwctx->texture, &texdesc);
517
518 guid_count = ID3D11VideoDevice_GetVideoDecoderProfileCount(device_hwctx->video_device);
519 guid_list = av_malloc_array(guid_count, sizeof(*guid_list));
520 if (guid_list == NULL || guid_count == 0) {
521 av_log(avctx, AV_LOG_ERROR, "Failed to get the decoder GUIDs\n");
522 av_free(guid_list);
523 return AVERROR(EINVAL);
524 }
525 for (i = 0; i < guid_count; i++) {
526 hr = ID3D11VideoDevice_GetVideoDecoderProfile(device_hwctx->video_device, i, &guid_list[i]);
527 if (FAILED(hr)) {
528 av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder GUID %d\n", i);
529 av_free(guid_list);
530 return AVERROR(EINVAL);
531 }
532 }
533
534 ret = dxva_get_decoder_guid(avctx, device_hwctx->video_device, &surface_format,
535 guid_count, guid_list, &decoder_guid);
536 av_free(guid_list);
537 if (ret < 0)
538 return AVERROR(EINVAL);
539
540 desc.SampleWidth = avctx->coded_width;
541 desc.SampleHeight = avctx->coded_height;
542 desc.OutputFormat = surface_format;
543 desc.Guid = decoder_guid;
544
545 ret = d3d11va_get_decoder_configuration(avctx, device_hwctx->video_device, &desc, &config);
546 if (ret < 0)
547 return AVERROR(EINVAL);
548
549 sctx->d3d11_views = av_calloc(texdesc.ArraySize, sizeof(sctx->d3d11_views[0]));
550 if (!sctx->d3d11_views)
551 return AVERROR(ENOMEM);
552 sctx->nb_d3d11_views = texdesc.ArraySize;
553
554 for (i = 0; i < sctx->nb_d3d11_views; i++) {
555 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc = {
556 .DecodeProfile = decoder_guid,
557 .ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D,
558 .Texture2D = {
559 .ArraySlice = i,
560 }
561 };
562 hr = ID3D11VideoDevice_CreateVideoDecoderOutputView(device_hwctx->video_device,
563 (ID3D11Resource*) frames_hwctx->texture,
564 &viewDesc,
565 (ID3D11VideoDecoderOutputView**) &sctx->d3d11_views[i]);
566 if (FAILED(hr)) {
567 av_log(avctx, AV_LOG_ERROR, "Could not create the decoder output view %d\n", i);
568 return AVERROR_UNKNOWN;
569 }
570 }
571
572 hr = ID3D11VideoDevice_CreateVideoDecoder(device_hwctx->video_device, &desc,
573 &config, &sctx->d3d11_decoder);
574 if (FAILED(hr)) {
575 av_log(avctx, AV_LOG_ERROR, "Failed to create D3D11VA video decoder\n");
576 return AVERROR(EINVAL);
577 }
578
579 sctx->d3d11_config = config;
580 sctx->d3d11_texture = frames_hwctx->texture;
581
582 sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->d3d11_decoder);
583 if (!sctx->decoder_ref)
584 return AVERROR(ENOMEM);
585
586 return 0;
587}
588
589#endif
590
591static void ff_dxva2_lock(AVCodecContext *avctx)
592{
593#if CONFIG_D3D11VA
594 if (ff_dxva2_is_d3d11(avctx)) {
597 if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
598 WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, FALSE);
599 if (sctx->device_ctx) {
601 hwctx->lock(hwctx->lock_ctx);
602 }
603 }
604#endif
605}
606
608{
609#if CONFIG_D3D11VA
610 if (ff_dxva2_is_d3d11(avctx)) {
613 if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
614 ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
615 if (sctx->device_ctx) {
617 hwctx->unlock(hwctx->lock_ctx);
618 }
619 }
620#endif
621}
622
624 AVBufferRef *hw_frames_ctx)
625{
626 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)hw_frames_ctx->data;
627 AVHWDeviceContext *device_ctx = frames_ctx->device_ctx;
628 int surface_alignment, num_surfaces;
629
630 if (device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
631 frames_ctx->format = AV_PIX_FMT_DXVA2_VLD;
632 } else if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
633 frames_ctx->format = AV_PIX_FMT_D3D11;
634 } else {
635 return AVERROR(EINVAL);
636 }
637
638 /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
639 but it causes issues for H.264 on certain AMD GPUs..... */
640 if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)
641 surface_alignment = 32;
642 /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
643 all coding features have enough room to work with */
644 else if (avctx->codec_id == AV_CODEC_ID_HEVC || avctx->codec_id == AV_CODEC_ID_AV1)
645 surface_alignment = 128;
646 else
647 surface_alignment = 16;
648
649 /* 1 base work surface */
650 num_surfaces = 1;
651
652 /* add surfaces based on number of possible refs */
653 if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
654 num_surfaces += 16;
655 else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1)
656 num_surfaces += 8;
657 else
658 num_surfaces += 2;
659
660 switch (avctx->sw_pix_fmt) {
661 case AV_PIX_FMT_YUV420P10: frames_ctx->sw_format = AV_PIX_FMT_P010; break;
662 case AV_PIX_FMT_YUV420P12: frames_ctx->sw_format = AV_PIX_FMT_P012; break;
663 case AV_PIX_FMT_YUV422P: frames_ctx->sw_format = AV_PIX_FMT_YUYV422; break;
664 case AV_PIX_FMT_YUV422P10: frames_ctx->sw_format = AV_PIX_FMT_Y210; break;
665 case AV_PIX_FMT_YUV422P12: frames_ctx->sw_format = AV_PIX_FMT_Y212; break;
666 case AV_PIX_FMT_YUV444P: frames_ctx->sw_format = AV_PIX_FMT_VUYX; break;
667 case AV_PIX_FMT_YUV444P10: frames_ctx->sw_format = AV_PIX_FMT_XV30; break;
668 case AV_PIX_FMT_YUV444P12: frames_ctx->sw_format = AV_PIX_FMT_XV36; break;
669 default: frames_ctx->sw_format = AV_PIX_FMT_NV12; break;
670 }
671 frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);
672 frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);
673 frames_ctx->initial_pool_size = num_surfaces;
674
675
676#if CONFIG_DXVA2
677 if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) {
678 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
679
680 frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
681 }
682#endif
683
684#if CONFIG_D3D11VA
685 if (frames_ctx->format == AV_PIX_FMT_D3D11) {
686 AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
687
688 frames_hwctx->BindFlags |= D3D11_BIND_DECODER | D3D11_BIND_SHADER_RESOURCE;
689 }
690#endif
691
692 return 0;
693}
694
696{
698 AVHWFramesContext *frames_ctx;
699 enum AVHWDeviceType dev_type = avctx->hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD
701 int ret = 0;
702
703 // Old API.
704 if (avctx->hwaccel_context)
705 return 0;
706
707 // (avctx->pix_fmt is not updated yet at this point)
708 sctx->pix_fmt = avctx->hwaccel->pix_fmt;
709
710 ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
711 if (ret < 0)
712 return ret;
713
714 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
715 sctx->device_ctx = frames_ctx->device_ctx;
716
717 if (frames_ctx->format != sctx->pix_fmt) {
718 av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
719 ret = AVERROR(EINVAL);
720 goto fail;
721 }
722
723#if CONFIG_D3D11VA
724 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
725 AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
726 AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va;
727
728 ff_dxva2_lock(avctx);
729 ret = d3d11va_create_decoder(avctx);
730 ff_dxva2_unlock(avctx);
731 if (ret < 0)
732 goto fail;
733
734 d3d11_ctx->decoder = sctx->d3d11_decoder;
735 d3d11_ctx->video_context = device_hwctx->video_context;
736 d3d11_ctx->cfg = &sctx->d3d11_config;
737 d3d11_ctx->surface_count = sctx->nb_d3d11_views;
738 d3d11_ctx->surface = sctx->d3d11_views;
739 d3d11_ctx->workaround = sctx->workaround;
740 d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;
741 }
742#endif
743
744#if CONFIG_DXVA2
745 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
746 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
747 struct dxva_context *dxva_ctx = &sctx->ctx.dxva2;
748
749 ff_dxva2_lock(avctx);
750 ret = dxva2_create_decoder(avctx);
751 ff_dxva2_unlock(avctx);
752 if (ret < 0)
753 goto fail;
754
755 dxva_ctx->decoder = sctx->dxva2_decoder;
756 dxva_ctx->cfg = &sctx->dxva2_config;
757 dxva_ctx->surface = frames_hwctx->surfaces;
758 dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
759 dxva_ctx->workaround = sctx->workaround;
760 }
761#endif
762
763 return 0;
764
765fail:
767 return ret;
768}
769
771{
773 int i;
774
776
777#if CONFIG_D3D11VA
778 for (i = 0; i < sctx->nb_d3d11_views; i++) {
779 if (sctx->d3d11_views[i])
780 ID3D11VideoDecoderOutputView_Release(sctx->d3d11_views[i]);
781 }
782 av_freep(&sctx->d3d11_views);
783#endif
784
785#if CONFIG_DXVA2
786 if (sctx->dxva2_service)
787 IDirectXVideoDecoderService_Release(sctx->dxva2_service);
788#endif
789
790 return 0;
791}
792
793static void *get_surface(const AVCodecContext *avctx, const AVFrame *frame)
794{
795#if CONFIG_D3D11VA
796 if (frame->format == AV_PIX_FMT_D3D11) {
798 intptr_t index = (intptr_t)frame->data[1];
799 if (index < 0 || index >= sctx->nb_d3d11_views ||
800 sctx->d3d11_texture != (ID3D11Texture2D *)frame->data[0]) {
801 av_log((void *)avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
802 return NULL;
803 }
804 return sctx->d3d11_views[index];
805 }
806#endif
807 return frame->data[3];
808}
809
812 int curr)
813{
814 void *surface = get_surface(avctx, frame);
815
816#if CONFIG_D3D12VA
817 if (avctx->pix_fmt == AV_PIX_FMT_D3D12) {
819 }
820#endif
821#if CONFIG_D3D11VA
822 if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
823 return (intptr_t)frame->data[1];
824 if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
825 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
826 ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
827 return viewDesc.Texture2D.ArraySlice;
828 }
829#endif
830#if CONFIG_DXVA2
831 for (unsigned i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
832 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
833 return i;
834 }
835#endif
836
837 av_log((AVCodecContext *)avctx, AV_LOG_WARNING, "Could not get surface index. Using 0 instead.\n");
838 return 0;
839}
840
844 unsigned type, const void *data, unsigned size,
845 unsigned mb_count)
846{
847 void *dxva_data = NULL;
848 unsigned dxva_size;
849 int result;
850 HRESULT hr = 0;
851
852#if CONFIG_D3D11VA
853 if (ff_dxva2_is_d3d11(avctx))
854 hr = ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
856 type,
857 &dxva_size, &dxva_data);
858#endif
859#if CONFIG_DXVA2
860 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
861 hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, type,
862 &dxva_data, &dxva_size);
863#endif
864 if (FAILED(hr)) {
865 av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%x\n",
866 type, (unsigned)hr);
867 return -1;
868 }
869 if (dxva_data && size <= dxva_size) {
870 memcpy(dxva_data, data, size);
871
872#if CONFIG_D3D11VA
873 if (ff_dxva2_is_d3d11(avctx)) {
874 D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
875 memset(dsc11, 0, sizeof(*dsc11));
876 dsc11->BufferType = type;
877 dsc11->DataSize = size;
878 dsc11->NumMBsInBuffer = mb_count;
879 }
880#endif
881#if CONFIG_DXVA2
882 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
883 DXVA2_DecodeBufferDesc *dsc2 = dsc;
884 memset(dsc2, 0, sizeof(*dsc2));
885 dsc2->CompressedBufferType = type;
886 dsc2->DataSize = size;
887 dsc2->NumMBsInBuffer = mb_count;
888 }
889#endif
890
891 result = 0;
892 } else {
893 av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", type);
894 result = -1;
895 }
896
897#if CONFIG_D3D11VA
898 if (ff_dxva2_is_d3d11(avctx))
899 hr = ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type);
900#endif
901#if CONFIG_DXVA2
902 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
903 hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type);
904#endif
905 if (FAILED(hr)) {
906 av_log(avctx, AV_LOG_ERROR,
907 "Failed to release buffer type %u: 0x%x\n",
908 type, (unsigned)hr);
909 result = -1;
910 }
911 return result;
912}
913
915{
916 int i;
917
918 for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
919 if (!frame->buf[i]) {
920 frame->buf[i] = av_buffer_ref(ref);
921 return frame->buf[i] ? 0 : AVERROR(ENOMEM);
922 }
923 }
924
925 // For now we expect that the caller does not use more than
926 // AV_NUM_DATA_POINTERS-1 buffers if the user uses a custom pool.
927 return AVERROR(EINVAL);
928}
929
931 const void *pp, unsigned pp_size,
932 const void *qm, unsigned qm_size,
933 int (*commit_bs_si)(AVCodecContext *,
935 DECODER_BUFFER_DESC *slice))
936{
938 unsigned buffer_count = 0;
939#if CONFIG_D3D11VA
940 D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
941#endif
942#if CONFIG_DXVA2
943 DXVA2_DecodeBufferDesc buffer2[4];
944#endif
945 DECODER_BUFFER_DESC *buffer = NULL, *buffer_slice = NULL;
946 int result, runs = 0;
947 HRESULT hr = -1;
948 unsigned type;
950
951 if (sctx->decoder_ref) {
952 result = frame_add_buf(frame, sctx->decoder_ref);
953 if (result < 0)
954 return result;
955 }
956
957 do {
958 ff_dxva2_lock(avctx);
959#if CONFIG_D3D11VA
960 if (ff_dxva2_is_d3d11(avctx))
961 hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder,
962 get_surface(avctx, frame),
963 0, NULL);
964#endif
965#if CONFIG_DXVA2
966 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
967 hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
968 get_surface(avctx, frame),
969 NULL);
970#endif
971 if (hr != E_PENDING || ++runs > 50)
972 break;
973 ff_dxva2_unlock(avctx);
974 av_usleep(2000);
975 } while(1);
976
977 if (FAILED(hr)) {
978 av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%x\n", (unsigned)hr);
979 ff_dxva2_unlock(avctx);
980 return -1;
981 }
982
983#if CONFIG_D3D11VA
984 if (ff_dxva2_is_d3d11(avctx)) {
985 buffer = &buffer11[buffer_count];
986 type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
987 }
988#endif
989#if CONFIG_DXVA2
990 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
991 buffer = &buffer2[buffer_count];
992 type = DXVA2_PictureParametersBufferType;
993 }
994#endif
995 result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
996 type,
997 pp, pp_size, 0);
998 if (result) {
999 av_log(avctx, AV_LOG_ERROR,
1000 "Failed to add picture parameter buffer\n");
1001 goto end;
1002 }
1003 buffer_count++;
1004
1005 if (qm_size > 0) {
1006#if CONFIG_D3D11VA
1007 if (ff_dxva2_is_d3d11(avctx)) {
1008 buffer = &buffer11[buffer_count];
1009 type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
1010 }
1011#endif
1012#if CONFIG_DXVA2
1013 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1014 buffer = &buffer2[buffer_count];
1015 type = DXVA2_InverseQuantizationMatrixBufferType;
1016 }
1017#endif
1018 result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
1019 type,
1020 qm, qm_size, 0);
1021 if (result) {
1022 av_log(avctx, AV_LOG_ERROR,
1023 "Failed to add inverse quantization matrix buffer\n");
1024 goto end;
1025 }
1026 buffer_count++;
1027 }
1028
1029#if CONFIG_D3D11VA
1030 if (ff_dxva2_is_d3d11(avctx)) {
1031 buffer = &buffer11[buffer_count + 0];
1032 buffer_slice = &buffer11[buffer_count + 1];
1033 }
1034#endif
1035#if CONFIG_DXVA2
1036 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1037 buffer = &buffer2[buffer_count + 0];
1038 buffer_slice = &buffer2[buffer_count + 1];
1039 }
1040#endif
1041
1042 result = commit_bs_si(avctx,
1043 buffer,
1044 buffer_slice);
1045 if (result) {
1046 av_log(avctx, AV_LOG_ERROR,
1047 "Failed to add bitstream or slice control buffer\n");
1048 goto end;
1049 }
1050 buffer_count += 2;
1051
1052 /* TODO Film Grain when possible */
1053
1054 av_assert0(buffer_count == 1 + (qm_size > 0) + 2);
1055
1056#if CONFIG_D3D11VA
1057 if (ff_dxva2_is_d3d11(avctx))
1058 hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
1060 buffer_count, buffer11);
1061#endif
1062#if CONFIG_DXVA2
1063 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1064 DXVA2_DecodeExecuteParams exec = {
1065 .NumCompBuffers = buffer_count,
1066 .pCompressedBuffers = buffer2,
1067 .pExtensionData = NULL,
1068 };
1069 hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, &exec);
1070 }
1071#endif
1072 if (FAILED(hr)) {
1073 av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%x\n", (unsigned)hr);
1074 result = -1;
1075 }
1076
1077end:
1078#if CONFIG_D3D11VA
1079 if (ff_dxva2_is_d3d11(avctx))
1080 hr = ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder);
1081#endif
1082#if CONFIG_DXVA2
1083 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
1084 hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, NULL);
1085#endif
1086 ff_dxva2_unlock(avctx);
1087 if (FAILED(hr)) {
1088 av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%x\n", (unsigned)hr);
1089 result = -1;
1090 }
1091
1092 return result;
1093}
1094
1096{
1097 if (CONFIG_D3D11VA)
1098 return avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ||
1099 avctx->pix_fmt == AV_PIX_FMT_D3D11;
1100 else
1101 return 0;
1102}
1103
1105{
1106 unsigned *report_id = NULL;
1107
1108#if CONFIG_D3D12VA
1109 if (avctx->pix_fmt == AV_PIX_FMT_D3D12)
1110 report_id = &ctx->d3d12va.report_id;
1111#endif
1112#if CONFIG_D3D11VA
1113 if (ff_dxva2_is_d3d11(avctx))
1114 report_id = &ctx->d3d11va.report_id;
1115#endif
1116#if CONFIG_DXVA2
1117 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
1118 report_id = &ctx->dxva2.report_id;
1119#endif
1120
1121 return report_id;
1122}
static const char *const format[]
Definition af_aiir.c:445
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
common internal and external API header
#define NULL
Definition coverity.c:32
unsigned ff_d3d12va_get_surface_index(const AVCodecContext *avctx, D3D12VADecodeContext *ctx, const AVFrame *frame, int curr)
static void bufref_free_interface(void *opaque, uint8_t *data)
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition decode.c:1073
#define AV_PROFILE_MPEG2_MAIN
Definition defs.h:113
#define AV_PROFILE_AV1_HIGH
Definition defs.h:179
#define AV_PROFILE_H264_MAIN
Definition defs.h:121
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_HEVC_MAIN
Definition defs.h:168
#define AV_PROFILE_HEVC_MAIN_10
Definition defs.h:169
#define AV_PROFILE_H264_HIGH
Definition defs.h:123
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition defs.h:120
#define AV_PROFILE_VP9_0
Definition defs.h:163
#define AV_PROFILE_VP9_2
Definition defs.h:165
#define AV_PROFILE_AV1_MAIN
Definition defs.h:178
#define AV_PROFILE_AV1_PROFESSIONAL
Definition defs.h:180
#define AV_PROFILE_MPEG2_SIMPLE
Definition defs.h:114
static enum AVPixelFormat pix_fmt
static AVFrame * frame
static const dxva_mode dxva_modes[]
Definition dxva2.c:88
int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
Definition dxva2.c:1095
static const int prof_hevc_main[]
Definition dxva2.c:73
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, AVDXVAContext *ctx, const AVFrame *frame, int curr)
Definition dxva2.c:810
static const int prof_vp9_profile0[]
Definition dxva2.c:77
static const int prof_av1_profile2[]
Definition dxva2.c:85
static void ff_dxva2_unlock(AVCodecContext *avctx)
Definition dxva2.c:607
static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
Definition dxva2.c:914
unsigned * ff_dxva2_get_report_id(const AVCodecContext *avctx, AVDXVAContext *ctx)
Definition dxva2.c:1104
static const int prof_hevc_main10[]
Definition dxva2.c:75
static void ff_dxva2_lock(AVCodecContext *avctx)
Definition dxva2.c:591
static void * get_surface(const AVCodecContext *avctx, const AVFrame *frame)
Definition dxva2.c:793
int ff_dxva2_decode_init(AVCodecContext *avctx)
Definition dxva2.c:695
static AVBufferRef * bufref_wrap_interface(IUnknown *iface)
Definition dxva2.c:325
int ff_dxva2_commit_buffer(AVCodecContext *avctx, AVDXVAContext *ctx, DECODER_BUFFER_DESC *dsc, unsigned type, const void *data, unsigned size, unsigned mb_count)
Definition dxva2.c:841
static int dxva_get_decoder_configuration(AVCodecContext *avctx, const void *cfg_list, unsigned cfg_count)
Definition dxva2.c:123
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
Definition dxva2.c:770
int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, const void *pp, unsigned pp_size, const void *qm, unsigned qm_size, int(*commit_bs_si)(AVCodecContext *, DECODER_BUFFER_DESC *bs, DECODER_BUFFER_DESC *slice))
Definition dxva2.c:930
static const int prof_mpeg2_main[]
Definition dxva2.c:66
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition dxva2.c:623
static const int prof_av1_profile1[]
Definition dxva2.c:83
static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *surface_format, unsigned guid_count, const GUID *guid_list, GUID *decoder_guid)
Definition dxva2.c:273
static const int prof_h264_high[]
Definition dxva2.c:69
static void dxva_list_guids_debug(AVCodecContext *avctx, void *service, unsigned guid_count, const GUID *guid_list)
Definition dxva2.c:228
static const int prof_vp9_profile2[]
Definition dxva2.c:79
static int dxva_check_codec_compatibility(AVCodecContext *avctx, const dxva_mode *mode)
Definition dxva2.c:208
static const int prof_av1_profile0[]
Definition dxva2.c:81
static void bufref_free_interface(void *opaque, uint8_t *data)
Definition dxva2.c:320
DEFINE_GUID(ff_DXVA2_ModeMPEG2_VLD, 0xee27417f, 0x5e28, 0x4e65, 0xbe, 0xea, 0x1d, 0x26, 0xb5, 0x08, 0xad, 0xc9)
#define DXVA_CONTEXT(avctx)
#define DXVA_SHARED_CONTEXT(avctx)
#define DXVA_CONTEXT_COUNT(avctx, ctx)
#define DXVA2_CONTEXT(ctx)
#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
Work around for DXVA2/Direct3D11 and old Intel GPUs with ClearVideo interface.
#define D3D11VA_CONTEXT(ctx)
void DECODER_BUFFER_DESC
static CheckasmConfig cfg
Definition checkasm.c:74
#define AV_NUM_DATA_POINTERS
Definition frame.h:473
#define fail
Definition test.h:479
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition codec_id.h:47
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_AV1
Definition codec_id.h:275
@ AV_CODEC_ID_VC1
Definition codec_id.h:120
@ AV_CODEC_ID_HEVC
Definition codec_id.h:223
@ AV_CODEC_ID_WMV3
Definition codec_id.h:121
@ AV_CODEC_ID_VP9
Definition codec_id.h:217
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition codec_id.h:52
#define AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH
Hardware acceleration should still be attempted for decoding when the codec profile does not match th...
Definition avcodec.h:2033
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:139
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition buffer.c:103
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:55
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int index
Definition gxfenc.c:90
AVHWDeviceType
Definition hwcontext.h:27
@ AV_HWDEVICE_TYPE_D3D11VA
Definition hwcontext.h:35
@ AV_HWDEVICE_TYPE_DXVA2
Definition hwcontext.h:32
cl_device_type type
static const chunk_decoder decoder[8]
Definition dfa.c:331
const char * desc
Definition libsvtav1.c:83
#define MKTAG(a, b, c, d)
Definition macros.h:55
#define FFALIGN(x, a)
Definition macros.h:78
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
const char data[16]
Definition mxf.c:149
#define AV_PIX_FMT_YUV444P12
Definition pixfmt.h:552
#define AV_PIX_FMT_YUV420P10
Definition pixfmt.h:545
#define AV_PIX_FMT_P012
Definition pixfmt.h:609
#define AV_PIX_FMT_YUV420P12
Definition pixfmt.h:549
#define AV_PIX_FMT_YUV422P12
Definition pixfmt.h:550
#define AV_PIX_FMT_Y210
Definition pixfmt.h:612
#define AV_PIX_FMT_P010
Definition pixfmt.h:608
#define AV_PIX_FMT_P016
Definition pixfmt.h:610
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_XV30
Definition pixfmt.h:615
#define AV_PIX_FMT_XV48
Definition pixfmt.h:617
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition pixfmt.h:96
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_VUYX
packed VUYX 4:4:4:4, 32bpp, Variant of VUYA where alpha channel is left undefined
Definition pixfmt.h:406
@ AV_PIX_FMT_D3D12
Hardware surfaces for Direct3D 12.
Definition pixfmt.h:440
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition pixfmt.h:134
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AV_PIX_FMT_D3D11
Hardware surfaces for Direct3D11.
Definition pixfmt.h:336
@ AV_PIX_FMT_D3D11VA_VLD
HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView p...
Definition pixfmt.h:254
@ AV_PIX_FMT_YUYV422
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition pixfmt.h:74
#define AV_PIX_FMT_Y216
Definition pixfmt.h:614
#define AV_PIX_FMT_Y212
Definition pixfmt.h:613
#define AV_PIX_FMT_XV36
Definition pixfmt.h:616
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
static int is_supported(enum AVCodecID id)
Definition rtpenc.c:52
formats
Definition signature.h:47
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition avcodec.h:1503
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1472
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition avcodec.h:1424
int profile
profile
Definition avcodec.h:1641
void * hwaccel_context
Legacy hardware accelerator context.
Definition avcodec.h:1448
enum AVCodecID codec_id
Definition avcodec.h:453
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition avcodec.h:619
This structure is used to provides the necessary configurations and data to the Direct3D11 FFmpeg HWA...
Definition d3d11va.h:56
D3D11_VIDEO_DECODER_CONFIG * cfg
D3D11 configuration used to create the decoder.
Definition d3d11va.h:70
ID3D11VideoContext * video_context
D3D11 VideoContext.
Definition d3d11va.h:65
ID3D11VideoDecoderOutputView ** surface
The array of Direct3D surfaces used to create the decoder.
Definition d3d11va.h:80
unsigned surface_count
The number of surface in the surface array.
Definition d3d11va.h:75
ID3D11VideoDecoder * decoder
D3D11 decoder object.
Definition d3d11va.h:60
HANDLE context_mutex
Mutex to access video_context.
Definition d3d11va.h:95
uint64_t workaround
A bit field configuring the workarounds needed for using the decoder.
Definition d3d11va.h:85
This struct is allocated as AVHWDeviceContext.hwctx.
void(* lock)(void *lock_ctx)
Callbacks for locking.
void(* unlock)(void *lock_ctx)
ID3D11VideoContext * video_context
If unset, this will be set from the device_context field on init.
ID3D11VideoDevice * video_device
If unset, this will be set from the device field on init.
This struct is allocated as AVHWFramesContext.hwctx.
ID3D11Texture2D * texture
The canonical texture used for pool allocation.
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
This struct is allocated as AVHWDeviceContext.hwctx.
IDirect3DDeviceManager9 * devmgr
This struct is allocated as AVHWFramesContext.hwctx.
IDirect3DSurface9 ** surfaces
The surface pool.
DWORD surface_type
The surface type (e.g.
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
enum AVPixelFormat pix_fmt
Supported pixel format.
Definition avcodec.h:1990
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition hwcontext.h:63
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition hwcontext.h:88
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
Definition hwcontext.h:75
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int initial_pool_size
Initial size of the frame pool.
Definition hwcontext.h:190
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition hwcontext.h:137
This structure is used to provide the necessary configurations and data to the FFmpeg Direct3D 12 HWA...
AVHWDeviceContext * device_ctx
enum AVPixelFormat pix_fmt
AVBufferRef * decoder_ref
This structure is used to provides the necessary configurations and data to the DXVA2 FFmpeg HWAccel ...
Definition dxva2.h:54
IDirectXVideoDecoder * decoder
DXVA2 decoder object.
Definition dxva2.h:58
uint64_t workaround
A bit field configuring the workarounds needed for using the decoder.
Definition dxva2.h:78
LPDIRECT3DSURFACE9 * surface
The array of Direct3D surfaces used to create the decoder.
Definition dxva2.h:73
unsigned surface_count
The number of surface in the surface array.
Definition dxva2.h:68
const DXVA2_ConfigPictureDecode * cfg
DXVA2 configuration used to create the decoder.
Definition dxva2.h:63
unsigned report_id
Private to the FFmpeg AVHWAccel implementation.
Definition dxva2.h:83
const int * profiles
Definition dxva2.c:63
enum AVCodecID codec
Definition dxva2.c:60
const GUID * guid
Definition dxva2.c:59
Definition swscale.c:71
#define av_free(p)
#define av_malloc_array(a, b)
#define av_freep(p)
#define av_log(a,...)
static int ref[MAX_W *MAX_W]
static char buffer[20]
Definition seek.c:32
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition time.c:93
int size