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