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