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