tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }