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 
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;
272  if (!dxva_check_codec_compatibility(avctx, mode))
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_mallocz_array(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,
811  D3D11VA_CONTEXT(ctx)->decoder,
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) {
908  result = frame_add_buf(frame, 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
951  result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
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
974  result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
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,
1015  D3D11VA_CONTEXT(ctx)->decoder,
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 }
#define FF_PROFILE_H264_MAIN
Definition: avcodec.h:1912
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
#define NULL
Definition: coverity.c:32
This structure is used to provides the necessary configurations and data to the Direct3D11 FFmpeg HWA...
Definition: d3d11va.h:59
static enum AVPixelFormat pix_fmt
#define AV_NUM_DATA_POINTERS
Definition: frame.h:315
#define FF_PROFILE_MPEG2_MAIN
Definition: avcodec.h:1904
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:125
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:719
DEFINE_GUID(ff_DXVA2_ModeMPEG2_VLD, 0xee27417f, 0x5e28, 0x4e65, 0xbe, 0xea, 0x1d, 0x26, 0xb5, 0x08, 0xad, 0xc9)
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
const char * desc
Definition: libsvtav1.c:79
This struct is allocated as AVHWFramesContext.hwctx.
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:505
enum AVPixelFormat pix_fmt
Supported pixel format.
Definition: avcodec.h:2449
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:229
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
GLint GLenum type
Definition: opengl_enc.c:104
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
static void * get_surface(const AVCodecContext *avctx, const AVFrame *frame)
Definition: dxva2.c:753
LPDIRECT3DSURFACE9 * surface
The array of Direct3D surfaces used to create the decoder.
Definition: dxva2.h:76
int av_usleep(unsigned usec)
Sleep for a period of time.
Definition: time.c:84
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1695
int profile
profile
Definition: avcodec.h:1871
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
#define D3D11VA_CONTEXT(ctx)
const DXVA2_ConfigPictureDecode * cfg
DXVA2 configuration used to create the decoder.
Definition: dxva2.h:66
UINT BindFlags
D3D11_TEXTURE2D_DESC.BindFlags used for texture creation.
unsigned surface_count
The number of surface in the surface array.
Definition: dxva2.h:71
#define FF_PROFILE_VP9_0
Definition: avcodec.h:1954
const int * profiles
Definition: dxva2.c:58
#define AV_PIX_FMT_P010
Definition: pixfmt.h:448
int ff_dxva2_common_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx)
Definition: dxva2.c:592
int ff_dxva2_decode_uninit(AVCodecContext *avctx)
Definition: dxva2.c:730
uint8_t
static const dxva_mode dxva_modes[]
Definition: dxva2.c:79
void * hwaccel_context
Hardware accelerator context.
Definition: avcodec.h:1707
HANDLE context_mutex
Mutex to access video_context.
Definition: d3d11va.h:98
ID3D11VideoDecoder * decoder
D3D11 decoder object.
Definition: d3d11va.h:63
DWORD surface_type
The surface type (e.g.
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:92
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
#define FF_PROFILE_HEVC_MAIN
Definition: avcodec.h:1959
#define DXVA_SHARED_CONTEXT(avctx)
static void ff_dxva2_lock(AVCodecContext *avctx)
Definition: dxva2.c:560
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:92
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:210
ptrdiff_t size
Definition: opengl_enc.c:100
#define FF_PROFILE_HEVC_MAIN_10
Definition: avcodec.h:1960
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
uint64_t workaround
A bit field configuring the workarounds needed for using the decoder.
Definition: dxva2.h:81
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:46
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
D3D11_VIDEO_DECODER_CONFIG * cfg
D3D11 configuration used to create the decoder.
Definition: d3d11va.h:73
static AVBufferRef * bufref_wrap_interface(IUnknown *iface)
Definition: dxva2.c:312
int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
Definition: dxva2.c:1051
#define FF_PROFILE_H264_HIGH
Definition: avcodec.h:1914
#define DXVA2_CONTEXT(ctx)
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
AVBufferRef * av_buffer_create(uint8_t *data, int size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:29
static const int prof_hevc_main10[]
Definition: dxva2.c:70
#define fail()
Definition: checkasm.h:123
ID3D11VideoContext * video_context
If unset, this will be set from the device_context field on init.
#define FF_PROFILE_VP9_2
Definition: avcodec.h:1956
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:199
static void ff_dxva2_unlock(AVCodecContext *avctx)
Definition: dxva2.c:576
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:149
static const chunk_decoder decoder[8]
Definition: dfa.c:330
#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO
Work around for Direct3D11 and old Intel GPUs with ClearVideo interface.
Definition: d3d11va.h:49
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:2238
#define FF_PROFILE_UNKNOWN
Definition: avcodec.h:1872
static void bufref_free_interface(void *opaque, uint8_t *data)
Definition: dxva2.c:307
unsigned surface_count
The number of surface in the surface array.
Definition: d3d11va.h:78
ID3D11VideoContext * video_context
D3D11 VideoContext.
Definition: d3d11va.h:68
AVFormatContext * ctx
Definition: movenc.c:48
static int dxva_get_decoder_configuration(AVCodecContext *avctx, const void *cfg_list, unsigned cfg_count)
Definition: dxva2.c:110
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
int ff_dxva2_decode_init(AVCodecContext *avctx)
Definition: dxva2.c:655
AVHWDeviceContext * device_ctx
void(* unlock)(void *lock_ctx)
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:51
enum AVPixelFormat pix_fmt
#define FF_ARRAY_ELEMS(a)
if(ret)
static int dxva_check_codec_compatibility(AVCodecContext *avctx, const dxva_mode *mode)
Definition: dxva2.c:195
static const int prof_h264_high[]
Definition: dxva2.c:64
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:387
Libavcodec external API header.
enum AVCodecID codec_id
Definition: avcodec.h:541
unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx, const AVDXVAContext *ctx, const AVFrame *frame)
Definition: dxva2.c:770
static int is_supported(enum AVCodecID id)
Definition: rtpenc.c:49
main external API structure.
Definition: avcodec.h:531
uint8_t * data
The data buffer.
Definition: buffer.h:89
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition: hwcontext.h:162
static const int prof_vp9_profile0[]
Definition: dxva2.c:72
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
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:399
int coded_height
Definition: avcodec.h:719
static const int prof_mpeg2_main[]
Definition: dxva2.c:61
int index
Definition: gxfenc.c:89
#define FF_PROFILE_AV1_MAIN
Definition: avcodec.h:1964
uint64_t workaround
A bit field configuring the workarounds needed for using the decoder.
Definition: d3d11va.h:88
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
const GUID * guid
Definition: dxva2.c:54
void DECODER_BUFFER_DESC
HW decoding through DXVA2, Picture.data[3] contains a LPDIRECT3DSURFACE9 pointer. ...
Definition: pixfmt.h:137
This struct is allocated as AVHWFramesContext.hwctx.
AVBufferRef * decoder_ref
int ff_decode_get_hw_frames_ctx(AVCodecContext *avctx, enum AVHWDeviceType dev_type)
Make sure avctx.hw_frames_ctx is set.
Definition: decode.c:1150
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
Hardware surfaces for Direct3D11.
Definition: pixfmt.h:313
A reference to a data buffer.
Definition: buffer.h:81
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
AVDXVAContext ctx
common internal and external API header
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:93
ID3D11VideoDecoderOutputView ** surface
The array of Direct3D surfaces used to create the decoder.
Definition: d3d11va.h:83
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
IDirect3DSurface9 ** surfaces
The surface pool.
static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
Definition: dxva2.c:870
AVHWDeviceType
Definition: hwcontext.h:27
This struct is allocated as AVHWDeviceContext.hwctx.
#define av_free(p)
static void dxva_list_guids_debug(AVCodecContext *avctx, void *service, unsigned guid_count, const GUID *guid_list)
Definition: dxva2.c:215
void(* lock)(void *lock_ctx)
Callbacks for locking.
#define FF_PROFILE_MPEG2_SIMPLE
Definition: avcodec.h:1905
static const int prof_av1_profile0[]
Definition: dxva2.c:76
#define DXVA_CONTEXT(avctx)
static const int prof_hevc_main[]
Definition: dxva2.c:68
and forward the result(frame or status change) to the corresponding input.If nothing is possible
This struct is allocated as AVHWDeviceContext.hwctx.
#define av_freep(p)
#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:2618
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active)...
Definition: avcodec.h:2299
HW decoding through Direct3D11 via old API, Picture.data[3] contains a ID3D11VideoDecoderOutputView p...
Definition: pixfmt.h:229
IDirectXVideoDecoder * decoder
DXVA2 decoder object.
Definition: dxva2.h:61
#define av_malloc_array(a, b)
formats
Definition: signature.h:48
#define FF_PROFILE_H264_CONSTRAINED_BASELINE
Definition: avcodec.h:1911
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
#define MKTAG(a, b, c, d)
Definition: common.h:405
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:222
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
enum AVCodecID codec
Definition: dxva2.c:55
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:2088
int i
Definition: input.c:407
GLuint buffer
Definition: opengl_enc.c:101
static const int prof_vp9_profile2[]
Definition: dxva2.c:74
This structure is used to provides the necessary configurations and data to the DXVA2 FFmpeg HWAccel ...
Definition: dxva2.h:57
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:190