aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2015-05-25 22:02:00 +0200
committerMichael Niedermayer <michaelni@gmx.at>2015-05-25 22:24:34 +0200
commit947b74ee7da7984b666a478164917e42d4f4592d (patch)
treec2de5e9e2059cf14329979e77981819cc5cee7d3
parent9aabc926ca14faf240d078c7e428045b62018c8b (diff)
parentd8039ef8d221ea273aa4f1e62e5df21bf618c772 (diff)
downloadffmpeg-947b74ee7da7984b666a478164917e42d4f4592d.tar.gz
Merge commit 'd8039ef8d221ea273aa4f1e62e5df21bf618c772'
* commit 'd8039ef8d221ea273aa4f1e62e5df21bf618c772': D3D11va: add a Direct3D11 video decoder similar to DXVA2 Conflicts: Changelog configure libavcodec/Makefile libavcodec/allcodecs.c libavcodec/dxva2_vc1.c libavcodec/version.h libavutil/pixdesc.c libavutil/pixfmt.h libavutil/version.h Merged-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--Changelog1
-rwxr-xr-xconfigure31
-rw-r--r--libavcodec/Makefile7
-rw-r--r--libavcodec/allcodecs.c5
-rw-r--r--libavcodec/d3d11va.h98
-rw-r--r--libavcodec/dxva2.c161
-rw-r--r--libavcodec/dxva2_h264.c138
-rw-r--r--libavcodec/dxva2_hevc.c108
-rw-r--r--libavcodec/dxva2_internal.h32
-rw-r--r--libavcodec/dxva2_mpeg2.c102
-rw-r--r--libavcodec/dxva2_vc1.c131
-rw-r--r--libavcodec/h264_slice.c3
-rw-r--r--libavcodec/hevc.c3
-rw-r--r--libavcodec/mpeg12dec.c3
-rw-r--r--libavcodec/vc1dec.c3
-rw-r--r--libavcodec/version.h2
-rw-r--r--libavutil/pixdesc.c6
-rw-r--r--libavutil/pixfmt.h2
-rw-r--r--libavutil/version.h4
19 files changed, 683 insertions, 157 deletions
diff --git a/Changelog b/Changelog
index e9e925af5d..3f47490627 100644
--- a/Changelog
+++ b/Changelog
@@ -22,6 +22,7 @@ version <next>:
- improved Quickdraw compatibility
- VP9 high bit-depth and extended colorspaces decoding support
- WebPAnimEncoder API when available for encoding and muxing WebP
+- Direct3D11-accelerated decoding
version 2.6:
diff --git a/configure b/configure
index 09f49d2024..f6c8e691c2 100755
--- a/configure
+++ b/configure
@@ -149,6 +149,7 @@ Component options:
--disable-pixelutils disable pixel utils in libavutil
Hardware accelerators:
+ --enable-d3d11va enable D3D11VA code
--disable-dxva2 disable DXVA2 code [autodetect]
--disable-vaapi disable VAAPI code [autodetect]
--disable-vda disable VDA code [autodetect]
@@ -1448,6 +1449,7 @@ FEATURE_LIST="
"
HWACCEL_LIST="
+ d3d11va
dxva2
vaapi
vda
@@ -1670,6 +1672,7 @@ HEADERS_LIST="
dev_video_meteor_ioctl_meteor_h
direct_h
dlfcn_h
+ d3d11_h
dxva_h
ES2_gl_h
gsm_h
@@ -1845,6 +1848,8 @@ HAVE_LIST="
$TYPES_LIST
atomics_native
dos_paths
+ d3d11_cobj
+ d3d11va_lib
dxva2api_cobj
dxva2_lib
libc_msvcrt
@@ -2314,6 +2319,7 @@ zmbv_encoder_select="zlib"
# hardware accelerators
crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
+d3d11va_deps="d3d11_h dxva_h"
dxva2_deps="dxva2api_h"
vaapi_deps="va_va_h"
vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
@@ -2326,6 +2332,8 @@ h263_vaapi_hwaccel_select="h263_decoder"
h263_vdpau_hwaccel_deps="vdpau"
h263_vdpau_hwaccel_select="h263_decoder"
h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
+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"
@@ -2345,6 +2353,8 @@ h264_vdpau_decoder_deps="vdpau"
h264_vdpau_decoder_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"
mpeg_vdpau_decoder_deps="vdpau"
@@ -2358,6 +2368,8 @@ mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
mpeg1_xvmc_hwaccel_deps="xvmc"
mpeg1_xvmc_hwaccel_select="mpeg1video_decoder"
mpeg2_crystalhd_decoder_select="crystalhd"
+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"
@@ -2375,6 +2387,8 @@ mpeg4_vdpau_hwaccel_deps="vdpau"
mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
msmpeg4_crystalhd_decoder_select="crystalhd"
vc1_crystalhd_decoder_select="crystalhd"
+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"
@@ -2384,6 +2398,7 @@ vc1_vdpau_decoder_select="vc1_decoder"
vc1_vdpau_hwaccel_deps="vdpau"
vc1_vdpau_hwaccel_select="vc1_decoder"
wmv3_crystalhd_decoder_select="crystalhd"
+wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
@@ -2814,7 +2829,7 @@ sws_max_filter_size_default=256
set_default sws_max_filter_size
# Enable hwaccels by default.
-enable dxva2 vaapi vda vdpau xvmc
+enable d3d11va dxva2 vaapi vda vdpau xvmc
enable xlib
# build settings
@@ -4945,6 +4960,7 @@ enabled xlib &&
check_header direct.h
check_header dlfcn.h
+check_header d3d11.h
check_header dxva.h
check_header dxva2api.h -D_WIN32_WINNT=0x0600
check_header io.h
@@ -5293,6 +5309,15 @@ enabled dxva2api_h &&
int main(void) { IDirectXVideoDecoder *o = NULL; IDirectXVideoDecoder_Release(o); return 0; }
EOF
+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 &&
check_lib va/va.h vaInitialize -lva ||
disable vaapi
@@ -5550,6 +5575,10 @@ if test $target_os = "haiku"; then
disable posix_memalign
fi
+enabled_all d3d11va d3d11_cobj CoTaskMemFree &&
+ prepend ffmpeg_libs $($ldflags_filter "-lole32") &&
+ enable d3d11va_lib
+
enabled_all dxva2 dxva2api_cobj CoTaskMemFree &&
prepend ffmpeg_libs $($ldflags_filter "-lole32" "-luser32") &&
enable dxva2_lib
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 02aa61e682..8bbf78c9cf 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -5,6 +5,7 @@ NAME = avcodec
HEADERS = avcodec.h \
avfft.h \
dv_profile.h \
+ d3d11va.h \
dxva2.h \
old_codec_ids.h \
qsv.h \
@@ -671,6 +672,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o
OBJS-$(CONFIG_VIMA_DECODER) += vima.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
@@ -678,19 +680,23 @@ 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_MPEG1_XVMC_HWACCEL) += mpegvideo_xvmc.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_MPEG2_XVMC_HWACCEL) += mpegvideo_xvmc.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
@@ -872,6 +878,7 @@ SKIPHEADERS += %_tablegen.h \
tableprint_vlc.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_LIBUTVIDEO) += libutvideo.h
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index fe79d0bb3b..a94d1dc8f6 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,18 +84,22 @@ 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_XVMC, mpeg1_xvmc);
REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau);
REGISTER_HWACCEL(MPEG2_XVMC, mpeg2_xvmc);
+ 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 0000000000..d51e2ff8f5
--- /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 FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; 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 FFmpeg 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 FFmpeg AVHWAccel implementation
+ */
+ unsigned report_id;
+};
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_D3D11VA_H */
diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c
index c1c7681402..477607957c 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 8915e47a6c..fe252bbae8 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 FFmpeg */
}
-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 4fba3ad648..dae990dd8f 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 427c1ffdf8..5a30bc6aef 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 7ef4a6ceb9..89c43e7f9c 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)
{
@@ -146,11 +146,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;
@@ -159,11 +159,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;
@@ -189,19 +205,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);
@@ -212,11 +253,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);
@@ -270,6 +313,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,
@@ -280,3 +324,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 3beeb9f751..1eb425383e 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;
@@ -51,13 +51,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) {
@@ -82,8 +82,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) |
(intcomp << 4) |
((v->profile == PROFILE_ADVANCED) << 3);
pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
@@ -91,11 +91,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) |
@@ -176,11 +176,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;
@@ -196,11 +196,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;
@@ -216,21 +232,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,
@@ -238,10 +279,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);
@@ -307,6 +350,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
};
#endif
+#if CONFIG_VC1_DXVA2_HWACCEL
AVHWAccel ff_vc1_dxva2_hwaccel = {
.name = "vc1_dxva2",
.type = AVMEDIA_TYPE_VIDEO,
@@ -317,3 +361,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 2064496775..738c359701 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -935,6 +935,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
#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 df6cce6f8a..028ece82f9 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -343,6 +343,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, enum AVPixelFormat pix_fm
#if CONFIG_HEVC_DXVA2_HWACCEL
*fmt++ = AV_PIX_FMT_DXVA2_VLD;
#endif
+#if CONFIG_HEVC_D3D11VA_HWACCEL
+ *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
+#endif
}
if (pix_fmt == AV_PIX_FMT_NONE) {
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c
index 3bb736f87c..f180c3d62b 100644
--- a/libavcodec/mpeg12dec.c
+++ b/libavcodec/mpeg12dec.c
@@ -1204,6 +1204,9 @@ static const enum AVPixelFormat mpeg2_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 d39f344102..eab6792f36 100644
--- a/libavcodec/vc1dec.c
+++ b/libavcodec/vc1dec.c
@@ -1074,6 +1074,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 b9f99d7181..74a1b3048e 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 40
+#define LIBAVCODEC_VERSION_MINOR 41
#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c
index 5086edc5e7..32dc4b80ab 100644
--- a/libavutil/pixdesc.c
+++ b/libavutil/pixdesc.c
@@ -1586,6 +1586,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 b1056d9504..3ddd30f0d8 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -258,6 +258,8 @@ enum AVPixelFormat {
*/
AV_PIX_FMT_MMAL,
+ AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer
+
#ifndef AV_PIX_FMT_ABI_GIT_MASTER
AV_PIX_FMT_RGBA64BE=0x123, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
AV_PIX_FMT_RGBA64LE, ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
diff --git a/libavutil/version.h b/libavutil/version.h
index 18a22952e0..eeafcfab6c 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -56,8 +56,8 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 54
-#define LIBAVUTIL_VERSION_MINOR 23
-#define LIBAVUTIL_VERSION_MICRO 101
+#define LIBAVUTIL_VERSION_MINOR 24
+#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
LIBAVUTIL_VERSION_MINOR, \