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_ModeAV1_VLD_Profile2,0x0c5f2aa1,0xe541,0x4089,0xbb,0x7b,0x98,0x11,0x0a,0x19,0xd7,0xc8);
51 DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2,0x17127009,0xa00f,0x4ce1,0x99,0x4e,0xbf,0x40,0x81,0xf6,0xf3,0xf0);
52 DEFINE_GUID(ff_DXVA2_ModeAV1_VLD_12bit_Profile2_420,0x2d80bed6,0x9cac,0x4835,0x9e,0x91,0x32,0x7b,0xbc,0x4f,0x9e,0xe8);
53 DEFINE_GUID(ff_DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
54 DEFINE_GUID(ff_GUID_NULL, 0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
55 DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
56 
57 typedef 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 
72 static const int prof_hevc_main[] = {AV_PROFILE_HEVC_MAIN,
76 static const int prof_vp9_profile0[] = {AV_PROFILE_VP9_0,
78 static const int prof_vp9_profile2[] = {AV_PROFILE_VP9_2,
80 static const int prof_av1_profile0[] = {AV_PROFILE_AV1_MAIN,
84 
85 static 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
170 static 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
183 static 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 
224 static 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 
269 static 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 
316 static void bufref_free_interface(void *opaque, uint8_t *data)
317 {
318  IUnknown_Release((IUnknown *)opaque);
319 }
320 
321 static 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 
328 static 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 
351 static 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;
364  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
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;
421 fail:
422  return AVERROR(EINVAL);
423 }
424 
425 #endif
426 
427 #if CONFIG_D3D11VA
428 
429 static 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 
464 static 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 
475 static 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 
570 static void ff_dxva2_lock(AVCodecContext *avctx)
571 {
572 #if CONFIG_D3D11VA
573  if (ff_dxva2_is_d3d11(avctx)) {
575  AVDXVAContext *ctx = DXVA_CONTEXT(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) {
579  AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
580  hwctx->lock(hwctx->lock_ctx);
581  }
582  }
583 #endif
584 }
585 
586 static void ff_dxva2_unlock(AVCodecContext *avctx)
587 {
588 #if CONFIG_D3D11VA
589  if (ff_dxva2_is_d3d11(avctx)) {
591  AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
592  if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
593  ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
594  if (sctx->device_ctx) {
595  AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
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 
738 fail:
739  ff_dxva2_decode_uninit(avctx);
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 
766 static 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 
784  AVDXVAContext *ctx, const AVFrame *frame,
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 
816  DECODER_BUFFER_DESC *dsc,
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 {
910  AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
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) {
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
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
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 
1050 end:
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 }
formats
formats
Definition: signature.h:47
AVHWDeviceContext::hwctx
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:88
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1423
AVCodecContext::hwaccel_context
void * hwaccel_context
Legacy hardware accelerator context.
Definition: avcodec.h:1447
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:216
dxva_mode::codec
enum AVCodecID codec
Definition: dxva2.c:59
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:316
FFDXVASharedContext::pix_fmt
enum AVPixelFormat pix_fmt
Definition: dxva2_internal.h:93
AV_PROFILE_MPEG2_SIMPLE
#define AV_PROFILE_MPEG2_SIMPLE
Definition: defs.h:105
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
AV_PROFILE_H264_MAIN
#define AV_PROFILE_H264_MAIN
Definition: defs.h:112
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:200
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:159
dxva_context::decoder
IDirectXVideoDecoder * decoder
DXVA2 decoder object.
Definition: dxva2.h:58
mode
Definition: swscale.c:71
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:472
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:72
data
const char data[16]
Definition: mxf.c:149
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:903
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:545
prof_h264_high
static const int prof_h264_high[]
Definition: dxva2.c:68
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:226
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:156
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
AV_PROFILE_AV1_PROFESSIONAL
#define AV_PROFILE_AV1_PROFESSIONAL
Definition: defs.h:171
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:220
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:80
AVD3D11VAFramesContext::BindFlags
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
Definition: hwcontext_d3d11va.h:174
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:331
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:62
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:619
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:52
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:63
avassert.h
prof_av1_profile2
static const int prof_av1_profile2[]
Definition: dxva2.c:82
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:210
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:220
ff_dxva2_unlock
static void ff_dxva2_unlock(AVCodecContext *avctx)
Definition: dxva2.c:586
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
prof_mpeg2_main
static const int prof_mpeg2_main[]
Definition: dxva2.c:65
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:217
prof_vp9_profile0
static const int prof_vp9_profile0[]
Definition: dxva2.c:76
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
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
static AVFormatContext * ctx
Definition: movenc.c:49
decode.h
bufref_wrap_interface
static AVBufferRef * bufref_wrap_interface(IUnknown *iface)
Definition: dxva2.c:321
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:269
av_usleep
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:93
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:77
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:1069
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:453
dxva2_internal.h
get_surface
static void * get_surface(const AVCodecContext *avctx, const AVFrame *frame)
Definition: dxva2.c:766
if
if(ret)
Definition: filter_design.txt:179
AV_CODEC_ID_WMV3
@ AV_CODEC_ID_WMV3
Definition: codec_id.h:121
fail
#define fail
Definition: test.h:478
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:668
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:213
format
New swscale design to change SwsGraph is what coordinates multiple passes These can include cascaded scaling error diffusion and so on Or we could have separate passes for the vertical and horizontal scaling In between each SwsPass lies a fully allocated image buffer Graph passes may have different levels of e g we can have a single threaded error diffusion pass following a multi threaded scaling pass SwsGraph is internally recreated whenever the image format
Definition: swscale-v2.txt:14
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:275
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:2018
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:783
AV_PROFILE_HEVC_MAIN_10
#define AV_PROFILE_HEVC_MAIN_10
Definition: defs.h:160
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:145
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
cfg
static CheckasmConfig cfg
Definition: checkasm.c:74
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:47
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:1077
dxva_mode::guid
const GUID * guid
Definition: dxva2.c:58
AV_PIX_FMT_P012
#define AV_PIX_FMT_P012
Definition: pixfmt.h:609
AVDXVA2FramesContext::surface_type
DWORD surface_type
The surface type (e.g.
Definition: hwcontext_dxva2.h:51
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
AV_NUM_DATA_POINTERS
#define AV_NUM_DATA_POINTERS
Definition: frame.h:473
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:119
ff_dxva2_lock
static void ff_dxva2_lock(AVCodecContext *avctx)
Definition: dxva2.c:570
frame_add_buf
static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
Definition: dxva2.c:887
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
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:32
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:1502
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:223
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:814
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:120
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:643
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:1471
ff_dxva2_common_frame_params
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: dxva2.c:602
avcodec.h
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:118
AV_PROFILE_VP9_2
#define AV_PROFILE_VP9_2
Definition: defs.h:156
ret
ret
Definition: filter_design.txt:187
dxva_modes
static const dxva_mode dxva_modes[]
Definition: dxva2.c:85
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:265
AVHWFramesContext::device_ctx
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:137
AVHWFramesContext::hwctx
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:153
dxva_list_guids_debug
static void dxva_list_guids_debug(AVCodecContext *avctx, void *service, unsigned guid_count, const GUID *guid_list)
Definition: dxva2.c:224
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:549
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:443
AV_PROFILE_H264_HIGH
#define AV_PROFILE_H264_HIGH
Definition: defs.h:114
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:1068
AVCodecContext::profile
int profile
profile
Definition: avcodec.h:1636
dxva_check_codec_compatibility
static int dxva_check_codec_compatibility(AVCodecContext *avctx, const dxva_mode *mode)
Definition: dxva2.c:204
AV_PROFILE_MPEG2_MAIN
#define AV_PROFILE_MPEG2_MAIN
Definition: defs.h:104
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:117
AV_PROFILE_H264_CONSTRAINED_BASELINE
#define AV_PROFILE_H264_CONSTRAINED_BASELINE
Definition: defs.h:111
AV_PROFILE_VP9_0
#define AV_PROFILE_VP9_0
Definition: defs.h:154
dxva_mode
Definition: dxva2.c:57
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:608
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:619
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:190
desc
const char * desc
Definition: libsvtav1.c:83
ff_dxva2_decode_uninit
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
Definition: dxva2.c:743
prof_hevc_main10
static const int prof_hevc_main10[]
Definition: dxva2.c:74
mem.h
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
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:35
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:650
AV_PROFILE_AV1_MAIN
#define AV_PROFILE_AV1_MAIN
Definition: defs.h:169
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:52
FFDXVASharedContext::decoder_ref
AVBufferRef * decoder_ref
Definition: dxva2_internal.h:87
AVHWAccel::pix_fmt
enum AVPixelFormat pix_fmt
Supported pixel format.
Definition: avcodec.h:1975
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:78
AVD3D11VAContext::surface
ID3D11VideoDecoderOutputView ** surface
The array of Direct3D surfaces used to create the decoder.
Definition: d3d11va.h:80