This latest patch keeps the original memset to init the output structures.
On Mon, May 11, 2015 at 10:52 AM, Steve Lhomme <[email protected]> wrote: > --- > Changelog | 1 + > configure | 31 ++++++++- > libavcodec/Makefile | 7 ++ > libavcodec/allcodecs.c | 5 ++ > libavcodec/d3d11va.h | 98 +++++++++++++++++++++++++++ > libavcodec/dxva2.c | 161 > +++++++++++++++++++++++++++++++++++--------- > libavcodec/dxva2_h264.c | 138 ++++++++++++++++++++++++++----------- > libavcodec/dxva2_hevc.c | 108 ++++++++++++++++++++++------- > libavcodec/dxva2_internal.h | 32 +++++++-- > libavcodec/dxva2_mpeg2.c | 102 ++++++++++++++++++++++------ > libavcodec/dxva2_vc1.c | 131 ++++++++++++++++++++++++++--------- > libavcodec/h264_slice.c | 3 + > libavcodec/hevc.c | 3 + > libavcodec/mpeg12dec.c | 3 + > libavcodec/vc1dec.c | 3 + > libavcodec/version.h | 2 +- > libavutil/pixdesc.c | 6 ++ > libavutil/pixfmt.h | 2 + > libavutil/version.h | 2 +- > 19 files changed, 682 insertions(+), 156 deletions(-) > create mode 100644 libavcodec/d3d11va.h > > diff --git a/Changelog b/Changelog > index 9d73449..41fe7c8 100644 > --- a/Changelog > +++ b/Changelog > @@ -12,6 +12,7 @@ version <next>: > - VP8 in Ogg demuxing > - OpenH264 encoder wrapper > - Support DNx100 (960x720@8) > +- Direct3D11-accelerated decoding > - DXVA2-accelerated HEVC decoding > - AAC ELD 480 decoding > - Intel QSV-accelerated H.264 decoding > diff --git a/configure b/configure > index f3e5154..ba1ca77 100755 > --- a/configure > +++ b/configure > @@ -133,6 +133,7 @@ Component options: > --disable-faan disable floating point AAN (I)DCT code > > Hardware accelerators: > + --enable-d3d11va enable D3D11VA code > --enable-dxva2 enable DXVA2 code > --enable-vaapi enable VAAPI code > --enable-vda enable VDA code > @@ -1206,6 +1207,7 @@ FEATURE_LIST=" > " > > HWACCEL_LIST=" > + d3d11va > dxva2 > vaapi > vda > @@ -1396,6 +1398,7 @@ HEADERS_LIST=" > dev_video_meteor_ioctl_meteor_h > direct_h > dlfcn_h > + d3d11_h > dxva_h > gsm_h > io_h > @@ -1551,6 +1554,8 @@ HAVE_LIST=" > $TYPES_LIST > atomics_native > dos_paths > + d3d11_cobj > + d3d11va_lib > dxva2_lib > libc_msvcrt > libdc1394_1 > @@ -1965,6 +1970,7 @@ zmbv_decoder_deps="zlib" > zmbv_encoder_deps="zlib" > > # hardware accelerators > +d3d11va_deps="d3d11_h dxva_h" > dxva2_deps="dxva2api_h" > vaapi_deps="va_va_h" > vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" > @@ -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)' > @@ -4155,6 +4170,7 @@ check_struct windows.h "CONDITION_VARIABLE" Ptr > > check_header direct.h > check_header dlfcn.h > +check_header d3d11.h > check_header dxva.h > check_header dxva2api.h > check_header io.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 > @@ -4593,6 +4618,10 @@ check_deps $CONFIG_LIST \ > $HAVE_LIST \ > $ALL_COMPONENTS \ > > +enabled_all d3d11va d3d11_cobj CoTaskMemFree && > + prepend avconv_libs $($ldflags_filter "-lole32") && > + enable d3d11va_lib > + > enabled_all dxva2 CoTaskMemFree && > prepend avconv_libs $($ldflags_filter "-lole32") && > enable dxva2_lib > 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..2163b35 > --- /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 AVD3D11VAContext { > + /** > + * 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..76a9d54 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 AVDXVAContext *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, > + AVDXVAContext *ctx, > + DECODER_BUFFER_DESC *dsc, > unsigned type, const void *data, unsigned size, > unsigned mb_count) > { > @@ -60,8 +61,18 @@ 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 +81,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 +106,14 @@ 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 +127,31 @@ 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; > + AVDXVAContext *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 +161,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 +184,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 +207,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 +234,36 @@ 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..a4a88ce 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, > AVDXVAContext *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, AVDXVAContext > *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, AVDXVAContext *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; > + AVDXVAContext *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; > + AVDXVAContext *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,43 @@ 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; > > - if (is_slice_short(ctx)) { > + 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(avctx, ctx)) { > slice_data = ctx_pic->slice_short; > slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short); > } else { > @@ -383,7 +424,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 +434,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; > + AVDXVAContext *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 +461,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; > + AVDXVAContext *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 +474,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 +506,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx) > return ret; > } > > +#if CONFIG_H264_DXVA2_HWACCEL > AVHWAccel ff_h264_dxva2_hwaccel = { > .name = "h264_dxva2", > .type = AVMEDIA_TYPE_VIDEO, > @@ -473,3 +517,17 @@ AVHWAccel ff_h264_dxva2_hwaccel = { > .end_frame = dxva2_h264_end_frame, > .frame_priv_data_size = sizeof(struct dxva2_picture_context), > }; > +#endif > + > +#if CONFIG_H264_D3D11VA_HWACCEL > +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..9d130d9 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, > AVDXVAContext *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(AVDXVAContext *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; > + AVDXVAContext *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,48 @@ 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 +351,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; > + AVDXVAContext *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 +412,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx) > return ret; > } > > +#if CONFIG_HEVC_DXVA2_HWACCEL > AVHWAccel ff_hevc_dxva2_hwaccel = { > .name = "hevc_dxva2", > .type = AVMEDIA_TYPE_VIDEO, > @@ -379,3 +423,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_HEVC_D3D11VA_HWACCEL > +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..23be2c3 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 AVD3D11VAContext d3d11va; > + struct dxva_context dxva2; > +} AVDXVAContext; > + > +#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 AVDXVAContext *, > const AVFrame *frame); > > -int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *, > - DXVA2_DecodeBufferDesc *, > +int ff_dxva2_commit_buffer(AVCodecContext *, AVDXVAContext *, > + 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..99a0787 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, > + AVDXVAContext *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, > + AVDXVAContext *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; > + AVDXVAContext *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,44 @@ 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 +254,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; > + AVDXVAContext *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 +314,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx) > return ret; > } > > +#if CONFIG_MPEG2_DXVA2_HWACCEL > AVHWAccel ff_mpeg2_dxva2_hwaccel = { > .name = "mpeg2_dxva2", > .type = AVMEDIA_TYPE_VIDEO, > @@ -281,3 +325,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = { > .end_frame = dxva2_mpeg2_end_frame, > .frame_priv_data_size = sizeof(struct dxva2_picture_context), > }; > +#endif > + > +#if CONFIG_MPEG2_D3D11VA_HWACCEL > +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..73f9fb4 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, > + AVDXVAContext *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; > + AVDXVAContext *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,46 @@ 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 +257,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; > + AVDXVAContext *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); > > @@ -285,6 +328,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = { > }; > #endif > > +#if CONFIG_VC1_DXVA2_HWACCEL > AVHWAccel ff_vc1_dxva2_hwaccel = { > .name = "vc1_dxva2", > .type = AVMEDIA_TYPE_VIDEO, > @@ -295,3 +339,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = { > .end_frame = dxva2_vc1_end_frame, > .frame_priv_data_size = sizeof(struct dxva2_picture_context), > }; > +#endif > + > +#if CONFIG_WMV3_D3D11VA_HWACCEL > +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 > + > +#if CONFIG_VC1_D3D11VA_HWACCEL > +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/libavcodec/version.h b/libavcodec/version.h > index 50c2b48..6409cf8 100644 > --- a/libavcodec/version.h > +++ b/libavcodec/version.h > @@ -29,7 +29,7 @@ > #include "libavutil/version.h" > > #define LIBAVCODEC_VERSION_MAJOR 56 > -#define LIBAVCODEC_VERSION_MINOR 23 > +#define LIBAVCODEC_VERSION_MINOR 24 > #define LIBAVCODEC_VERSION_MICRO 2 > > #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ > 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 > diff --git a/libavutil/version.h b/libavutil/version.h > index 9c45e0e..13bb6f0 100644 > --- a/libavutil/version.h > +++ b/libavutil/version.h > @@ -54,7 +54,7 @@ > */ > > #define LIBAVUTIL_VERSION_MAJOR 54 > -#define LIBAVUTIL_VERSION_MINOR 12 > +#define LIBAVUTIL_VERSION_MINOR 13 > #define LIBAVUTIL_VERSION_MICRO 1 > > #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ > -- > 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
