Ticket #10877: 0001-Add-support-d3d11va-Intel-Hevc-Rext-decoder.patch

File 0001-Add-support-d3d11va-Intel-Hevc-Rext-decoder.patch, 16.3 KB (added by Aleksoid1978, 2 years ago)

Patch

  • libavcodec/d3d12va_hevc.c

    From ed8fda62bbdbc62f7565891c935966c931d001ca Mon Sep 17 00:00:00 2001
    From: Aleksoid <Aleksoid1978@mail.ru>
    Date: Thu, 22 Feb 2024 19:15:48 +1000
    Subject: [PATCH] Add support d3d11va Intel Hevc Rext decoder.
    
    Signed-off-by: Aleksoid <Aleksoid1978@mail.ru>
    ---
     libavcodec/d3d12va_hevc.c     |  2 +-
     libavcodec/dxva2.c            | 68 +++++++++++++++++++++++++++++++++--
     libavcodec/dxva2_hevc.c       | 41 ++++++++++++++++++---
     libavcodec/dxva2_internal.h   | 38 +++++++++++++++++++-
     libavcodec/hevcdec.c          | 16 +++++++++
     libavutil/hwcontext_d3d11va.c | 26 +++++++++++---
     6 files changed, 178 insertions(+), 13 deletions(-)
    
    diff --git a/libavcodec/d3d12va_hevc.c b/libavcodec/d3d12va_hevc.c
    index a4964a05c6..0912e01b7d 100644
    a b static int d3d12va_hevc_start_frame(AVCodecContext *avctx, av_unused const uint8  
    6262
    6363    ctx->used_mask = 0;
    6464
    65     ff_dxva2_hevc_fill_picture_parameters(avctx, (AVDXVAContext *)ctx, &ctx_pic->pp);
     65    ff_dxva2_hevc_fill_picture_parameters(avctx, (AVDXVAContext *)ctx, (DXVA_PicParams_HEVC_Rext*)&ctx_pic->pp);
    6666
    6767    ff_dxva2_hevc_fill_scaling_lists(avctx, (AVDXVAContext *)ctx, &ctx_pic->qm);
    6868
  • libavcodec/dxva2.c

    diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
    index 59025633f7..a611989911 100644
    a b DEFINE_GUID(ff_DXVA2_NoEncrypt, 0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x0  
    5050DEFINE_GUID(ff_GUID_NULL,                0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
    5151DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
    5252
     53DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main12_Intel,     0x8FF8A3AA, 0xC456, 0x4132, 0xB6, 0xEF, 0x69, 0xD9, 0xDD, 0x72, 0x57, 0x1D);
     54DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main422_10_Intel, 0xE484DCB8, 0xCAC9, 0x4859, 0x99, 0xF5, 0x5C, 0x0D, 0x45, 0x06, 0x90, 0x89);
     55DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main422_12_Intel, 0xC23DD857, 0x874B, 0x423C, 0xB6, 0xE0, 0x82, 0xCE, 0xAA, 0x9B, 0x11, 0x8A);
     56DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main444_Intel,    0x41A5AF96, 0xE415, 0x4B0C, 0x9D, 0x03, 0x90, 0x78, 0x58, 0xE2, 0x3E, 0x78);
     57DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main444_10_Intel, 0x6A6A81BA, 0x912A, 0x485D, 0xB5, 0x7F, 0xCC, 0xD2, 0xD3, 0x7B, 0x8D, 0x94);
     58DEFINE_GUID(ff_DXVA2_HEVC_VLD_Main444_12_Intel, 0x5B08E35D, 0x0C66, 0x4C51, 0xA6, 0xF1, 0x89, 0xD0, 0x0C, 0xB2, 0xC1, 0x97);
     59
    5360typedef struct dxva_mode {
    5461    const GUID     *guid;
    5562    enum AVCodecID codec;
    static const int prof_vp9_profile2[] = {AV_PROFILE_VP9_2,  
    7582                                        AV_PROFILE_UNKNOWN};
    7683static const int prof_av1_profile0[] = {AV_PROFILE_AV1_MAIN,
    7784                                        AV_PROFILE_UNKNOWN};
     85static const int prof_hevc_rext[]    = {AV_PROFILE_HEVC_REXT,
     86                                        AV_PROFILE_UNKNOWN};
    7887
    7988static const dxva_mode dxva_modes[] = {
    8089    /* MPEG-2 */
    static const dxva_mode dxva_modes[] = {  
    104113    /* AV1 */
    105114    { &ff_DXVA2_ModeAV1_VLD_Profile0,       AV_CODEC_ID_AV1, prof_av1_profile0 },
    106115
     116    /* HEVC/H.265 Rext */
     117    { &ff_DXVA2_HEVC_VLD_Main12_Intel,     AV_CODEC_ID_HEVC, prof_hevc_rext },
     118    { &ff_DXVA2_HEVC_VLD_Main422_10_Intel, AV_CODEC_ID_HEVC, prof_hevc_rext },
     119    { &ff_DXVA2_HEVC_VLD_Main422_12_Intel, AV_CODEC_ID_HEVC, prof_hevc_rext },
     120    { &ff_DXVA2_HEVC_VLD_Main444_Intel,    AV_CODEC_ID_HEVC, prof_hevc_rext },
     121    { &ff_DXVA2_HEVC_VLD_Main444_10_Intel, AV_CODEC_ID_HEVC, prof_hevc_rext },
     122    { &ff_DXVA2_HEVC_VLD_Main444_12_Intel, AV_CODEC_ID_HEVC, prof_hevc_rext },
     123
    107124    { NULL,                          0 },
    108125};
    109126
    static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *sur  
    301318    if (IsEqualGUID(decoder_guid, &ff_DXVADDI_Intel_ModeH264_E))
    302319        sctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
    303320
     321    av_log(avctx, AV_LOG_VERBOSE,
     322           "Used guid : {%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x}\n",
     323           (unsigned)decoder_guid->Data1, decoder_guid->Data2, decoder_guid->Data3,
     324           decoder_guid->Data4[0], decoder_guid->Data4[1],
     325           decoder_guid->Data4[2], decoder_guid->Data4[3],
     326           decoder_guid->Data4[4], decoder_guid->Data4[5],
     327           decoder_guid->Data4[6], decoder_guid->Data4[7]);
     328
    304329    return 0;
    305330}
    306331
    static DXGI_FORMAT d3d11va_map_sw_to_hw_format(enum AVPixelFormat pix_fmt)  
    458483    case AV_PIX_FMT_NV12:       return DXGI_FORMAT_NV12;
    459484    case AV_PIX_FMT_P010:       return DXGI_FORMAT_P010;
    460485    case AV_PIX_FMT_YUV420P:    return DXGI_FORMAT_420_OPAQUE;
     486    case AV_PIX_FMT_P016:       return DXGI_FORMAT_P016;
     487    case AV_PIX_FMT_YUYV422:    return DXGI_FORMAT_YUY2;
     488    case AV_PIX_FMT_Y210:       return DXGI_FORMAT_Y210;
     489    case AV_PIX_FMT_Y212:       return DXGI_FORMAT_Y216;
     490    case AV_PIX_FMT_VUYX:       return DXGI_FORMAT_AYUV;
     491    case AV_PIX_FMT_XV30:       return DXGI_FORMAT_Y410;
     492    case AV_PIX_FMT_XV36:       return DXGI_FORMAT_Y416;
    461493    default:                    return DXGI_FORMAT_UNKNOWN;
    462494    }
    463495}
    static void ff_dxva2_unlock(AVCodecContext *avctx)  
    589621#endif
    590622}
    591623
     624static enum AVPixelFormat map_sw_pix_format(enum AVPixelFormat pix_fmt, enum AVPixelFormat hw_pix_fmt)
     625{
     626#if CONFIG_D3D11VA
     627    if (hw_pix_fmt == AV_PIX_FMT_D3D11) {
     628        switch (pix_fmt)
     629        {
     630        case AV_PIX_FMT_YUV420P10:
     631        case AV_PIX_FMT_P010:
     632            return AV_PIX_FMT_P010;
     633        case AV_PIX_FMT_YUV420P12:
     634            return AV_PIX_FMT_P016;
     635        case AV_PIX_FMT_YUV422P:
     636            return AV_PIX_FMT_YUYV422;
     637        case AV_PIX_FMT_YUV422P10:
     638            return AV_PIX_FMT_Y210;
     639        case AV_PIX_FMT_YUV444P:
     640            return AV_PIX_FMT_VUYX;
     641        case AV_PIX_FMT_YUV444P10:
     642            return AV_PIX_FMT_XV30;
     643        case AV_PIX_FMT_YUV422P12:
     644            return AV_PIX_FMT_Y212;
     645        case AV_PIX_FMT_YUV444P12:
     646            return AV_PIX_FMT_XV36;
     647        case AV_PIX_FMT_NV12:
     648        default:
     649            return AV_PIX_FMT_NV12;
     650        }
     651    }
     652#endif
     653    return pix_fmt == AV_PIX_FMT_YUV420P10 ?
     654        AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
     655}
     656
    592657int ff_dxva2_common_frame_params(AVCodecContext *avctx,
    593658                                 AVBufferRef *hw_frames_ctx)
    594659{
    int ff_dxva2_common_frame_params(AVCodecContext *avctx,  
    626691    else
    627692        num_surfaces += 2;
    628693
    629     frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
    630                             AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
     694    frames_ctx->sw_format = map_sw_pix_format(avctx->sw_pix_fmt, frames_ctx->format);
    631695    frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);
    632696    frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);
    633697    frames_ctx->initial_pool_size = num_surfaces;
  • libavcodec/dxva2_hevc.c

    diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
    index 31d74a7164..7153b2e604 100644
    a b  
    3232#define MAX_SLICES 256
    3333
    3434struct hevc_dxva2_picture_context {
    35     DXVA_PicParams_HEVC   pp;
     35    DXVA_PicParams_HEVC_Rext   pp;
    3636    DXVA_Qmatrix_HEVC     qm;
    3737    unsigned              slice_count;
    3838    DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
    static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)  
    5858}
    5959
    6060void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx,
    61                                     DXVA_PicParams_HEVC *pp)
     61                                    DXVA_PicParams_HEVC_Rext *ppext)
    6262{
    6363    const HEVCContext *h = avctx->priv_data;
    6464    const HEVCFrame *current_picture = h->ref;
    6565    const HEVCSPS *sps = h->ps.sps;
    6666    const HEVCPPS *pps = h->ps.pps;
    6767    int i, j;
     68    DXVA_PicParams_HEVC *pp = &ppext->main;
    6869
    69     memset(pp, 0, sizeof(*pp));
     70    memset(ppext, 0, sizeof(*ppext));
    7071
    7172    pp->PicWidthInMinCbsY  = sps->min_cb_width;
    7273    pp->PicHeightInMinCbsY = sps->min_cb_height;
    7374
     75    if (sps->sps_range_extension_flag) {
     76        ppext->dwRangeExtensionFlags |= (sps->transform_skip_rotation_enabled_flag     <<  0) |
     77                                        (sps->transform_skip_context_enabled_flag      <<  1) |
     78                                        (sps->implicit_rdpcm_enabled_flag              <<  2) |
     79                                        (sps->explicit_rdpcm_enabled_flag              <<  3) |
     80                                        (sps->extended_precision_processing_flag       <<  4) |
     81                                        (sps->intra_smoothing_disabled_flag            <<  5) |
     82                                        (sps->high_precision_offsets_enabled_flag      <<  5) |
     83                                        (sps->persistent_rice_adaptation_enabled_flag  <<  7) |
     84                                        (sps->cabac_bypass_alignment_enabled_flag      <<  8);
     85    }
     86    if (pps->pps_range_extensions_flag) {
     87        ppext->dwRangeExtensionFlags |= (pps->cross_component_prediction_enabled_flag  <<  9) |
     88                                        (pps->chroma_qp_offset_list_enabled_flag       << 10);
     89        if (pps->chroma_qp_offset_list_enabled_flag) {
     90            ppext->diff_cu_chroma_qp_offset_depth   = pps->diff_cu_chroma_qp_offset_depth;
     91            ppext->chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1;
     92            for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
     93                ppext->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
     94                ppext->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
     95            }
     96        }
     97        ppext->log2_sao_offset_scale_luma   = pps->log2_sao_offset_scale_luma;
     98        ppext->log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma;
     99        if (pps->transform_skip_enabled_flag) {
     100            ppext->log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size - 2;
     101        }
     102    }
     103
    74104    pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc             <<  0) |
    75105                                      (sps->separate_colour_plane_flag    <<  2) |
    76106                                      ((sps->bit_depth - 8)               <<  3) |
    static int dxva2_hevc_end_frame(AVCodecContext *avctx)  
    409439{
    410440    HEVCContext *h = avctx->priv_data;
    411441    struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
    412     int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
     442    int scale = ctx_pic->pp.main.dwCodingParamToolFlags & 1;
     443    int rext = avctx->profile == AV_PROFILE_HEVC_REXT && ff_dxva2_is_d3d11(avctx);
    413444    int ret;
    414445
    415446    if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
    416447        return -1;
    417448
    418449    ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
    419                                     &ctx_pic->pp, sizeof(ctx_pic->pp),
     450                                    &ctx_pic->pp, rext ? sizeof(ctx_pic->pp) : sizeof(ctx_pic->pp.main),
    420451                                    scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
    421452                                    commit_bitstream_and_slice_buffer);
    422453    return ret;
  • libavcodec/dxva2_internal.h

    diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
    index 224a867ebc..38e34ce64f 100644
    a b  
    6464#include <dxva.h>
    6565#endif
    6666
     67#pragma pack(push, 1)
     68typedef struct
     69{
     70    DXVA_PicParams_HEVC main;
     71
     72    // HEVC Range Extension
     73    __C89_NAMELESS union {
     74        __C89_NAMELESS struct {
     75            UINT32 transform_skip_rotation_enabled_flag : 1;
     76            UINT32 transform_skip_context_enabled_flag : 1;
     77            UINT32 implicit_rdpcm_enabled_flag : 1;
     78            UINT32 explicit_rdpcm_enabled_flag : 1;
     79            UINT32 extended_precision_processing_flag : 1;
     80            UINT32 intra_smoothing_disabled_flag : 1;
     81            UINT32 high_precision_offsets_enabled_flag : 1;
     82            UINT32 persistent_rice_adaptation_enabled_flag : 1;
     83            UINT32 cabac_bypass_alignment_enabled_flag : 1;
     84            UINT32 cross_component_prediction_enabled_flag : 1;
     85            UINT32 chroma_qp_offset_list_enabled_flag : 1;
     86            UINT32 BitDepthLuma16 : 1; // TODO merge in ReservedBits5 if not needed
     87            UINT32 BitDepthChroma16 : 1; // TODO merge in ReservedBits5 if not needed
     88            UINT32 ReservedBits8 : 19;
     89        };
     90        UINT32 dwRangeExtensionFlags;
     91    };
     92
     93    UCHAR diff_cu_chroma_qp_offset_depth;
     94    UCHAR chroma_qp_offset_list_len_minus1;
     95    UCHAR log2_sao_offset_scale_luma;
     96    UCHAR log2_sao_offset_scale_chroma;
     97    UCHAR log2_max_transform_skip_block_size_minus2;
     98    CHAR cb_qp_offset_list[6];
     99    CHAR cr_qp_offset_list[6];
     100} DXVA_PicParams_HEVC_Rext;
     101#pragma pack(pop)
     102
    67103#include "libavutil/hwcontext.h"
    68104
    69105#include "avcodec.h"
    void ff_dxva2_h264_fill_picture_parameters(const AVCodecContext *avctx, AVDXVACo  
    171207
    172208void ff_dxva2_h264_fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_Qmatrix_H264 *qm);
    173209
    174 void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_PicParams_HEVC *pp);
     210void ff_dxva2_hevc_fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_PicParams_HEVC_Rext *ppext);
    175211
    176212void ff_dxva2_hevc_fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, DXVA_Qmatrix_HEVC *qm);
    177213
  • libavcodec/hevcdec.c

    diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
    index b5311ae510..508f279933 100644
    a b static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)  
    463463#endif
    464464        break;
    465465    case AV_PIX_FMT_YUV444P:
     466#if CONFIG_HEVC_D3D11VA_HWACCEL
     467        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
     468        *fmt++ = AV_PIX_FMT_D3D11;
     469#endif
    466470#if CONFIG_HEVC_VAAPI_HWACCEL
    467471        *fmt++ = AV_PIX_FMT_VAAPI;
    468472#endif
    static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)  
    481485        break;
    482486    case AV_PIX_FMT_YUV422P:
    483487    case AV_PIX_FMT_YUV422P10LE:
     488#if CONFIG_HEVC_D3D11VA_HWACCEL
     489        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
     490        *fmt++ = AV_PIX_FMT_D3D11;
     491#endif
    484492#if CONFIG_HEVC_VAAPI_HWACCEL
    485493       *fmt++ = AV_PIX_FMT_VAAPI;
    486494#endif
    static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)  
    498506    /* NOTE: fallthrough */
    499507    case AV_PIX_FMT_YUV420P12:
    500508    case AV_PIX_FMT_YUV444P12:
     509#if CONFIG_HEVC_D3D11VA_HWACCEL
     510        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
     511        *fmt++ = AV_PIX_FMT_D3D11;
     512#endif
    501513#if CONFIG_HEVC_VAAPI_HWACCEL
    502514       *fmt++ = AV_PIX_FMT_VAAPI;
    503515#endif
    static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)  
    512524#endif
    513525        break;
    514526    case AV_PIX_FMT_YUV422P12:
     527#if CONFIG_HEVC_D3D11VA_HWACCEL
     528        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
     529        *fmt++ = AV_PIX_FMT_D3D11;
     530#endif
    515531#if CONFIG_HEVC_VAAPI_HWACCEL
    516532       *fmt++ = AV_PIX_FMT_VAAPI;
    517533#endif
  • libavutil/hwcontext_d3d11va.c

    diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c
    index 2fd3561c88..79b1f34b3b 100644
    a b static const struct {  
    9494    { DXGI_FORMAT_Y210,         AV_PIX_FMT_Y210 },
    9595    { DXGI_FORMAT_Y410,         AV_PIX_FMT_XV30 },
    9696    { DXGI_FORMAT_P016,         AV_PIX_FMT_P012 },
     97    { DXGI_FORMAT_P016,         AV_PIX_FMT_P016 },
    9798    { DXGI_FORMAT_Y216,         AV_PIX_FMT_Y212 },
    9899    { DXGI_FORMAT_Y416,         AV_PIX_FMT_XV36 },
    99100    // Special opaque formats. The pix_fmt is merely a place holder, as the
    static void fill_texture_ptrs(uint8_t *data[4], int linesize[4],  
    394395                              D3D11_TEXTURE2D_DESC *desc,
    395396                              D3D11_MAPPED_SUBRESOURCE *map)
    396397{
    397     int i;
    398 
    399     for (i = 0; i < 4; i++)
    400         linesize[i] = map->RowPitch;
     398    int width;
     399    int codedbytes = 1;
     400
     401    switch (ctx->sw_format) {
     402    case AV_PIX_FMT_P010:
     403    case AV_PIX_FMT_P016:
     404    case AV_PIX_FMT_YUYV422:
     405        codedbytes = 2;
     406        break;
     407    case AV_PIX_FMT_Y210:
     408    case AV_PIX_FMT_Y212:
     409    case AV_PIX_FMT_VUYX:
     410    case AV_PIX_FMT_XV30:
     411        codedbytes = 4;
     412        break;
     413    case AV_PIX_FMT_XV36:
     414        codedbytes = 8;
     415        break;
     416    }
    401417
     418    width = map->RowPitch / codedbytes;
     419    av_image_fill_linesizes(linesize, ctx->sw_format, width);
    402420    av_image_fill_pointers(data, ctx->sw_format, desc->Height,
    403421                           (uint8_t*)map->pData, linesize);
    404422}