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_Profile2,0x0c5f2aa1,0xe541,0x4089,0xbb,0x7b,0x98,0x11,0x0a,0x19,0xd7,0xc8);
51DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2,0x17127009,0xa00f,0x4ce1,0x99,0x4e,0xbf,0x40,0x81,0xf6,0xf3,0xf0);
52DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2_420,0x2d80bed6,0x9cac,0x4835,0x9e,0x91,0x32,0x7b,0xbc,0x4f,0x9e,0xe8);
53DEFINE_GUID(ff_DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
54DEFINE_GUID(ff_GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
55DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
56
57typedef struct dxva_mode {
58 const GUID *guid;
60 // List of supported profiles, terminated by a AV_PROFILE_UNKNOWN entry.
61 // If NULL, don't check profile.
62 const int *profiles;
63} dxva_mode;
64
84
85static const dxva_mode dxva_modes[] = {
86 /* MPEG-2 */
87 { &ff_DXVA2_ModeMPEG2_VLD, AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
88 { &ff_DXVA2_ModeMPEG2and1_VLD, AV_CODEC_ID_MPEG2VIDEO, prof_mpeg2_main },
89
90 /* H.264 */
91 { &ff_DXVA2_ModeH264_F, AV_CODEC_ID_H264, prof_h264_high },
92 { &ff_DXVA2_ModeH264_E, AV_CODEC_ID_H264, prof_h264_high },
93 /* Intel specific H.264 mode */
94 { &ff_DXVADDI_Intel_ModeH264_E, AV_CODEC_ID_H264, prof_h264_high },
95
96 /* VC-1 / WMV3 */
97 { &ff_DXVA2_ModeVC1_D2010, AV_CODEC_ID_VC1 },
98 { &ff_DXVA2_ModeVC1_D2010, AV_CODEC_ID_WMV3 },
99 { &ff_DXVA2_ModeVC1_D, AV_CODEC_ID_VC1 },
100 { &ff_DXVA2_ModeVC1_D, AV_CODEC_ID_WMV3 },
101
102 /* HEVC/H.265 */
103 { &ff_DXVA2_ModeHEVC_VLD_Main10, AV_CODEC_ID_HEVC, prof_hevc_main10 },
104 { &ff_DXVA2_ModeHEVC_VLD_Main, AV_CODEC_ID_HEVC, prof_hevc_main },
105
106 /* VP8/9 */
107 { &ff_DXVA2_ModeVP9_VLD_Profile0, AV_CODEC_ID_VP9, prof_vp9_profile0 },
108 { &ff_DXVA2_ModeVP9_VLD_10bit_Profile2, AV_CODEC_ID_VP9, prof_vp9_profile2 },
109
110 /* AV1 */
111 { &ff_DXVA2_ModeAV1_VLD_Profile0, AV_CODEC_ID_AV1, prof_av1_profile0 },
112 { &ff_DXVA2_ModeAV1_VLD_12bit_Profile2_420, AV_CODEC_ID_AV1, prof_av1_profile2 },
113 { &ff_DXVA2_ModeAV1_VLD_12bit_Profile2, AV_CODEC_ID_AV1, prof_av1_profile2 },
114 { &ff_DXVA2_ModeAV1_VLD_Profile2, AV_CODEC_ID_AV1, prof_av1_profile2 },
115
116 { NULL, 0 },
117};
118
120 const void *cfg_list,
121 unsigned cfg_count)
122{
124 unsigned i, best_score = 0;
125 int best_cfg = -1;
126
127 for (i = 0; i < cfg_count; i++) {
128 unsigned score;
129 UINT ConfigBitstreamRaw = 0;
130 GUID guidConfigBitstreamEncryption;
131
132#if CONFIG_D3D11VA
133 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
134 D3D11_VIDEO_DECODER_CONFIG *cfg = &((D3D11_VIDEO_DECODER_CONFIG *)cfg_list)[i];
135 ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
136 guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
137 }
138#endif
139#if CONFIG_DXVA2
140 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
141 DXVA2_ConfigPictureDecode *cfg = &((DXVA2_ConfigPictureDecode *)cfg_list)[i];
142 ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
143 guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
144 }
145#endif
146
147 if (ConfigBitstreamRaw == 1)
148 score = 1;
149 else if (avctx->codec_id == AV_CODEC_ID_H264 && ConfigBitstreamRaw == 2)
150 score = 2;
151 else
152 continue;
153 if (IsEqualGUID(&guidConfigBitstreamEncryption, &ff_DXVA2_NoEncrypt))
154 score += 16;
155 if (score > best_score) {
156 best_score = score;
157 best_cfg = i;
158 }
159 }
160
161 if (!best_score) {
162 av_log(avctx, AV_LOG_VERBOSE, "No valid decoder configuration available\n");
163 return AVERROR(EINVAL);
164 }
165
166 return best_cfg;
167}
168
169#if CONFIG_D3D11VA
170static int d3d11va_validate_output(void *service, GUID guid, const void *surface_format)
171{
172 HRESULT hr;
173 BOOL is_supported = FALSE;
174 hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice *)service,
175 &guid,
176 *(DXGI_FORMAT *)surface_format,
177 &is_supported);
178 return SUCCEEDED(hr) && is_supported;
179}
180#endif
181
182#if CONFIG_DXVA2
183static int dxva2_validate_output(void *decoder_service, GUID guid, const void *surface_format)
184{
185 HRESULT hr;
186 int ret = 0;
187 unsigned j, target_count;
188 D3DFORMAT *target_list;
189 hr = IDirectXVideoDecoderService_GetDecoderRenderTargets((IDirectXVideoDecoderService *)decoder_service, &guid, &target_count, &target_list);
190 if (SUCCEEDED(hr)) {
191 for (j = 0; j < target_count; j++) {
192 const D3DFORMAT format = target_list[j];
193 if (format == *(D3DFORMAT *)surface_format) {
194 ret = 1;
195 break;
196 }
197 }
198 CoTaskMemFree(target_list);
199 }
200 return ret;
201}
202#endif
203
205{
206 if (mode->codec != avctx->codec_id)
207 return 0;
208
209 if (mode->profiles && !(avctx->hwaccel_flags & AV_HWACCEL_FLAG_ALLOW_PROFILE_MISMATCH)) {
210 int i, found = 0;
211 for (i = 0; mode->profiles[i] != AV_PROFILE_UNKNOWN; i++) {
212 if (avctx->profile == mode->profiles[i]) {
213 found = 1;
214 break;
215 }
216 }
217 if (!found)
218 return 0;
219 }
220
221 return 1;
222}
223
224static void dxva_list_guids_debug(AVCodecContext *avctx, void *service,
225 unsigned guid_count, const GUID *guid_list)
226{
228 int i;
229
230 av_log(avctx, AV_LOG_VERBOSE, "Decoder GUIDs reported as supported:\n");
231
232 for (i = 0; i < guid_count; i++) {
233 const GUID *guid = &guid_list[i];
234
235 av_log(avctx, AV_LOG_VERBOSE,
236 "{%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}",
237 (unsigned) guid->Data1, guid->Data2, guid->Data3,
238 guid->Data4[0], guid->Data4[1],
239 guid->Data4[2], guid->Data4[3],
240 guid->Data4[4], guid->Data4[5],
241 guid->Data4[6], guid->Data4[7]);
242
243#if CONFIG_D3D11VA
244 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
245 DXGI_FORMAT format;
246 // We don't know the maximum valid DXGI_FORMAT, so use 200 as
247 // arbitrary upper bound (that could become outdated).
248 for (format = 0; format < 200; format++) {
249 if (d3d11va_validate_output(service, *guid, &format))
250 av_log(avctx, AV_LOG_VERBOSE, " %d", (int)format);
251 }
252 }
253#endif
254#if CONFIG_DXVA2
255 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
256 const D3DFORMAT formats[] = {MKTAG('N', 'V', '1', '2'),
257 MKTAG('P', '0', '1', '0')};
258 int i;
259 for (i = 0; i < FF_ARRAY_ELEMS(formats); i++) {
260 if (dxva2_validate_output(service, *guid, &formats[i]))
261 av_log(avctx, AV_LOG_VERBOSE, " %d", i);
262 }
263 }
264#endif
265 av_log(avctx, AV_LOG_VERBOSE, "\n");
266 }
267}
268
269static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *surface_format,
270 unsigned guid_count, const GUID *guid_list, GUID *decoder_guid)
271{
273 unsigned i, j;
274
275 dxva_list_guids_debug(avctx, service, guid_count, guid_list);
276
277 *decoder_guid = ff_GUID_NULL;
278 for (i = 0; dxva_modes[i].guid; i++) {
279 const dxva_mode *mode = &dxva_modes[i];
280 int validate = 0;
282 continue;
283
284 for (j = 0; j < guid_count; j++) {
285 if (IsEqualGUID(mode->guid, &guid_list[j]))
286 break;
287 }
288 if (j == guid_count)
289 continue;
290
291#if CONFIG_D3D11VA
292 if (sctx->pix_fmt == AV_PIX_FMT_D3D11)
293 validate = d3d11va_validate_output(service, *mode->guid, surface_format);
294#endif
295#if CONFIG_DXVA2
296 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
297 validate = dxva2_validate_output(service, *mode->guid, surface_format);
298#endif
299 if (validate) {
300 *decoder_guid = *mode->guid;
301 break;
302 }
303 }
304
305 if (IsEqualGUID(decoder_guid, &ff_GUID_NULL)) {
306 av_log(avctx, AV_LOG_VERBOSE, "No decoder device for codec found\n");
307 return AVERROR(EINVAL);
308 }
309
310 if (IsEqualGUID(decoder_guid, &ff_DXVADDI_Intel_ModeH264_E))
312
313 return 0;
314}
315
316static void bufref_free_interface(void *opaque, uint8_t *data)
317{
318 IUnknown_Release((IUnknown *)opaque);
319}
320
321static AVBufferRef *bufref_wrap_interface(IUnknown *iface)
322{
323 return av_buffer_create((uint8_t*)iface, 1, bufref_free_interface, iface, 0);
324}
325
326#if CONFIG_DXVA2
327
328static int dxva2_get_decoder_configuration(AVCodecContext *avctx, const GUID *device_guid,
329 const DXVA2_VideoDesc *desc,
330 DXVA2_ConfigPictureDecode *config)
331{
333 unsigned cfg_count;
334 DXVA2_ConfigPictureDecode *cfg_list;
335 HRESULT hr;
336 int ret;
337
338 hr = IDirectXVideoDecoderService_GetDecoderConfigurations(sctx->dxva2_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
339 if (FAILED(hr)) {
340 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
341 return AVERROR(EINVAL);
342 }
343
344 ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
345 if (ret >= 0)
346 *config = cfg_list[ret];
347 CoTaskMemFree(cfg_list);
348 return ret;
349}
350
351static int dxva2_create_decoder(AVCodecContext *avctx)
352{
354 GUID *guid_list;
355 unsigned guid_count;
356 GUID device_guid;
357 D3DFORMAT surface_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
358 MKTAG('P', '0', '1', '0') : MKTAG('N', 'V', '1', '2');
359 DXVA2_VideoDesc desc = { 0 };
360 DXVA2_ConfigPictureDecode config;
361 HRESULT hr;
362 int ret;
363 HANDLE device_handle;
365 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
366 AVDXVA2DeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
367
368 hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
369 &device_handle);
370 if (FAILED(hr)) {
371 av_log(avctx, AV_LOG_ERROR, "Failed to open a device handle\n");
372 goto fail;
373 }
374
375 hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle,
376 &ff_IID_IDirectXVideoDecoderService,
377 (void **)&sctx->dxva2_service);
378 IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle);
379 if (FAILED(hr)) {
380 av_log(avctx, AV_LOG_ERROR, "Failed to create IDirectXVideoDecoderService\n");
381 goto fail;
382 }
383
384 hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(sctx->dxva2_service, &guid_count, &guid_list);
385 if (FAILED(hr)) {
386 av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder device GUIDs\n");
387 goto fail;
388 }
389
390 ret = dxva_get_decoder_guid(avctx, sctx->dxva2_service, &surface_format,
391 guid_count, guid_list, &device_guid);
392 CoTaskMemFree(guid_list);
393 if (ret < 0) {
394 goto fail;
395 }
396
397 desc.SampleWidth = avctx->coded_width;
398 desc.SampleHeight = avctx->coded_height;
399 desc.Format = surface_format;
400
401 ret = dxva2_get_decoder_configuration(avctx, &device_guid, &desc, &config);
402 if (ret < 0) {
403 goto fail;
404 }
405
406 hr = IDirectXVideoDecoderService_CreateVideoDecoder(sctx->dxva2_service, &device_guid,
407 &desc, &config, frames_hwctx->surfaces,
408 frames_hwctx->nb_surfaces, &sctx->dxva2_decoder);
409 if (FAILED(hr)) {
410 av_log(avctx, AV_LOG_ERROR, "Failed to create DXVA2 video decoder\n");
411 goto fail;
412 }
413
414 sctx->dxva2_config = config;
415
416 sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->dxva2_decoder);
417 if (!sctx->decoder_ref)
418 return AVERROR(ENOMEM);
419
420 return 0;
421fail:
422 return AVERROR(EINVAL);
423}
424
425#endif
426
427#if CONFIG_D3D11VA
428
429static int d3d11va_get_decoder_configuration(AVCodecContext *avctx,
430 ID3D11VideoDevice *video_device,
431 const D3D11_VIDEO_DECODER_DESC *desc,
432 D3D11_VIDEO_DECODER_CONFIG *config)
433{
434 unsigned cfg_count = 0;
435 D3D11_VIDEO_DECODER_CONFIG *cfg_list = NULL;
436 HRESULT hr;
437 int i, ret;
438
439 hr = ID3D11VideoDevice_GetVideoDecoderConfigCount(video_device, desc, &cfg_count);
440 if (FAILED(hr)) {
441 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
442 return AVERROR(EINVAL);
443 }
444
445 cfg_list = av_malloc_array(cfg_count, sizeof(D3D11_VIDEO_DECODER_CONFIG));
446 if (cfg_list == NULL)
447 return AVERROR(ENOMEM);
448 for (i = 0; i < cfg_count; i++) {
449 hr = ID3D11VideoDevice_GetVideoDecoderConfig(video_device, desc, i, &cfg_list[i]);
450 if (FAILED(hr)) {
451 av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations. (hr=0x%lX)\n", hr);
452 av_free(cfg_list);
453 return AVERROR(EINVAL);
454 }
455 }
456
457 ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
458 if (ret >= 0)
459 *config = cfg_list[ret];
460 av_free(cfg_list);
461 return ret;
462}
463
464static DXGI_FORMAT d3d11va_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)
465{
466 switch (pix_fmt) {
467 case AV_PIX_FMT_NV12: return DXGI_FORMAT_NV12;
468 case AV_PIX_FMT_P010: return DXGI_FORMAT_P010;
469 case AV_PIX_FMT_P012: return DXGI_FORMAT_P016;
470 case AV_PIX_FMT_YUV420P: return DXGI_FORMAT_420_OPAQUE;
471 default: return DXGI_FORMAT_UNKNOWN;
472 }
473}
474
475static int d3d11va_create_decoder(AVCodecContext *avctx)
476{
478 GUID *guid_list;
479 unsigned guid_count, i;
480 GUID decoder_guid;
481 D3D11_VIDEO_DECODER_DESC desc = { 0 };
482 D3D11_VIDEO_DECODER_CONFIG config;
483 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
484 AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
485 AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
486 DXGI_FORMAT surface_format = d3d11va_map_sw_to_hw_format(frames_ctx->sw_format);
487 D3D11_TEXTURE2D_DESC texdesc;
488 HRESULT hr;
489 int ret;
490
491 if (!frames_hwctx->texture) {
492 av_log(avctx, AV_LOG_ERROR, "AVD3D11VAFramesContext.texture not set.\n");
493 return AVERROR(EINVAL);
494 }
495 ID3D11Texture2D_GetDesc(frames_hwctx->texture, &texdesc);
496
497 guid_count = ID3D11VideoDevice_GetVideoDecoderProfileCount(device_hwctx->video_device);
498 guid_list = av_malloc_array(guid_count, sizeof(*guid_list));
499 if (guid_list == NULL || guid_count == 0) {
500 av_log(avctx, AV_LOG_ERROR, "Failed to get the decoder GUIDs\n");
501 av_free(guid_list);
502 return AVERROR(EINVAL);
503 }
504 for (i = 0; i < guid_count; i++) {
505 hr = ID3D11VideoDevice_GetVideoDecoderProfile(device_hwctx->video_device, i, &guid_list[i]);
506 if (FAILED(hr)) {
507 av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder GUID %d\n", i);
508 av_free(guid_list);
509 return AVERROR(EINVAL);
510 }
511 }
512
513 ret = dxva_get_decoder_guid(avctx, device_hwctx->video_device, &surface_format,
514 guid_count, guid_list, &decoder_guid);
515 av_free(guid_list);
516 if (ret < 0)
517 return AVERROR(EINVAL);
518
519 desc.SampleWidth = avctx->coded_width;
520 desc.SampleHeight = avctx->coded_height;
521 desc.OutputFormat = surface_format;
522 desc.Guid = decoder_guid;
523
524 ret = d3d11va_get_decoder_configuration(avctx, device_hwctx->video_device, &desc, &config);
525 if (ret < 0)
526 return AVERROR(EINVAL);
527
528 sctx->d3d11_views = av_calloc(texdesc.ArraySize, sizeof(sctx->d3d11_views[0]));
529 if (!sctx->d3d11_views)
530 return AVERROR(ENOMEM);
531 sctx->nb_d3d11_views = texdesc.ArraySize;
532
533 for (i = 0; i < sctx->nb_d3d11_views; i++) {
534 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc = {
535 .DecodeProfile = decoder_guid,
536 .ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D,
537 .Texture2D = {
538 .ArraySlice = i,
539 }
540 };
541 hr = ID3D11VideoDevice_CreateVideoDecoderOutputView(device_hwctx->video_device,
542 (ID3D11Resource*) frames_hwctx->texture,
543 &viewDesc,
544 (ID3D11VideoDecoderOutputView**) &sctx->d3d11_views[i]);
545 if (FAILED(hr)) {
546 av_log(avctx, AV_LOG_ERROR, "Could not create the decoder output view %d\n", i);
547 return AVERROR_UNKNOWN;
548 }
549 }
550
551 hr = ID3D11VideoDevice_CreateVideoDecoder(device_hwctx->video_device, &desc,
552 &config, &sctx->d3d11_decoder);
553 if (FAILED(hr)) {
554 av_log(avctx, AV_LOG_ERROR, "Failed to create D3D11VA video decoder\n");
555 return AVERROR(EINVAL);
556 }
557
558 sctx->d3d11_config = config;
559 sctx->d3d11_texture = frames_hwctx->texture;
560
561 sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->d3d11_decoder);
562 if (!sctx->decoder_ref)
563 return AVERROR(ENOMEM);
564
565 return 0;
566}
567
568#endif
569
570static void ff_dxva2_lock(AVCodecContext *avctx)
571{
572#if CONFIG_D3D11VA
573 if (ff_dxva2_is_d3d11(avctx)) {
576 if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
577 WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, FALSE);
578 if (sctx->device_ctx) {
580 hwctx->lock(hwctx->lock_ctx);
581 }
582 }
583#endif
584}
585
587{
588#if CONFIG_D3D11VA
589 if (ff_dxva2_is_d3d11(avctx)) {
592 if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
593 ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
594 if (sctx->device_ctx) {
596 hwctx->unlock(hwctx->lock_ctx);
597 }
598 }
599#endif
600}
601
603 AVBufferRef *hw_frames_ctx)
604{
605 AVHWFramesContext *frames_ctx = (AVHWFramesContext *)hw_frames_ctx->data;
606 AVHWDeviceContext *device_ctx = frames_ctx->device_ctx;
607 int surface_alignment, num_surfaces;
608
609 if (device_ctx->type == AV_HWDEVICE_TYPE_DXVA2) {
610 frames_ctx->format = AV_PIX_FMT_DXVA2_VLD;
611 } else if (device_ctx->type == AV_HWDEVICE_TYPE_D3D11VA) {
612 frames_ctx->format = AV_PIX_FMT_D3D11;
613 } else {
614 return AVERROR(EINVAL);
615 }
616
617 /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
618 but it causes issues for H.264 on certain AMD GPUs..... */
619 if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)
620 surface_alignment = 32;
621 /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
622 all coding features have enough room to work with */
623 else if (avctx->codec_id == AV_CODEC_ID_HEVC || avctx->codec_id == AV_CODEC_ID_AV1)
624 surface_alignment = 128;
625 else
626 surface_alignment = 16;
627
628 /* 1 base work surface */
629 num_surfaces = 1;
630
631 /* add surfaces based on number of possible refs */
632 if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
633 num_surfaces += 16;
634 else if (avctx->codec_id == AV_CODEC_ID_VP9 || avctx->codec_id == AV_CODEC_ID_AV1)
635 num_surfaces += 8;
636 else
637 num_surfaces += 2;
638
639 switch (avctx->sw_pix_fmt) {
640 case AV_PIX_FMT_YUV420P10: frames_ctx->sw_format = AV_PIX_FMT_P010; break;
641 case AV_PIX_FMT_YUV420P12: frames_ctx->sw_format = AV_PIX_FMT_P012; break;
642 default: frames_ctx->sw_format = AV_PIX_FMT_NV12; break;
643 }
644 frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);
645 frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);
646 frames_ctx->initial_pool_size = num_surfaces;
647
648
649#if CONFIG_DXVA2
650 if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) {
651 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
652
653 frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
654 }
655#endif
656
657#if CONFIG_D3D11VA
658 if (frames_ctx->format == AV_PIX_FMT_D3D11) {
659 AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
660
661 frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
662 }
663#endif
664
665 return 0;
666}
667
669{
671 AVHWFramesContext *frames_ctx;
672 enum AVHWDeviceType dev_type = avctx->hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD
674 int ret = 0;
675
676 // Old API.
677 if (avctx->hwaccel_context)
678 return 0;
679
680 // (avctx->pix_fmt is not updated yet at this point)
681 sctx->pix_fmt = avctx->hwaccel->pix_fmt;
682
683 ret = ff_decode_get_hw_frames_ctx(avctx, dev_type);
684 if (ret < 0)
685 return ret;
686
687 frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
688 sctx->device_ctx = frames_ctx->device_ctx;
689
690 if (frames_ctx->format != sctx->pix_fmt) {
691 av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
692 ret = AVERROR(EINVAL);
693 goto fail;
694 }
695
696#if CONFIG_D3D11VA
697 if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
698 AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
699 AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va;
700
701 ff_dxva2_lock(avctx);
702 ret = d3d11va_create_decoder(avctx);
703 ff_dxva2_unlock(avctx);
704 if (ret < 0)
705 goto fail;
706
707 d3d11_ctx->decoder = sctx->d3d11_decoder;
708 d3d11_ctx->video_context = device_hwctx->video_context;
709 d3d11_ctx->cfg = &sctx->d3d11_config;
710 d3d11_ctx->surface_count = sctx->nb_d3d11_views;
711 d3d11_ctx->surface = sctx->d3d11_views;
712 d3d11_ctx->workaround = sctx->workaround;
713 d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;
714 }
715#endif
716
717#if CONFIG_DXVA2
718 if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
719 AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
720 struct dxva_context *dxva_ctx = &sctx->ctx.dxva2;
721
722 ff_dxva2_lock(avctx);
723 ret = dxva2_create_decoder(avctx);
724 ff_dxva2_unlock(avctx);
725 if (ret < 0)
726 goto fail;
727
728 dxva_ctx->decoder = sctx->dxva2_decoder;
729 dxva_ctx->cfg = &sctx->dxva2_config;
730 dxva_ctx->surface = frames_hwctx->surfaces;
731 dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
732 dxva_ctx->workaround = sctx->workaround;
733 }
734#endif
735
736 return 0;
737
738fail:
740 return ret;
741}
742
744{
746 int i;
747
749
750#if CONFIG_D3D11VA
751 for (i = 0; i < sctx->nb_d3d11_views; i++) {
752 if (sctx->d3d11_views[i])
753 ID3D11VideoDecoderOutputView_Release(sctx->d3d11_views[i]);
754 }
755 av_freep(&sctx->d3d11_views);
756#endif
757
758#if CONFIG_DXVA2
759 if (sctx->dxva2_service)
760 IDirectXVideoDecoderService_Release(sctx->dxva2_service);
761#endif
762
763 return 0;
764}
765
766static void *get_surface(const AVCodecContext *avctx, const AVFrame *frame)
767{
768#if CONFIG_D3D11VA
769 if (frame->format == AV_PIX_FMT_D3D11) {
771 intptr_t index = (intptr_t)frame->data[1];
772 if (index < 0 || index >= sctx->nb_d3d11_views ||
773 sctx->d3d11_texture != (ID3D11Texture2D *)frame->data[0]) {
774 av_log((void *)avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
775 return NULL;
776 }
777 return sctx->d3d11_views[index];
778 }
779#endif
780 return frame->data[3];
781}
782
785 int curr)
786{
787 void *surface = get_surface(avctx, frame);
788
789#if CONFIG_D3D12VA
790 if (avctx->pix_fmt == AV_PIX_FMT_D3D12) {
792 }
793#endif
794#if CONFIG_D3D11VA
795 if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
796 return (intptr_t)frame->data[1];
797 if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
798 D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
799 ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
800 return viewDesc.Texture2D.ArraySlice;
801 }
802#endif
803#if CONFIG_DXVA2
804 for (unsigned i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++) {
805 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && ctx->dxva2.surface[i] == surface)
806 return i;
807 }
808#endif
809
810 av_log((AVCodecContext *)avctx, AV_LOG_WARNING, "Could not get surface index. Using 0 instead.\n");
811 return 0;
812}
813
817 unsigned type, const void *data, unsigned size,
818 unsigned mb_count)
819{
820 void *dxva_data = NULL;
821 unsigned dxva_size;
822 int result;
823 HRESULT hr = 0;
824
825#if CONFIG_D3D11VA
826 if (ff_dxva2_is_d3d11(avctx))
827 hr = ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
829 type,
830 &dxva_size, &dxva_data);
831#endif
832#if CONFIG_DXVA2
833 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
834 hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, type,
835 &dxva_data, &dxva_size);
836#endif
837 if (FAILED(hr)) {
838 av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%x\n",
839 type, (unsigned)hr);
840 return -1;
841 }
842 if (dxva_data && size <= dxva_size) {
843 memcpy(dxva_data, data, size);
844
845#if CONFIG_D3D11VA
846 if (ff_dxva2_is_d3d11(avctx)) {
847 D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
848 memset(dsc11, 0, sizeof(*dsc11));
849 dsc11->BufferType = type;
850 dsc11->DataSize = size;
851 dsc11->NumMBsInBuffer = mb_count;
852 }
853#endif
854#if CONFIG_DXVA2
855 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
856 DXVA2_DecodeBufferDesc *dsc2 = dsc;
857 memset(dsc2, 0, sizeof(*dsc2));
858 dsc2->CompressedBufferType = type;
859 dsc2->DataSize = size;
860 dsc2->NumMBsInBuffer = mb_count;
861 }
862#endif
863
864 result = 0;
865 } else {
866 av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", type);
867 result = -1;
868 }
869
870#if CONFIG_D3D11VA
871 if (ff_dxva2_is_d3d11(avctx))
872 hr = ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type);
873#endif
874#if CONFIG_DXVA2
875 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
876 hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type);
877#endif
878 if (FAILED(hr)) {
879 av_log(avctx, AV_LOG_ERROR,
880 "Failed to release buffer type %u: 0x%x\n",
881 type, (unsigned)hr);
882 result = -1;
883 }
884 return result;
885}
886
888{
889 int i;
890
891 for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
892 if (!frame->buf[i]) {
893 frame->buf[i] = av_buffer_ref(ref);
894 return frame->buf[i] ? 0 : AVERROR(ENOMEM);
895 }
896 }
897
898 // For now we expect that the caller does not use more than
899 // AV_NUM_DATA_POINTERS-1 buffers if the user uses a custom pool.
900 return AVERROR(EINVAL);
901}
902
904 const void *pp, unsigned pp_size,
905 const void *qm, unsigned qm_size,
906 int (*commit_bs_si)(AVCodecContext *,
908 DECODER_BUFFER_DESC *slice))
909{
911 unsigned buffer_count = 0;
912#if CONFIG_D3D11VA
913 D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
914#endif
915#if CONFIG_DXVA2
916 DXVA2_DecodeBufferDesc buffer2[4];
917#endif
918 DECODER_BUFFER_DESC *buffer = NULL, *buffer_slice = NULL;
919 int result, runs = 0;
920 HRESULT hr = -1;
921 unsigned type;
923
924 if (sctx->decoder_ref) {
925 result = frame_add_buf(frame, sctx->decoder_ref);
926 if (result < 0)
927 return result;
928 }
929
930 do {
931 ff_dxva2_lock(avctx);
932#if CONFIG_D3D11VA
933 if (ff_dxva2_is_d3d11(avctx))
934 hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder,
935 get_surface(avctx, frame),
936 0, NULL);
937#endif
938#if CONFIG_DXVA2
939 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
940 hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
941 get_surface(avctx, frame),
942 NULL);
943#endif
944 if (hr != E_PENDING || ++runs > 50)
945 break;
946 ff_dxva2_unlock(avctx);
947 av_usleep(2000);
948 } while(1);
949
950 if (FAILED(hr)) {
951 av_log(avctx, AV_LOG_ERROR, "Failed to begin frame: 0x%x\n", (unsigned)hr);
952 ff_dxva2_unlock(avctx);
953 return -1;
954 }
955
956#if CONFIG_D3D11VA
957 if (ff_dxva2_is_d3d11(avctx)) {
958 buffer = &buffer11[buffer_count];
959 type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
960 }
961#endif
962#if CONFIG_DXVA2
963 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
964 buffer = &buffer2[buffer_count];
965 type = DXVA2_PictureParametersBufferType;
966 }
967#endif
968 result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
969 type,
970 pp, pp_size, 0);
971 if (result) {
972 av_log(avctx, AV_LOG_ERROR,
973 "Failed to add picture parameter buffer\n");
974 goto end;
975 }
976 buffer_count++;
977
978 if (qm_size > 0) {
979#if CONFIG_D3D11VA
980 if (ff_dxva2_is_d3d11(avctx)) {
981 buffer = &buffer11[buffer_count];
982 type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
983 }
984#endif
985#if CONFIG_DXVA2
986 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
987 buffer = &buffer2[buffer_count];
988 type = DXVA2_InverseQuantizationMatrixBufferType;
989 }
990#endif
991 result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
992 type,
993 qm, qm_size, 0);
994 if (result) {
995 av_log(avctx, AV_LOG_ERROR,
996 "Failed to add inverse quantization matrix buffer\n");
997 goto end;
998 }
999 buffer_count++;
1000 }
1001
1002#if CONFIG_D3D11VA
1003 if (ff_dxva2_is_d3d11(avctx)) {
1004 buffer = &buffer11[buffer_count + 0];
1005 buffer_slice = &buffer11[buffer_count + 1];
1006 }
1007#endif
1008#if CONFIG_DXVA2
1009 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1010 buffer = &buffer2[buffer_count + 0];
1011 buffer_slice = &buffer2[buffer_count + 1];
1012 }
1013#endif
1014
1015 result = commit_bs_si(avctx,
1016 buffer,
1017 buffer_slice);
1018 if (result) {
1019 av_log(avctx, AV_LOG_ERROR,
1020 "Failed to add bitstream or slice control buffer\n");
1021 goto end;
1022 }
1023 buffer_count += 2;
1024
1025 /* TODO Film Grain when possible */
1026
1027 av_assert0(buffer_count == 1 + (qm_size > 0) + 2);
1028
1029#if CONFIG_D3D11VA
1030 if (ff_dxva2_is_d3d11(avctx))
1031 hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
1033 buffer_count, buffer11);
1034#endif
1035#if CONFIG_DXVA2
1036 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
1037 DXVA2_DecodeExecuteParams exec = {
1038 .NumCompBuffers = buffer_count,
1039 .pCompressedBuffers = buffer2,
1040 .pExtensionData = NULL,
1041 };
1042 hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, &exec);
1043 }
1044#endif
1045 if (FAILED(hr)) {
1046 av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%x\n", (unsigned)hr);
1047 result = -1;
1048 }
1049
1050end:
1051#if CONFIG_D3D11VA
1052 if (ff_dxva2_is_d3d11(avctx))
1053 hr = ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder);
1054#endif
1055#if CONFIG_DXVA2
1056 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
1057 hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, NULL);
1058#endif
1059 ff_dxva2_unlock(avctx);
1060 if (FAILED(hr)) {
1061 av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%x\n", (unsigned)hr);
1062 result = -1;
1063 }
1064
1065 return result;
1066}
1067
1069{
1070 if (CONFIG_D3D11VA)
1071 return avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ||
1072 avctx->pix_fmt == AV_PIX_FMT_D3D11;
1073 else
1074 return 0;
1075}
1076
1078{
1079 unsigned *report_id = NULL;
1080
1081#if CONFIG_D3D12VA
1082 if (avctx->pix_fmt == AV_PIX_FMT_D3D12)
1083 report_id = &ctx->d3d12va.report_id;
1084#endif
1085#if CONFIG_D3D11VA
1086 if (ff_dxva2_is_d3d11(avctx))
1087 report_id = &ctx->d3d11va.report_id;
1088#endif
1089#if CONFIG_DXVA2
1090 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
1091 report_id = &ctx->dxva2.report_id;
1092#endif
1093
1094 return report_id;
1095}
static const char *const format[]
Definition af_aiir.c:444
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:1069
#define AV_PROFILE_MPEG2_MAIN
Definition defs.h:104
#define AV_PROFILE_H264_MAIN
Definition defs.h:112
#define AV_PROFILE_UNKNOWN
Definition defs.h:65
#define AV_PROFILE_HEVC_MAIN
Definition defs.h:159
#define AV_PROFILE_HEVC_MAIN_10
Definition defs.h:160
#define AV_PROFILE_H264_HIGH
Definition defs.h:114
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition defs.h:111
#define AV_PROFILE_VP9_0
Definition defs.h:154
#define AV_PROFILE_VP9_2
Definition defs.h:156
#define AV_PROFILE_AV1_MAIN
Definition defs.h:169
#define AV_PROFILE_AV1_PROFESSIONAL
Definition defs.h:171
#define AV_PROFILE_MPEG2_SIMPLE
Definition defs.h:105
static enum AVPixelFormat pix_fmt
static AVFrame * frame
static const dxva_mode dxva_modes[]
Definition dxva2.c:85
int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
Definition dxva2.c:1068
static const int prof_hevc_main[]
Definition dxva2.c:72
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, AVDXVAContext *ctx, const AVFrame *frame, int curr)
Definition dxva2.c:783
static const int prof_vp9_profile0[]
Definition dxva2.c:76
static const int prof_av1_profile2[]
Definition dxva2.c:82
static void ff_dxva2_unlock(AVCodecContext *avctx)
Definition dxva2.c:586
static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
Definition dxva2.c:887
unsigned * ff_dxva2_get_report_id(const AVCodecContext *avctx, AVDXVAContext *ctx)
Definition dxva2.c:1077
static const int prof_hevc_main10[]
Definition dxva2.c:74
static void ff_dxva2_lock(AVCodecContext *avctx)
Definition dxva2.c:570
static void * get_surface(const AVCodecContext *avctx, const AVFrame *frame)
Definition dxva2.c:766
int ff_dxva2_decode_init(AVCodecContext *avctx)
Definition dxva2.c:668
static AVBufferRef * bufref_wrap_interface(IUnknown *iface)
Definition dxva2.c:321
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:814
static int dxva_get_decoder_configuration(AVCodecContext *avctx, const void *cfg_list, unsigned cfg_count)
Definition dxva2.c:119
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
Definition dxva2.c:743
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:903
static const int prof_mpeg2_main[]
Definition dxva2.c:65
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition dxva2.c:602
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:269
static const int prof_h264_high[]
Definition dxva2.c:68
static void dxva_list_guids_debug(AVCodecContext *avctx, void *service, unsigned guid_count, const GUID *guid_list)
Definition dxva2.c:224
static const int prof_vp9_profile2[]
Definition dxva2.c:78
static int dxva_check_codec_compatibility(AVCodecContext *avctx, const dxva_mode *mode)
Definition dxva2.c:204
static const int prof_av1_profile0[]
Definition dxva2.c:80
static void bufref_free_interface(void *opaque, uint8_t *data)
Definition dxva2.c:316
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:2018
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
if(svq3)
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_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_P010
Definition pixfmt.h:608
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_D3D12
Hardware surfaces for Direct3D 12.
Definition pixfmt.h:440
@ AV_PIX_FMT_DXVA2_VLD
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer.
Definition pixfmt.h:134
@ 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
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:1502
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:1471
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition avcodec.h:1423
int profile
profile
Definition avcodec.h:1636
void * hwaccel_context
Legacy hardware accelerator context.
Definition avcodec.h:1447
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.
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:1975
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:62
enum AVCodecID codec
Definition dxva2.c:59
const GUID * guid
Definition dxva2.c:58
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 AVFormatContext * ctx
Definition movenc.c:49
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