Signed-off-by: Luca Barbato <lu_zero@gentoo.org>tags/n2.7
| @@ -12,6 +12,7 @@ version <next>: | |||
| - VP8 in Ogg demuxing | |||
| - OpenH264 encoder wrapper | |||
| - Support DNx100 (960x720@8) | |||
| - Direct3D11-accelerated decoding | |||
| - DXVA2-accelerated HEVC decoding | |||
| - AAC ELD 480 decoding | |||
| - Intel QSV-accelerated H.264 decoding | |||
| @@ -133,6 +133,7 @@ Component options: | |||
| --disable-faan disable floating point AAN (I)DCT code | |||
| Hardware accelerators: | |||
| --enable-d3d11va enable D3D11VA code | |||
| --enable-dxva2 enable DXVA2 code | |||
| --enable-vaapi enable VAAPI code | |||
| --enable-vda enable VDA code | |||
| @@ -1206,6 +1207,7 @@ FEATURE_LIST=" | |||
| " | |||
| HWACCEL_LIST=" | |||
| d3d11va | |||
| dxva2 | |||
| vaapi | |||
| vda | |||
| @@ -1396,6 +1398,7 @@ HEADERS_LIST=" | |||
| dev_video_meteor_ioctl_meteor_h | |||
| direct_h | |||
| dlfcn_h | |||
| d3d11_h | |||
| dxva_h | |||
| gsm_h | |||
| io_h | |||
| @@ -1551,6 +1554,8 @@ HAVE_LIST=" | |||
| $TYPES_LIST | |||
| atomics_native | |||
| dos_paths | |||
| d3d11_cobj | |||
| d3d11va_lib | |||
| dxva2_lib | |||
| libc_msvcrt | |||
| libdc1394_1 | |||
| @@ -1965,6 +1970,7 @@ zmbv_decoder_deps="zlib" | |||
| zmbv_encoder_deps="zlib" | |||
| # hardware accelerators | |||
| d3d11va_deps="d3d11_h dxva_h" | |||
| dxva2_deps="dxva2api_h" | |||
| vaapi_deps="va_va_h" | |||
| vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads" | |||
| @@ -1975,6 +1981,8 @@ h263_vaapi_hwaccel_deps="vaapi" | |||
| h263_vaapi_hwaccel_select="h263_decoder" | |||
| h263_vdpau_hwaccel_deps="vdpau" | |||
| h263_vdpau_hwaccel_select="h263_decoder" | |||
| h264_d3d11va_hwaccel_deps="d3d11va" | |||
| h264_d3d11va_hwaccel_select="h264_decoder" | |||
| h264_dxva2_hwaccel_deps="dxva2" | |||
| h264_dxva2_hwaccel_select="h264_decoder" | |||
| h264_mmal_decoder_deps="mmal" | |||
| @@ -1990,10 +1998,14 @@ h264_vda_old_hwaccel_deps="vda" | |||
| h264_vda_old_hwaccel_select="h264_decoder" | |||
| h264_vdpau_hwaccel_deps="vdpau" | |||
| h264_vdpau_hwaccel_select="h264_decoder" | |||
| hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC" | |||
| hevc_d3d11va_hwaccel_select="hevc_decoder" | |||
| hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC" | |||
| hevc_dxva2_hwaccel_select="hevc_decoder" | |||
| mpeg1_vdpau_hwaccel_deps="vdpau" | |||
| mpeg1_vdpau_hwaccel_select="mpeg1video_decoder" | |||
| mpeg2_d3d11va_hwaccel_deps="d3d11va" | |||
| mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder" | |||
| mpeg2_dxva2_hwaccel_deps="dxva2" | |||
| mpeg2_dxva2_hwaccel_select="mpeg2video_decoder" | |||
| mpeg2_vaapi_hwaccel_deps="vaapi" | |||
| @@ -2004,12 +2016,15 @@ mpeg4_vaapi_hwaccel_deps="vaapi" | |||
| mpeg4_vaapi_hwaccel_select="mpeg4_decoder" | |||
| mpeg4_vdpau_hwaccel_deps="vdpau" | |||
| mpeg4_vdpau_hwaccel_select="mpeg4_decoder" | |||
| vc1_d3d11va_hwaccel_deps="d3d11va" | |||
| vc1_d3d11va_hwaccel_select="vc1_decoder" | |||
| vc1_dxva2_hwaccel_deps="dxva2" | |||
| vc1_dxva2_hwaccel_select="vc1_decoder" | |||
| vc1_vaapi_hwaccel_deps="vaapi" | |||
| vc1_vaapi_hwaccel_select="vc1_decoder" | |||
| vc1_vdpau_hwaccel_deps="vdpau" | |||
| vc1_vdpau_hwaccel_select="vc1_decoder" | |||
| wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel" | |||
| wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" | |||
| wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" | |||
| wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" | |||
| @@ -2288,7 +2303,7 @@ enable swscale_alpha | |||
| enable valgrind_backtrace | |||
| # By default, enable only those hwaccels that have no external dependencies. | |||
| enable dxva2 vda vdpau | |||
| enable d3d11va dxva2 vda vdpau | |||
| # build settings | |||
| SHFLAGS='-shared -Wl,-soname,$$(@F)' | |||
| @@ -4155,6 +4170,7 @@ check_struct windows.h "CONDITION_VARIABLE" Ptr | |||
| check_header direct.h | |||
| check_header dlfcn.h | |||
| check_header d3d11.h | |||
| check_header dxva.h | |||
| check_header dxva2api.h | |||
| check_header io.h | |||
| @@ -4372,6 +4388,15 @@ if enabled x11grab; then | |||
| require Xfixes X11/extensions/Xfixes.h XFixesGetCursorImage -lXfixes | |||
| fi | |||
| enabled d3d11_h && | |||
| check_cc <<EOF && enable d3d11_cobj | |||
| #define _WIN32_WINNT 0x0600 | |||
| #define COBJMACROS | |||
| #include <windows.h> | |||
| #include <d3d11.h> | |||
| int main(void) { ID3D11VideoDecoder *o = NULL; ID3D11VideoDecoder_Release(o); return 0; } | |||
| EOF | |||
| enabled vaapi && enabled xlib && | |||
| check_lib2 "va/va.h va/va_x11.h" vaGetDisplay -lva -lva-x11 && | |||
| enable vaapi_x11 | |||
| @@ -4593,6 +4618,10 @@ check_deps $CONFIG_LIST \ | |||
| $HAVE_LIST \ | |||
| $ALL_COMPONENTS \ | |||
| enabled_all d3d11va d3d11_cobj CoTaskMemFree && | |||
| prepend avconv_libs $($ldflags_filter "-lole32") && | |||
| enable d3d11va_lib | |||
| enabled_all dxva2 CoTaskMemFree && | |||
| prepend avconv_libs $($ldflags_filter "-lole32") && | |||
| enable dxva2_lib | |||
| @@ -3,6 +3,7 @@ NAME = avcodec | |||
| HEADERS = avcodec.h \ | |||
| avfft.h \ | |||
| dv_profile.h \ | |||
| d3d11va.h \ | |||
| dxva2.h \ | |||
| qsv.h \ | |||
| vaapi.h \ | |||
| @@ -557,6 +558,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_DECODER) += adpcm.o adpcm_data.o | |||
| OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o | |||
| # hardware accelerators | |||
| OBJS-$(CONFIG_D3D11VA) += dxva2.o | |||
| OBJS-$(CONFIG_DXVA2) += dxva2.o | |||
| OBJS-$(CONFIG_VAAPI) += vaapi.o | |||
| OBJS-$(CONFIG_VDA) += vda.o | |||
| @@ -564,17 +566,21 @@ OBJS-$(CONFIG_VDPAU) += vdpau.o | |||
| OBJS-$(CONFIG_H263_VAAPI_HWACCEL) += vaapi_mpeg4.o | |||
| OBJS-$(CONFIG_H263_VDPAU_HWACCEL) += vdpau_mpeg4.o | |||
| OBJS-$(CONFIG_H264_D3D11VA_HWACCEL) += dxva2_h264.o | |||
| OBJS-$(CONFIG_H264_DXVA2_HWACCEL) += dxva2_h264.o | |||
| OBJS-$(CONFIG_H264_VAAPI_HWACCEL) += vaapi_h264.o | |||
| OBJS-$(CONFIG_H264_VDA_HWACCEL) += vda_h264.o | |||
| OBJS-$(CONFIG_H264_VDPAU_HWACCEL) += vdpau_h264.o | |||
| OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL) += dxva2_hevc.o | |||
| OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL) += dxva2_hevc.o | |||
| OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL) += vdpau_mpeg12.o | |||
| OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL) += dxva2_mpeg2.o | |||
| OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL) += dxva2_mpeg2.o | |||
| OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL) += vaapi_mpeg2.o | |||
| OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL) += vdpau_mpeg12.o | |||
| OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o | |||
| OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL) += vdpau_mpeg4.o | |||
| OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL) += dxva2_vc1.o | |||
| OBJS-$(CONFIG_VC1_DXVA2_HWACCEL) += dxva2_vc1.o | |||
| OBJS-$(CONFIG_VC1_VAAPI_HWACCEL) += vaapi_vc1.o | |||
| OBJS-$(CONFIG_VC1_VDPAU_HWACCEL) += vdpau_vc1.o | |||
| @@ -723,6 +729,7 @@ SKIPHEADERS += %_tablegen.h \ | |||
| tableprint.h \ | |||
| $(ARCH)/vp56_arith.h \ | |||
| SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h | |||
| SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h | |||
| SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER) += libschroedinger.h | |||
| SKIPHEADERS-$(CONFIG_MPEG_XVMC_DECODER) += xvmc.h | |||
| @@ -76,6 +76,7 @@ void avcodec_register_all(void) | |||
| /* hardware accelerators */ | |||
| REGISTER_HWACCEL(H263_VAAPI, h263_vaapi); | |||
| REGISTER_HWACCEL(H263_VDPAU, h263_vdpau); | |||
| REGISTER_HWACCEL(H264_D3D11VA, h264_d3d11va); | |||
| REGISTER_HWACCEL(H264_DXVA2, h264_dxva2); | |||
| REGISTER_HWACCEL(H264_MMAL, h264_mmal); | |||
| REGISTER_HWACCEL(H264_QSV, h264_qsv); | |||
| @@ -83,16 +84,20 @@ void avcodec_register_all(void) | |||
| REGISTER_HWACCEL(H264_VDA, h264_vda); | |||
| REGISTER_HWACCEL(H264_VDA_OLD, h264_vda_old); | |||
| REGISTER_HWACCEL(H264_VDPAU, h264_vdpau); | |||
| REGISTER_HWACCEL(HEVC_D3D11VA, hevc_d3d11va); | |||
| REGISTER_HWACCEL(HEVC_DXVA2, hevc_dxva2); | |||
| REGISTER_HWACCEL(MPEG1_VDPAU, mpeg1_vdpau); | |||
| REGISTER_HWACCEL(MPEG2_D3D11VA, mpeg2_d3d11va); | |||
| REGISTER_HWACCEL(MPEG2_DXVA2, mpeg2_dxva2); | |||
| REGISTER_HWACCEL(MPEG2_VAAPI, mpeg2_vaapi); | |||
| REGISTER_HWACCEL(MPEG2_VDPAU, mpeg2_vdpau); | |||
| REGISTER_HWACCEL(MPEG4_VAAPI, mpeg4_vaapi); | |||
| REGISTER_HWACCEL(MPEG4_VDPAU, mpeg4_vdpau); | |||
| REGISTER_HWACCEL(VC1_D3D11VA, vc1_d3d11va); | |||
| REGISTER_HWACCEL(VC1_DXVA2, vc1_dxva2); | |||
| REGISTER_HWACCEL(VC1_VAAPI, vc1_vaapi); | |||
| REGISTER_HWACCEL(VC1_VDPAU, vc1_vdpau); | |||
| REGISTER_HWACCEL(WMV3_D3D11VA, wmv3_d3d11va); | |||
| REGISTER_HWACCEL(WMV3_DXVA2, wmv3_dxva2); | |||
| REGISTER_HWACCEL(WMV3_VAAPI, wmv3_vaapi); | |||
| REGISTER_HWACCEL(WMV3_VDPAU, wmv3_vdpau); | |||
| @@ -0,0 +1,98 @@ | |||
| /* | |||
| * Direct3D11 HW acceleration | |||
| * | |||
| * copyright (c) 2009 Laurent Aimar | |||
| * copyright (c) 2015 Steve Lhomme | |||
| * | |||
| * This file is part of Libav. | |||
| * | |||
| * Libav is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU Lesser General Public | |||
| * License as published by the Free Software Foundation; either | |||
| * version 2.1 of the License, or (at your option) any later version. | |||
| * | |||
| * Libav is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
| * Lesser General Public License for more details. | |||
| * | |||
| * You should have received a copy of the GNU Lesser General Public | |||
| * License along with Libav; if not, write to the Free Software | |||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
| */ | |||
| #ifndef AVCODEC_D3D11VA_H | |||
| #define AVCODEC_D3D11VA_H | |||
| /** | |||
| * @file | |||
| * @ingroup lavc_codec_hwaccel_d3d11va | |||
| * Public libavcodec D3D11VA header. | |||
| */ | |||
| #if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600 | |||
| #undef _WIN32_WINNT | |||
| #define _WIN32_WINNT 0x0600 | |||
| #endif | |||
| #include <stdint.h> | |||
| #include <d3d11.h> | |||
| /** | |||
| * @defgroup lavc_codec_hwaccel_d3d11va Direct3D11 | |||
| * @ingroup lavc_codec_hwaccel | |||
| * | |||
| * @{ | |||
| */ | |||
| #define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards | |||
| #define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO 2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface | |||
| /** | |||
| * This structure is used to provides the necessary configurations and data | |||
| * to the Direct3D11 Libav HWAccel implementation. | |||
| * | |||
| * The application must make it available as AVCodecContext.hwaccel_context. | |||
| */ | |||
| struct AVD3D11VAContext { | |||
| /** | |||
| * D3D11 decoder object | |||
| */ | |||
| ID3D11VideoDecoder *decoder; | |||
| /** | |||
| * D3D11 VideoContext | |||
| */ | |||
| ID3D11VideoContext *video_context; | |||
| /** | |||
| * D3D11 configuration used to create the decoder | |||
| */ | |||
| D3D11_VIDEO_DECODER_CONFIG *cfg; | |||
| /** | |||
| * The number of surface in the surface array | |||
| */ | |||
| unsigned surface_count; | |||
| /** | |||
| * The array of Direct3D surfaces used to create the decoder | |||
| */ | |||
| ID3D11VideoDecoderOutputView **surface; | |||
| /** | |||
| * A bit field configuring the workarounds needed for using the decoder | |||
| */ | |||
| uint64_t workaround; | |||
| /** | |||
| * Private to the Libav AVHWAccel implementation | |||
| */ | |||
| unsigned report_id; | |||
| }; | |||
| /** | |||
| * @} | |||
| */ | |||
| #endif /* AVCODEC_D3D11VA_H */ | |||
| @@ -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; | |||
| @@ -42,7 +42,7 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic, | |||
| pic->bPicEntry = index | (flag << 7); | |||
| } | |||
| static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h, | |||
| static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, | |||
| DXVA_PicParams_H264 *pp) | |||
| { | |||
| const H264Picture *current_picture = h->cur_pic_ptr; | |||
| @@ -51,7 +51,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context | |||
| memset(pp, 0, sizeof(*pp)); | |||
| /* Configure current picture */ | |||
| fill_picture_entry(&pp->CurrPic, | |||
| ff_dxva2_get_surface_index(ctx, current_picture->f), | |||
| ff_dxva2_get_surface_index(avctx, ctx, current_picture->f), | |||
| h->picture_structure == PICT_BOTTOM_FIELD); | |||
| /* Configure the set of references */ | |||
| pp->UsedForReferenceFlags = 0; | |||
| @@ -67,7 +67,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context | |||
| } | |||
| if (r) { | |||
| fill_picture_entry(&pp->RefFrameList[i], | |||
| ff_dxva2_get_surface_index(ctx, r->f), | |||
| ff_dxva2_get_surface_index(avctx, ctx, r->f), | |||
| r->long_ref != 0); | |||
| if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX) | |||
| @@ -114,13 +114,13 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context | |||
| pp->bit_depth_luma_minus8 = h->sps.bit_depth_luma - 8; | |||
| pp->bit_depth_chroma_minus8 = h->sps.bit_depth_chroma - 8; | |||
| if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) | |||
| if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) | |||
| pp->Reserved16Bits = 0; | |||
| else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) | |||
| else if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) | |||
| pp->Reserved16Bits = 0x34c; | |||
| else | |||
| pp->Reserved16Bits = 3; /* FIXME is there a way to detect the right mode ? */ | |||
| pp->StatusReportFeedbackNumber = 1 + ctx->report_id++; | |||
| pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++; | |||
| pp->CurrFieldOrderCnt[0] = 0; | |||
| if ((h->picture_structure & PICT_TOP_FIELD) && | |||
| current_picture->field_poc[0] != INT_MAX) | |||
| @@ -156,11 +156,11 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context | |||
| //pp->SliceGroupMap[810]; /* XXX not implemented by Libav */ | |||
| } | |||
| static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm) | |||
| static void fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm) | |||
| { | |||
| unsigned i, j; | |||
| memset(qm, 0, sizeof(*qm)); | |||
| if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) { | |||
| if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) { | |||
| for (i = 0; i < 6; i++) | |||
| for (j = 0; j < 16; j++) | |||
| qm->bScalingLists4x4[i][j] = h->pps.scaling_matrix4[i][j]; | |||
| @@ -181,11 +181,11 @@ static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, D | |||
| } | |||
| } | |||
| static int is_slice_short(struct dxva_context *ctx) | |||
| static int is_slice_short(const AVCodecContext *avctx, AVDXVAContext *ctx) | |||
| { | |||
| assert(ctx->cfg->ConfigBitstreamRaw == 1 || | |||
| ctx->cfg->ConfigBitstreamRaw == 2); | |||
| return ctx->cfg->ConfigBitstreamRaw == 2; | |||
| assert(DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 1 || | |||
| DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2); | |||
| return DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2; | |||
| } | |||
| static void fill_slice_short(DXVA_Slice_H264_Short *slice, | |||
| @@ -212,7 +212,7 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, | |||
| { | |||
| const H264Context *h = avctx->priv_data; | |||
| H264SliceContext *sl = &h->slice_ctx[0]; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| unsigned list; | |||
| memset(slice, 0, sizeof(*slice)); | |||
| @@ -243,10 +243,10 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, | |||
| const H264Picture *r = sl->ref_list[list][i].parent; | |||
| unsigned plane; | |||
| unsigned index; | |||
| if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) | |||
| index = ff_dxva2_get_surface_index(ctx, r->f); | |||
| if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO) | |||
| index = ff_dxva2_get_surface_index(avctx, ctx, r->f); | |||
| else | |||
| index = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, r->f)); | |||
| index = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, r->f)); | |||
| fill_picture_entry(&slice->RefPicList[list][i], index, | |||
| r->reference == PICT_BOTTOM_FIELD); | |||
| for (plane = 0; plane < 3; plane++) { | |||
| @@ -289,12 +289,12 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice, | |||
| } | |||
| static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| DXVA2_DecodeBufferDesc *bs, | |||
| DXVA2_DecodeBufferDesc *sc) | |||
| DECODER_BUFFER_DESC *bs, | |||
| DECODER_BUFFER_DESC *sc) | |||
| { | |||
| const H264Context *h = avctx->priv_data; | |||
| const unsigned mb_count = h->mb_width * h->mb_height; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| const H264Picture *current_picture = h->cur_pic_ptr; | |||
| struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; | |||
| DXVA_Slice_H264_Short *slice = NULL; | |||
| @@ -305,12 +305,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| unsigned slice_size; | |||
| unsigned padding; | |||
| unsigned i; | |||
| unsigned type; | |||
| /* Create an annex B bitstream buffer with only slice NAL and finalize slice */ | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM; | |||
| if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, | |||
| D3D11VA_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_size, &dxva_data_ptr))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| type = DXVA2_BitStreamDateBufferType; | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| dxva_data = dxva_data_ptr; | |||
| current = dxva_data; | |||
| @@ -326,7 +342,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) == | |||
| offsetof(DXVA_Slice_H264_Long, SliceBytesInBuffer)); | |||
| if (is_slice_short(ctx)) | |||
| if (is_slice_short(avctx, ctx)) | |||
| slice = &ctx_pic->slice_short[i]; | |||
| else | |||
| slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i]; | |||
| @@ -341,7 +357,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| slice->BSNALunitDataLocation = current - dxva_data; | |||
| slice->SliceBytesInBuffer = start_code_size + size; | |||
| if (!is_slice_short(ctx)) { | |||
| if (!is_slice_short(avctx, ctx)) { | |||
| DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice; | |||
| if (i < ctx_pic->slice_count - 1) | |||
| slice_long->NumMbsForSlice = | |||
| @@ -363,18 +379,43 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| slice->SliceBytesInBuffer += padding; | |||
| } | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) | |||
| if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| if (i < ctx_pic->slice_count) | |||
| return -1; | |||
| memset(bs, 0, sizeof(*bs)); | |||
| bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; | |||
| bs->DataSize = current - dxva_data; | |||
| bs->NumMBsInBuffer = mb_count; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs; | |||
| memset(dsc11, 0, sizeof(*dsc11)); | |||
| dsc11->BufferType = type; | |||
| dsc11->DataSize = current - dxva_data; | |||
| dsc11->NumMBsInBuffer = mb_count; | |||
| if (is_slice_short(ctx)) { | |||
| type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| DXVA2_DecodeBufferDesc *dsc2 = bs; | |||
| memset(dsc2, 0, sizeof(*dsc2)); | |||
| dsc2->CompressedBufferType = type; | |||
| dsc2->DataSize = current - dxva_data; | |||
| dsc2->NumMBsInBuffer = mb_count; | |||
| type = DXVA2_SliceControlBufferType; | |||
| } | |||
| #endif | |||
| if (is_slice_short(avctx, ctx)) { | |||
| slice_data = ctx_pic->slice_short; | |||
| slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short); | |||
| } else { | |||
| @@ -383,7 +424,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| } | |||
| assert((bs->DataSize & 127) == 0); | |||
| return ff_dxva2_commit_buffer(avctx, ctx, sc, | |||
| DXVA2_SliceControlBufferType, | |||
| type, | |||
| slice_data, slice_size, mb_count); | |||
| } | |||
| @@ -393,18 +434,20 @@ static int dxva2_h264_start_frame(AVCodecContext *avctx, | |||
| av_unused uint32_t size) | |||
| { | |||
| const H264Context *h = avctx->priv_data; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private; | |||
| if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) | |||
| if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_CFG(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) | |||
| return -1; | |||
| assert(ctx_pic); | |||
| /* Fill up DXVA_PicParams_H264 */ | |||
| fill_picture_parameters(ctx, h, &ctx_pic->pp); | |||
| fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp); | |||
| /* Fill up DXVA_Qmatrix_H264 */ | |||
| fill_scaling_lists(ctx, h, &ctx_pic->qm); | |||
| fill_scaling_lists(avctx, ctx, h, &ctx_pic->qm); | |||
| ctx_pic->slice_count = 0; | |||
| ctx_pic->bitstream_size = 0; | |||
| @@ -418,7 +461,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx, | |||
| { | |||
| const H264Context *h = avctx->priv_data; | |||
| const H264SliceContext *sl = &h->slice_ctx[0]; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| const H264Picture *current_picture = h->cur_pic_ptr; | |||
| struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private; | |||
| unsigned position; | |||
| @@ -431,7 +474,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx, | |||
| ctx_pic->bitstream_size += size; | |||
| position = buffer - ctx_pic->bitstream; | |||
| if (is_slice_short(ctx)) | |||
| if (is_slice_short(avctx, ctx)) | |||
| fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count], | |||
| position, size); | |||
| else | |||
| @@ -463,6 +506,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx) | |||
| return ret; | |||
| } | |||
| #if CONFIG_H264_DXVA2_HWACCEL | |||
| AVHWAccel ff_h264_dxva2_hwaccel = { | |||
| .name = "h264_dxva2", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| @@ -473,3 +517,17 @@ AVHWAccel ff_h264_dxva2_hwaccel = { | |||
| .end_frame = dxva2_h264_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| #if CONFIG_H264_D3D11VA_HWACCEL | |||
| AVHWAccel ff_h264_d3d11va_hwaccel = { | |||
| .name = "h264_d3d11va", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| .id = AV_CODEC_ID_H264, | |||
| .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, | |||
| .start_frame = dxva2_h264_start_frame, | |||
| .decode_slice = dxva2_h264_decode_slice, | |||
| .end_frame = dxva2_h264_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| @@ -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 | |||
| @@ -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 */ | |||
| @@ -36,7 +36,7 @@ struct dxva2_picture_context { | |||
| }; | |||
| static void fill_picture_parameters(AVCodecContext *avctx, | |||
| struct dxva_context *ctx, | |||
| AVDXVAContext *ctx, | |||
| const struct MpegEncContext *s, | |||
| DXVA_PictureParameters *pp) | |||
| { | |||
| @@ -44,14 +44,14 @@ static void fill_picture_parameters(AVCodecContext *avctx, | |||
| int is_field = s->picture_structure != PICT_FRAME; | |||
| memset(pp, 0, sizeof(*pp)); | |||
| pp->wDecodedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture->f); | |||
| pp->wDecodedPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f); | |||
| pp->wDeblockedPictureIndex = 0; | |||
| if (s->pict_type != AV_PICTURE_TYPE_I) | |||
| pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->last_picture.f); | |||
| pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f); | |||
| else | |||
| pp->wForwardRefPictureIndex = 0xffff; | |||
| if (s->pict_type == AV_PICTURE_TYPE_B) | |||
| pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->next_picture.f); | |||
| pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f); | |||
| else | |||
| pp->wBackwardRefPictureIndex = 0xffff; | |||
| pp->wPicWidthInMBminus1 = s->mb_width - 1; | |||
| @@ -102,7 +102,7 @@ static void fill_picture_parameters(AVCodecContext *avctx, | |||
| } | |||
| static void fill_quantization_matrices(AVCodecContext *avctx, | |||
| struct dxva_context *ctx, | |||
| AVDXVAContext *ctx, | |||
| const struct MpegEncContext *s, | |||
| DXVA_QmatrixData *qm) | |||
| { | |||
| @@ -147,11 +147,11 @@ static void fill_slice(AVCodecContext *avctx, | |||
| slice->wMBbitOffset = 4 * 8 + get_bits_count(&gb); | |||
| } | |||
| static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| DXVA2_DecodeBufferDesc *bs, | |||
| DXVA2_DecodeBufferDesc *sc) | |||
| DECODER_BUFFER_DESC *bs, | |||
| DECODER_BUFFER_DESC *sc) | |||
| { | |||
| const struct MpegEncContext *s = avctx->priv_data; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| struct dxva2_picture_context *ctx_pic = | |||
| s->current_picture_ptr->hwaccel_picture_private; | |||
| const int is_field = s->picture_structure != PICT_FRAME; | |||
| @@ -160,11 +160,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| uint8_t *dxva_data, *current, *end; | |||
| unsigned dxva_size; | |||
| unsigned i; | |||
| unsigned type; | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM; | |||
| if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, | |||
| D3D11VA_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_size, &dxva_data_ptr))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| type = DXVA2_BitStreamDateBufferType; | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| dxva_data = dxva_data_ptr; | |||
| current = dxva_data; | |||
| @@ -190,19 +206,44 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| memcpy(current, &ctx_pic->bitstream[position], size); | |||
| current += size; | |||
| } | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) | |||
| if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| if (i < ctx_pic->slice_count) | |||
| return -1; | |||
| memset(bs, 0, sizeof(*bs)); | |||
| bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; | |||
| bs->DataSize = current - dxva_data; | |||
| bs->NumMBsInBuffer = mb_count; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs; | |||
| memset(dsc11, 0, sizeof(*dsc11)); | |||
| dsc11->BufferType = type; | |||
| dsc11->DataSize = current - dxva_data; | |||
| dsc11->NumMBsInBuffer = mb_count; | |||
| type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| DXVA2_DecodeBufferDesc *dsc2 = bs; | |||
| memset(dsc2, 0, sizeof(*dsc2)); | |||
| dsc2->CompressedBufferType = type; | |||
| dsc2->DataSize = current - dxva_data; | |||
| dsc2->NumMBsInBuffer = mb_count; | |||
| type = DXVA2_SliceControlBufferType; | |||
| } | |||
| #endif | |||
| return ff_dxva2_commit_buffer(avctx, ctx, sc, | |||
| DXVA2_SliceControlBufferType, | |||
| type, | |||
| ctx_pic->slice, | |||
| ctx_pic->slice_count * sizeof(*ctx_pic->slice), | |||
| mb_count); | |||
| @@ -213,11 +254,13 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx, | |||
| av_unused uint32_t size) | |||
| { | |||
| const struct MpegEncContext *s = avctx->priv_data; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| struct dxva2_picture_context *ctx_pic = | |||
| s->current_picture_ptr->hwaccel_picture_private; | |||
| if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) | |||
| if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_CFG(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) | |||
| return -1; | |||
| assert(ctx_pic); | |||
| @@ -271,6 +314,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx) | |||
| return ret; | |||
| } | |||
| #if CONFIG_MPEG2_DXVA2_HWACCEL | |||
| AVHWAccel ff_mpeg2_dxva2_hwaccel = { | |||
| .name = "mpeg2_dxva2", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| @@ -281,3 +325,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = { | |||
| .end_frame = dxva2_mpeg2_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| #if CONFIG_MPEG2_D3D11VA_HWACCEL | |||
| AVHWAccel ff_mpeg2_d3d11va_hwaccel = { | |||
| .name = "mpeg2_d3d11va", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| .id = AV_CODEC_ID_MPEG2VIDEO, | |||
| .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, | |||
| .start_frame = dxva2_mpeg2_start_frame, | |||
| .decode_slice = dxva2_mpeg2_decode_slice, | |||
| .end_frame = dxva2_mpeg2_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| @@ -34,7 +34,7 @@ struct dxva2_picture_context { | |||
| }; | |||
| static void fill_picture_parameters(AVCodecContext *avctx, | |||
| struct dxva_context *ctx, const VC1Context *v, | |||
| AVDXVAContext *ctx, const VC1Context *v, | |||
| DXVA_PictureParameters *pp) | |||
| { | |||
| const MpegEncContext *s = &v->s; | |||
| @@ -42,13 +42,13 @@ static void fill_picture_parameters(AVCodecContext *avctx, | |||
| memset(pp, 0, sizeof(*pp)); | |||
| pp->wDecodedPictureIndex = | |||
| pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(ctx, current_picture->f); | |||
| pp->wDeblockedPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f); | |||
| if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type) | |||
| pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->last_picture.f); | |||
| pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f); | |||
| else | |||
| pp->wForwardRefPictureIndex = 0xffff; | |||
| if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type) | |||
| pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->next_picture.f); | |||
| pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f); | |||
| else | |||
| pp->wBackwardRefPictureIndex = 0xffff; | |||
| if (v->profile == PROFILE_ADVANCED) { | |||
| @@ -73,8 +73,8 @@ static void fill_picture_parameters(AVCodecContext *avctx, | |||
| pp->bPicIntra = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type; | |||
| pp->bPicBackwardPrediction = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type; | |||
| pp->bBidirectionalAveragingMode = (1 << 7) | | |||
| ((ctx->cfg->ConfigIntraResidUnsigned != 0) << 6) | | |||
| ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) | | |||
| ((DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) != 0) << 6) | | |||
| ((DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) != 0) << 5) | | |||
| ((v->lumscale != 32 || v->lumshift != 0) << 4) | | |||
| ((v->profile == PROFILE_ADVANCED) << 3); | |||
| pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) | | |||
| @@ -82,11 +82,11 @@ static void fill_picture_parameters(AVCodecContext *avctx, | |||
| (0 << 1) | | |||
| (!s->quarter_sample ); | |||
| pp->bChromaFormat = v->chromaformat; | |||
| ctx->report_id++; | |||
| if (ctx->report_id >= (1 << 16)) | |||
| ctx->report_id = 1; | |||
| pp->bPicScanFixed = ctx->report_id >> 8; | |||
| pp->bPicScanMethod = ctx->report_id & 0xff; | |||
| DXVA_CONTEXT_REPORT_ID(avctx, ctx)++; | |||
| if (DXVA_CONTEXT_REPORT_ID(avctx, ctx) >= (1 << 16)) | |||
| DXVA_CONTEXT_REPORT_ID(avctx, ctx) = 1; | |||
| pp->bPicScanFixed = DXVA_CONTEXT_REPORT_ID(avctx, ctx) >> 8; | |||
| pp->bPicScanMethod = DXVA_CONTEXT_REPORT_ID(avctx, ctx) & 0xff; | |||
| pp->bPicReadbackRequests = 0; | |||
| pp->bRcontrol = v->rnd; | |||
| pp->bPicSpatialResid8 = (v->panscanflag << 7) | | |||
| @@ -157,11 +157,11 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice, | |||
| } | |||
| static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| DXVA2_DecodeBufferDesc *bs, | |||
| DXVA2_DecodeBufferDesc *sc) | |||
| DECODER_BUFFER_DESC *bs, | |||
| DECODER_BUFFER_DESC *sc) | |||
| { | |||
| const VC1Context *v = avctx->priv_data; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| const MpegEncContext *s = &v->s; | |||
| struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private; | |||
| @@ -177,11 +177,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| uint8_t *dxva_data; | |||
| unsigned dxva_size; | |||
| int result; | |||
| unsigned type; | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM; | |||
| if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, | |||
| D3D11VA_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_size, &dxva_data_ptr))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| type = DXVA2_BitStreamDateBufferType; | |||
| if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, | |||
| type, | |||
| &dxva_data_ptr, &dxva_size))) | |||
| return -1; | |||
| } | |||
| #endif | |||
| dxva_data = dxva_data_ptr; | |||
| result = data_size <= dxva_size ? 0 : -1; | |||
| @@ -194,21 +210,46 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx, | |||
| memset(dxva_data + start_code_size + slice_size, 0, padding); | |||
| slice->dwSliceBitsInBuffer = 8 * data_size; | |||
| } | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, | |||
| DXVA2_BitStreamDateBufferType))) | |||
| return -1; | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) | |||
| if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) | |||
| if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type))) | |||
| return -1; | |||
| #endif | |||
| if (result) | |||
| return result; | |||
| memset(bs, 0, sizeof(*bs)); | |||
| bs->CompressedBufferType = DXVA2_BitStreamDateBufferType; | |||
| bs->DataSize = data_size; | |||
| bs->NumMBsInBuffer = s->mb_width * s->mb_height; | |||
| assert((bs->DataSize & 127) == 0); | |||
| #if CONFIG_D3D11VA | |||
| if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { | |||
| D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs; | |||
| memset(dsc11, 0, sizeof(*dsc11)); | |||
| dsc11->BufferType = type; | |||
| dsc11->DataSize = data_size; | |||
| dsc11->NumMBsInBuffer = s->mb_width * s->mb_height; | |||
| type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL; | |||
| } | |||
| #endif | |||
| #if CONFIG_DXVA2 | |||
| if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { | |||
| DXVA2_DecodeBufferDesc *dsc2 = bs; | |||
| memset(dsc2, 0, sizeof(*dsc2)); | |||
| dsc2->CompressedBufferType = type; | |||
| dsc2->DataSize = data_size; | |||
| dsc2->NumMBsInBuffer = s->mb_width * s->mb_height; | |||
| type = DXVA2_SliceControlBufferType; | |||
| } | |||
| #endif | |||
| assert((data_size & 127) == 0); | |||
| return ff_dxva2_commit_buffer(avctx, ctx, sc, | |||
| DXVA2_SliceControlBufferType, | |||
| slice, sizeof(*slice), bs->NumMBsInBuffer); | |||
| type, | |||
| slice, sizeof(*slice), s->mb_width * s->mb_height); | |||
| } | |||
| static int dxva2_vc1_start_frame(AVCodecContext *avctx, | |||
| @@ -216,10 +257,12 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx, | |||
| av_unused uint32_t size) | |||
| { | |||
| const VC1Context *v = avctx->priv_data; | |||
| struct dxva_context *ctx = avctx->hwaccel_context; | |||
| AVDXVAContext *ctx = avctx->hwaccel_context; | |||
| struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private; | |||
| if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0) | |||
| if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_CFG(avctx, ctx) == NULL || | |||
| DXVA_CONTEXT_COUNT(avctx, ctx) <= 0) | |||
| return -1; | |||
| assert(ctx_pic); | |||
| @@ -285,6 +328,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = { | |||
| }; | |||
| #endif | |||
| #if CONFIG_VC1_DXVA2_HWACCEL | |||
| AVHWAccel ff_vc1_dxva2_hwaccel = { | |||
| .name = "vc1_dxva2", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| @@ -295,3 +339,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = { | |||
| .end_frame = dxva2_vc1_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| #if CONFIG_WMV3_D3D11VA_HWACCEL | |||
| AVHWAccel ff_wmv3_d3d11va_hwaccel = { | |||
| .name = "wmv3_d3d11va", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| .id = AV_CODEC_ID_WMV3, | |||
| .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, | |||
| .start_frame = dxva2_vc1_start_frame, | |||
| .decode_slice = dxva2_vc1_decode_slice, | |||
| .end_frame = dxva2_vc1_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| #if CONFIG_VC1_D3D11VA_HWACCEL | |||
| AVHWAccel ff_vc1_d3d11va_hwaccel = { | |||
| .name = "vc1_d3d11va", | |||
| .type = AVMEDIA_TYPE_VIDEO, | |||
| .id = AV_CODEC_ID_VC1, | |||
| .pix_fmt = AV_PIX_FMT_D3D11VA_VLD, | |||
| .start_frame = dxva2_vc1_start_frame, | |||
| .decode_slice = dxva2_vc1_decode_slice, | |||
| .end_frame = dxva2_vc1_end_frame, | |||
| .frame_priv_data_size = sizeof(struct dxva2_picture_context), | |||
| }; | |||
| #endif | |||
| @@ -861,6 +861,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h) | |||
| #if CONFIG_H264_DXVA2_HWACCEL | |||
| *fmt++ = AV_PIX_FMT_DXVA2_VLD; | |||
| #endif | |||
| #if CONFIG_H264_D3D11VA_HWACCEL | |||
| *fmt++ = AV_PIX_FMT_D3D11VA_VLD; | |||
| #endif | |||
| #if CONFIG_H264_VAAPI_HWACCEL | |||
| *fmt++ = AV_PIX_FMT_VAAPI_VLD; | |||
| #endif | |||
| @@ -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 CONFIG_HEVC_DXVA2_HWACCEL | |||
| *fmt++ = AV_PIX_FMT_DXVA2_VLD; | |||
| #endif | |||
| #if CONFIG_HEVC_D3D11VA_HWACCEL | |||
| *fmt++ = AV_PIX_FMT_D3D11VA_VLD; | |||
| #endif | |||
| } | |||
| @@ -1173,6 +1173,9 @@ static const enum AVPixelFormat mpeg12_hwaccel_pixfmt_list_420[] = { | |||
| #if CONFIG_MPEG2_DXVA2_HWACCEL | |||
| AV_PIX_FMT_DXVA2_VLD, | |||
| #endif | |||
| #if CONFIG_MPEG2_D3D11VA_HWACCEL | |||
| AV_PIX_FMT_D3D11VA_VLD, | |||
| #endif | |||
| #if CONFIG_MPEG2_VAAPI_HWACCEL | |||
| AV_PIX_FMT_VAAPI_VLD, | |||
| #endif | |||
| @@ -954,6 +954,9 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = { | |||
| #if CONFIG_VC1_DXVA2_HWACCEL | |||
| AV_PIX_FMT_DXVA2_VLD, | |||
| #endif | |||
| #if CONFIG_VC1_D3D11VA_HWACCEL | |||
| AV_PIX_FMT_D3D11VA_VLD, | |||
| #endif | |||
| #if CONFIG_VC1_VAAPI_HWACCEL | |||
| AV_PIX_FMT_VAAPI_VLD, | |||
| #endif | |||
| @@ -29,7 +29,7 @@ | |||
| #include "libavutil/version.h" | |||
| #define LIBAVCODEC_VERSION_MAJOR 56 | |||
| #define LIBAVCODEC_VERSION_MINOR 24 | |||
| #define LIBAVCODEC_VERSION_MINOR 25 | |||
| #define LIBAVCODEC_VERSION_MICRO 0 | |||
| #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | |||
| @@ -1333,6 +1333,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { | |||
| }, | |||
| .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR, | |||
| }, | |||
| [AV_PIX_FMT_D3D11VA_VLD] = { | |||
| .name = "d3d11va_vld", | |||
| .log2_chroma_w = 1, | |||
| .log2_chroma_h = 1, | |||
| .flags = AV_PIX_FMT_FLAG_HWACCEL, | |||
| }, | |||
| [AV_PIX_FMT_DXVA2_VLD] = { | |||
| .name = "dxva2_vld", | |||
| .log2_chroma_w = 1, | |||
| @@ -220,6 +220,8 @@ enum AVPixelFormat { | |||
| */ | |||
| AV_PIX_FMT_MMAL, | |||
| AV_PIX_FMT_D3D11VA_VLD, ///< HW decoding through Direct3D11, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer | |||
| AV_PIX_FMT_NB, ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions | |||
| #if FF_API_PIX_FMT | |||
| @@ -54,7 +54,7 @@ | |||
| */ | |||
| #define LIBAVUTIL_VERSION_MAJOR 54 | |||
| #define LIBAVUTIL_VERSION_MINOR 12 | |||
| #define LIBAVUTIL_VERSION_MINOR 13 | |||
| #define LIBAVUTIL_VERSION_MICRO 1 | |||
| #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ | |||