Commit d8039ef8 authored by Steve Lhomme's avatar Steve Lhomme Committed by Luca Barbato

D3D11va: add a Direct3D11 video decoder similar to DXVA2

Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 4e17946f
...@@ -12,6 +12,7 @@ version <next>: ...@@ -12,6 +12,7 @@ version <next>:
- VP8 in Ogg demuxing - VP8 in Ogg demuxing
- OpenH264 encoder wrapper - OpenH264 encoder wrapper
- Support DNx100 (960x720@8) - Support DNx100 (960x720@8)
- Direct3D11-accelerated decoding
- DXVA2-accelerated HEVC decoding - DXVA2-accelerated HEVC decoding
- AAC ELD 480 decoding - AAC ELD 480 decoding
- Intel QSV-accelerated H.264 decoding - Intel QSV-accelerated H.264 decoding
......
...@@ -133,6 +133,7 @@ Component options: ...@@ -133,6 +133,7 @@ Component options:
--disable-faan disable floating point AAN (I)DCT code --disable-faan disable floating point AAN (I)DCT code
Hardware accelerators: Hardware accelerators:
--enable-d3d11va enable D3D11VA code
--enable-dxva2 enable DXVA2 code --enable-dxva2 enable DXVA2 code
--enable-vaapi enable VAAPI code --enable-vaapi enable VAAPI code
--enable-vda enable VDA code --enable-vda enable VDA code
...@@ -1206,6 +1207,7 @@ FEATURE_LIST=" ...@@ -1206,6 +1207,7 @@ FEATURE_LIST="
" "
HWACCEL_LIST=" HWACCEL_LIST="
d3d11va
dxva2 dxva2
vaapi vaapi
vda vda
...@@ -1396,6 +1398,7 @@ HEADERS_LIST=" ...@@ -1396,6 +1398,7 @@ HEADERS_LIST="
dev_video_meteor_ioctl_meteor_h dev_video_meteor_ioctl_meteor_h
direct_h direct_h
dlfcn_h dlfcn_h
d3d11_h
dxva_h dxva_h
gsm_h gsm_h
io_h io_h
...@@ -1551,6 +1554,8 @@ HAVE_LIST=" ...@@ -1551,6 +1554,8 @@ HAVE_LIST="
$TYPES_LIST $TYPES_LIST
atomics_native atomics_native
dos_paths dos_paths
d3d11_cobj
d3d11va_lib
dxva2_lib dxva2_lib
libc_msvcrt libc_msvcrt
libdc1394_1 libdc1394_1
...@@ -1965,6 +1970,7 @@ zmbv_decoder_deps="zlib" ...@@ -1965,6 +1970,7 @@ zmbv_decoder_deps="zlib"
zmbv_encoder_deps="zlib" zmbv_encoder_deps="zlib"
# hardware accelerators # hardware accelerators
d3d11va_deps="d3d11_h dxva_h"
dxva2_deps="dxva2api_h" dxva2_deps="dxva2api_h"
vaapi_deps="va_va_h" vaapi_deps="va_va_h"
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
...@@ -1975,6 +1981,8 @@ h263_vaapi_hwaccel_deps="vaapi" ...@@ -1975,6 +1981,8 @@ h263_vaapi_hwaccel_deps="vaapi"
h263_vaapi_hwaccel_select="h263_decoder" h263_vaapi_hwaccel_select="h263_decoder"
h263_vdpau_hwaccel_deps="vdpau" h263_vdpau_hwaccel_deps="vdpau"
h263_vdpau_hwaccel_select="h263_decoder" 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_deps="dxva2"
h264_dxva2_hwaccel_select="h264_decoder" h264_dxva2_hwaccel_select="h264_decoder"
h264_mmal_decoder_deps="mmal" h264_mmal_decoder_deps="mmal"
...@@ -1990,10 +1998,14 @@ h264_vda_old_hwaccel_deps="vda" ...@@ -1990,10 +1998,14 @@ h264_vda_old_hwaccel_deps="vda"
h264_vda_old_hwaccel_select="h264_decoder" h264_vda_old_hwaccel_select="h264_decoder"
h264_vdpau_hwaccel_deps="vdpau" h264_vdpau_hwaccel_deps="vdpau"
h264_vdpau_hwaccel_select="h264_decoder" 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_deps="dxva2 DXVA_PicParams_HEVC"
hevc_dxva2_hwaccel_select="hevc_decoder" hevc_dxva2_hwaccel_select="hevc_decoder"
mpeg1_vdpau_hwaccel_deps="vdpau" mpeg1_vdpau_hwaccel_deps="vdpau"
mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" 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_deps="dxva2"
mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
mpeg2_vaapi_hwaccel_deps="vaapi" mpeg2_vaapi_hwaccel_deps="vaapi"
...@@ -2004,12 +2016,15 @@ mpeg4_vaapi_hwaccel_deps="vaapi" ...@@ -2004,12 +2016,15 @@ mpeg4_vaapi_hwaccel_deps="vaapi"
mpeg4_vaapi_hwaccel_select="mpeg4_decoder" mpeg4_vaapi_hwaccel_select="mpeg4_decoder"
mpeg4_vdpau_hwaccel_deps="vdpau" mpeg4_vdpau_hwaccel_deps="vdpau"
mpeg4_vdpau_hwaccel_select="mpeg4_decoder" 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_deps="dxva2"
vc1_dxva2_hwaccel_select="vc1_decoder" vc1_dxva2_hwaccel_select="vc1_decoder"
vc1_vaapi_hwaccel_deps="vaapi" vc1_vaapi_hwaccel_deps="vaapi"
vc1_vaapi_hwaccel_select="vc1_decoder" vc1_vaapi_hwaccel_select="vc1_decoder"
vc1_vdpau_hwaccel_deps="vdpau" vc1_vdpau_hwaccel_deps="vdpau"
vc1_vdpau_hwaccel_select="vc1_decoder" vc1_vdpau_hwaccel_select="vc1_decoder"
wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
...@@ -2288,7 +2303,7 @@ enable swscale_alpha ...@@ -2288,7 +2303,7 @@ enable swscale_alpha
enable valgrind_backtrace enable valgrind_backtrace
# By default, enable only those hwaccels that have no external dependencies. # By default, enable only those hwaccels that have no external dependencies.
enable dxva2 vda vdpau enable d3d11va dxva2 vda vdpau
# build settings # build settings
SHFLAGS='-shared -Wl,-soname,$$(@F)' SHFLAGS='-shared -Wl,-soname,$$(@F)'
...@@ -4155,6 +4170,7 @@ check_struct windows.h "CONDITION_VARIABLE" Ptr ...@@ -4155,6 +4170,7 @@ check_struct windows.h "CONDITION_VARIABLE" Ptr
check_header direct.h check_header direct.h
check_header dlfcn.h check_header dlfcn.h
check_header d3d11.h
check_header dxva.h check_header dxva.h
check_header dxva2api.h check_header dxva2api.h
check_header io.h check_header io.h
...@@ -4372,6 +4388,15 @@ if enabled x11grab; then ...@@ -4372,6 +4388,15 @@ if enabled x11grab; then
require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes
fi 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 && enabled vaapi && enabled xlib &&
check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 &&
enable vaapi_x11 enable vaapi_x11
...@@ -4593,6 +4618,10 @@ check_deps $CONFIG_LIST \ ...@@ -4593,6 +4618,10 @@ check_deps $CONFIG_LIST \
$HAVE_LIST \ $HAVE_LIST \
$ALL_COMPONENTS \ $ALL_COMPONENTS \
enabled_all d3d11va d3d11_cobj CoTaskMemFree &&
prepend avconv_libs $($ldflags_filter "-lole32") &&
enable d3d11va_lib
enabled_all dxva2 CoTaskMemFree && enabled_all dxva2 CoTaskMemFree &&
prepend avconv_libs $($ldflags_filter "-lole32") && prepend avconv_libs $($ldflags_filter "-lole32") &&
enable dxva2_lib enable dxva2_lib
......
...@@ -3,6 +3,7 @@ NAME = avcodec ...@@ -3,6 +3,7 @@ NAME = avcodec
HEADERS = avcodec.h \ HEADERS = avcodec.h \
avfft.h \ avfft.h \
dv_profile.h \ dv_profile.h \
d3d11va.h \
dxva2.h \ dxva2.h \
qsv.h \ qsv.h \
vaapi.h \ vaapi.h \
...@@ -557,6 +558,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o ...@@ -557,6 +558,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o
OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
# hardware accelerators # hardware accelerators
OBJS-$(CONFIG_D3D11VA) += dxva2.o
OBJS-$(CONFIG_DXVA2) += dxva2.o OBJS-$(CONFIG_DXVA2) += dxva2.o
OBJS-$(CONFIG_VAAPI) += vaapi.o OBJS-$(CONFIG_VAAPI) += vaapi.o
OBJS-$(CONFIG_VDA) += vda.o OBJS-$(CONFIG_VDA) += vda.o
...@@ -564,17 +566,21 @@ OBJS-$(CONFIG_VDPAU) += vdpau.o ...@@ -564,17 +566,21 @@ OBJS-$(CONFIG_VDPAU) += vdpau.o
OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o
OBJS-$(CONFIG_H263_VDPAU_HWACCEL) += vdpau_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_DXVA2_HWACCEL) += dxva2_h264.o
OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o
OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o
OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_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_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o
OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.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_DXVA2_HWACCEL) += dxva2_mpeg2.o
OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o
OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o
OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o
OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_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_DXVA2_HWACCEL) += dxva2_vc1.o
OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o
OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o
...@@ -723,6 +729,7 @@ SKIPHEADERS += %_tablegen.h \ ...@@ -723,6 +729,7 @@ SKIPHEADERS += %_tablegen.h \
tableprint.h \ tableprint.h \
$(ARCH)/vp56_arith.h \ $(ARCH)/vp56_arith.h \
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h
SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h
......
...@@ -76,6 +76,7 @@ void avcodec_register_all(void) ...@@ -76,6 +76,7 @@ void avcodec_register_all(void)
/* hardware accelerators */ /* hardware accelerators */
REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); REGISTER_HWACCEL(H263_VAAPI, h263_vaapi);
REGISTER_HWACCEL(H263_VDPAU, h263_vdpau); REGISTER_HWACCEL(H263_VDPAU, h263_vdpau);
REGISTER_HWACCEL(H264_D3D11VA, h264_d3d11va);
REGISTER_HWACCEL(H264_DXVA2, h264_dxva2); REGISTER_HWACCEL(H264_DXVA2, h264_dxva2);
REGISTER_HWACCEL(H264_MMAL, h264_mmal); REGISTER_HWACCEL(H264_MMAL, h264_mmal);
REGISTER_HWACCEL(H264_QSV, h264_qsv); REGISTER_HWACCEL(H264_QSV, h264_qsv);
...@@ -83,16 +84,20 @@ void avcodec_register_all(void) ...@@ -83,16 +84,20 @@ void avcodec_register_all(void)
REGISTER_HWACCEL(H264_VDA, h264_vda); REGISTER_HWACCEL(H264_VDA, h264_vda);
REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old); REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old);
REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); REGISTER_HWACCEL(H264_VDPAU, h264_vdpau);
REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va);
REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2);
REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va);
REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2);
REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi);
REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau);
REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi); REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi);
REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau); REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau);
REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va);
REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2);
REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi);
REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau);
REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va);
REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2);
REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi);
REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau);
......
/*
* 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 */
...@@ -35,14 +35,15 @@ void *ff_dxva2_get_surface(const AVFrame *frame) ...@@ -35,14 +35,15 @@ void *ff_dxva2_get_surface(const AVFrame *frame)
return frame->data[3]; 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) const AVFrame *frame)
{ {
void *surface = ff_dxva2_get_surface(frame); void *surface = ff_dxva2_get_surface(frame);
unsigned i; unsigned i;
for (i = 0; i < ctx->surface_count; i++) for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
if (ctx->surface[i] == surface) if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)
return i; return i;
assert(0); assert(0);
...@@ -50,8 +51,8 @@ unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx, ...@@ -50,8 +51,8 @@ unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
} }
int ff_dxva2_commit_buffer(AVCodecContext *avctx, int ff_dxva2_commit_buffer(AVCodecContext *avctx,
struct dxva_context *ctx, AVDXVAContext *ctx,
DXVA2_DecodeBufferDesc *dsc, DECODER_BUFFER_DESC *dsc,
unsigned type, const void *data, unsigned size, unsigned type, const void *data, unsigned size,
unsigned mb_count) unsigned mb_count)
{ {
...@@ -60,8 +61,18 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, ...@@ -60,8 +61,18 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
int result; int result;
HRESULT hr; HRESULT hr;
hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type, #if CONFIG_D3D11VA
&dxva_data, &dxva_size); 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)) { if (FAILED(hr)) {
av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n", av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
type, hr); type, hr);
...@@ -70,10 +81,24 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, ...@@ -70,10 +81,24 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
if (size <= dxva_size) { if (size <= dxva_size) {
memcpy(dxva_data, data, size); memcpy(dxva_data, data, size);
memset(dsc, 0, sizeof(*dsc)); #if CONFIG_D3D11VA
dsc->CompressedBufferType = type; if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
dsc->DataSize = size; D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
dsc->NumMBsInBuffer = mb_count; 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; result = 0;
} else { } else {
...@@ -81,7 +106,14 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, ...@@ -81,7 +106,14 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
result = -1; 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)) { if (FAILED(hr)) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Failed to release buffer type %u: 0x%lx\n", "Failed to release buffer type %u: 0x%lx\n",
...@@ -95,20 +127,31 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, ...@@ -95,20 +127,31 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
const void *pp, unsigned pp_size, const void *pp, unsigned pp_size,
const void *qm, unsigned qm_size, const void *qm, unsigned qm_size,
int (*commit_bs_si)(AVCodecContext *, int (*commit_bs_si)(AVCodecContext *,
DXVA2_DecodeBufferDesc *bs, DECODER_BUFFER_DESC *bs,
DXVA2_DecodeBufferDesc *slice)) DECODER_BUFFER_DESC *slice))
{ {
struct dxva_context *ctx = avctx->hwaccel_context; AVDXVAContext *ctx = avctx->hwaccel_context;
unsigned buffer_count = 0; unsigned buffer_count = 0;
DXVA2_DecodeBufferDesc buffer[4]; D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
DXVA2_DecodeExecuteParams exec = { 0 }; DXVA2_DecodeBufferDesc buffer2[4];
DECODER_BUFFER_DESC *buffer,*buffer_slice;
int result, runs = 0; int result, runs = 0;
HRESULT hr; HRESULT hr;
unsigned type;
do { do {
hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder, #if CONFIG_D3D11VA
ff_dxva2_get_surface(frame), if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
NULL); 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) if (hr == E_PENDING)
av_usleep(2000); av_usleep(2000);
} while (hr == E_PENDING && ++runs < 50); } while (hr == E_PENDING && ++runs < 50);
...@@ -118,8 +161,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, ...@@ -118,8 +161,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
return -1; return -1;
} }
result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count], #if CONFIG_D3D11VA
DXVA2_PictureParametersBufferType, 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); pp, pp_size, 0);
if (result) { if (result) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
...@@ -129,8 +184,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, ...@@ -129,8 +184,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
buffer_count++; buffer_count++;
if (qm_size > 0) { if (qm_size > 0) {
result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count], #if CONFIG_D3D11VA
DXVA2_InverseQuantizationMatrixBufferType, 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); qm, qm_size, 0);
if (result) { if (result) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
...@@ -140,9 +207,22 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, ...@@ -140,9 +207,22 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
buffer_count++; 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, result = commit_bs_si(avctx,
&buffer[buffer_count + 0], buffer,
&buffer[buffer_count + 1]); buffer_slice);
if (result) { if (result) {
av_log(avctx, AV_LOG_ERROR, av_log(avctx, AV_LOG_ERROR,
"Failed to add bitstream or slice control buffer\n"); "Failed to add bitstream or slice control buffer\n");
...@@ -154,17 +234,36 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, ...@@ -154,17 +234,36 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
assert(buffer_count == 1 + (qm_size > 0) + 2); assert(buffer_count == 1 + (qm_size > 0) + 2);
exec.NumCompBuffers = buffer_count; #if CONFIG_D3D11VA
exec.pCompressedBuffers = buffer; if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
exec.pExtensionData = NULL; hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec); 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)) { if (FAILED(hr)) {
av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr); av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
result = -1; result = -1;
} }
end: 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)) { if (FAILED(hr)) {
av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr); av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
result = -1; result = -1;
......
This diff is collapsed.
...@@ -53,7 +53,7 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index) ...@@ -53,7 +53,7 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
return 0xff; 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) DXVA_PicParams_HEVC *pp)
{ {
const HEVCFrame *current_picture = h->ref; const HEVCFrame *current_picture = h->ref;
...@@ -73,7 +73,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext ...@@ -73,7 +73,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext
(0 << 14) | (0 << 14) |
(0 << 15); (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->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; 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 ...@@ -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++) { for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
const HEVCFrame *frame = &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))) { 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; pp->PicOrderCntValList[j] = frame->poc;
j++; j++;
} }
...@@ -176,7 +176,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext ...@@ -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)); \ av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
for (j = 0, k = 0; j < rpl->nb_refs; j++) { \ for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
if (rpl->ref[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++; \ k++; \
} \ } \
} \ } \
...@@ -187,10 +187,10 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext ...@@ -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(ST_CURR_AFT, RefPicSetStCurrAfter);
DO_REF_LIST(LT_CURR, RefPicSetLtCurr); 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; unsigned i, j, pos;
const ScalingList *sl = h->pps->scaling_list_data_present_flag ? const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
...@@ -228,11 +228,11 @@ static void fill_slice_short(DXVA_Slice_HEVC_Short *slice, ...@@ -228,11 +228,11 @@ static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
} }
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
DXVA2_DecodeBufferDesc *bs, DECODER_BUFFER_DESC *bs,
DXVA2_DecodeBufferDesc *sc) DECODER_BUFFER_DESC *sc)
{ {
const HEVCContext *h = avctx->priv_data; const HEVCContext *h = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context; AVDXVAContext *ctx = avctx->hwaccel_context;
const HEVCFrame *current_picture = h->ref; const HEVCFrame *current_picture = h->ref;
struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
DXVA_Slice_HEVC_Short *slice = NULL; DXVA_Slice_HEVC_Short *slice = NULL;
...@@ -243,12 +243,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, ...@@ -243,12 +243,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
unsigned slice_size; unsigned slice_size;
unsigned padding; unsigned padding;
unsigned i; unsigned i;
unsigned type;
/* Create an annex B bitstream buffer with only slice NAL and finalize slice */ /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType, if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
&dxva_data_ptr, &dxva_size))) type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
return -1; 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; dxva_data = dxva_data_ptr;
current = dxva_data; current = dxva_data;
...@@ -284,23 +300,48 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, ...@@ -284,23 +300,48 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
slice->SliceBytesInBuffer += padding; slice->SliceBytesInBuffer += padding;
} }
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType))) if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
return -1; 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) if (i < ctx_pic->slice_count)
return -1; return -1;
memset(bs, 0, sizeof(*bs)); #if CONFIG_D3D11VA
bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
bs->DataSize = current - dxva_data; D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
bs->NumMBsInBuffer = 0; 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_data = ctx_pic->slice_short;
slice_size = ctx_pic->slice_count * sizeof(*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, return ff_dxva2_commit_buffer(avctx, ctx, sc,
DXVA2_SliceControlBufferType, type,
slice_data, slice_size, 0); slice_data, slice_size, 0);
} }
...@@ -310,15 +351,17 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx, ...@@ -310,15 +351,17 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx,
av_unused uint32_t size) av_unused uint32_t size)
{ {
const HEVCContext *h = avctx->priv_data; 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; 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; return -1;
av_assert0(ctx_pic); av_assert0(ctx_pic);
/* Fill up DXVA_PicParams_HEVC */ /* 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 up DXVA_Qmatrix_HEVC */
fill_scaling_lists(ctx, h, &ctx_pic->qm); fill_scaling_lists(ctx, h, &ctx_pic->qm);
...@@ -369,6 +412,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx) ...@@ -369,6 +412,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx)
return ret; return ret;
} }
#if CONFIG_HEVC_DXVA2_HWACCEL
AVHWAccel ff_hevc_dxva2_hwaccel = { AVHWAccel ff_hevc_dxva2_hwaccel = {
.name = "hevc_dxva2", .name = "hevc_dxva2",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -379,3 +423,17 @@ AVHWAccel ff_hevc_dxva2_hwaccel = { ...@@ -379,3 +423,17 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
.end_frame = dxva2_hevc_end_frame, .end_frame = dxva2_hevc_end_frame,
.frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context), .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
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "config.h" #include "config.h"
#include "dxva2.h" #include "dxva2.h"
#include "d3d11va.h"
#if HAVE_DXVA_H #if HAVE_DXVA_H
#include <dxva.h> #include <dxva.h>
#endif #endif
...@@ -35,13 +36,34 @@ ...@@ -35,13 +36,34 @@
#include "avcodec.h" #include "avcodec.h"
#include "mpegvideo.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); 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); const AVFrame *frame);
int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *, int ff_dxva2_commit_buffer(AVCodecContext *, AVDXVAContext *,
DXVA2_DecodeBufferDesc *, DECODER_BUFFER_DESC *,
unsigned type, const void *data, unsigned size, unsigned type, const void *data, unsigned size,
unsigned mb_count); unsigned mb_count);
...@@ -50,7 +72,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *, ...@@ -50,7 +72,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
const void *pp, unsigned pp_size, const void *pp, unsigned pp_size,
const void *qm, unsigned qm_size, const void *qm, unsigned qm_size,
int (*commit_bs_si)(AVCodecContext *, int (*commit_bs_si)(AVCodecContext *,
DXVA2_DecodeBufferDesc *bs, DECODER_BUFFER_DESC *bs,
DXVA2_DecodeBufferDesc *slice)); DECODER_BUFFER_DESC *slice));
#endif /* AVCODEC_DXVA_INTERNAL_H */ #endif /* AVCODEC_DXVA_INTERNAL_H */
...@@ -36,7 +36,7 @@ struct dxva2_picture_context { ...@@ -36,7 +36,7 @@ struct dxva2_picture_context {
}; };
static void fill_picture_parameters(AVCodecContext *avctx, static void fill_picture_parameters(AVCodecContext *avctx,
struct dxva_context *ctx, AVDXVAContext *ctx,
const struct MpegEncContext *s, const struct MpegEncContext *s,
DXVA_PictureParameters *pp) DXVA_PictureParameters *pp)
{ {
...@@ -44,14 +44,14 @@ static void fill_picture_parameters(AVCodecContext *avctx, ...@@ -44,14 +44,14 @@ static void fill_picture_parameters(AVCodecContext *avctx,
int is_field = s->picture_structure != PICT_FRAME; int is_field = s->picture_structure != PICT_FRAME;
memset(pp, 0, sizeof(*pp)); 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; pp->wDeblockedPictureIndex = 0;
if (s->pict_type != AV_PICTURE_TYPE_I) 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 else
pp->wForwardRefPictureIndex = 0xffff; pp->wForwardRefPictureIndex = 0xffff;
if (s->pict_type == AV_PICTURE_TYPE_B) 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 else
pp->wBackwardRefPictureIndex = 0xffff; pp->wBackwardRefPictureIndex = 0xffff;
pp->wPicWidthInMBminus1 = s->mb_width - 1; pp->wPicWidthInMBminus1 = s->mb_width - 1;
...@@ -102,7 +102,7 @@ static void fill_picture_parameters(AVCodecContext *avctx, ...@@ -102,7 +102,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
} }
static void fill_quantization_matrices(AVCodecContext *avctx, static void fill_quantization_matrices(AVCodecContext *avctx,
struct dxva_context *ctx, AVDXVAContext *ctx,
const struct MpegEncContext *s, const struct MpegEncContext *s,
DXVA_QmatrixData *qm) DXVA_QmatrixData *qm)
{ {
...@@ -147,11 +147,11 @@ static void fill_slice(AVCodecContext *avctx, ...@@ -147,11 +147,11 @@ static void fill_slice(AVCodecContext *avctx,
slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb); slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb);
} }
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
DXVA2_DecodeBufferDesc *bs, DECODER_BUFFER_DESC *bs,
DXVA2_DecodeBufferDesc *sc) DECODER_BUFFER_DESC *sc)
{ {
const struct MpegEncContext *s = avctx->priv_data; 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 = struct dxva2_picture_context *ctx_pic =
s->current_picture_ptr->hwaccel_picture_private; s->current_picture_ptr->hwaccel_picture_private;
const int is_field = s->picture_structure != PICT_FRAME; const int is_field = s->picture_structure != PICT_FRAME;
...@@ -160,11 +160,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, ...@@ -160,11 +160,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
uint8_t *dxva_data, *current, *end; uint8_t *dxva_data, *current, *end;
unsigned dxva_size; unsigned dxva_size;
unsigned i; unsigned i;
unsigned type;
if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType, if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
&dxva_data_ptr, &dxva_size))) type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
return -1; 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; dxva_data = dxva_data_ptr;
current = dxva_data; current = dxva_data;
...@@ -190,19 +206,44 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, ...@@ -190,19 +206,44 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
memcpy(current, &ctx_pic->bitstream[position], size); memcpy(current, &ctx_pic->bitstream[position], size);
current += size; current += size;
} }
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType))) if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
return -1; 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) if (i < ctx_pic->slice_count)
return -1; return -1;
memset(bs, 0, sizeof(*bs)); #if CONFIG_D3D11VA
bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
bs->DataSize = current - dxva_data; D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
bs->NumMBsInBuffer = mb_count; 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, return ff_dxva2_commit_buffer(avctx, ctx, sc,
DXVA2_SliceControlBufferType, type,
ctx_pic->slice, ctx_pic->slice,
ctx_pic->slice_count * sizeof(*ctx_pic->slice), ctx_pic->slice_count * sizeof(*ctx_pic->slice),
mb_count); mb_count);
...@@ -213,11 +254,13 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx, ...@@ -213,11 +254,13 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
av_unused uint32_t size) av_unused uint32_t size)
{ {
const struct MpegEncContext *s = avctx->priv_data; 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 = struct dxva2_picture_context *ctx_pic =
s->current_picture_ptr->hwaccel_picture_private; 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; return -1;
assert(ctx_pic); assert(ctx_pic);
...@@ -271,6 +314,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx) ...@@ -271,6 +314,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
return ret; return ret;
} }
#if CONFIG_MPEG2_DXVA2_HWACCEL
AVHWAccel ff_mpeg2_dxva2_hwaccel = { AVHWAccel ff_mpeg2_dxva2_hwaccel = {
.name = "mpeg2_dxva2", .name = "mpeg2_dxva2",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -281,3 +325,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = { ...@@ -281,3 +325,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
.end_frame = dxva2_mpeg2_end_frame, .end_frame = dxva2_mpeg2_end_frame,
.frame_priv_data_size = sizeof(struct dxva2_picture_context), .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
...@@ -34,7 +34,7 @@ struct dxva2_picture_context { ...@@ -34,7 +34,7 @@ struct dxva2_picture_context {
}; };
static void fill_picture_parameters(AVCodecContext *avctx, static void fill_picture_parameters(AVCodecContext *avctx,
struct dxva_context *ctx, const VC1Context *v, AVDXVAContext *ctx, const VC1Context *v,
DXVA_PictureParameters *pp) DXVA_PictureParameters *pp)
{ {
const MpegEncContext *s = &v->s; const MpegEncContext *s = &v->s;
...@@ -42,13 +42,13 @@ static void fill_picture_parameters(AVCodecContext *avctx, ...@@ -42,13 +42,13 @@ static void fill_picture_parameters(AVCodecContext *avctx,
memset(pp, 0, sizeof(*pp)); memset(pp, 0, sizeof(*pp));
pp->wDecodedPictureIndex = 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) 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 else
pp->wForwardRefPictureIndex = 0xffff; pp->wForwardRefPictureIndex = 0xffff;
if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) 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 else
pp->wBackwardRefPictureIndex = 0xffff; pp->wBackwardRefPictureIndex = 0xffff;
if (v->profile == PROFILE_ADVANCED) { if (v->profile == PROFILE_ADVANCED) {
...@@ -73,8 +73,8 @@ static void fill_picture_parameters(AVCodecContext *avctx, ...@@ -73,8 +73,8 @@ static void fill_picture_parameters(AVCodecContext *avctx,
pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type; 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->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type;
pp->bBidirectionalAveragingMode = (1 << 7) | pp->bBidirectionalAveragingMode = (1 << 7) |
((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) | ((DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) != 0) << 6) |
((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) | ((DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) != 0) << 5) |
((v->lumscale != 32 || v->lumshift != 0) << 4) | ((v->lumscale != 32 || v->lumshift != 0) << 4) |
((v->profile == PROFILE_ADVANCED) << 3); ((v->profile == PROFILE_ADVANCED) << 3);
pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) | pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
...@@ -82,11 +82,11 @@ static void fill_picture_parameters(AVCodecContext *avctx, ...@@ -82,11 +82,11 @@ static void fill_picture_parameters(AVCodecContext *avctx,
(0 << 1) | (0 << 1) |
(!s->quarter_sample ); (!s->quarter_sample );
pp->bChromaFormat = v->chromaformat; pp->bChromaFormat = v->chromaformat;
ctx->report_id++; DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
if (ctx->report_id >= (1 << 16)) if (DXVA_CONTEXT_REPORT_ID(avctx, ctx) >= (1 << 16))
ctx->report_id = 1; DXVA_CONTEXT_REPORT_ID(avctx, ctx) = 1;
pp->bPicScanFixed = ctx->report_id >> 8; pp->bPicScanFixed = DXVA_CONTEXT_REPORT_ID(avctx, ctx) >> 8;
pp->bPicScanMethod = ctx->report_id & 0xff; pp->bPicScanMethod = DXVA_CONTEXT_REPORT_ID(avctx, ctx) & 0xff;
pp->bPicReadbackRequests = 0; pp->bPicReadbackRequests = 0;
pp->bRcontrol = v->rnd; pp->bRcontrol = v->rnd;
pp->bPicSpatialResid8 = (v->panscanflag << 7) | pp->bPicSpatialResid8 = (v->panscanflag << 7) |
...@@ -157,11 +157,11 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice, ...@@ -157,11 +157,11 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
} }
static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
DXVA2_DecodeBufferDesc *bs, DECODER_BUFFER_DESC *bs,
DXVA2_DecodeBufferDesc *sc) DECODER_BUFFER_DESC *sc)
{ {
const VC1Context *v = avctx->priv_data; const VC1Context *v = avctx->priv_data;
struct dxva_context *ctx = avctx->hwaccel_context; AVDXVAContext *ctx = avctx->hwaccel_context;
const MpegEncContext *s = &v->s; const MpegEncContext *s = &v->s;
struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private; 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, ...@@ -177,11 +177,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
uint8_t *dxva_data; uint8_t *dxva_data;
unsigned dxva_size; unsigned dxva_size;
int result; int result;
unsigned type;
if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType, if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
&dxva_data_ptr, &dxva_size))) type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
return -1; 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; dxva_data = dxva_data_ptr;
result = data_size <= dxva_size ? 0 : -1; result = data_size <= dxva_size ? 0 : -1;
...@@ -194,21 +210,46 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, ...@@ -194,21 +210,46 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
memset(dxva_data + start_code_size + slice_size, 0, padding); memset(dxva_data + start_code_size + slice_size, 0, padding);
slice->dwSliceBitsInBuffer = 8 * data_size; slice->dwSliceBitsInBuffer = 8 * data_size;
} }
if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, #if CONFIG_D3D11VA
DXVA2_BitStreamDateBufferType))) if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
return -1; 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) if (result)
return result; return result;
memset(bs, 0, sizeof(*bs)); #if CONFIG_D3D11VA
bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
bs->DataSize = data_size; D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
bs->NumMBsInBuffer = s->mb_width * s->mb_height; memset(dsc11, 0, sizeof(*dsc11));
assert((bs->DataSize & 127) == 0); 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, return ff_dxva2_commit_buffer(avctx, ctx, sc,
DXVA2_SliceControlBufferType, type,
slice, sizeof(*slice), bs->NumMBsInBuffer); slice, sizeof(*slice), s->mb_width * s->mb_height);
} }
static int dxva2_vc1_start_frame(AVCodecContext *avctx, static int dxva2_vc1_start_frame(AVCodecContext *avctx,
...@@ -216,10 +257,12 @@ 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) av_unused uint32_t size)
{ {
const VC1Context *v = avctx->priv_data; 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; 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; return -1;
assert(ctx_pic); assert(ctx_pic);
...@@ -285,6 +328,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = { ...@@ -285,6 +328,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
}; };
#endif #endif
#if CONFIG_VC1_DXVA2_HWACCEL
AVHWAccel ff_vc1_dxva2_hwaccel = { AVHWAccel ff_vc1_dxva2_hwaccel = {
.name = "vc1_dxva2", .name = "vc1_dxva2",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -295,3 +339,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = { ...@@ -295,3 +339,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
.end_frame = dxva2_vc1_end_frame, .end_frame = dxva2_vc1_end_frame,
.frame_priv_data_size = sizeof(struct dxva2_picture_context), .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
...@@ -861,6 +861,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h) ...@@ -861,6 +861,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h)
#if CONFIG_H264_DXVA2_HWACCEL #if CONFIG_H264_DXVA2_HWACCEL
*fmt++ = AV_PIX_FMT_DXVA2_VLD; *fmt++ = AV_PIX_FMT_DXVA2_VLD;
#endif #endif
#if CONFIG_H264_D3D11VA_HWACCEL
*fmt++ = AV_PIX_FMT_D3D11VA_VLD;
#endif
#if CONFIG_H264_VAAPI_HWACCEL #if CONFIG_H264_VAAPI_HWACCEL
*fmt++ = AV_PIX_FMT_VAAPI_VLD; *fmt++ = AV_PIX_FMT_VAAPI_VLD;
#endif #endif
......
...@@ -445,6 +445,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps) ...@@ -445,6 +445,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps)
if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P) { if (sps->pix_fmt == AV_PIX_FMT_YUV420P || sps->pix_fmt == AV_PIX_FMT_YUVJ420P) {
#if CONFIG_HEVC_DXVA2_HWACCEL #if CONFIG_HEVC_DXVA2_HWACCEL
*fmt++ = AV_PIX_FMT_DXVA2_VLD; *fmt++ = AV_PIX_FMT_DXVA2_VLD;
#endif
#if CONFIG_HEVC_D3D11VA_HWACCEL
*fmt++ = AV_PIX_FMT_D3D11VA_VLD;
#endif #endif
} }
......
...@@ -1173,6 +1173,9 @@ static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = { ...@@ -1173,6 +1173,9 @@ static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = {
#if CONFIG_MPEG2_DXVA2_HWACCEL #if CONFIG_MPEG2_DXVA2_HWACCEL
AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_DXVA2_VLD,
#endif #endif
#if CONFIG_MPEG2_D3D11VA_HWACCEL
AV_PIX_FMT_D3D11VA_VLD,
#endif
#if CONFIG_MPEG2_VAAPI_HWACCEL #if CONFIG_MPEG2_VAAPI_HWACCEL
AV_PIX_FMT_VAAPI_VLD, AV_PIX_FMT_VAAPI_VLD,
#endif #endif
......
...@@ -954,6 +954,9 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { ...@@ -954,6 +954,9 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
#if CONFIG_VC1_DXVA2_HWACCEL #if CONFIG_VC1_DXVA2_HWACCEL
AV_PIX_FMT_DXVA2_VLD, AV_PIX_FMT_DXVA2_VLD,
#endif #endif
#if CONFIG_VC1_D3D11VA_HWACCEL
AV_PIX_FMT_D3D11VA_VLD,
#endif
#if CONFIG_VC1_VAAPI_HWACCEL #if CONFIG_VC1_VAAPI_HWACCEL
AV_PIX_FMT_VAAPI_VLD, AV_PIX_FMT_VAAPI_VLD,
#endif #endif
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "libavutil/version.h" #include "libavutil/version.h"
#define LIBAVCODEC_VERSION_MAJOR 56 #define LIBAVCODEC_VERSION_MAJOR 56
#define LIBAVCODEC_VERSION_MINOR 24 #define LIBAVCODEC_VERSION_MINOR 25
#define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_MICRO 0
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
......
...@@ -1333,6 +1333,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { ...@@ -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, .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] = { [AV_PIX_FMT_DXVA2_VLD] = {
.name = "dxva2_vld", .name = "dxva2_vld",
.log2_chroma_w = 1, .log2_chroma_w = 1,
......
...@@ -220,6 +220,8 @@ enum AVPixelFormat { ...@@ -220,6 +220,8 @@ enum AVPixelFormat {
*/ */
AV_PIX_FMT_MMAL, 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 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 #if FF_API_PIX_FMT
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
*/ */
#define LIBAVUTIL_VERSION_MAJOR 54 #define LIBAVUTIL_VERSION_MAJOR 54
#define LIBAVUTIL_VERSION_MINOR 12 #define LIBAVUTIL_VERSION_MINOR 13
#define LIBAVUTIL_VERSION_MICRO 1 #define LIBAVUTIL_VERSION_MICRO 1
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment