On Thu, May 7, 2015 at 10:04 PM, Steve Lhomme <[email protected]> wrote:
> ---
>  configure                   |  31 +++++++-
>  libavcodec/Makefile         |   7 ++
>  libavcodec/allcodecs.c      |   5 ++
>  libavcodec/d3d11va.h        |  98 +++++++++++++++++++++++++
>  libavcodec/dxva2.c          | 170 
> ++++++++++++++++++++++++++++++++++++--------
>  libavcodec/dxva2_h264.c     | 140 +++++++++++++++++++++++++-----------
>  libavcodec/dxva2_hevc.c     | 110 +++++++++++++++++++++-------
>  libavcodec/dxva2_internal.h |  32 +++++++--
>  libavcodec/dxva2_mpeg2.c    | 104 +++++++++++++++++++++------
>  libavcodec/dxva2_vc1.c      | 133 ++++++++++++++++++++++++++--------
>  libavcodec/h264_slice.c     |   3 +
>  libavcodec/hevc.c           |   3 +
>  libavcodec/mpeg12dec.c      |   3 +
>  libavcodec/vc1dec.c         |   3 +
>  libavutil/pixdesc.c         |   6 ++
>  libavutil/pixfmt.h          |   2 +
>  16 files changed, 696 insertions(+), 154 deletions(-)
>  create mode 100644 libavcodec/d3d11va.h
>
> diff --git a/configure b/configure
> index f3e5154..1896447 100755
> --- a/configure
> +++ b/configure
> @@ -134,6 +134,7 @@ Component options:
>
>  Hardware accelerators:
>    --enable-dxva2           enable DXVA2 code
> +  --enable-d3d11va        disable D3D11VA code [autodetect]
>    --enable-vaapi           enable VAAPI code
>    --enable-vda             enable VDA code
>    --enable-vdpau           enable VDPAU code
> @@ -1207,6 +1208,7 @@ FEATURE_LIST="
>
>  HWACCEL_LIST="
>      dxva2
> +    d3d11va
>      vaapi
>      vda
>      vdpau
> @@ -1397,6 +1399,7 @@ HEADERS_LIST="
>      direct_h
>      dlfcn_h
>      dxva_h
> +    d3d11_h
>      gsm_h
>      io_h
>      mach_mach_time_h
> @@ -1552,6 +1555,8 @@ HAVE_LIST="
>      atomics_native
>      dos_paths
>      dxva2_lib
> +    d3d11_cobj
> +    d3d11va_lib
>      libc_msvcrt
>      libdc1394_1
>      libdc1394_2
> @@ -1966,6 +1971,7 @@ zmbv_encoder_deps="zlib"
>
>  # hardware accelerators
>  dxva2_deps="dxva2api_h"
> +d3d11va_deps="d3d11_h dxva_h"
>  vaapi_deps="va_va_h"
>  vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
>  vda_extralibs="-framework CoreFoundation -framework VideoDecodeAcceleration 
> -framework QuartzCore"
> @@ -1975,6 +1981,8 @@ h263_vaapi_hwaccel_deps="vaapi"
>  h263_vaapi_hwaccel_select="h263_decoder"
>  h263_vdpau_hwaccel_deps="vdpau"
>  h263_vdpau_hwaccel_select="h263_decoder"
> +h264_d3d11va_hwaccel_deps="d3d11va"
> +h264_d3d11va_hwaccel_select="h264_decoder"
>  h264_dxva2_hwaccel_deps="dxva2"
>  h264_dxva2_hwaccel_select="h264_decoder"
>  h264_mmal_decoder_deps="mmal"
> @@ -1990,10 +1998,14 @@ h264_vda_old_hwaccel_deps="vda"
>  h264_vda_old_hwaccel_select="h264_decoder"
>  h264_vdpau_hwaccel_deps="vdpau"
>  h264_vdpau_hwaccel_select="h264_decoder"
> +hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
> +hevc_d3d11va_hwaccel_select="hevc_decoder"
>  hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
>  hevc_dxva2_hwaccel_select="hevc_decoder"
>  mpeg1_vdpau_hwaccel_deps="vdpau"
>  mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
> +mpeg2_d3d11va_hwaccel_deps="d3d11va"
> +mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
>  mpeg2_dxva2_hwaccel_deps="dxva2"
>  mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
>  mpeg2_vaapi_hwaccel_deps="vaapi"
> @@ -2004,12 +2016,15 @@ mpeg4_vaapi_hwaccel_deps="vaapi"
>  mpeg4_vaapi_hwaccel_select="mpeg4_decoder"
>  mpeg4_vdpau_hwaccel_deps="vdpau"
>  mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
> +vc1_d3d11va_hwaccel_deps="d3d11va"
> +vc1_d3d11va_hwaccel_select="vc1_decoder"
>  vc1_dxva2_hwaccel_deps="dxva2"
>  vc1_dxva2_hwaccel_select="vc1_decoder"
>  vc1_vaapi_hwaccel_deps="vaapi"
>  vc1_vaapi_hwaccel_select="vc1_decoder"
>  vc1_vdpau_hwaccel_deps="vdpau"
>  vc1_vdpau_hwaccel_select="vc1_decoder"
> +wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
>  wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
>  wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
>  wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
> @@ -2288,7 +2303,7 @@ enable swscale_alpha
>  enable valgrind_backtrace
>
>  # By default, enable only those hwaccels that have no external dependencies.
> -enable dxva2 vda vdpau
> +enable d3d11va dxva2 vda vdpau
>
>  # build settings
>  SHFLAGS='-shared -Wl,-soname,$$(@F)'
> @@ -4157,6 +4172,7 @@ check_header direct.h
>  check_header dlfcn.h
>  check_header dxva.h
>  check_header dxva2api.h
> +check_header d3d11.h
>  check_header io.h
>  check_header mach/mach_time.h
>  check_header malloc.h
> @@ -4372,6 +4388,15 @@ if enabled x11grab; then
>      require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
>  fi
>
> +enabled d3d11_h &&
> +    check_cc <<EOF && enable d3d11_cobj
> +#define _WIN32_WINNT 0x0600
> +#define COBJMACROS
> +#include <windows.h>
> +#include <d3d11.h>
> +int main(void) { ID3D11VideoDecoder *o = NULL; 
> ID3D11VideoDecoder_Release(o); return 0; }
> +EOF
> +
>  enabled vaapi && enabled xlib &&
>      check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 &&
>      enable vaapi_x11
> @@ -4597,6 +4622,10 @@ enabled_all dxva2 CoTaskMemFree &&
>      prepend avconv_libs $($ldflags_filter "-lole32") &&
>      enable dxva2_lib
>
> +enabled_all d3d11va d3d11_cobj CoTaskMemFree &&
> +    prepend avconv_libs $($ldflags_filter "-lole32") &&
> +    enable d3d11va_lib
> +
>  ! enabled_any memalign posix_memalign aligned_malloc &&
>      enabled simd_align_16 && enable memalign_hack
>
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index fc8c6e9..e4ca551 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -3,6 +3,7 @@ NAME = avcodec
>  HEADERS = avcodec.h                                                     \
>            avfft.h                                                       \
>            dv_profile.h                                                  \
> +          d3d11va.h                                                     \
>            dxva2.h                                                       \
>            qsv.h                                                         \
>            vaapi.h                                                       \
> @@ -557,6 +558,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER)       += adpcm.o 
> adpcm_data.o
>  OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
>
>  # hardware accelerators
> +OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
>  OBJS-$(CONFIG_DXVA2)                      += dxva2.o
>  OBJS-$(CONFIG_VAAPI)                      += vaapi.o
>  OBJS-$(CONFIG_VDA)                        += vda.o
> @@ -564,17 +566,21 @@ OBJS-$(CONFIG_VDPAU)                      += vdpau.o
>
>  OBJS-$(CONFIG_H263_VAAPI_HWACCEL)         += vaapi_mpeg4.o
>  OBJS-$(CONFIG_H263_VDPAU_HWACCEL)         += vdpau_mpeg4.o
> +OBJS-$(CONFIG_H264_D3D11VA_HWACCEL)       += dxva2_h264.o
>  OBJS-$(CONFIG_H264_DXVA2_HWACCEL)         += dxva2_h264.o
>  OBJS-$(CONFIG_H264_VAAPI_HWACCEL)         += vaapi_h264.o
>  OBJS-$(CONFIG_H264_VDA_HWACCEL)           += vda_h264.o
>  OBJS-$(CONFIG_H264_VDPAU_HWACCEL)         += vdpau_h264.o
> +OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL)       += dxva2_hevc.o
>  OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL)         += dxva2_hevc.o
>  OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
> +OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL)      += dxva2_mpeg2.o
>  OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva2_mpeg2.o
>  OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o
>  OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)        += vdpau_mpeg12.o
>  OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o
>  OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)        += vdpau_mpeg4.o
> +OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL)        += dxva2_vc1.o
>  OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva2_vc1.o
>  OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o
>  OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)          += vdpau_vc1.o
> @@ -723,6 +729,7 @@ SKIPHEADERS                            += %_tablegen.h    
>               \
>                                            tableprint.h                  \
>                                            $(ARCH)/vp56_arith.h          \
>
> +SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
>  SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
>  SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
>  SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
> diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
> index d2679ad..a8b5b53 100644
> --- a/libavcodec/allcodecs.c
> +++ b/libavcodec/allcodecs.c
> @@ -76,6 +76,7 @@ void avcodec_register_all(void)
>      /* hardware accelerators */
>      REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
>      REGISTER_HWACCEL(H263_VDPAU,        h263_vdpau);
> +    REGISTER_HWACCEL(H264_D3D11VA,      h264_d3d11va);
>      REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
>      REGISTER_HWACCEL(H264_MMAL,         h264_mmal);
>      REGISTER_HWACCEL(H264_QSV,          h264_qsv);
> @@ -83,16 +84,20 @@ void avcodec_register_all(void)
>      REGISTER_HWACCEL(H264_VDA,          h264_vda);
>      REGISTER_HWACCEL(H264_VDA_OLD,      h264_vda_old);
>      REGISTER_HWACCEL(H264_VDPAU,        h264_vdpau);
> +    REGISTER_HWACCEL(HEVC_D3D11VA,      hevc_d3d11va);
>      REGISTER_HWACCEL(HEVC_DXVA2,        hevc_dxva2);
>      REGISTER_HWACCEL(MPEG1_VDPAU,       mpeg1_vdpau);
> +    REGISTER_HWACCEL(MPEG2_D3D11VA,     mpeg2_d3d11va);
>      REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
>      REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
>      REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
>      REGISTER_HWACCEL(MPEG4_VAAPI,       mpeg4_vaapi);
>      REGISTER_HWACCEL(MPEG4_VDPAU,       mpeg4_vdpau);
> +    REGISTER_HWACCEL(VC1_D3D11VA,       vc1_d3d11va);
>      REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
>      REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
>      REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
> +    REGISTER_HWACCEL(WMV3_D3D11VA,      wmv3_d3d11va);
>      REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
>      REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
>      REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);
> diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
> new file mode 100644
> index 0000000..bc2852e
> --- /dev/null
> +++ b/libavcodec/d3d11va.h
> @@ -0,0 +1,98 @@
> +/*
> + * Direct3D11 HW acceleration
> + *
> + * copyright (c) 2009 Laurent Aimar
> + * copyright (c) 2015 Steve Lhomme
> + *
> + * This file is part of Libav.
> + *
> + * Libav is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * Libav is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with Libav; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
> USA
> + */
> +
> +#ifndef AVCODEC_D3D11VA_H
> +#define AVCODEC_D3D11VA_H
> +
> +/**
> + * @file
> + * @ingroup lavc_codec_hwaccel_d3d11va
> + * Public libavcodec D3D11VA header.
> + */
> +
> +#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
> +#undef _WIN32_WINNT
> +#define _WIN32_WINNT 0x0600
> +#endif
> +
> +#include <stdint.h>
> +#include <d3d11.h>
> +
> +/**
> + * @defgroup lavc_codec_hwaccel_d3d11va Direct3D11
> + * @ingroup lavc_codec_hwaccel
> + *
> + * @{
> + */
> +
> +#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for 
> Direct3D11 and old UVD/UVD+ ATI video cards
> +#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO    2 ///< Work around for 
> Direct3D11 and old Intel GPUs with ClearVideo interface
> +
> +/**
> + * This structure is used to provides the necessary configurations and data
> + * to the Direct3D11 Libav HWAccel implementation.
> + *
> + * The application must make it available as AVCodecContext.hwaccel_context.
> + */
> +struct av_d3d11va_context {

AVD3D11VAContext would be more inline with other struct naming.
For bonus points, we could also implement a allocator function, that
way we can add new fields at the end of the struct in the future
without breaking ABI.

> +    /**
> +     * D3D11 decoder object
> +     */
> +    ID3D11VideoDecoder *decoder;
> +
> +    /**
> +      * D3D11 VideoContext
> +      */
> +    ID3D11VideoContext *video_context;
> +
> +    /**
> +     * D3D11 configuration used to create the decoder
> +     */
> +    D3D11_VIDEO_DECODER_CONFIG *cfg;
> +
> +    /**
> +     * The number of surface in the surface array
> +     */
> +    unsigned surface_count;
> +
> +    /**
> +     * The array of Direct3D surfaces used to create the decoder
> +     */
> +    ID3D11VideoDecoderOutputView **surface;
> +
> +    /**
> +     * A bit field configuring the workarounds needed for using the decoder
> +     */
> +    uint64_t workaround;
> +
> +    /**
> +     * Private to the Libav AVHWAccel implementation
> +     */
> +    unsigned report_id;
> +};
> +
> +/**
> + * @}
> + */
> +
> +#endif /* AVCODEC_D3D11VA_H */
> diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
> index 9ee22c8..190a2e5 100644
> --- a/libavcodec/dxva2.c
> +++ b/libavcodec/dxva2.c
> @@ -35,14 +35,15 @@ void *ff_dxva2_get_surface(const AVFrame *frame)
>      return frame->data[3];
>  }
>
> -unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
> +unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
> +                                    const av_dxva_context_t *ctx,
>                                      const AVFrame *frame)
>  {
>      void *surface = ff_dxva2_get_surface(frame);
>      unsigned i;
>
> -    for (i = 0; i < ctx->surface_count; i++)
> -        if (ctx->surface[i] == surface)
> +    for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
> +        if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)
>              return i;
>
>      assert(0);
> @@ -50,8 +51,8 @@ unsigned ff_dxva2_get_surface_index(const struct 
> dxva_context *ctx,
>  }
>
>  int ff_dxva2_commit_buffer(AVCodecContext *avctx,
> -                           struct dxva_context *ctx,
> -                           DXVA2_DecodeBufferDesc *dsc,
> +                           av_dxva_context_t *ctx,
> +                           DECODER_BUFFER_DESC *dsc,
>                             unsigned type, const void *data, unsigned size,
>                             unsigned mb_count)
>  {
> @@ -60,8 +61,20 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
>      int      result;
>      HRESULT hr;
>
> -    hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
> -                                        &dxva_data, &dxva_size);
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        hr = 
> ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                 
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                 type,
> +                                                 &dxva_size, &dxva_data);
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type,
> +                                            &dxva_data, &dxva_size);
> +    }
> +#endif
>      if (FAILED(hr)) {
>          av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
>                 type, hr);
> @@ -70,10 +83,24 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
>      if (size <= dxva_size) {
>          memcpy(dxva_data, data, size);
>
> -        memset(dsc, 0, sizeof(*dsc));
> -        dsc->CompressedBufferType = type;
> -        dsc->DataSize             = size;
> -        dsc->NumMBsInBuffer       = mb_count;
> +#if CONFIG_D3D11VA
> +        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +            D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
> +            memset(dsc11, 0, sizeof(*dsc11));
> +            dsc11->BufferType           = type;
> +            dsc11->DataSize             = size;
> +            dsc11->NumMBsInBuffer       = mb_count;
> +        }
> +#endif
> +#if CONFIG_DXVA2
> +        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +            DXVA2_DecodeBufferDesc *dsc2 = dsc;
> +            memset(dsc2, 0, sizeof(*dsc2));
> +            dsc2->CompressedBufferType = type;
> +            dsc2->DataSize             = size;
> +            dsc2->NumMBsInBuffer       = mb_count;
> +        }
> +#endif
>
>          result = 0;
>      } else {
> @@ -81,7 +108,16 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
>          result = -1;
>      }
>
> -    hr = IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type);
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        hr = 
> ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, 
> D3D11VA_CONTEXT(ctx)->decoder, type);
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type);
> +    }
> +#endif
>      if (FAILED(hr)) {
>          av_log(avctx, AV_LOG_ERROR,
>                 "Failed to release buffer type %u: 0x%lx\n",
> @@ -95,20 +131,33 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> AVFrame *frame,
>                                const void *pp, unsigned pp_size,
>                                const void *qm, unsigned qm_size,
>                                int (*commit_bs_si)(AVCodecContext *,
> -                                                  DXVA2_DecodeBufferDesc *bs,
> -                                                  DXVA2_DecodeBufferDesc 
> *slice))
> +                                                  DECODER_BUFFER_DESC *bs,
> +                                                  DECODER_BUFFER_DESC 
> *slice))
>  {
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      unsigned               buffer_count = 0;
> -    DXVA2_DecodeBufferDesc buffer[4];
> -    DXVA2_DecodeExecuteParams exec = { 0 };
> +    D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
> +    DXVA2_DecodeBufferDesc          buffer2[4];
> +    DECODER_BUFFER_DESC             *buffer,*buffer_slice;
>      int result, runs = 0;
>      HRESULT hr;
> +    unsigned type;
>
>      do {
> -        hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder,
> -                                             ff_dxva2_get_surface(frame),
> -                                             NULL);
> +#if CONFIG_D3D11VA
> +        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +            hr = 
> ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, 
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                      
> ff_dxva2_get_surface(frame),
> +                                                      0, NULL);
> +        }
> +#endif
> +#if CONFIG_DXVA2
> +        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +            hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
> +                                                 ff_dxva2_get_surface(frame),
> +                                                 NULL);
> +        }
> +#endif
>          if (hr == E_PENDING)
>              av_usleep(2000);
>      } while (hr == E_PENDING && ++runs < 50);
> @@ -118,8 +167,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> AVFrame *frame,
>          return -1;
>      }
>
> -    result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
> -                                    DXVA2_PictureParametersBufferType,
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        buffer = &buffer11[buffer_count];
> +        type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        buffer = &buffer2[buffer_count];
> +        type = DXVA2_PictureParametersBufferType;
> +    }
> +#endif
> +    result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
> +                                    type,
>                                      pp, pp_size, 0);
>      if (result) {
>          av_log(avctx, AV_LOG_ERROR,
> @@ -129,8 +190,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> AVFrame *frame,
>      buffer_count++;
>
>      if (qm_size > 0) {
> -        result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
> -                                        
> DXVA2_InverseQuantizationMatrixBufferType,
> +#if CONFIG_D3D11VA
> +        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +            buffer = &buffer11[buffer_count];
> +            type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
> +        }
> +#endif
> +#if CONFIG_DXVA2
> +        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +            buffer = &buffer2[buffer_count];
> +            type = DXVA2_InverseQuantizationMatrixBufferType;
> +        }
> +#endif
> +        result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
> +                                        type,
>                                          qm, qm_size, 0);
>          if (result) {
>              av_log(avctx, AV_LOG_ERROR,
> @@ -140,9 +213,22 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> AVFrame *frame,
>          buffer_count++;
>      }
>
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        buffer       = &buffer11[buffer_count + 0];
> +        buffer_slice = &buffer11[buffer_count + 1];
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        buffer       = &buffer2[buffer_count + 0];
> +        buffer_slice = &buffer2[buffer_count + 1];
> +    }
> +#endif
> +
>      result = commit_bs_si(avctx,
> -                          &buffer[buffer_count + 0],
> -                          &buffer[buffer_count + 1]);
> +                          buffer,
> +                          buffer_slice);
>      if (result) {
>          av_log(avctx, AV_LOG_ERROR,
>                 "Failed to add bitstream or slice control buffer\n");
> @@ -154,17 +240,39 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, 
> AVFrame *frame,
>
>      assert(buffer_count == 1 + (qm_size > 0) + 2);
>
> -    exec.NumCompBuffers      = buffer_count;
> -    exec.pCompressedBuffers  = buffer;
> -    exec.pExtensionData      = NULL;
> -    hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec);
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        hr = 
> ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                     
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                     buffer_count, buffer11);
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        DXVA2_DecodeExecuteParams exec = {
> +            .NumCompBuffers = buffer_count,
> +            .pCompressedBuffers = buffer2,
> +            .pExtensionData = NULL,
> +        };
> +        hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, 
> &exec);
> +    }
> +#endif
>      if (FAILED(hr)) {
>          av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
>          result = -1;
>      }
>
>  end:
> -    hr = IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL);
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        hr = 
> ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, 
> D3D11VA_CONTEXT(ctx)->decoder);
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, 
> NULL);
> +    }
> +#endif
>      if (FAILED(hr)) {
>          av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
>          result = -1;
> diff --git a/libavcodec/dxva2_h264.c b/libavcodec/dxva2_h264.c
> index a5e9705..ec02c47 100644
> --- a/libavcodec/dxva2_h264.c
> +++ b/libavcodec/dxva2_h264.c
> @@ -42,7 +42,7 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
>      pic->bPicEntry = index | (flag << 7);
>  }
>
> -static void fill_picture_parameters(struct dxva_context *ctx, const 
> H264Context *h,
> +static void fill_picture_parameters(const AVCodecContext *avctx, 
> av_dxva_context_t *ctx, const H264Context *h,
>                                      DXVA_PicParams_H264 *pp)
>  {
>      const H264Picture *current_picture = h->cur_pic_ptr;
> @@ -51,7 +51,7 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const H264Context
>      memset(pp, 0, sizeof(*pp));
>      /* Configure current picture */
>      fill_picture_entry(&pp->CurrPic,
> -                       ff_dxva2_get_surface_index(ctx, current_picture->f),
> +                       ff_dxva2_get_surface_index(avctx, ctx, 
> current_picture->f),
>                         h->picture_structure == PICT_BOTTOM_FIELD);
>      /* Configure the set of references */
>      pp->UsedForReferenceFlags  = 0;
> @@ -67,7 +67,7 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const H264Context
>          }
>          if (r) {
>              fill_picture_entry(&pp->RefFrameList[i],
> -                               ff_dxva2_get_surface_index(ctx, r->f),
> +                               ff_dxva2_get_surface_index(avctx, ctx, r->f),
>                                 r->long_ref != 0);
>
>              if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != 
> INT_MAX)
> @@ -114,13 +114,13 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const H264Context
>
>      pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
>      pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
> -    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
> +    if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & 
> FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
>          pp->Reserved16Bits            = 0;
> -    else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
> +    else if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & 
> FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
>          pp->Reserved16Bits            = 0x34c;
>      else
>          pp->Reserved16Bits            = 3; /* FIXME is there a way to detect 
> the right mode ? */
> -    pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
> +    pp->StatusReportFeedbackNumber    = 1 + DXVA_CONTEXT_REPORT_ID(avctx, 
> ctx)++;
>      pp->CurrFieldOrderCnt[0] = 0;
>      if ((h->picture_structure & PICT_TOP_FIELD) &&
>          current_picture->field_poc[0] != INT_MAX)
> @@ -156,11 +156,11 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const H264Context
>      //pp->SliceGroupMap[810];               /* XXX not implemented by Libav 
> */
>  }
>
> -static void fill_scaling_lists(struct dxva_context *ctx, const H264Context 
> *h, DXVA_Qmatrix_H264 *qm)
> +static void fill_scaling_lists(const AVCodecContext *avctx, 
> av_dxva_context_t *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
>  {
>      unsigned i, j;
>      memset(qm, 0, sizeof(*qm));
> -    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
> +    if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & 
> FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
>          for (i = 0; i < 6; i++)
>              for (j = 0; j < 16; j++)
>                  qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j];
> @@ -181,11 +181,11 @@ static void fill_scaling_lists(struct dxva_context 
> *ctx, const H264Context *h, D
>      }
>  }
>
> -static int is_slice_short(struct dxva_context *ctx)
> +static int is_slice_short(const AVCodecContext *avctx, av_dxva_context_t 
> *ctx)
>  {
> -    assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
> -           ctx->cfg->ConfigBitstreamRaw == 2);
> -    return ctx->cfg->ConfigBitstreamRaw == 2;
> +    assert(DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 1 ||
> +           DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2);
> +    return DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2;
>  }
>
>  static void fill_slice_short(DXVA_Slice_H264_Short *slice,
> @@ -212,7 +212,7 @@ static void fill_slice_long(AVCodecContext *avctx, 
> DXVA_Slice_H264_Long *slice,
>  {
>      const H264Context *h = avctx->priv_data;
>      H264SliceContext *sl = &h->slice_ctx[0];
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      unsigned list;
>
>      memset(slice, 0, sizeof(*slice));
> @@ -243,10 +243,10 @@ static void fill_slice_long(AVCodecContext *avctx, 
> DXVA_Slice_H264_Long *slice,
>                  const H264Picture *r = sl->ref_list[list][i].parent;
>                  unsigned plane;
>                  unsigned index;
> -                if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
> -                    index = ff_dxva2_get_surface_index(ctx, r->f);
> +                if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & 
> FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
> +                    index = ff_dxva2_get_surface_index(avctx, ctx, r->f);
>                  else
> -                    index = get_refpic_index(pp, 
> ff_dxva2_get_surface_index(ctx, r->f));
> +                    index = get_refpic_index(pp, 
> ff_dxva2_get_surface_index(avctx, ctx, r->f));
>                  fill_picture_entry(&slice->RefPicList[list][i], index,
>                                     r->reference == PICT_BOTTOM_FIELD);
>                  for (plane = 0; plane < 3; plane++) {
> @@ -289,12 +289,12 @@ static void fill_slice_long(AVCodecContext *avctx, 
> DXVA_Slice_H264_Long *slice,
>  }
>
>  static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
> -                                             DXVA2_DecodeBufferDesc *bs,
> -                                             DXVA2_DecodeBufferDesc *sc)
> +                                             DECODER_BUFFER_DESC *bs,
> +                                             DECODER_BUFFER_DESC *sc)
>  {
>      const H264Context *h = avctx->priv_data;
>      const unsigned mb_count = h->mb_width * h->mb_height;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      const H264Picture *current_picture = h->cur_pic_ptr;
>      struct dxva2_picture_context *ctx_pic = 
> current_picture->hwaccel_picture_private;
>      DXVA_Slice_H264_Short *slice = NULL;
> @@ -305,12 +305,28 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>      unsigned slice_size;
>      unsigned padding;
>      unsigned i;
> +    unsigned type;
>
>      /* Create an annex B bitstream buffer with only slice NAL and finalize 
> slice */
> -    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
> -                                              DXVA2_BitStreamDateBufferType,
> -                                              &dxva_data_ptr, &dxva_size)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
> +        if 
> (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                       
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                       type,
> +                                                       &dxva_size, 
> &dxva_data_ptr)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        type = DXVA2_BitStreamDateBufferType;
> +        if 
> (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
> +                                                  type,
> +                                                  &dxva_data_ptr, 
> &dxva_size)))
> +            return -1;
> +    }
> +#endif
>
>      dxva_data = dxva_data_ptr;
>      current = dxva_data;
> @@ -326,7 +342,7 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>          assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
>                 offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));
>
> -        if (is_slice_short(ctx))
> +        if (is_slice_short(avctx, ctx))
>              slice = &ctx_pic->slice_short[i];
>          else
>              slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
> @@ -341,7 +357,7 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>          slice->BSNALunitDataLocation = current - dxva_data;
>          slice->SliceBytesInBuffer    = start_code_size + size;
>
> -        if (!is_slice_short(ctx)) {
> +        if (!is_slice_short(avctx, ctx)) {
>              DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
>              if (i < ctx_pic->slice_count - 1)
>                  slice_long->NumMbsForSlice =
> @@ -363,18 +379,45 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>
>          slice->SliceBytesInBuffer += padding;
>      }
> -    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
> -                                                  
> DXVA2_BitStreamDateBufferType)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        if 
> (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
>  D3D11VA_CONTEXT(ctx)->decoder, type)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        if 
> (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type)))
> +            return -1;
> +    }
> +#endif
>      if (i < ctx_pic->slice_count)
>          return -1;
>
> -    memset(bs, 0, sizeof(*bs));
> -    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
> -    bs->DataSize             = current - dxva_data;
> -    bs->NumMBsInBuffer       = mb_count;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
> +        memset(dsc11, 0, sizeof(*dsc11));
> +        dsc11->BufferType           = type;
> +        dsc11->DataSize             = current - dxva_data;
> +        dsc11->NumMBsInBuffer       = mb_count;
> +
> +        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        DXVA2_DecodeBufferDesc *dsc2 = bs;
> +        memset(dsc2, 0, sizeof(*dsc2));
> +        dsc2->CompressedBufferType = type;
> +        dsc2->DataSize             = current - dxva_data;
> +        dsc2->NumMBsInBuffer       = mb_count;
> +
> +        type = DXVA2_SliceControlBufferType;
> +    }
> +#endif
>
> -    if (is_slice_short(ctx)) {
> +    if (is_slice_short(avctx, ctx)) {
>          slice_data = ctx_pic->slice_short;
>          slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
>      } else {
> @@ -383,7 +426,7 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>      }
>      assert((bs->DataSize & 127) == 0);
>      return ff_dxva2_commit_buffer(avctx, ctx, sc,
> -                                  DXVA2_SliceControlBufferType,
> +                                  type,
>                                    slice_data, slice_size, mb_count);
>  }
>
> @@ -393,18 +436,20 @@ static int dxva2_h264_start_frame(AVCodecContext *avctx,
>                                    av_unused uint32_t size)
>  {
>      const H264Context *h = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      struct dxva2_picture_context *ctx_pic = 
> h->cur_pic_ptr->hwaccel_picture_private;
>
> -    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
> +    if (DXVA_CONTEXT_DECODER(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_CFG(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
>          return -1;
>      assert(ctx_pic);
>
>      /* Fill up DXVA_PicParams_H264 */
> -    fill_picture_parameters(ctx, h, &ctx_pic->pp);
> +    fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
>
>      /* Fill up DXVA_Qmatrix_H264 */
> -    fill_scaling_lists(ctx, h, &ctx_pic->qm);
> +    fill_scaling_lists(avctx, ctx, h, &ctx_pic->qm);
>
>      ctx_pic->slice_count    = 0;
>      ctx_pic->bitstream_size = 0;
> @@ -418,7 +463,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
>  {
>      const H264Context *h = avctx->priv_data;
>      const H264SliceContext *sl = &h->slice_ctx[0];
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      const H264Picture *current_picture = h->cur_pic_ptr;
>      struct dxva2_picture_context *ctx_pic = 
> current_picture->hwaccel_picture_private;
>      unsigned position;
> @@ -431,7 +476,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
>      ctx_pic->bitstream_size += size;
>
>      position = buffer - ctx_pic->bitstream;
> -    if (is_slice_short(ctx))
> +    if (is_slice_short(avctx, ctx))
>          fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
>                           position, size);
>      else
> @@ -463,6 +508,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx)
>      return ret;
>  }
>
> +#if CONFIG_DXVA2

CONFIG_H264_DXVA2_HWACCEL, more of the same changes for the other codecs.

>  AVHWAccel ff_h264_dxva2_hwaccel = {
>      .name           = "h264_dxva2",
>      .type           = AVMEDIA_TYPE_VIDEO,
> @@ -473,3 +519,17 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
>      .end_frame      = dxva2_h264_end_frame,
>      .frame_priv_data_size = sizeof(struct dxva2_picture_context),
>  };
> +#endif
> +
> +#if CONFIG_D3D11VA

CONFIG_H264_D3D11VA_HWACCEL, same for the other codecs.

> +AVHWAccel ff_h264_d3d11va_hwaccel = {
> +    .name           = "h264_d3d11va",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_H264,
> +    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
> +    .start_frame    = dxva2_h264_start_frame,
> +    .decode_slice   = dxva2_h264_decode_slice,
> +    .end_frame      = dxva2_h264_end_frame,
> +    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
> +};
> +#endif
> diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
> index 257bee7..ac79fc2 100644
> --- a/libavcodec/dxva2_hevc.c
> +++ b/libavcodec/dxva2_hevc.c
> @@ -53,7 +53,7 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, 
> int surface_index)
>      return 0xff;
>  }
>
> -static void fill_picture_parameters(struct dxva_context *ctx, const 
> HEVCContext *h,
> +static void fill_picture_parameters(const AVCodecContext *avctx, 
> av_dxva_context_t *ctx, const HEVCContext *h,
>                                      DXVA_PicParams_HEVC *pp)
>  {
>      const HEVCFrame *current_picture = h->ref;
> @@ -73,7 +73,7 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const HEVCContext
>                                        (0                                  << 
> 14) |
>                                        (0                                  << 
> 15);
>
> -    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(ctx, 
> current_picture->frame), 0);
> +    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, 
> current_picture->frame), 0);
>
>      pp->sps_max_dec_pic_buffering_minus1         = 
> h->sps->temporal_layer[h->sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
>      pp->log2_min_luma_coding_block_size_minus3   = h->sps->log2_min_cb_size 
> - 3;
> @@ -165,7 +165,7 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const HEVCContext
>      for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
>          const HEVCFrame *frame = &h->DPB[i];
>          if (frame != current_picture && (frame->flags & 
> (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
> -            fill_picture_entry(&pp->RefPicList[j], 
> ff_dxva2_get_surface_index(ctx, frame->frame), !!(frame->flags & 
> HEVC_FRAME_FLAG_LONG_REF));
> +            fill_picture_entry(&pp->RefPicList[j], 
> ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & 
> HEVC_FRAME_FLAG_LONG_REF));
>              pp->PicOrderCntValList[j] = frame->poc;
>              j++;
>          }
> @@ -176,7 +176,7 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const HEVCContext
>          av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
>          for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
>              if (rpl->ref[j]) { \
> -                pp->ref_list[k] = get_refpic_index(pp, 
> ff_dxva2_get_surface_index(ctx, rpl->ref[j]->frame)); \
> +                pp->ref_list[k] = get_refpic_index(pp, 
> ff_dxva2_get_surface_index(avctx, ctx, rpl->ref[j]->frame)); \
>                  k++; \
>              } \
>          } \
> @@ -187,10 +187,10 @@ static void fill_picture_parameters(struct dxva_context 
> *ctx, const HEVCContext
>      DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
>      DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
>
> -    pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
> +    pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, 
> ctx)++;
>  }
>
> -static void fill_scaling_lists(struct dxva_context *ctx, const HEVCContext 
> *h, DXVA_Qmatrix_HEVC *qm)
> +static void fill_scaling_lists(av_dxva_context_t *ctx, const HEVCContext *h, 
> DXVA_Qmatrix_HEVC *qm)
>  {
>      unsigned i, j, pos;
>      const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
> @@ -228,11 +228,11 @@ static void fill_slice_short(DXVA_Slice_HEVC_Short 
> *slice,
>  }
>
>  static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
> -                                             DXVA2_DecodeBufferDesc *bs,
> -                                             DXVA2_DecodeBufferDesc *sc)
> +                                             DECODER_BUFFER_DESC *bs,
> +                                             DECODER_BUFFER_DESC *sc)
>  {
>      const HEVCContext *h = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      const HEVCFrame *current_picture = h->ref;
>      struct hevc_dxva2_picture_context *ctx_pic = 
> current_picture->hwaccel_picture_private;
>      DXVA_Slice_HEVC_Short *slice = NULL;
> @@ -243,12 +243,28 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>      unsigned slice_size;
>      unsigned padding;
>      unsigned i;
> +    unsigned type;
>
>      /* Create an annex B bitstream buffer with only slice NAL and finalize 
> slice */
> -    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
> -                                              DXVA2_BitStreamDateBufferType,
> -                                              &dxva_data_ptr, &dxva_size)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
> +        if 
> (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                       
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                       type,
> +                                                       &dxva_size, 
> &dxva_data_ptr)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        type = DXVA2_BitStreamDateBufferType;
> +        if 
> (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
> +                                                  type,
> +                                                  &dxva_data_ptr, 
> &dxva_size)))
> +            return -1;
> +    }
> +#endif
>
>      dxva_data = dxva_data_ptr;
>      current = dxva_data;
> @@ -284,23 +300,50 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>
>          slice->SliceBytesInBuffer += padding;
>      }
> -    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
> -                                                  
> DXVA2_BitStreamDateBufferType)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        if 
> (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
>  D3D11VA_CONTEXT(ctx)->decoder, type)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        if 
> (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type)))
> +            return -1;
> +    }
> +#endif
>      if (i < ctx_pic->slice_count)
>          return -1;
>
> -    memset(bs, 0, sizeof(*bs));
> -    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
> -    bs->DataSize             = current - dxva_data;
> -    bs->NumMBsInBuffer       = 0;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
> +        memset(dsc11, 0, sizeof(*dsc11));
> +        dsc11->BufferType           = type;
> +        dsc11->DataSize             = current - dxva_data;
> +        dsc11->NumMBsInBuffer       = 0;
> +
> +        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        DXVA2_DecodeBufferDesc *dsc2 = bs;
> +        memset(dsc2, 0, sizeof(*dsc2));
> +        dsc2->CompressedBufferType = type;
> +        dsc2->DataSize             = current - dxva_data;
> +        dsc2->NumMBsInBuffer       = 0;
> +
> +        type = DXVA2_SliceControlBufferType;
> +    }
> +#endif
>
>      slice_data = ctx_pic->slice_short;
>      slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
>
> -    av_assert0((bs->DataSize & 127) == 0);
> +    av_assert0(((current - dxva_data) & 127) == 0);
>      return ff_dxva2_commit_buffer(avctx, ctx, sc,
> -                                  DXVA2_SliceControlBufferType,
> +                                  type,
>                                    slice_data, slice_size, 0);
>  }
>
> @@ -310,15 +353,17 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx,
>                                    av_unused uint32_t size)
>  {
>      const HEVCContext *h = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      struct hevc_dxva2_picture_context *ctx_pic = 
> h->ref->hwaccel_picture_private;
>
> -    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
> +    if (DXVA_CONTEXT_DECODER(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_CFG(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
>          return -1;
>      av_assert0(ctx_pic);
>
>      /* Fill up DXVA_PicParams_HEVC */
> -    fill_picture_parameters(ctx, h, &ctx_pic->pp);
> +    fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
>
>      /* Fill up DXVA_Qmatrix_HEVC */
>      fill_scaling_lists(ctx, h, &ctx_pic->qm);
> @@ -369,6 +414,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx)
>      return ret;
>  }
>
> +#if CONFIG_DXVA2
>  AVHWAccel ff_hevc_dxva2_hwaccel = {
>      .name           = "hevc_dxva2",
>      .type           = AVMEDIA_TYPE_VIDEO,
> @@ -379,3 +425,17 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
>      .end_frame      = dxva2_hevc_end_frame,
>      .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
>  };
> +#endif
> +
> +#if CONFIG_D3D11VA
> +AVHWAccel ff_hevc_d3d11va_hwaccel = {
> +    .name           = "hevc_d3d11va",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_HEVC,
> +    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
> +    .start_frame    = dxva2_hevc_start_frame,
> +    .decode_slice   = dxva2_hevc_decode_slice,
> +    .end_frame      = dxva2_hevc_end_frame,
> +    .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
> +};
> +#endif
> diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h
> index b775e6c..8013c73 100644
> --- a/libavcodec/dxva2_internal.h
> +++ b/libavcodec/dxva2_internal.h
> @@ -28,6 +28,7 @@
>  #include "config.h"
>
>  #include "dxva2.h"
> +#include "d3d11va.h"
>  #if HAVE_DXVA_H
>  #include <dxva.h>
>  #endif
> @@ -35,13 +36,34 @@
>  #include "avcodec.h"
>  #include "mpegvideo.h"
>
> +typedef void DECODER_BUFFER_DESC;
> +
> +typedef union {
> +    struct av_d3d11va_context  d3d11va;
> +    struct dxva_context        dxva2;
> +} av_dxva_context_t;
> +
> +#define D3D11VA_CONTEXT(ctx) (&ctx->d3d11va)
> +#define DXVA2_CONTEXT(ctx)   (&ctx->dxva2)
> +
> +#define DXVA_CONTEXT_WORKAROUND(avctx, ctx)     (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround)
> +#define DXVA_CONTEXT_COUNT(avctx, ctx)          (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface_count : 
> ctx->dxva2.surface_count)
> +#define DXVA_CONTEXT_SURFACE(avctx, ctx, i)     (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface[i] : ctx->dxva2.surface[i])
> +#define DXVA_CONTEXT_DECODER(avctx, ctx)        (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.decoder : ctx->dxva2.decoder)
> +#define DXVA_CONTEXT_REPORT_ID(avctx, ctx)      (*(avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? &ctx->d3d11va.report_id : &ctx->dxva2.report_id))
> +#define DXVA_CONTEXT_CFG(avctx, ctx)            (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg : ctx->dxva2.cfg)
> +#define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx)  (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigBitstreamRaw : 
> ctx->dxva2.cfg->ConfigBitstreamRaw)
> +#define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigIntraResidUnsigned : 
> ctx->dxva2.cfg->ConfigIntraResidUnsigned)
> +#define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (avctx->pix_fmt == 
> AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigResidDiffAccelerator : 
> ctx->dxva2.cfg->ConfigResidDiffAccelerator)
> +
>  void *ff_dxva2_get_surface(const AVFrame *frame);
>
> -unsigned ff_dxva2_get_surface_index(const struct dxva_context *,
> +unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
> +                                    const av_dxva_context_t *,
>                                      const AVFrame *frame);
>
> -int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
> -                           DXVA2_DecodeBufferDesc *,
> +int ff_dxva2_commit_buffer(AVCodecContext *, av_dxva_context_t *,
> +                           DECODER_BUFFER_DESC *,
>                             unsigned type, const void *data, unsigned size,
>                             unsigned mb_count);
>
> @@ -50,7 +72,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
>                                const void *pp, unsigned pp_size,
>                                const void *qm, unsigned qm_size,
>                                int (*commit_bs_si)(AVCodecContext *,
> -                                                  DXVA2_DecodeBufferDesc *bs,
> -                                                  DXVA2_DecodeBufferDesc 
> *slice));
> +                                                  DECODER_BUFFER_DESC *bs,
> +                                                  DECODER_BUFFER_DESC 
> *slice));
>
>  #endif /* AVCODEC_DXVA_INTERNAL_H */
> diff --git a/libavcodec/dxva2_mpeg2.c b/libavcodec/dxva2_mpeg2.c
> index 65624e3..fab2b7f 100644
> --- a/libavcodec/dxva2_mpeg2.c
> +++ b/libavcodec/dxva2_mpeg2.c
> @@ -36,7 +36,7 @@ struct dxva2_picture_context {
>  };
>
>  static void fill_picture_parameters(AVCodecContext *avctx,
> -                                    struct dxva_context *ctx,
> +                                    av_dxva_context_t *ctx,
>                                      const struct MpegEncContext *s,
>                                      DXVA_PictureParameters *pp)
>  {
> @@ -44,14 +44,14 @@ static void fill_picture_parameters(AVCodecContext *avctx,
>      int is_field = s->picture_structure != PICT_FRAME;
>
>      memset(pp, 0, sizeof(*pp));
> -    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(ctx, 
> current_picture->f);
> +    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(avctx, 
> ctx, current_picture->f);
>      pp->wDeblockedPictureIndex       = 0;
>      if (s->pict_type != AV_PICTURE_TYPE_I)
> -        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(ctx, 
> s->last_picture.f);
> +        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(avctx, 
> ctx, s->last_picture.f);
>      else
>          pp->wForwardRefPictureIndex  = 0xffff;
>      if (s->pict_type == AV_PICTURE_TYPE_B)
> -        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
> s->next_picture.f);
> +        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, 
> ctx, s->next_picture.f);
>      else
>          pp->wBackwardRefPictureIndex = 0xffff;
>      pp->wPicWidthInMBminus1          = s->mb_width  - 1;
> @@ -102,7 +102,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
>  }
>
>  static void fill_quantization_matrices(AVCodecContext *avctx,
> -                                       struct dxva_context *ctx,
> +                                       av_dxva_context_t *ctx,
>                                         const struct MpegEncContext *s,
>                                         DXVA_QmatrixData *qm)
>  {
> @@ -147,11 +147,11 @@ static void fill_slice(AVCodecContext *avctx,
>      slice->wMBbitOffset        = 4 * 8 + get_bits_count(&gb);
>  }
>  static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
> -                                             DXVA2_DecodeBufferDesc *bs,
> -                                             DXVA2_DecodeBufferDesc *sc)
> +                                             DECODER_BUFFER_DESC *bs,
> +                                             DECODER_BUFFER_DESC *sc)
>  {
>      const struct MpegEncContext *s = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      struct dxva2_picture_context *ctx_pic =
>          s->current_picture_ptr->hwaccel_picture_private;
>      const int is_field = s->picture_structure != PICT_FRAME;
> @@ -160,11 +160,27 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>      uint8_t  *dxva_data, *current, *end;
>      unsigned dxva_size;
>      unsigned i;
> +    unsigned type;
>
> -    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
> -                                              DXVA2_BitStreamDateBufferType,
> -                                              &dxva_data_ptr, &dxva_size)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
> +        if 
> (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                       
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                       type,
> +                                                       &dxva_size, 
> &dxva_data_ptr)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        type = DXVA2_BitStreamDateBufferType;
> +        if 
> (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
> +                                                  type,
> +                                                  &dxva_data_ptr, 
> &dxva_size)))
> +            return -1;
> +    }
> +#endif
>
>      dxva_data = dxva_data_ptr;
>      current = dxva_data;
> @@ -190,19 +206,46 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>          memcpy(current, &ctx_pic->bitstream[position], size);
>          current += size;
>      }
> -    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
> -                                                  
> DXVA2_BitStreamDateBufferType)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        if 
> (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
>  D3D11VA_CONTEXT(ctx)->decoder, type)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        if 
> (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type)))
> +            return -1;
> +    }
> +#endif
>      if (i < ctx_pic->slice_count)
>          return -1;
>
> -    memset(bs, 0, sizeof(*bs));
> -    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
> -    bs->DataSize             = current - dxva_data;
> -    bs->NumMBsInBuffer       = mb_count;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
> +        memset(dsc11, 0, sizeof(*dsc11));
> +        dsc11->BufferType           = type;
> +        dsc11->DataSize             = current - dxva_data;
> +        dsc11->NumMBsInBuffer       = mb_count;
> +
> +        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        DXVA2_DecodeBufferDesc *dsc2 = bs;
> +        memset(dsc2, 0, sizeof(*dsc2));
> +        dsc2->CompressedBufferType = type;
> +        dsc2->DataSize             = current - dxva_data;
> +        dsc2->NumMBsInBuffer       = mb_count;
> +
> +        type = DXVA2_SliceControlBufferType;
> +    }
> +#endif
>
>      return ff_dxva2_commit_buffer(avctx, ctx, sc,
> -                                  DXVA2_SliceControlBufferType,
> +                                  type,
>                                    ctx_pic->slice,
>                                    ctx_pic->slice_count * 
> sizeof(*ctx_pic->slice),
>                                    mb_count);
> @@ -213,11 +256,13 @@ static int dxva2_mpeg2_start_frame(AVCodecContext 
> *avctx,
>                                     av_unused uint32_t size)
>  {
>      const struct MpegEncContext *s = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      struct dxva2_picture_context *ctx_pic =
>          s->current_picture_ptr->hwaccel_picture_private;
>
> -    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
> +    if (DXVA_CONTEXT_DECODER(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_CFG(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
>          return -1;
>      assert(ctx_pic);
>
> @@ -271,6 +316,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
>      return ret;
>  }
>
> +#if CONFIG_DXVA2
>  AVHWAccel ff_mpeg2_dxva2_hwaccel = {
>      .name           = "mpeg2_dxva2",
>      .type           = AVMEDIA_TYPE_VIDEO,
> @@ -281,3 +327,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
>      .end_frame      = dxva2_mpeg2_end_frame,
>      .frame_priv_data_size = sizeof(struct dxva2_picture_context),
>  };
> +#endif
> +
> +#if CONFIG_D3D11VA
> +AVHWAccel ff_mpeg2_d3d11va_hwaccel = {
> +    .name           = "mpeg2_d3d11va",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_MPEG2VIDEO,
> +    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
> +    .start_frame    = dxva2_mpeg2_start_frame,
> +    .decode_slice   = dxva2_mpeg2_decode_slice,
> +    .end_frame      = dxva2_mpeg2_end_frame,
> +    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
> +};
> +#endif
> diff --git a/libavcodec/dxva2_vc1.c b/libavcodec/dxva2_vc1.c
> index 1524b51..191d225 100644
> --- a/libavcodec/dxva2_vc1.c
> +++ b/libavcodec/dxva2_vc1.c
> @@ -34,7 +34,7 @@ struct dxva2_picture_context {
>  };
>
>  static void fill_picture_parameters(AVCodecContext *avctx,
> -                                    struct dxva_context *ctx, const 
> VC1Context *v,
> +                                    av_dxva_context_t *ctx, const VC1Context 
> *v,
>                                      DXVA_PictureParameters *pp)
>  {
>      const MpegEncContext *s = &v->s;
> @@ -42,13 +42,13 @@ static void fill_picture_parameters(AVCodecContext *avctx,
>
>      memset(pp, 0, sizeof(*pp));
>      pp->wDecodedPictureIndex    =
> -    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(ctx, 
> current_picture->f);
> +    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, 
> current_picture->f);
>      if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
> -        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
> s->last_picture.f);
> +        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, 
> s->last_picture.f);
>      else
>          pp->wForwardRefPictureIndex = 0xffff;
>      if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
> -        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, 
> s->next_picture.f);
> +        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, 
> ctx, s->next_picture.f);
>      else
>          pp->wBackwardRefPictureIndex = 0xffff;
>      if (v->profile == PROFILE_ADVANCED) {
> @@ -73,8 +73,8 @@ static void fill_picture_parameters(AVCodecContext *avctx,
>      pp->bPicIntra               = s->pict_type == AV_PICTURE_TYPE_I || 
> v->bi_type;
>      pp->bPicBackwardPrediction  = s->pict_type == AV_PICTURE_TYPE_B && 
> !v->bi_type;
>      pp->bBidirectionalAveragingMode = (1                                     
>       << 7) |
> -                                      ((ctx->cfg->ConfigIntraResidUnsigned 
> != 0)   << 6) |
> -                                      ((ctx->cfg->ConfigResidDiffAccelerator 
> != 0) << 5) |
> +                                      ((DXVA_CONTEXT_CFG_INTRARESID(avctx, 
> ctx) != 0) << 6) |
> +                                      ((DXVA_CONTEXT_CFG_RESIDACCEL(avctx, 
> ctx) != 0) << 5) |
>                                        ((v->lumscale != 32 || v->lumshift != 
> 0)     << 4) |
>                                        ((v->profile == PROFILE_ADVANCED)      
>       << 3);
>      pp->bMVprecisionAndChromaRelation = ((v->mv_mode == 
> MV_PMODE_1MV_HPEL_BILIN) << 3) |
> @@ -82,11 +82,11 @@ static void fill_picture_parameters(AVCodecContext *avctx,
>                                          (0                                   
>     << 1) |
>                                          (!s->quarter_sample                  
>         );
>      pp->bChromaFormat           = v->chromaformat;
> -    ctx->report_id++;
> -    if (ctx->report_id >= (1 << 16))
> -        ctx->report_id = 1;
> -    pp->bPicScanFixed           = ctx->report_id >> 8;
> -    pp->bPicScanMethod          = ctx->report_id & 0xff;
> +    DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
> +    if (DXVA_CONTEXT_REPORT_ID(avctx, ctx) >= (1 << 16))
> +        DXVA_CONTEXT_REPORT_ID(avctx, ctx) = 1;
> +    pp->bPicScanFixed           = DXVA_CONTEXT_REPORT_ID(avctx, ctx) >> 8;
> +    pp->bPicScanMethod          = DXVA_CONTEXT_REPORT_ID(avctx, ctx) & 0xff;
>      pp->bPicReadbackRequests    = 0;
>      pp->bRcontrol               = v->rnd;
>      pp->bPicSpatialResid8       = (v->panscanflag  << 7) |
> @@ -157,11 +157,11 @@ static void fill_slice(AVCodecContext *avctx, 
> DXVA_SliceInfo *slice,
>  }
>
>  static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
> -                                             DXVA2_DecodeBufferDesc *bs,
> -                                             DXVA2_DecodeBufferDesc *sc)
> +                                             DECODER_BUFFER_DESC *bs,
> +                                             DECODER_BUFFER_DESC *sc)
>  {
>      const VC1Context *v = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      const MpegEncContext *s = &v->s;
>      struct dxva2_picture_context *ctx_pic = 
> s->current_picture_ptr->hwaccel_picture_private;
>
> @@ -177,11 +177,27 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>      uint8_t  *dxva_data;
>      unsigned dxva_size;
>      int result;
> +    unsigned type;
>
> -    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
> -                                              DXVA2_BitStreamDateBufferType,
> -                                              &dxva_data_ptr, &dxva_size)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
> +        if 
> (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
> +                                                       
> D3D11VA_CONTEXT(ctx)->decoder,
> +                                                       type,
> +                                                       &dxva_size, 
> &dxva_data_ptr)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        type = DXVA2_BitStreamDateBufferType;
> +        if 
> (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
> +                                                  type,
> +                                                  &dxva_data_ptr, 
> &dxva_size)))
> +            return -1;
> +    }
> +#endif
>
>      dxva_data = dxva_data_ptr;
>      result = data_size <= dxva_size ? 0 : -1;
> @@ -194,21 +210,48 @@ static int 
> commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
>              memset(dxva_data + start_code_size + slice_size, 0, padding);
>          slice->dwSliceBitsInBuffer = 8 * data_size;
>      }
> -    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
> -                                                  
> DXVA2_BitStreamDateBufferType)))
> -        return -1;
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        if 
> (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
>  D3D11VA_CONTEXT(ctx)->decoder, type)))
> +            return -1;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        if 
> (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, 
> type)))
> +            return -1;
> +    }
> +#endif
>      if (result)
>          return result;
>
> -    memset(bs, 0, sizeof(*bs));
> -    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
> -    bs->DataSize             = data_size;
> -    bs->NumMBsInBuffer       = s->mb_width * s->mb_height;
> -    assert((bs->DataSize & 127) == 0);
> +#if CONFIG_D3D11VA
> +    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
> +        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
> +        memset(dsc11, 0, sizeof(*dsc11));
> +        dsc11->BufferType           = type;
> +        dsc11->DataSize             = data_size;
> +        dsc11->NumMBsInBuffer       = s->mb_width * s->mb_height;
> +
> +        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
> +    }
> +#endif
> +#if CONFIG_DXVA2
> +    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
> +        DXVA2_DecodeBufferDesc *dsc2 = bs;
> +        memset(dsc2, 0, sizeof(*dsc2));
> +        dsc2->CompressedBufferType = type;
> +        dsc2->DataSize             = data_size;
> +        dsc2->NumMBsInBuffer       = s->mb_width * s->mb_height;
> +
> +        type = DXVA2_SliceControlBufferType;
> +    }
> +#endif
> +    assert((data_size & 127) == 0);
>
>      return ff_dxva2_commit_buffer(avctx, ctx, sc,
> -                                  DXVA2_SliceControlBufferType,
> -                                  slice, sizeof(*slice), bs->NumMBsInBuffer);
> +                                  type,
> +                                  slice, sizeof(*slice), s->mb_width * 
> s->mb_height);
>  }
>
>  static int dxva2_vc1_start_frame(AVCodecContext *avctx,
> @@ -216,10 +259,12 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx,
>                                   av_unused uint32_t size)
>  {
>      const VC1Context *v = avctx->priv_data;
> -    struct dxva_context *ctx = avctx->hwaccel_context;
> +    av_dxva_context_t *ctx = avctx->hwaccel_context;
>      struct dxva2_picture_context *ctx_pic = 
> v->s.current_picture_ptr->hwaccel_picture_private;
>
> -    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
> +    if (DXVA_CONTEXT_DECODER(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_CFG(avctx, ctx)==NULL ||
> +        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
>          return -1;
>      assert(ctx_pic);
>
> @@ -272,6 +317,7 @@ static int dxva2_vc1_end_frame(AVCodecContext *avctx)
>      return ret;
>  }
>
> +#if CONFIG_DXVA2
>  #if CONFIG_WMV3_DXVA2_HWACCEL

redundant #if, only use the long codec-specific #ifs

>  AVHWAccel ff_wmv3_dxva2_hwaccel = {
>      .name           = "wmv3_dxva2",
> @@ -295,3 +341,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
>      .end_frame      = dxva2_vc1_end_frame,
>      .frame_priv_data_size = sizeof(struct dxva2_picture_context),
>  };
> +#endif
> +
> +#if CONFIG_D3D11VA
> +#if CONFIG_WMV3_D3D11VA_HWACCEL

same here, only one check is needed, configure should track the deps.

> +AVHWAccel ff_wmv3_d3d11va_hwaccel = {
> +    .name           = "wmv3_d3d11va",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_WMV3,
> +    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
> +    .start_frame    = dxva2_vc1_start_frame,
> +    .decode_slice   = dxva2_vc1_decode_slice,
> +    .end_frame      = dxva2_vc1_end_frame,
> +    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
> +};
> +#endif
> +
> +AVHWAccel ff_vc1_d3d11va_hwaccel = {
> +    .name           = "vc1_d3d11va",
> +    .type           = AVMEDIA_TYPE_VIDEO,
> +    .id             = AV_CODEC_ID_VC1,
> +    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
> +    .start_frame    = dxva2_vc1_start_frame,
> +    .decode_slice   = dxva2_vc1_decode_slice,
> +    .end_frame      = dxva2_vc1_end_frame,
> +    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
> +};
> +#endif
> diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
> index a250237..1cee634 100644
> --- a/libavcodec/h264_slice.c
> +++ b/libavcodec/h264_slice.c
> @@ -861,6 +861,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h)
>  #if CONFIG_H264_DXVA2_HWACCEL
>              *fmt++ = AV_PIX_FMT_DXVA2_VLD;
>  #endif
> +#if CONFIG_H264_D3D11VA_HWACCEL
> +            *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
> +#endif
>  #if CONFIG_H264_VAAPI_HWACCEL
>              *fmt++ = AV_PIX_FMT_VAAPI_VLD;
>  #endif
> diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
> index 4c06fb8..a6ee773 100644
> --- a/libavcodec/hevc.c
> +++ b/libavcodec/hevc.c
> @@ -446,6 +446,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
>  #if CONFIG_HEVC_DXVA2_HWACCEL
>          *fmt++ = AV_PIX_FMT_DXVA2_VLD;
>  #endif
> +#if CONFIG_HEVC_D3D11VA_HWACCEL
> +        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
> +#endif
>      }
>
>      *fmt++ = sps->pix_fmt;
> diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
> index 6ed151a..e8eaa86 100644
> --- a/libavcodec/mpeg12dec.c
> +++ b/libavcodec/mpeg12dec.c
> @@ -1175,6 +1175,9 @@ static const enum AVPixelFormat 
> mpeg12_hwaccel_pixfmt_list_420[] = {
>  #if CONFIG_MPEG2_DXVA2_HWACCEL
>      AV_PIX_FMT_DXVA2_VLD,
>  #endif
> +#if CONFIG_MPEG2_D3D11VA_HWACCEL
> +    AV_PIX_FMT_D3D11VA_VLD,
> +#endif
>  #if CONFIG_MPEG2_VAAPI_HWACCEL
>      AV_PIX_FMT_VAAPI_VLD,
>  #endif
> diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c
> index 0d578cd..b027d08 100644
> --- a/libavcodec/vc1dec.c
> +++ b/libavcodec/vc1dec.c
> @@ -954,6 +954,9 @@ static const enum AVPixelFormat 
> vc1_hwaccel_pixfmt_list_420[] = {
>  #if CONFIG_VC1_DXVA2_HWACCEL
>      AV_PIX_FMT_DXVA2_VLD,
>  #endif
> +#if CONFIG_VC1_D3D11VA_HWACCEL
> +    AV_PIX_FMT_D3D11VA_VLD,
> +#endif
>  #if CONFIG_VC1_VAAPI_HWACCEL
>      AV_PIX_FMT_VAAPI_VLD,
>  #endif
> diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
> index ea432f9..c2c0157 100644
> --- a/libavutil/pixdesc.c
> +++ b/libavutil/pixdesc.c
> @@ -1333,6 +1333,12 @@ const AVPixFmtDescriptor 
> av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
>          },
>          .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
>      },
> +    [AV_PIX_FMT_D3D11VA_VLD] = {
> +        .name = "d3d11va_vld",
> +        .log2_chroma_w = 1,
> +        .log2_chroma_h = 1,
> +        .flags = AV_PIX_FMT_FLAG_HWACCEL,
> +    },
>      [AV_PIX_FMT_DXVA2_VLD] = {
>          .name = "dxva2_vld",
>          .log2_chroma_w = 1,
> diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
> index e21100f..360015c 100644
> --- a/libavutil/pixfmt.h
> +++ b/libavutil/pixfmt.h
> @@ -220,6 +220,8 @@ enum AVPixelFormat {
>       */
>      AV_PIX_FMT_MMAL,
>
> +    AV_PIX_FMT_D3D11VA_VLD,  ///< HW decoding through Direct3D11, 
> Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer
> +
>      AV_PIX_FMT_NB,        ///< number of pixel formats, DO NOT USE THIS if 
> you want to link with shared libav* because the number of formats might 
> differ between versions
>
>  #if FF_API_PIX_FMT
> --
> 2.4.0
>
> _______________________________________________
> libav-devel mailing list
> [email protected]
> https://lists.libav.org/mailman/listinfo/libav-devel
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to