Browse code

dxva: add support for new dxva2 and d3d11 hwaccel APIs

This also adds support to avconv (which is trivial due to the new
hwaccel API being generic enough).

The new decoder setup code in dxva2.c is significantly based on work by
Steve Lhomme <robux4@gmail.com>, but with heavy changes/rewrites.

Merges Libav commit f9e7a2f95a7194a8736cc1416a03a1a0155a3e9f.
Also adds untested VP9 support.
The check for DXVA2 COBJs is removed. Just update your MinGW to
something newer than a 5 year old release.

Signed-off-by: Diego Biurrun <diego@biurrun.de>

wm4 authored on 2017/06/08 00:11:17
Showing 22 changed files
... ...
@@ -25,6 +25,7 @@ version <next>:
25 25
 - The x86 assembler default switched from yasm to nasm, pass
26 26
   --x86asmexe=yasm to configure to restore the old behavior.
27 27
 - additional frame format support for Interplay MVE movies
28
+- support for decoding through D3D11VA in ffmpeg
28 29
 
29 30
 version 3.3:
30 31
 - CrystalHD decoder moved to new decode API
... ...
@@ -38,7 +38,6 @@ ifndef CONFIG_VIDEOTOOLBOX
38 38
 OBJS-ffmpeg-$(CONFIG_VDA)     += ffmpeg_videotoolbox.o
39 39
 endif
40 40
 OBJS-ffmpeg-$(CONFIG_CUVID)   += ffmpeg_cuvid.o
41
-OBJS-ffmpeg-$(HAVE_DXVA2_LIB) += ffmpeg_dxva2.o
42 41
 OBJS-ffserver                 += ffserver_config.o
43 42
 
44 43
 TESTTOOLS   = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
... ...
@@ -2056,8 +2056,6 @@ HAVE_LIST="
2056 2056
     alsa
2057 2057
     atomics_native
2058 2058
     dos_paths
2059
-    dxva2_lib
2060
-    dxva2api_cobj
2061 2059
     jack
2062 2060
     libc_msvcrt
2063 2061
     makeinfo
... ...
@@ -2594,9 +2592,8 @@ crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
2594 2594
 cuda_deps_any="dlopen LoadLibrary"
2595 2595
 cuvid_deps="cuda"
2596 2596
 d3d11va_deps="d3d11_h dxva_h ID3D11VideoDecoder ID3D11VideoContext"
2597
-dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode"
2597
+dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32"
2598 2598
 dxva2_extralibs="-luser32"
2599
-dxva2_lib_deps="dxva2"
2600 2599
 vda_framework_deps="VideoDecodeAcceleration_VDADecoder_h blocks_extension"
2601 2600
 vda_framework_extralibs="-framework VideoDecodeAcceleration"
2602 2601
 vda_deps="vda_framework pthreads"
... ...
@@ -2613,6 +2610,8 @@ h264_cuvid_hwaccel_deps="cuda cuvid"
2613 2613
 h264_cuvid_hwaccel_select="h264_cuvid_decoder"
2614 2614
 h264_d3d11va_hwaccel_deps="d3d11va"
2615 2615
 h264_d3d11va_hwaccel_select="h264_decoder"
2616
+h264_d3d11va2_hwaccel_deps="d3d11va"
2617
+h264_d3d11va2_hwaccel_select="h264_decoder"
2616 2618
 h264_dxva2_hwaccel_deps="dxva2"
2617 2619
 h264_dxva2_hwaccel_select="h264_decoder"
2618 2620
 h264_mediacodec_hwaccel_deps="mediacodec"
... ...
@@ -2633,6 +2632,8 @@ hevc_cuvid_hwaccel_select="hevc_cuvid_decoder"
2633 2633
 hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
2634 2634
 hevc_d3d11va_hwaccel_select="hevc_decoder"
2635 2635
 hevc_mediacodec_hwaccel_deps="mediacodec"
2636
+hevc_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
2637
+hevc_d3d11va2_hwaccel_select="hevc_decoder"
2636 2638
 hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
2637 2639
 hevc_dxva2_hwaccel_select="hevc_decoder"
2638 2640
 hevc_qsv_hwaccel_deps="libmfx"
... ...
@@ -2656,6 +2657,8 @@ mpeg2_cuvid_hwaccel_deps="cuda cuvid"
2656 2656
 mpeg2_cuvid_hwaccel_select="mpeg2_cuvid_decoder"
2657 2657
 mpeg2_d3d11va_hwaccel_deps="d3d11va"
2658 2658
 mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
2659
+mpeg2_d3d11va2_hwaccel_deps="d3d11va"
2660
+mpeg2_d3d11va2_hwaccel_select="mpeg2video_decoder"
2659 2661
 mpeg2_dxva2_hwaccel_deps="dxva2"
2660 2662
 mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
2661 2663
 mpeg2_mediacodec_hwaccel_deps="mediacodec"
... ...
@@ -2684,6 +2687,8 @@ vc1_cuvid_hwaccel_deps="cuda cuvid"
2684 2684
 vc1_cuvid_hwaccel_select="vc1_cuvid_decoder"
2685 2685
 vc1_d3d11va_hwaccel_deps="d3d11va"
2686 2686
 vc1_d3d11va_hwaccel_select="vc1_decoder"
2687
+vc1_d3d11va2_hwaccel_deps="d3d11va"
2688
+vc1_d3d11va2_hwaccel_select="vc1_decoder"
2687 2689
 vc1_dxva2_hwaccel_deps="dxva2"
2688 2690
 vc1_dxva2_hwaccel_select="vc1_decoder"
2689 2691
 vc1_mmal_hwaccel_deps="mmal"
... ...
@@ -2701,12 +2706,15 @@ vp8_mediacodec_hwaccel_deps="mediacodec"
2701 2701
 vp8_qsv_hwaccel_deps="libmfx"
2702 2702
 vp9_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
2703 2703
 vp9_d3d11va_hwaccel_select="vp9_decoder"
2704
+vp9_d3d11va2_hwaccel_deps="d3d11va DXVA_PicParams_VP9"
2705
+vp9_d3d11va2_hwaccel_select="vp9_decoder"
2704 2706
 vp9_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_VP9"
2705 2707
 vp9_dxva2_hwaccel_select="vp9_decoder"
2706 2708
 vp9_mediacodec_hwaccel_deps="mediacodec"
2707 2709
 vp9_vaapi_hwaccel_deps="vaapi VADecPictureParameterBufferVP9_bit_depth"
2708 2710
 vp9_vaapi_hwaccel_select="vp9_decoder"
2709 2711
 wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
2712
+wmv3_d3d11va2_hwaccel_select="vc1_d3d11va2_hwaccel"
2710 2713
 wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
2711 2714
 wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
2712 2715
 wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
... ...
@@ -5705,6 +5713,7 @@ check_header asm/types.h
5705 5705
 # so we also check that atomics actually work here
5706 5706
 check_builtin stdatomic_h stdatomic.h "atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0)"
5707 5707
 
5708
+check_lib ole32    "windows.h"            CoTaskMemFree        -lole32
5708 5709
 check_lib shell32  "windows.h shellapi.h" CommandLineToArgvW   -lshell32
5709 5710
 check_lib wincrypt "windows.h wincrypt.h" CryptGenRandom       -ladvapi32
5710 5711
 check_lib psapi    "windows.h psapi.h"    GetProcessMemoryInfo -lpsapi
... ...
@@ -6111,19 +6120,6 @@ fi
6111 6111
 
6112 6112
 check_func_headers "windows.h" CreateDIBSection "$gdigrab_indev_extralibs"
6113 6113
 
6114
-enabled dxva2api_h &&
6115
-    check_cc <<EOF && enable dxva2api_cobj
6116
-#define _WIN32_WINNT 0x0600
6117
-#define COBJMACROS
6118
-#include <windows.h>
6119
-#include <d3d9.h>
6120
-#include <dxva2api.h>
6121
-int main(void) { IDirectXVideoDecoder *o = NULL; IDirectXVideoDecoder_Release(o); return 0; }
6122
-EOF
6123
-
6124
-enabled dxva2 &&
6125
-    check_lib dxva2_lib windows.h CoTaskMemFree -lole32
6126
-
6127 6114
 enabled vaapi &&
6128 6115
     check_lib vaapi va/va.h vaInitialize -lva
6129 6116
 
... ...
@@ -15,6 +15,12 @@ libavutil:     2015-08-28
15 15
 
16 16
 API changes, most recent first:
17 17
 
18
+2017-xx-xx - xxxxxxx - lavc 57.100.100 - avcodec.h
19
+  DXVA2 and D3D11 hardware accelerated decoding now supports the new hwaccel API,
20
+  which can create the decoder context and allocate hardware frame automatically.
21
+  See AVCodecContext.hw_device_ctx and AVCodecContext.hw_frames_ctx. For D3D11,
22
+  the new AV_PIX_FMT_D3D11 pixfmt must be used with the new API.
23
+
18 24
 2017-xx-xx - xxxxxxx - lavu 56.67.100 - hwcontext.h
19 25
   Add AV_HWDEVICE_TYPE_D3D11VA and AV_PIX_FMT_D3D11.
20 26
 
... ...
@@ -68,6 +68,7 @@ enum HWAccelID {
68 68
     HWACCEL_QSV,
69 69
     HWACCEL_VAAPI,
70 70
     HWACCEL_CUVID,
71
+    HWACCEL_D3D11VA,
71 72
 };
72 73
 
73 74
 typedef struct HWAccel {
... ...
@@ -661,7 +662,6 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame);
661 661
 
662 662
 int ffmpeg_parse_options(int argc, char **argv);
663 663
 
664
-int dxva2_init(AVCodecContext *s);
665 664
 int vda_init(AVCodecContext *s);
666 665
 int videotoolbox_init(AVCodecContext *s);
667 666
 int qsv_init(AVCodecContext *s);
668 667
deleted file mode 100644
... ...
@@ -1,444 +0,0 @@
1
-/*
2
- * This file is part of FFmpeg.
3
- *
4
- * FFmpeg is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU Lesser General Public
6
- * License as published by the Free Software Foundation; either
7
- * version 2.1 of the License, or (at your option) any later version.
8
- *
9
- * FFmpeg is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
- * Lesser General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU Lesser General Public
15
- * License along with FFmpeg; if not, write to the Free Software
16
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
- */
18
-
19
-#include <windows.h>
20
-
21
-#ifdef _WIN32_WINNT
22
-#undef _WIN32_WINNT
23
-#endif
24
-#define _WIN32_WINNT 0x0600
25
-#define DXVA2API_USE_BITFIELDS
26
-#define COBJMACROS
27
-
28
-#include <stdint.h>
29
-
30
-#include <d3d9.h>
31
-#include <dxva2api.h>
32
-
33
-#include "ffmpeg.h"
34
-
35
-#include "libavcodec/dxva2.h"
36
-
37
-#include "libavutil/avassert.h"
38
-#include "libavutil/buffer.h"
39
-#include "libavutil/frame.h"
40
-#include "libavutil/imgutils.h"
41
-#include "libavutil/pixfmt.h"
42
-
43
-#include "libavutil/hwcontext.h"
44
-#include "libavutil/hwcontext_dxva2.h"
45
-
46
-/* define all the GUIDs used directly here,
47
-   to avoid problems with inconsistent dxva2api.h versions in mingw-w64 and different MSVC version */
48
-#include <initguid.h>
49
-DEFINE_GUID(IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
50
-
51
-DEFINE_GUID(DXVA2_ModeMPEG2_VLD,      0xee27417f, 0x5e28,0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
52
-DEFINE_GUID(DXVA2_ModeMPEG2and1_VLD,  0x86695f12, 0x340e,0x4f04,0x9f,0xd3,0x92,0x53,0xdd,0x32,0x74,0x60);
53
-DEFINE_GUID(DXVA2_ModeH264_E,         0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
54
-DEFINE_GUID(DXVA2_ModeH264_F,         0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
55
-DEFINE_GUID(DXVADDI_Intel_ModeH264_E, 0x604F8E68, 0x4951,0x4C54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
56
-DEFINE_GUID(DXVA2_ModeVC1_D,          0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
57
-DEFINE_GUID(DXVA2_ModeVC1_D2010,      0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
58
-DEFINE_GUID(DXVA2_ModeHEVC_VLD_Main,  0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
59
-DEFINE_GUID(DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
60
-DEFINE_GUID(DXVA2_ModeVP9_VLD_Profile0, 0x463707f8, 0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e);
61
-DEFINE_GUID(DXVA2_NoEncrypt,          0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
62
-DEFINE_GUID(GUID_NULL,                0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
63
-
64
-typedef struct dxva2_mode {
65
-  const GUID     *guid;
66
-  enum AVCodecID codec;
67
-} dxva2_mode;
68
-
69
-static const dxva2_mode dxva2_modes[] = {
70
-    /* MPEG-2 */
71
-    { &DXVA2_ModeMPEG2_VLD,      AV_CODEC_ID_MPEG2VIDEO },
72
-    { &DXVA2_ModeMPEG2and1_VLD,  AV_CODEC_ID_MPEG2VIDEO },
73
-
74
-    /* H.264 */
75
-    { &DXVA2_ModeH264_F,         AV_CODEC_ID_H264 },
76
-    { &DXVA2_ModeH264_E,         AV_CODEC_ID_H264 },
77
-    /* Intel specific H.264 mode */
78
-    { &DXVADDI_Intel_ModeH264_E, AV_CODEC_ID_H264 },
79
-
80
-    /* VC-1 / WMV3 */
81
-    { &DXVA2_ModeVC1_D2010,      AV_CODEC_ID_VC1  },
82
-    { &DXVA2_ModeVC1_D2010,      AV_CODEC_ID_WMV3 },
83
-    { &DXVA2_ModeVC1_D,          AV_CODEC_ID_VC1  },
84
-    { &DXVA2_ModeVC1_D,          AV_CODEC_ID_WMV3 },
85
-
86
-    /* HEVC/H.265 */
87
-    { &DXVA2_ModeHEVC_VLD_Main,  AV_CODEC_ID_HEVC },
88
-    { &DXVA2_ModeHEVC_VLD_Main10,AV_CODEC_ID_HEVC },
89
-
90
-    /* VP8/9 */
91
-    { &DXVA2_ModeVP9_VLD_Profile0, AV_CODEC_ID_VP9 },
92
-
93
-    { NULL,                      0 },
94
-};
95
-
96
-typedef struct DXVA2Context {
97
-    IDirectXVideoDecoder        *decoder;
98
-
99
-    GUID                        decoder_guid;
100
-    DXVA2_ConfigPictureDecode   decoder_config;
101
-    IDirectXVideoDecoderService *decoder_service;
102
-
103
-    AVFrame                     *tmp_frame;
104
-
105
-    AVBufferRef                 *hw_device_ctx;
106
-    AVBufferRef                 *hw_frames_ctx;
107
-} DXVA2Context;
108
-
109
-static void dxva2_uninit(AVCodecContext *s)
110
-{
111
-    InputStream  *ist = s->opaque;
112
-    DXVA2Context *ctx = ist->hwaccel_ctx;
113
-
114
-    ist->hwaccel_uninit        = NULL;
115
-    ist->hwaccel_get_buffer    = NULL;
116
-    ist->hwaccel_retrieve_data = NULL;
117
-
118
-    if (ctx->decoder_service)
119
-        IDirectXVideoDecoderService_Release(ctx->decoder_service);
120
-
121
-    av_buffer_unref(&ctx->hw_frames_ctx);
122
-    av_buffer_unref(&ctx->hw_device_ctx);
123
-
124
-    av_frame_free(&ctx->tmp_frame);
125
-
126
-    av_freep(&ist->hwaccel_ctx);
127
-    av_freep(&s->hwaccel_context);
128
-}
129
-
130
-static int dxva2_get_buffer(AVCodecContext *s, AVFrame *frame, int flags)
131
-{
132
-    InputStream  *ist = s->opaque;
133
-    DXVA2Context *ctx = ist->hwaccel_ctx;
134
-
135
-    return av_hwframe_get_buffer(ctx->hw_frames_ctx, frame, 0);
136
-}
137
-
138
-static int dxva2_retrieve_data(AVCodecContext *s, AVFrame *frame)
139
-{
140
-    InputStream        *ist = s->opaque;
141
-    DXVA2Context       *ctx = ist->hwaccel_ctx;
142
-    int                ret;
143
-
144
-    ret = av_hwframe_transfer_data(ctx->tmp_frame, frame, 0);
145
-    if (ret < 0)
146
-        return ret;
147
-
148
-    ret = av_frame_copy_props(ctx->tmp_frame, frame);
149
-    if (ret < 0) {
150
-        av_frame_unref(ctx->tmp_frame);
151
-        return ret;
152
-    }
153
-
154
-    av_frame_unref(frame);
155
-    av_frame_move_ref(frame, ctx->tmp_frame);
156
-
157
-    return 0;
158
-}
159
-
160
-static int dxva2_alloc(AVCodecContext *s)
161
-{
162
-    InputStream  *ist = s->opaque;
163
-    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
164
-    DXVA2Context *ctx;
165
-    HANDLE device_handle;
166
-    HRESULT hr;
167
-
168
-    AVHWDeviceContext    *device_ctx;
169
-    AVDXVA2DeviceContext *device_hwctx;
170
-    int ret;
171
-
172
-    ctx = av_mallocz(sizeof(*ctx));
173
-    if (!ctx)
174
-        return AVERROR(ENOMEM);
175
-
176
-    ist->hwaccel_ctx           = ctx;
177
-    ist->hwaccel_uninit        = dxva2_uninit;
178
-    ist->hwaccel_get_buffer    = dxva2_get_buffer;
179
-    ist->hwaccel_retrieve_data = dxva2_retrieve_data;
180
-
181
-    ret = av_hwdevice_ctx_create(&ctx->hw_device_ctx, AV_HWDEVICE_TYPE_DXVA2,
182
-                                 ist->hwaccel_device, NULL, 0);
183
-    if (ret < 0)
184
-        goto fail;
185
-    device_ctx   = (AVHWDeviceContext*)ctx->hw_device_ctx->data;
186
-    device_hwctx = device_ctx->hwctx;
187
-
188
-    hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
189
-                                                  &device_handle);
190
-    if (FAILED(hr)) {
191
-        av_log(NULL, loglevel, "Failed to open a device handle\n");
192
-        goto fail;
193
-    }
194
-
195
-    hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle,
196
-                                                 &IID_IDirectXVideoDecoderService,
197
-                                                 (void **)&ctx->decoder_service);
198
-    IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle);
199
-    if (FAILED(hr)) {
200
-        av_log(NULL, loglevel, "Failed to create IDirectXVideoDecoderService\n");
201
-        goto fail;
202
-    }
203
-
204
-    ctx->tmp_frame = av_frame_alloc();
205
-    if (!ctx->tmp_frame)
206
-        goto fail;
207
-
208
-    s->hwaccel_context = av_mallocz(sizeof(struct dxva_context));
209
-    if (!s->hwaccel_context)
210
-        goto fail;
211
-
212
-    return 0;
213
-fail:
214
-    dxva2_uninit(s);
215
-    return AVERROR(EINVAL);
216
-}
217
-
218
-static int dxva2_get_decoder_configuration(AVCodecContext *s, const GUID *device_guid,
219
-                                           const DXVA2_VideoDesc *desc,
220
-                                           DXVA2_ConfigPictureDecode *config)
221
-{
222
-    InputStream  *ist = s->opaque;
223
-    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
224
-    DXVA2Context *ctx = ist->hwaccel_ctx;
225
-    unsigned cfg_count = 0, best_score = 0;
226
-    DXVA2_ConfigPictureDecode *cfg_list = NULL;
227
-    DXVA2_ConfigPictureDecode best_cfg = {{0}};
228
-    HRESULT hr;
229
-    int i;
230
-
231
-    hr = IDirectXVideoDecoderService_GetDecoderConfigurations(ctx->decoder_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
232
-    if (FAILED(hr)) {
233
-        av_log(NULL, loglevel, "Unable to retrieve decoder configurations\n");
234
-        return AVERROR(EINVAL);
235
-    }
236
-
237
-    for (i = 0; i < cfg_count; i++) {
238
-        DXVA2_ConfigPictureDecode *cfg = &cfg_list[i];
239
-
240
-        unsigned score;
241
-        if (cfg->ConfigBitstreamRaw == 1)
242
-            score = 1;
243
-        else if (s->codec_id == AV_CODEC_ID_H264 && cfg->ConfigBitstreamRaw == 2)
244
-            score = 2;
245
-        else
246
-            continue;
247
-        if (IsEqualGUID(&cfg->guidConfigBitstreamEncryption, &DXVA2_NoEncrypt))
248
-            score += 16;
249
-        if (score > best_score) {
250
-            best_score = score;
251
-            best_cfg   = *cfg;
252
-        }
253
-    }
254
-    CoTaskMemFree(cfg_list);
255
-
256
-    if (!best_score) {
257
-        av_log(NULL, loglevel, "No valid decoder configuration available\n");
258
-        return AVERROR(EINVAL);
259
-    }
260
-
261
-    *config = best_cfg;
262
-    return 0;
263
-}
264
-
265
-static int dxva2_create_decoder(AVCodecContext *s)
266
-{
267
-    InputStream  *ist = s->opaque;
268
-    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
269
-    DXVA2Context *ctx = ist->hwaccel_ctx;
270
-    struct dxva_context *dxva_ctx = s->hwaccel_context;
271
-    GUID *guid_list = NULL;
272
-    unsigned guid_count = 0, i, j;
273
-    GUID device_guid = GUID_NULL;
274
-    const D3DFORMAT surface_format = (s->sw_pix_fmt == AV_PIX_FMT_YUV420P10) ? MKTAG('P','0','1','0') : MKTAG('N','V','1','2');
275
-    D3DFORMAT target_format = 0;
276
-    DXVA2_VideoDesc desc = { 0 };
277
-    DXVA2_ConfigPictureDecode config;
278
-    HRESULT hr;
279
-    int surface_alignment, num_surfaces;
280
-    int ret;
281
-
282
-    AVDXVA2FramesContext *frames_hwctx;
283
-    AVHWFramesContext *frames_ctx;
284
-
285
-    hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(ctx->decoder_service, &guid_count, &guid_list);
286
-    if (FAILED(hr)) {
287
-        av_log(NULL, loglevel, "Failed to retrieve decoder device GUIDs\n");
288
-        goto fail;
289
-    }
290
-
291
-    for (i = 0; dxva2_modes[i].guid; i++) {
292
-        D3DFORMAT *target_list = NULL;
293
-        unsigned target_count = 0;
294
-        const dxva2_mode *mode = &dxva2_modes[i];
295
-        if (mode->codec != s->codec_id)
296
-            continue;
297
-
298
-        for (j = 0; j < guid_count; j++) {
299
-            if (IsEqualGUID(mode->guid, &guid_list[j]))
300
-                break;
301
-        }
302
-        if (j == guid_count)
303
-            continue;
304
-
305
-        hr = IDirectXVideoDecoderService_GetDecoderRenderTargets(ctx->decoder_service, mode->guid, &target_count, &target_list);
306
-        if (FAILED(hr)) {
307
-            continue;
308
-        }
309
-        for (j = 0; j < target_count; j++) {
310
-            const D3DFORMAT format = target_list[j];
311
-            if (format == surface_format) {
312
-                target_format = format;
313
-                break;
314
-            }
315
-        }
316
-        CoTaskMemFree(target_list);
317
-        if (target_format) {
318
-            device_guid = *mode->guid;
319
-            break;
320
-        }
321
-    }
322
-    CoTaskMemFree(guid_list);
323
-
324
-    if (IsEqualGUID(&device_guid, &GUID_NULL)) {
325
-        av_log(NULL, loglevel, "No decoder device for codec found\n");
326
-        goto fail;
327
-    }
328
-
329
-    desc.SampleWidth  = s->coded_width;
330
-    desc.SampleHeight = s->coded_height;
331
-    desc.Format       = target_format;
332
-
333
-    ret = dxva2_get_decoder_configuration(s, &device_guid, &desc, &config);
334
-    if (ret < 0) {
335
-        goto fail;
336
-    }
337
-
338
-    /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
339
-       but it causes issues for H.264 on certain AMD GPUs..... */
340
-    if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO)
341
-        surface_alignment = 32;
342
-    /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
343
-       all coding features have enough room to work with */
344
-    else if  (s->codec_id == AV_CODEC_ID_HEVC)
345
-        surface_alignment = 128;
346
-    else
347
-        surface_alignment = 16;
348
-
349
-    /* 4 base work surfaces */
350
-    num_surfaces = 4;
351
-
352
-    /* add surfaces based on number of possible refs */
353
-    if (s->codec_id == AV_CODEC_ID_H264 || s->codec_id == AV_CODEC_ID_HEVC)
354
-        num_surfaces += 16;
355
-    else if (s->codec_id == AV_CODEC_ID_VP9)
356
-        num_surfaces += 8;
357
-    else
358
-        num_surfaces += 2;
359
-
360
-    /* add extra surfaces for frame threading */
361
-    if (s->active_thread_type & FF_THREAD_FRAME)
362
-        num_surfaces += s->thread_count;
363
-
364
-    ctx->hw_frames_ctx = av_hwframe_ctx_alloc(ctx->hw_device_ctx);
365
-    if (!ctx->hw_frames_ctx)
366
-        goto fail;
367
-    frames_ctx   = (AVHWFramesContext*)ctx->hw_frames_ctx->data;
368
-    frames_hwctx = frames_ctx->hwctx;
369
-
370
-    frames_ctx->format            = AV_PIX_FMT_DXVA2_VLD;
371
-    frames_ctx->sw_format         = (target_format == MKTAG('P','0','1','0') ? AV_PIX_FMT_P010 : AV_PIX_FMT_NV12);
372
-    frames_ctx->width             = FFALIGN(s->coded_width, surface_alignment);
373
-    frames_ctx->height            = FFALIGN(s->coded_height, surface_alignment);
374
-    frames_ctx->initial_pool_size = num_surfaces;
375
-
376
-    frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
377
-
378
-    ret = av_hwframe_ctx_init(ctx->hw_frames_ctx);
379
-    if (ret < 0) {
380
-        av_log(NULL, loglevel, "Failed to initialize the HW frames context\n");
381
-        goto fail;
382
-    }
383
-
384
-    hr = IDirectXVideoDecoderService_CreateVideoDecoder(ctx->decoder_service, &device_guid,
385
-                                                        &desc, &config, frames_hwctx->surfaces,
386
-                                                        frames_hwctx->nb_surfaces, &frames_hwctx->decoder_to_release);
387
-    if (FAILED(hr)) {
388
-        av_log(NULL, loglevel, "Failed to create DXVA2 video decoder\n");
389
-        goto fail;
390
-    }
391
-
392
-    ctx->decoder_guid   = device_guid;
393
-    ctx->decoder_config = config;
394
-
395
-    dxva_ctx->cfg           = &ctx->decoder_config;
396
-    dxva_ctx->decoder       = frames_hwctx->decoder_to_release;
397
-    dxva_ctx->surface       = frames_hwctx->surfaces;
398
-    dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
399
-
400
-    if (IsEqualGUID(&ctx->decoder_guid, &DXVADDI_Intel_ModeH264_E))
401
-        dxva_ctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
402
-
403
-    return 0;
404
-fail:
405
-    av_buffer_unref(&ctx->hw_frames_ctx);
406
-    return AVERROR(EINVAL);
407
-}
408
-
409
-int dxva2_init(AVCodecContext *s)
410
-{
411
-    InputStream *ist = s->opaque;
412
-    int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
413
-    DXVA2Context *ctx;
414
-    int ret;
415
-
416
-    if (!ist->hwaccel_ctx) {
417
-        ret = dxva2_alloc(s);
418
-        if (ret < 0)
419
-            return ret;
420
-    }
421
-    ctx = ist->hwaccel_ctx;
422
-
423
-    if (s->codec_id == AV_CODEC_ID_H264 &&
424
-        (s->profile & ~FF_PROFILE_H264_CONSTRAINED) > FF_PROFILE_H264_HIGH) {
425
-        av_log(NULL, loglevel, "Unsupported H.264 profile for DXVA2 HWAccel: %d\n", s->profile);
426
-        return AVERROR(EINVAL);
427
-    }
428
-
429
-    if (s->codec_id == AV_CODEC_ID_HEVC &&
430
-        s->profile != FF_PROFILE_HEVC_MAIN && s->profile != FF_PROFILE_HEVC_MAIN_10) {
431
-        av_log(NULL, loglevel, "Unsupported HEVC profile for DXVA2 HWAccel: %d\n", s->profile);
432
-        return AVERROR(EINVAL);
433
-    }
434
-
435
-    av_buffer_unref(&ctx->hw_frames_ctx);
436
-
437
-    ret = dxva2_create_decoder(s);
438
-    if (ret < 0) {
439
-        av_log(NULL, loglevel, "Error creating the DXVA2 decoder\n");
440
-        return ret;
441
-    }
442
-
443
-    return 0;
444
-}
... ...
@@ -70,9 +70,13 @@ const HWAccel hwaccels[] = {
70 70
     { "vdpau", hwaccel_decode_init, HWACCEL_VDPAU, AV_PIX_FMT_VDPAU,
71 71
       AV_HWDEVICE_TYPE_VDPAU },
72 72
 #endif
73
-#if HAVE_DXVA2_LIB
74
-    { "dxva2", dxva2_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD,
75
-      AV_HWDEVICE_TYPE_NONE },
73
+#if CONFIG_D3D11VA
74
+    { "d3d11va", hwaccel_decode_init, HWACCEL_D3D11VA, AV_PIX_FMT_D3D11,
75
+      AV_HWDEVICE_TYPE_D3D11VA },
76
+#endif
77
+#if CONFIG_DXVA2
78
+    { "dxva2", hwaccel_decode_init, HWACCEL_DXVA2, AV_PIX_FMT_DXVA2_VLD,
79
+      AV_HWDEVICE_TYPE_DXVA2 },
76 80
 #endif
77 81
 #if CONFIG_VDA
78 82
     { "vda",   videotoolbox_init,   HWACCEL_VDA,   AV_PIX_FMT_VDA,
... ...
@@ -66,6 +66,7 @@ static void register_all(void)
66 66
     REGISTER_HWACCEL(H263_VIDEOTOOLBOX, h263_videotoolbox);
67 67
     REGISTER_HWACCEL(H264_CUVID,        h264_cuvid);
68 68
     REGISTER_HWACCEL(H264_D3D11VA,      h264_d3d11va);
69
+    REGISTER_HWACCEL(H264_D3D11VA2,     h264_d3d11va2);
69 70
     REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
70 71
     REGISTER_HWACCEL(H264_MEDIACODEC,   h264_mediacodec);
71 72
     REGISTER_HWACCEL(H264_MMAL,         h264_mmal);
... ...
@@ -77,6 +78,7 @@ static void register_all(void)
77 77
     REGISTER_HWACCEL(H264_VIDEOTOOLBOX, h264_videotoolbox);
78 78
     REGISTER_HWACCEL(HEVC_CUVID,        hevc_cuvid);
79 79
     REGISTER_HWACCEL(HEVC_D3D11VA,      hevc_d3d11va);
80
+    REGISTER_HWACCEL(HEVC_D3D11VA2,     hevc_d3d11va2);
80 81
     REGISTER_HWACCEL(HEVC_DXVA2,        hevc_dxva2);
81 82
     REGISTER_HWACCEL(HEVC_MEDIACODEC,   hevc_mediacodec);
82 83
     REGISTER_HWACCEL(HEVC_QSV,          hevc_qsv);
... ...
@@ -90,6 +92,7 @@ static void register_all(void)
90 90
     REGISTER_HWACCEL(MPEG2_CUVID,       mpeg2_cuvid);
91 91
     REGISTER_HWACCEL(MPEG2_XVMC,        mpeg2_xvmc);
92 92
     REGISTER_HWACCEL(MPEG2_D3D11VA,     mpeg2_d3d11va);
93
+    REGISTER_HWACCEL(MPEG2_D3D11VA2,    mpeg2_d3d11va2);
93 94
     REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
94 95
     REGISTER_HWACCEL(MPEG2_MMAL,        mpeg2_mmal);
95 96
     REGISTER_HWACCEL(MPEG2_QSV,         mpeg2_qsv);
... ...
@@ -105,6 +108,7 @@ static void register_all(void)
105 105
     REGISTER_HWACCEL(MPEG4_VIDEOTOOLBOX, mpeg4_videotoolbox);
106 106
     REGISTER_HWACCEL(VC1_CUVID,         vc1_cuvid);
107 107
     REGISTER_HWACCEL(VC1_D3D11VA,       vc1_d3d11va);
108
+    REGISTER_HWACCEL(VC1_D3D11VA2,      vc1_d3d11va2);
108 109
     REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
109 110
     REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
110 111
     REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
... ...
@@ -115,10 +119,12 @@ static void register_all(void)
115 115
     REGISTER_HWACCEL(VP8_QSV,           vp8_qsv);
116 116
     REGISTER_HWACCEL(VP9_CUVID,         vp9_cuvid);
117 117
     REGISTER_HWACCEL(VP9_D3D11VA,       vp9_d3d11va);
118
+    REGISTER_HWACCEL(VP9_D3D11VA2,      vp9_d3d11va2);
118 119
     REGISTER_HWACCEL(VP9_DXVA2,         vp9_dxva2);
119 120
     REGISTER_HWACCEL(VP9_MEDIACODEC,    vp9_mediacodec);
120 121
     REGISTER_HWACCEL(VP9_VAAPI,         vp9_vaapi);
121 122
     REGISTER_HWACCEL(WMV3_D3D11VA,      wmv3_d3d11va);
123
+    REGISTER_HWACCEL(WMV3_D3D11VA2,     wmv3_d3d11va2);
122 124
     REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
123 125
     REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
124 126
     REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);
... ...
@@ -22,20 +22,450 @@
22 22
 
23 23
 #include <assert.h>
24 24
 #include <string.h>
25
+#include <initguid.h>
25 26
 
27
+#include "libavutil/common.h"
26 28
 #include "libavutil/log.h"
27 29
 #include "libavutil/time.h"
28 30
 
29 31
 #include "avcodec.h"
30 32
 #include "dxva2_internal.h"
31 33
 
34
+/* define all the GUIDs used directly here,
35
+ to avoid problems with inconsistent dxva2api.h versions in mingw-w64 and different MSVC version */
36
+DEFINE_GUID(ff_DXVA2_ModeMPEG2_VLD,      0xee27417f, 0x5e28,0x4e65,0xbe,0xea,0x1d,0x26,0xb5,0x08,0xad,0xc9);
37
+DEFINE_GUID(ff_DXVA2_ModeMPEG2and1_VLD,  0x86695f12, 0x340e,0x4f04,0x9f,0xd3,0x92,0x53,0xdd,0x32,0x74,0x60);
38
+DEFINE_GUID(ff_DXVA2_ModeH264_E,         0x1b81be68, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
39
+DEFINE_GUID(ff_DXVA2_ModeH264_F,         0x1b81be69, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
40
+DEFINE_GUID(ff_DXVADDI_Intel_ModeH264_E, 0x604F8E68, 0x4951,0x4C54,0x88,0xFE,0xAB,0xD2,0x5C,0x15,0xB3,0xD6);
41
+DEFINE_GUID(ff_DXVA2_ModeVC1_D,          0x1b81beA3, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
42
+DEFINE_GUID(ff_DXVA2_ModeVC1_D2010,      0x1b81beA4, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
43
+DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main,  0x5b11d51b, 0x2f4c,0x4452,0xbc,0xc3,0x09,0xf2,0xa1,0x16,0x0c,0xc0);
44
+DEFINE_GUID(ff_DXVA2_ModeHEVC_VLD_Main10,0x107af0e0, 0xef1a,0x4d19,0xab,0xa8,0x67,0xa1,0x63,0x07,0x3d,0x13);
45
+DEFINE_GUID(ff_DXVA2_ModeVP9_VLD_Profile0,0x463707f8,0xa1d0,0x4585,0x87,0x6d,0x83,0xaa,0x6d,0x60,0xb8,0x9e);
46
+DEFINE_GUID(ff_DXVA2_NoEncrypt,          0x1b81beD0, 0xa0c7,0x11d3,0xb9,0x84,0x00,0xc0,0x4f,0x2e,0x73,0xc5);
47
+DEFINE_GUID(ff_GUID_NULL,                0x00000000, 0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00);
48
+DEFINE_GUID(ff_IID_IDirectXVideoDecoderService, 0xfc51a551,0xd5e7,0x11d9,0xaf,0x55,0x00,0x05,0x4e,0x43,0xff,0x02);
49
+
50
+typedef struct dxva_mode {
51
+    const GUID     *guid;
52
+    enum AVCodecID codec;
53
+} dxva_mode;
54
+
55
+static const dxva_mode dxva_modes[] = {
56
+    /* MPEG-2 */
57
+    { &ff_DXVA2_ModeMPEG2_VLD,       AV_CODEC_ID_MPEG2VIDEO },
58
+    { &ff_DXVA2_ModeMPEG2and1_VLD,   AV_CODEC_ID_MPEG2VIDEO },
59
+
60
+    /* H.264 */
61
+    { &ff_DXVA2_ModeH264_F,          AV_CODEC_ID_H264 },
62
+    { &ff_DXVA2_ModeH264_E,          AV_CODEC_ID_H264 },
63
+    /* Intel specific H.264 mode */
64
+    { &ff_DXVADDI_Intel_ModeH264_E,  AV_CODEC_ID_H264 },
65
+
66
+    /* VC-1 / WMV3 */
67
+    { &ff_DXVA2_ModeVC1_D2010,       AV_CODEC_ID_VC1 },
68
+    { &ff_DXVA2_ModeVC1_D2010,       AV_CODEC_ID_WMV3 },
69
+    { &ff_DXVA2_ModeVC1_D,           AV_CODEC_ID_VC1 },
70
+    { &ff_DXVA2_ModeVC1_D,           AV_CODEC_ID_WMV3 },
71
+
72
+    /* HEVC/H.265 */
73
+    { &ff_DXVA2_ModeHEVC_VLD_Main,   AV_CODEC_ID_HEVC },
74
+    { &ff_DXVA2_ModeHEVC_VLD_Main10, AV_CODEC_ID_HEVC },
75
+
76
+    /* VP8/9 */
77
+    { &ff_DXVA2_ModeVP9_VLD_Profile0,AV_CODEC_ID_VP9 },
78
+
79
+    { NULL,                          0 },
80
+};
81
+
82
+static int dxva_get_decoder_configuration(AVCodecContext *avctx,
83
+                                          const void *cfg_list,
84
+                                          unsigned cfg_count)
85
+{
86
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
87
+    unsigned i, best_score = 0;
88
+    int best_cfg = -1;
89
+
90
+    for (i = 0; i < cfg_count; i++) {
91
+        unsigned score;
92
+        UINT ConfigBitstreamRaw;
93
+        GUID guidConfigBitstreamEncryption;
94
+
95
+#if CONFIG_D3D11VA
96
+        if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
97
+            D3D11_VIDEO_DECODER_CONFIG *cfg = &((D3D11_VIDEO_DECODER_CONFIG *)cfg_list)[i];
98
+            ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
99
+            guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
100
+        }
101
+#endif
102
+#if CONFIG_DXVA2
103
+        if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
104
+            DXVA2_ConfigPictureDecode *cfg = &((DXVA2_ConfigPictureDecode *)cfg_list)[i];
105
+            ConfigBitstreamRaw = cfg->ConfigBitstreamRaw;
106
+            guidConfigBitstreamEncryption = cfg->guidConfigBitstreamEncryption;
107
+        }
108
+#endif
109
+
110
+        if (ConfigBitstreamRaw == 1)
111
+            score = 1;
112
+        else if (avctx->codec_id == AV_CODEC_ID_H264 && ConfigBitstreamRaw == 2)
113
+            score = 2;
114
+        else
115
+            continue;
116
+        if (IsEqualGUID(&guidConfigBitstreamEncryption, &ff_DXVA2_NoEncrypt))
117
+            score += 16;
118
+        if (score > best_score) {
119
+            best_score = score;
120
+            best_cfg = i;
121
+        }
122
+    }
123
+
124
+    if (!best_score) {
125
+        av_log(avctx, AV_LOG_VERBOSE, "No valid decoder configuration available\n");
126
+        return AVERROR(EINVAL);
127
+    }
128
+
129
+    return best_cfg;
130
+}
131
+
132
+#if CONFIG_D3D11VA
133
+static int d3d11va_validate_output(void *service, GUID guid, const void *surface_format)
134
+{
135
+    HRESULT hr;
136
+    BOOL is_supported = FALSE;
137
+    hr = ID3D11VideoDevice_CheckVideoDecoderFormat((ID3D11VideoDevice *)service,
138
+                                                   &guid,
139
+                                                   *(DXGI_FORMAT *)surface_format,
140
+                                                   &is_supported);
141
+    return SUCCEEDED(hr) && is_supported;
142
+}
143
+#endif
144
+
145
+#if CONFIG_DXVA2
146
+static int dxva2_validate_output(void *decoder_service, GUID guid, const void *surface_format)
147
+{
148
+    HRESULT hr;
149
+    int ret = 0;
150
+    unsigned j, target_count;
151
+    D3DFORMAT *target_list;
152
+    hr = IDirectXVideoDecoderService_GetDecoderRenderTargets((IDirectXVideoDecoderService *)decoder_service, &guid, &target_count, &target_list);
153
+    if (SUCCEEDED(hr)) {
154
+        for (j = 0; j < target_count; j++) {
155
+            const D3DFORMAT format = target_list[j];
156
+            if (format == *(D3DFORMAT *)surface_format) {
157
+                ret = 1;
158
+                break;
159
+            }
160
+        }
161
+        CoTaskMemFree(target_list);
162
+    }
163
+    return ret;
164
+}
165
+#endif
166
+
167
+static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *surface_format,
168
+                                 unsigned guid_count, const GUID *guid_list, GUID *decoder_guid)
169
+{
170
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
171
+    unsigned i, j;
172
+
173
+    *decoder_guid = ff_GUID_NULL;
174
+    for (i = 0; dxva_modes[i].guid; i++) {
175
+        const dxva_mode *mode = &dxva_modes[i];
176
+        int validate;
177
+        if (mode->codec != avctx->codec_id)
178
+            continue;
179
+
180
+        for (j = 0; j < guid_count; j++) {
181
+            if (IsEqualGUID(mode->guid, &guid_list[j]))
182
+                break;
183
+        }
184
+        if (j == guid_count)
185
+            continue;
186
+
187
+#if CONFIG_D3D11VA
188
+        if (sctx->pix_fmt == AV_PIX_FMT_D3D11)
189
+            validate = d3d11va_validate_output(service, *mode->guid, surface_format);
190
+#endif
191
+#if CONFIG_DXVA2
192
+        if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
193
+            validate = dxva2_validate_output(service, *mode->guid, surface_format);
194
+#endif
195
+        if (validate) {
196
+            *decoder_guid = *mode->guid;
197
+            break;
198
+        }
199
+    }
200
+
201
+    if (IsEqualGUID(decoder_guid, &ff_GUID_NULL)) {
202
+        av_log(avctx, AV_LOG_VERBOSE, "No decoder device for codec found\n");
203
+        return AVERROR(EINVAL);
204
+    }
205
+
206
+    if (IsEqualGUID(decoder_guid, &ff_DXVADDI_Intel_ModeH264_E))
207
+        sctx->workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
208
+
209
+    return 0;
210
+}
211
+
212
+static void bufref_free_interface(void *opaque, uint8_t *data)
213
+{
214
+    IUnknown_Release((IUnknown *)opaque);
215
+}
216
+
217
+static AVBufferRef *bufref_wrap_interface(IUnknown *iface)
218
+{
219
+    return av_buffer_create((uint8_t*)iface, 1, bufref_free_interface, iface, 0);
220
+}
221
+
222
+#if CONFIG_DXVA2
223
+
224
+static int dxva2_get_decoder_configuration(AVCodecContext *avctx, const GUID *device_guid,
225
+                                           const DXVA2_VideoDesc *desc,
226
+                                           DXVA2_ConfigPictureDecode *config)
227
+{
228
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
229
+    unsigned cfg_count;
230
+    DXVA2_ConfigPictureDecode *cfg_list;
231
+    HRESULT hr;
232
+    int ret;
233
+
234
+    hr = IDirectXVideoDecoderService_GetDecoderConfigurations(sctx->dxva2_service, device_guid, desc, NULL, &cfg_count, &cfg_list);
235
+    if (FAILED(hr)) {
236
+        av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
237
+        return AVERROR(EINVAL);
238
+    }
239
+
240
+    ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
241
+    if (ret >= 0)
242
+        *config = cfg_list[ret];
243
+    CoTaskMemFree(cfg_list);
244
+    return ret;
245
+}
246
+
247
+static int dxva2_create_decoder(AVCodecContext *avctx)
248
+{
249
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
250
+    GUID *guid_list;
251
+    unsigned guid_count;
252
+    GUID device_guid;
253
+    D3DFORMAT surface_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
254
+                               MKTAG('P', '0', '1', '0') : MKTAG('N', 'V', '1', '2');
255
+    DXVA2_VideoDesc desc = { 0 };
256
+    DXVA2_ConfigPictureDecode config;
257
+    HRESULT hr;
258
+    int ret;
259
+    HANDLE device_handle;
260
+    AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
261
+    AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
262
+    AVDXVA2DeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
263
+
264
+    hr = IDirect3DDeviceManager9_OpenDeviceHandle(device_hwctx->devmgr,
265
+                                                  &device_handle);
266
+    if (FAILED(hr)) {
267
+        av_log(avctx, AV_LOG_ERROR, "Failed to open a device handle\n");
268
+        goto fail;
269
+    }
270
+
271
+    hr = IDirect3DDeviceManager9_GetVideoService(device_hwctx->devmgr, device_handle,
272
+                                                 &ff_IID_IDirectXVideoDecoderService,
273
+                                                 (void **)&sctx->dxva2_service);
274
+    IDirect3DDeviceManager9_CloseDeviceHandle(device_hwctx->devmgr, device_handle);
275
+    if (FAILED(hr)) {
276
+        av_log(avctx, AV_LOG_ERROR, "Failed to create IDirectXVideoDecoderService\n");
277
+        goto fail;
278
+    }
279
+
280
+    hr = IDirectXVideoDecoderService_GetDecoderDeviceGuids(sctx->dxva2_service, &guid_count, &guid_list);
281
+    if (FAILED(hr)) {
282
+        av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder device GUIDs\n");
283
+        goto fail;
284
+    }
285
+
286
+    ret = dxva_get_decoder_guid(avctx, sctx->dxva2_service, &surface_format,
287
+                                guid_count, guid_list, &device_guid);
288
+    CoTaskMemFree(guid_list);
289
+    if (ret < 0) {
290
+        goto fail;
291
+    }
292
+
293
+    desc.SampleWidth  = avctx->coded_width;
294
+    desc.SampleHeight = avctx->coded_height;
295
+    desc.Format       = surface_format;
296
+
297
+    ret = dxva2_get_decoder_configuration(avctx, &device_guid, &desc, &config);
298
+    if (ret < 0) {
299
+        goto fail;
300
+    }
301
+
302
+    hr = IDirectXVideoDecoderService_CreateVideoDecoder(sctx->dxva2_service, &device_guid,
303
+                                                        &desc, &config, frames_hwctx->surfaces,
304
+                                                        frames_hwctx->nb_surfaces, &sctx->dxva2_decoder);
305
+    if (FAILED(hr)) {
306
+        av_log(avctx, AV_LOG_ERROR, "Failed to create DXVA2 video decoder\n");
307
+        goto fail;
308
+    }
309
+
310
+    sctx->dxva2_config = config;
311
+
312
+    sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->dxva2_decoder);
313
+    if (!sctx->decoder_ref)
314
+        return AVERROR(ENOMEM);
315
+
316
+    return 0;
317
+fail:
318
+    return AVERROR(EINVAL);
319
+}
320
+
321
+#endif
322
+
323
+#if CONFIG_D3D11VA
324
+
325
+static int d3d11va_get_decoder_configuration(AVCodecContext *avctx,
326
+                                             ID3D11VideoDevice *video_device,
327
+                                             const D3D11_VIDEO_DECODER_DESC *desc,
328
+                                             D3D11_VIDEO_DECODER_CONFIG *config)
329
+{
330
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
331
+    unsigned cfg_count = 0;
332
+    D3D11_VIDEO_DECODER_CONFIG *cfg_list = NULL;
333
+    HRESULT hr;
334
+    int i, ret;
335
+
336
+    hr = ID3D11VideoDevice_GetVideoDecoderConfigCount(video_device, desc, &cfg_count);
337
+    if (FAILED(hr)) {
338
+        av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations\n");
339
+        return AVERROR(EINVAL);
340
+    }
341
+
342
+    cfg_list = av_malloc_array(cfg_count, sizeof(D3D11_VIDEO_DECODER_CONFIG));
343
+    if (cfg_list == NULL)
344
+        return AVERROR(ENOMEM);
345
+    for (i = 0; i < cfg_count; i++) {
346
+        hr = ID3D11VideoDevice_GetVideoDecoderConfig(video_device, desc, i, &cfg_list[i]);
347
+        if (FAILED(hr)) {
348
+            av_log(avctx, AV_LOG_ERROR, "Unable to retrieve decoder configurations. (hr=0x%lX)\n", hr);
349
+            av_free(cfg_list);
350
+            return AVERROR(EINVAL);
351
+        }
352
+    }
353
+
354
+    ret = dxva_get_decoder_configuration(avctx, cfg_list, cfg_count);
355
+    if (ret >= 0)
356
+        *config = cfg_list[ret];
357
+    av_free(cfg_list);
358
+    return ret;
359
+}
360
+
361
+static int d3d11va_create_decoder(AVCodecContext *avctx)
362
+{
363
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
364
+    GUID *guid_list;
365
+    unsigned guid_count, i;
366
+    GUID decoder_guid;
367
+    DXGI_FORMAT surface_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
368
+                                 DXGI_FORMAT_P010 : DXGI_FORMAT_NV12;
369
+    D3D11_VIDEO_DECODER_DESC desc = { 0 };
370
+    D3D11_VIDEO_DECODER_CONFIG config;
371
+    AVHWFramesContext *frames_ctx = (AVHWFramesContext *)avctx->hw_frames_ctx->data;
372
+    AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
373
+    AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
374
+    D3D11_TEXTURE2D_DESC texdesc;
375
+    HRESULT hr;
376
+    int ret;
377
+
378
+    if (!frames_hwctx->texture) {
379
+        av_log(avctx, AV_LOG_ERROR, "AVD3D11VAFramesContext.texture not set.\n");
380
+        return AVERROR(EINVAL);
381
+    }
382
+    ID3D11Texture2D_GetDesc(frames_hwctx->texture, &texdesc);
383
+
384
+    guid_count = ID3D11VideoDevice_GetVideoDecoderProfileCount(device_hwctx->video_device);
385
+    guid_list = av_malloc_array(guid_count, sizeof(*guid_list));
386
+    if (guid_list == NULL || guid_count == 0) {
387
+        av_log(avctx, AV_LOG_ERROR, "Failed to get the decoder GUIDs\n");
388
+        av_free(guid_list);
389
+        return AVERROR(EINVAL);
390
+    }
391
+    for (i = 0; i < guid_count; i++) {
392
+        hr = ID3D11VideoDevice_GetVideoDecoderProfile(device_hwctx->video_device, i, &guid_list[i]);
393
+        if (FAILED(hr)) {
394
+            av_log(avctx, AV_LOG_ERROR, "Failed to retrieve decoder GUID %d\n", i);
395
+            av_free(guid_list);
396
+            return AVERROR(EINVAL);
397
+        }
398
+    }
399
+
400
+    ret = dxva_get_decoder_guid(avctx, device_hwctx->video_device, &surface_format,
401
+                                guid_count, guid_list, &decoder_guid);
402
+    av_free(guid_list);
403
+    if (ret < 0)
404
+        return AVERROR(EINVAL);
405
+
406
+    desc.SampleWidth  = avctx->coded_width;
407
+    desc.SampleHeight = avctx->coded_height;
408
+    desc.OutputFormat = surface_format;
409
+    desc.Guid         = decoder_guid;
410
+
411
+    ret = d3d11va_get_decoder_configuration(avctx, device_hwctx->video_device, &desc, &config);
412
+    if (ret < 0)
413
+        return AVERROR(EINVAL);
414
+
415
+    sctx->d3d11_views = av_mallocz_array(texdesc.ArraySize, sizeof(sctx->d3d11_views[0]));
416
+    if (!sctx->d3d11_views)
417
+        return AVERROR(ENOMEM);
418
+    sctx->nb_d3d11_views = texdesc.ArraySize;
419
+
420
+    for (i = 0; i < sctx->nb_d3d11_views; i++) {
421
+        D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc = {
422
+            .DecodeProfile = decoder_guid,
423
+            .ViewDimension = D3D11_VDOV_DIMENSION_TEXTURE2D,
424
+            .Texture2D = {
425
+                .ArraySlice = i,
426
+            }
427
+        };
428
+        hr = ID3D11VideoDevice_CreateVideoDecoderOutputView(device_hwctx->video_device,
429
+                                                            (ID3D11Resource*) frames_hwctx->texture,
430
+                                                            &viewDesc,
431
+                                                            (ID3D11VideoDecoderOutputView**) &sctx->d3d11_views[i]);
432
+        if (FAILED(hr)) {
433
+            av_log(avctx, AV_LOG_ERROR, "Could not create the decoder output view %d\n", i);
434
+            return AVERROR_UNKNOWN;
435
+        }
436
+    }
437
+
438
+    hr = ID3D11VideoDevice_CreateVideoDecoder(device_hwctx->video_device, &desc,
439
+                                              &config, &sctx->d3d11_decoder);
440
+    if (FAILED(hr)) {
441
+        av_log(avctx, AV_LOG_ERROR, "Failed to create D3D11VA video decoder\n");
442
+        return AVERROR(EINVAL);
443
+    }
444
+
445
+    sctx->d3d11_config = config;
446
+    sctx->d3d11_texture = frames_hwctx->texture;
447
+
448
+    sctx->decoder_ref = bufref_wrap_interface((IUnknown *)sctx->d3d11_decoder);
449
+    if (!sctx->decoder_ref)
450
+        return AVERROR(ENOMEM);
451
+
452
+    return 0;
453
+}
454
+
455
+#endif
456
+
32 457
 static void ff_dxva2_lock(AVCodecContext *avctx)
33 458
 {
34 459
 #if CONFIG_D3D11VA
35 460
     if (ff_dxva2_is_d3d11(avctx)) {
461
+        FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
36 462
         AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
37 463
         if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
38 464
             WaitForSingleObjectEx(D3D11VA_CONTEXT(ctx)->context_mutex, INFINITE, FALSE);
465
+        if (sctx->device_ctx) {
466
+            AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
467
+            hwctx->lock(hwctx->lock_ctx);
468
+        }
39 469
     }
40 470
 #endif
41 471
 }
... ...
@@ -44,15 +474,218 @@ static void ff_dxva2_unlock(AVCodecContext *avctx)
44 44
 {
45 45
 #if CONFIG_D3D11VA
46 46
     if (ff_dxva2_is_d3d11(avctx)) {
47
+        FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
47 48
         AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
48 49
         if (D3D11VA_CONTEXT(ctx)->context_mutex != INVALID_HANDLE_VALUE)
49 50
             ReleaseMutex(D3D11VA_CONTEXT(ctx)->context_mutex);
51
+        if (sctx->device_ctx) {
52
+            AVD3D11VADeviceContext *hwctx = sctx->device_ctx->hwctx;
53
+            hwctx->unlock(hwctx->lock_ctx);
54
+        }
55
+    }
56
+#endif
57
+}
58
+
59
+// This must work before the decoder is created.
60
+// This somehow needs to be exported to the user.
61
+static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frames_ctx)
62
+{
63
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
64
+    int surface_alignment, num_surfaces;
65
+
66
+    frames_ctx->format = sctx->pix_fmt;
67
+
68
+    /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
69
+    but it causes issues for H.264 on certain AMD GPUs..... */
70
+    if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)
71
+        surface_alignment = 32;
72
+    /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure
73
+    all coding features have enough room to work with */
74
+    else if (avctx->codec_id == AV_CODEC_ID_HEVC)
75
+        surface_alignment = 128;
76
+    else
77
+        surface_alignment = 16;
78
+
79
+    /* 4 base work surfaces */
80
+    num_surfaces = 4;
81
+
82
+    /* add surfaces based on number of possible refs */
83
+    if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)
84
+        num_surfaces += 16;
85
+    else if (avctx->codec_id == AV_CODEC_ID_VP9)
86
+        num_surfaces += 8;
87
+    else
88
+        num_surfaces += 2;
89
+
90
+    /* add extra surfaces for frame threading */
91
+    if (avctx->active_thread_type & FF_THREAD_FRAME)
92
+        num_surfaces += avctx->thread_count;
93
+
94
+    frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?
95
+                            AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;
96
+    frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);
97
+    frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);
98
+    frames_ctx->initial_pool_size = num_surfaces;
99
+
100
+
101
+#if CONFIG_DXVA2
102
+    if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) {
103
+        AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
104
+
105
+        frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;
106
+    }
107
+#endif
108
+
109
+#if CONFIG_D3D11VA
110
+    if (frames_ctx->format == AV_PIX_FMT_D3D11) {
111
+        AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;
112
+
113
+        frames_hwctx->BindFlags |= D3D11_BIND_DECODER;
50 114
     }
51 115
 #endif
52 116
 }
53 117
 
54
-static void *get_surface(const AVFrame *frame)
118
+int ff_dxva2_decode_init(AVCodecContext *avctx)
55 119
 {
120
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
121
+    AVHWFramesContext *frames_ctx = NULL;
122
+    int ret = 0;
123
+
124
+    // Old API.
125
+    if (avctx->hwaccel_context)
126
+        return 0;
127
+
128
+    // (avctx->pix_fmt is not updated yet at this point)
129
+    sctx->pix_fmt = avctx->hwaccel->pix_fmt;
130
+
131
+    if (avctx->codec_id == AV_CODEC_ID_H264 &&
132
+        (avctx->profile & ~FF_PROFILE_H264_CONSTRAINED) > FF_PROFILE_H264_HIGH) {
133
+        av_log(avctx, AV_LOG_VERBOSE, "Unsupported H.264 profile for DXVA HWAccel: %d\n",avctx->profile);
134
+        return AVERROR(ENOTSUP);
135
+    }
136
+
137
+    if (avctx->codec_id == AV_CODEC_ID_HEVC &&
138
+        avctx->profile != FF_PROFILE_HEVC_MAIN && avctx->profile != FF_PROFILE_HEVC_MAIN_10) {
139
+        av_log(avctx, AV_LOG_VERBOSE, "Unsupported HEVC profile for DXVA HWAccel: %d\n", avctx->profile);
140
+        return AVERROR(ENOTSUP);
141
+    }
142
+
143
+    if (!avctx->hw_frames_ctx && !avctx->hw_device_ctx) {
144
+        av_log(avctx, AV_LOG_ERROR, "Either a hw_frames_ctx or a hw_device_ctx needs to be set for hardware decoding.\n");
145
+        return AVERROR(EINVAL);
146
+    }
147
+
148
+    if (avctx->hw_frames_ctx) {
149
+        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
150
+    } else {
151
+        avctx->hw_frames_ctx = av_hwframe_ctx_alloc(avctx->hw_device_ctx);
152
+        if (!avctx->hw_frames_ctx)
153
+            return AVERROR(ENOMEM);
154
+
155
+        frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
156
+
157
+        dxva_adjust_hwframes(avctx, frames_ctx);
158
+
159
+        ret = av_hwframe_ctx_init(avctx->hw_frames_ctx);
160
+        if (ret < 0)
161
+            goto fail;
162
+    }
163
+
164
+    sctx->device_ctx = frames_ctx->device_ctx;
165
+
166
+    if (frames_ctx->format != sctx->pix_fmt ||
167
+        !((sctx->pix_fmt == AV_PIX_FMT_D3D11 && CONFIG_D3D11VA) ||
168
+          (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD && CONFIG_DXVA2))) {
169
+        av_log(avctx, AV_LOG_ERROR, "Invalid pixfmt for hwaccel!\n");
170
+        ret = AVERROR(EINVAL);
171
+        goto fail;
172
+    }
173
+
174
+#if CONFIG_D3D11VA
175
+    if (sctx->pix_fmt == AV_PIX_FMT_D3D11) {
176
+        AVD3D11VADeviceContext *device_hwctx = frames_ctx->device_ctx->hwctx;
177
+        AVD3D11VAContext *d3d11_ctx = &sctx->ctx.d3d11va;
178
+        HRESULT hr;
179
+
180
+        ff_dxva2_lock(avctx);
181
+        ret = d3d11va_create_decoder(avctx);
182
+        ff_dxva2_unlock(avctx);
183
+        if (ret < 0)
184
+            goto fail;
185
+
186
+        d3d11_ctx->decoder       = sctx->d3d11_decoder;
187
+        d3d11_ctx->video_context = device_hwctx->video_context;
188
+        d3d11_ctx->cfg           = &sctx->d3d11_config;
189
+        d3d11_ctx->surface_count = sctx->nb_d3d11_views;
190
+        d3d11_ctx->surface       = sctx->d3d11_views;
191
+        d3d11_ctx->workaround    = sctx->workaround;
192
+        d3d11_ctx->context_mutex = INVALID_HANDLE_VALUE;
193
+    }
194
+#endif
195
+
196
+#if CONFIG_DXVA2
197
+    if (sctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
198
+        AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;
199
+        struct dxva_context *dxva_ctx = &sctx->ctx.dxva2;
200
+
201
+        ff_dxva2_lock(avctx);
202
+        ret = dxva2_create_decoder(avctx);
203
+        ff_dxva2_unlock(avctx);
204
+        if (ret < 0)
205
+            goto fail;
206
+
207
+        dxva_ctx->decoder       = sctx->dxva2_decoder;
208
+        dxva_ctx->cfg           = &sctx->dxva2_config;
209
+        dxva_ctx->surface       = frames_hwctx->surfaces;
210
+        dxva_ctx->surface_count = frames_hwctx->nb_surfaces;
211
+        dxva_ctx->workaround    = sctx->workaround;
212
+    }
213
+#endif
214
+
215
+    return 0;
216
+
217
+fail:
218
+    ff_dxva2_decode_uninit(avctx);
219
+    return ret;
220
+}
221
+
222
+int ff_dxva2_decode_uninit(AVCodecContext *avctx)
223
+{
224
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
225
+    int i;
226
+
227
+    av_buffer_unref(&sctx->decoder_ref);
228
+
229
+#if CONFIG_D3D11VA
230
+    for (i = 0; i < sctx->nb_d3d11_views; i++) {
231
+        if (sctx->d3d11_views[i])
232
+            ID3D11VideoDecoderOutputView_Release(sctx->d3d11_views[i]);
233
+    }
234
+    av_freep(&sctx->d3d11_views);
235
+#endif
236
+
237
+#if CONFIG_DXVA2
238
+    if (sctx->dxva2_service)
239
+        IDirectXVideoDecoderService_Release(sctx->dxva2_service);
240
+#endif
241
+
242
+    return 0;
243
+}
244
+
245
+static void *get_surface(AVCodecContext *avctx, const AVFrame *frame)
246
+{
247
+#if CONFIG_D3D11VA
248
+    if (frame->format == AV_PIX_FMT_D3D11) {
249
+        FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
250
+        intptr_t index = (intptr_t)frame->data[1];
251
+        if (index < 0 || index >= sctx->nb_d3d11_views ||
252
+            sctx->d3d11_texture != (ID3D11Texture2D *)frame->data[0]) {
253
+            av_log(avctx, AV_LOG_ERROR, "get_buffer frame is invalid!\n");
254
+            return NULL;
255
+        }
256
+        return sctx->d3d11_views[index];
257
+    }
258
+#endif
56 259
     return frame->data[3];
57 260
 }
58 261
 
... ...
@@ -60,10 +693,12 @@ unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
60 60
                                     const AVDXVAContext *ctx,
61 61
                                     const AVFrame *frame)
62 62
 {
63
-    void *surface = get_surface(frame);
63
+    void *surface = get_surface(avctx, frame);
64 64
     unsigned i;
65 65
 
66 66
 #if CONFIG_D3D11VA
67
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11)
68
+        return (intptr_t)frame->data[1];
67 69
     if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
68 70
         D3D11_VIDEO_DECODER_OUTPUT_VIEW_DESC viewDesc;
69 71
         ID3D11VideoDecoderOutputView_GetDesc((ID3D11VideoDecoderOutputView*) surface, &viewDesc);
... ...
@@ -154,6 +789,22 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
154 154
     return result;
155 155
 }
156 156
 
157
+static int frame_add_buf(AVFrame *frame, AVBufferRef *ref)
158
+{
159
+    int i;
160
+
161
+    for (i = 0; i < AV_NUM_DATA_POINTERS; i++) {
162
+        if (!frame->buf[i]) {
163
+            frame->buf[i] = av_buffer_ref(ref);
164
+            return frame->buf[i] ? 0 : AVERROR(ENOMEM);
165
+        }
166
+    }
167
+
168
+    // For now we expect that the caller does not use more than
169
+    // AV_NUM_DATA_POINTERS-1 buffers if the user uses a custom pool.
170
+    return AVERROR(EINVAL);
171
+}
172
+
157 173
 int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
158 174
                               const void *pp, unsigned pp_size,
159 175
                               const void *qm, unsigned qm_size,
... ...
@@ -173,19 +824,26 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
173 173
     int result, runs = 0;
174 174
     HRESULT hr;
175 175
     unsigned type;
176
+    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);
177
+
178
+    if (sctx->decoder_ref) {
179
+        result = frame_add_buf(frame, sctx->decoder_ref);
180
+        if (result < 0)
181
+            return result;
182
+    }
176 183
 
177 184
     do {
178 185
         ff_dxva2_lock(avctx);
179 186
 #if CONFIG_D3D11VA
180 187
         if (ff_dxva2_is_d3d11(avctx))
181 188
             hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder,
182
-                                                      get_surface(frame),
189
+                                                      get_surface(avctx, frame),
183 190
                                                       0, NULL);
184 191
 #endif
185 192
 #if CONFIG_DXVA2
186 193
         if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
187 194
             hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
188
-                                                 get_surface(frame),
195
+                                                 get_surface(avctx, frame),
189 196
                                                  NULL);
190 197
 #endif
191 198
         if (hr != E_PENDING || ++runs > 50)
... ...
@@ -315,7 +973,8 @@ end:
315 315
 int ff_dxva2_is_d3d11(const AVCodecContext *avctx)
316 316
 {
317 317
     if (CONFIG_D3D11VA)
318
-        return avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD;
318
+        return avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ||
319
+               avctx->pix_fmt == AV_PIX_FMT_D3D11;
319 320
     else
320 321
         return 0;
321 322
 }
... ...
@@ -523,10 +523,13 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
523 523
     .type           = AVMEDIA_TYPE_VIDEO,
524 524
     .id             = AV_CODEC_ID_H264,
525 525
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
526
+    .init           = ff_dxva2_decode_init,
527
+    .uninit         = ff_dxva2_decode_uninit,
526 528
     .start_frame    = dxva2_h264_start_frame,
527 529
     .decode_slice   = dxva2_h264_decode_slice,
528 530
     .end_frame      = dxva2_h264_end_frame,
529 531
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
532
+    .priv_data_size = sizeof(FFDXVASharedContext),
530 533
 };
531 534
 #endif
532 535
 
... ...
@@ -536,9 +539,28 @@ AVHWAccel ff_h264_d3d11va_hwaccel = {
536 536
     .type           = AVMEDIA_TYPE_VIDEO,
537 537
     .id             = AV_CODEC_ID_H264,
538 538
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
539
+    .init           = ff_dxva2_decode_init,
540
+    .uninit         = ff_dxva2_decode_uninit,
539 541
     .start_frame    = dxva2_h264_start_frame,
540 542
     .decode_slice   = dxva2_h264_decode_slice,
541 543
     .end_frame      = dxva2_h264_end_frame,
542 544
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
545
+    .priv_data_size = sizeof(FFDXVASharedContext),
546
+};
547
+#endif
548
+
549
+#if CONFIG_H264_D3D11VA2_HWACCEL
550
+AVHWAccel ff_h264_d3d11va2_hwaccel = {
551
+    .name           = "h264_d3d11va2",
552
+    .type           = AVMEDIA_TYPE_VIDEO,
553
+    .id             = AV_CODEC_ID_H264,
554
+    .pix_fmt        = AV_PIX_FMT_D3D11,
555
+    .init           = ff_dxva2_decode_init,
556
+    .uninit         = ff_dxva2_decode_uninit,
557
+    .start_frame    = dxva2_h264_start_frame,
558
+    .decode_slice   = dxva2_h264_decode_slice,
559
+    .end_frame      = dxva2_h264_end_frame,
560
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
561
+    .priv_data_size = sizeof(FFDXVASharedContext),
543 562
 };
544 563
 #endif
... ...
@@ -427,10 +427,13 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
427 427
     .type           = AVMEDIA_TYPE_VIDEO,
428 428
     .id             = AV_CODEC_ID_HEVC,
429 429
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
430
+    .init           = ff_dxva2_decode_init,
431
+    .uninit         = ff_dxva2_decode_uninit,
430 432
     .start_frame    = dxva2_hevc_start_frame,
431 433
     .decode_slice   = dxva2_hevc_decode_slice,
432 434
     .end_frame      = dxva2_hevc_end_frame,
433 435
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
436
+    .priv_data_size = sizeof(FFDXVASharedContext),
434 437
 };
435 438
 #endif
436 439
 
... ...
@@ -440,9 +443,28 @@ AVHWAccel ff_hevc_d3d11va_hwaccel = {
440 440
     .type           = AVMEDIA_TYPE_VIDEO,
441 441
     .id             = AV_CODEC_ID_HEVC,
442 442
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
443
+    .init           = ff_dxva2_decode_init,
444
+    .uninit         = ff_dxva2_decode_uninit,
443 445
     .start_frame    = dxva2_hevc_start_frame,
444 446
     .decode_slice   = dxva2_hevc_decode_slice,
445 447
     .end_frame      = dxva2_hevc_end_frame,
446 448
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
449
+    .priv_data_size = sizeof(FFDXVASharedContext),
450
+};
451
+#endif
452
+
453
+#if CONFIG_HEVC_D3D11VA2_HWACCEL
454
+AVHWAccel ff_hevc_d3d11va2_hwaccel = {
455
+    .name           = "hevc_d3d11va2",
456
+    .type           = AVMEDIA_TYPE_VIDEO,
457
+    .id             = AV_CODEC_ID_HEVC,
458
+    .pix_fmt        = AV_PIX_FMT_D3D11,
459
+    .init           = ff_dxva2_decode_init,
460
+    .uninit         = ff_dxva2_decode_uninit,
461
+    .start_frame    = dxva2_hevc_start_frame,
462
+    .decode_slice   = dxva2_hevc_decode_slice,
463
+    .end_frame      = dxva2_hevc_end_frame,
464
+    .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
465
+    .priv_data_size = sizeof(FFDXVASharedContext),
447 466
 };
448 467
 #endif
... ...
@@ -32,9 +32,11 @@
32 32
 
33 33
 #if CONFIG_DXVA2
34 34
 #include "dxva2.h"
35
+#include "libavutil/hwcontext_dxva2.h"
35 36
 #endif
36 37
 #if CONFIG_D3D11VA
37 38
 #include "d3d11va.h"
39
+#include "libavutil/hwcontext_d3d11va.h"
38 40
 #endif
39 41
 #if HAVE_DXVA_H
40 42
 /* When targeting WINAPI_FAMILY_PHONE_APP or WINAPI_FAMILY_APP, dxva.h
... ...
@@ -46,7 +48,10 @@
46 46
 #include <dxva.h>
47 47
 #endif
48 48
 
49
+#include "libavutil/hwcontext.h"
50
+
49 51
 #include "avcodec.h"
52
+#include "internal.h"
50 53
 
51 54
 typedef void DECODER_BUFFER_DESC;
52 55
 
... ...
@@ -59,7 +64,39 @@ typedef union {
59 59
 #endif
60 60
 } AVDXVAContext;
61 61
 
62
-#define DXVA_CONTEXT(avctx) ((AVDXVAContext *)(avctx)->hwaccel_context)
62
+typedef struct FFDXVASharedContext {
63
+    AVBufferRef *decoder_ref;
64
+
65
+    // FF_DXVA2_WORKAROUND_* flags
66
+    uint64_t workaround;
67
+
68
+    // E.g. AV_PIX_FMT_D3D11 (same as AVCodecContext.pix_fmt, except during init)
69
+    enum AVPixelFormat pix_fmt;
70
+
71
+    AVHWDeviceContext *device_ctx;
72
+
73
+#if CONFIG_D3D11VA
74
+    ID3D11VideoDecoder             *d3d11_decoder;
75
+    D3D11_VIDEO_DECODER_CONFIG      d3d11_config;
76
+    ID3D11VideoDecoderOutputView  **d3d11_views;
77
+    int                          nb_d3d11_views;
78
+    ID3D11Texture2D                *d3d11_texture;
79
+#endif
80
+
81
+#if CONFIG_DXVA2
82
+    IDirectXVideoDecoder           *dxva2_decoder;
83
+    IDirectXVideoDecoderService    *dxva2_service;
84
+    DXVA2_ConfigPictureDecode       dxva2_config;
85
+#endif
86
+
87
+    // Legacy (but used by code outside of setup)
88
+    // In generic mode, DXVA_CONTEXT() will return a pointer to this.
89
+    AVDXVAContext ctx;
90
+} FFDXVASharedContext;
91
+
92
+#define DXVA_SHARED_CONTEXT(avctx) ((FFDXVASharedContext *)((avctx)->internal->hwaccel_priv_data))
93
+
94
+#define DXVA_CONTEXT(avctx) (AVDXVAContext *)((avctx)->hwaccel_context ? (avctx)->hwaccel_context : (&(DXVA_SHARED_CONTEXT(avctx)->ctx)))
63 95
 
64 96
 #define D3D11VA_CONTEXT(ctx) (&ctx->d3d11va)
65 97
 #define DXVA2_CONTEXT(ctx)   (&ctx->dxva2)
... ...
@@ -115,6 +152,10 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
115 115
                                                   DECODER_BUFFER_DESC *bs,
116 116
                                                   DECODER_BUFFER_DESC *slice));
117 117
 
118
+int ff_dxva2_decode_init(AVCodecContext *avctx);
119
+
120
+int ff_dxva2_decode_uninit(AVCodecContext *avctx);
121
+
118 122
 int ff_dxva2_is_d3d11(const AVCodecContext *avctx);
119 123
 
120 124
 #endif /* AVCODEC_DXVA2_INTERNAL_H */
... ...
@@ -322,10 +322,13 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
322 322
     .type           = AVMEDIA_TYPE_VIDEO,
323 323
     .id             = AV_CODEC_ID_MPEG2VIDEO,
324 324
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
325
+    .init           = ff_dxva2_decode_init,
326
+    .uninit         = ff_dxva2_decode_uninit,
325 327
     .start_frame    = dxva2_mpeg2_start_frame,
326 328
     .decode_slice   = dxva2_mpeg2_decode_slice,
327 329
     .end_frame      = dxva2_mpeg2_end_frame,
328 330
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
331
+    .priv_data_size = sizeof(FFDXVASharedContext),
329 332
 };
330 333
 #endif
331 334
 
... ...
@@ -335,9 +338,28 @@ AVHWAccel ff_mpeg2_d3d11va_hwaccel = {
335 335
     .type           = AVMEDIA_TYPE_VIDEO,
336 336
     .id             = AV_CODEC_ID_MPEG2VIDEO,
337 337
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
338
+    .init           = ff_dxva2_decode_init,
339
+    .uninit         = ff_dxva2_decode_uninit,
338 340
     .start_frame    = dxva2_mpeg2_start_frame,
339 341
     .decode_slice   = dxva2_mpeg2_decode_slice,
340 342
     .end_frame      = dxva2_mpeg2_end_frame,
341 343
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
344
+    .priv_data_size = sizeof(FFDXVASharedContext),
345
+};
346
+#endif
347
+
348
+#if CONFIG_MPEG2_D3D11VA2_HWACCEL
349
+AVHWAccel ff_mpeg2_d3d11va2_hwaccel = {
350
+    .name           = "mpeg2_d3d11va2",
351
+    .type           = AVMEDIA_TYPE_VIDEO,
352
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
353
+    .pix_fmt        = AV_PIX_FMT_D3D11,
354
+    .init           = ff_dxva2_decode_init,
355
+    .uninit         = ff_dxva2_decode_uninit,
356
+    .start_frame    = dxva2_mpeg2_start_frame,
357
+    .decode_slice   = dxva2_mpeg2_decode_slice,
358
+    .end_frame      = dxva2_mpeg2_end_frame,
359
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
360
+    .priv_data_size = sizeof(FFDXVASharedContext),
342 361
 };
343 362
 #endif
... ...
@@ -383,10 +383,13 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
383 383
     .type           = AVMEDIA_TYPE_VIDEO,
384 384
     .id             = AV_CODEC_ID_WMV3,
385 385
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
386
+    .init           = ff_dxva2_decode_init,
387
+    .uninit         = ff_dxva2_decode_uninit,
386 388
     .start_frame    = dxva2_vc1_start_frame,
387 389
     .decode_slice   = dxva2_vc1_decode_slice,
388 390
     .end_frame      = dxva2_vc1_end_frame,
389 391
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
392
+    .priv_data_size = sizeof(FFDXVASharedContext),
390 393
 };
391 394
 #endif
392 395
 
... ...
@@ -396,10 +399,13 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
396 396
     .type           = AVMEDIA_TYPE_VIDEO,
397 397
     .id             = AV_CODEC_ID_VC1,
398 398
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
399
+    .init           = ff_dxva2_decode_init,
400
+    .uninit         = ff_dxva2_decode_uninit,
399 401
     .start_frame    = dxva2_vc1_start_frame,
400 402
     .decode_slice   = dxva2_vc1_decode_slice,
401 403
     .end_frame      = dxva2_vc1_end_frame,
402 404
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
405
+    .priv_data_size = sizeof(FFDXVASharedContext),
403 406
 };
404 407
 #endif
405 408
 
... ...
@@ -409,10 +415,29 @@ AVHWAccel ff_wmv3_d3d11va_hwaccel = {
409 409
     .type           = AVMEDIA_TYPE_VIDEO,
410 410
     .id             = AV_CODEC_ID_WMV3,
411 411
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
412
+    .init           = ff_dxva2_decode_init,
413
+    .uninit         = ff_dxva2_decode_uninit,
412 414
     .start_frame    = dxva2_vc1_start_frame,
413 415
     .decode_slice   = dxva2_vc1_decode_slice,
414 416
     .end_frame      = dxva2_vc1_end_frame,
415 417
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
418
+    .priv_data_size = sizeof(FFDXVASharedContext),
419
+};
420
+#endif
421
+
422
+#if CONFIG_WMV3_D3D11VA2_HWACCEL
423
+AVHWAccel ff_wmv3_d3d11va2_hwaccel = {
424
+    .name           = "wmv3_d3d11va2",
425
+    .type           = AVMEDIA_TYPE_VIDEO,
426
+    .id             = AV_CODEC_ID_WMV3,
427
+    .pix_fmt        = AV_PIX_FMT_D3D11,
428
+    .init           = ff_dxva2_decode_init,
429
+    .uninit         = ff_dxva2_decode_uninit,
430
+    .start_frame    = dxva2_vc1_start_frame,
431
+    .decode_slice   = dxva2_vc1_decode_slice,
432
+    .end_frame      = dxva2_vc1_end_frame,
433
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
434
+    .priv_data_size = sizeof(FFDXVASharedContext),
416 435
 };
417 436
 #endif
418 437
 
... ...
@@ -422,9 +447,28 @@ AVHWAccel ff_vc1_d3d11va_hwaccel = {
422 422
     .type           = AVMEDIA_TYPE_VIDEO,
423 423
     .id             = AV_CODEC_ID_VC1,
424 424
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
425
+    .init           = ff_dxva2_decode_init,
426
+    .uninit         = ff_dxva2_decode_uninit,
427
+    .start_frame    = dxva2_vc1_start_frame,
428
+    .decode_slice   = dxva2_vc1_decode_slice,
429
+    .end_frame      = dxva2_vc1_end_frame,
430
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
431
+    .priv_data_size = sizeof(FFDXVASharedContext),
432
+};
433
+#endif
434
+
435
+#if CONFIG_VC1_D3D11VA2_HWACCEL
436
+AVHWAccel ff_vc1_d3d11va2_hwaccel = {
437
+    .name           = "vc1_d3d11va2",
438
+    .type           = AVMEDIA_TYPE_VIDEO,
439
+    .id             = AV_CODEC_ID_VC1,
440
+    .pix_fmt        = AV_PIX_FMT_D3D11,
441
+    .init           = ff_dxva2_decode_init,
442
+    .uninit         = ff_dxva2_decode_uninit,
425 443
     .start_frame    = dxva2_vc1_start_frame,
426 444
     .decode_slice   = dxva2_vc1_decode_slice,
427 445
     .end_frame      = dxva2_vc1_end_frame,
428 446
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
447
+    .priv_data_size = sizeof(FFDXVASharedContext),
429 448
 };
430 449
 #endif
... ...
@@ -314,10 +314,13 @@ AVHWAccel ff_vp9_dxva2_hwaccel = {
314 314
     .type           = AVMEDIA_TYPE_VIDEO,
315 315
     .id             = AV_CODEC_ID_VP9,
316 316
     .pix_fmt        = AV_PIX_FMT_DXVA2_VLD,
317
+    .init           = ff_dxva2_decode_init,
318
+    .uninit         = ff_dxva2_decode_uninit,
317 319
     .start_frame    = dxva2_vp9_start_frame,
318 320
     .decode_slice   = dxva2_vp9_decode_slice,
319 321
     .end_frame      = dxva2_vp9_end_frame,
320 322
     .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
323
+    .priv_data_size = sizeof(FFDXVASharedContext),
321 324
 };
322 325
 #endif
323 326
 
... ...
@@ -327,9 +330,28 @@ AVHWAccel ff_vp9_d3d11va_hwaccel = {
327 327
     .type           = AVMEDIA_TYPE_VIDEO,
328 328
     .id             = AV_CODEC_ID_VP9,
329 329
     .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
330
+    .init           = ff_dxva2_decode_init,
331
+    .uninit         = ff_dxva2_decode_uninit,
330 332
     .start_frame    = dxva2_vp9_start_frame,
331 333
     .decode_slice   = dxva2_vp9_decode_slice,
332 334
     .end_frame      = dxva2_vp9_end_frame,
333 335
     .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
336
+    .priv_data_size = sizeof(FFDXVASharedContext),
337
+};
338
+#endif
339
+
340
+#if CONFIG_VP9_D3D11VA2_HWACCEL
341
+AVHWAccel ff_vp9_d3d11va2_hwaccel = {
342
+    .name           = "vp9_d3d11va2",
343
+    .type           = AVMEDIA_TYPE_VIDEO,
344
+    .id             = AV_CODEC_ID_VP9,
345
+    .pix_fmt        = AV_PIX_FMT_D3D11,
346
+    .init           = ff_dxva2_decode_init,
347
+    .uninit         = ff_dxva2_decode_uninit,
348
+    .start_frame    = dxva2_vp9_start_frame,
349
+    .decode_slice   = dxva2_vp9_decode_slice,
350
+    .end_frame      = dxva2_vp9_end_frame,
351
+    .frame_priv_data_size = sizeof(struct vp9_dxva2_picture_context),
352
+    .priv_data_size = sizeof(FFDXVASharedContext),
334 353
 };
335 354
 #endif
... ...
@@ -758,7 +758,7 @@ static void init_scan_tables(H264Context *h)
758 758
 static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
759 759
 {
760 760
 #define HWACCEL_MAX (CONFIG_H264_DXVA2_HWACCEL + \
761
-                     CONFIG_H264_D3D11VA_HWACCEL + \
761
+                     (CONFIG_H264_D3D11VA_HWACCEL * 2) + \
762 762
                      CONFIG_H264_VAAPI_HWACCEL + \
763 763
                      (CONFIG_H264_VDA_HWACCEL * 2) + \
764 764
                      CONFIG_H264_VIDEOTOOLBOX_HWACCEL + \
... ...
@@ -834,6 +834,7 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
834 834
 #endif
835 835
 #if CONFIG_H264_D3D11VA_HWACCEL
836 836
             *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
837
+            *fmt++ = AV_PIX_FMT_D3D11;
837 838
 #endif
838 839
 #if CONFIG_H264_VAAPI_HWACCEL
839 840
             *fmt++ = AV_PIX_FMT_VAAPI;
... ...
@@ -339,7 +339,7 @@ static void export_stream_params(AVCodecContext *avctx, const HEVCParamSets *ps,
339 339
 
340 340
 static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
341 341
 {
342
-    #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL + CONFIG_HEVC_VAAPI_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL)
342
+    #define HWACCEL_MAX (CONFIG_HEVC_DXVA2_HWACCEL + CONFIG_HEVC_D3D11VA_HWACCEL * 2 + CONFIG_HEVC_VAAPI_HWACCEL + CONFIG_HEVC_VDPAU_HWACCEL)
343 343
     enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmt = pix_fmts;
344 344
 
345 345
     switch (sps->pix_fmt) {
... ...
@@ -350,6 +350,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
350 350
 #endif
351 351
 #if CONFIG_HEVC_D3D11VA_HWACCEL
352 352
         *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
353
+        *fmt++ = AV_PIX_FMT_D3D11;
353 354
 #endif
354 355
 #if CONFIG_HEVC_VAAPI_HWACCEL
355 356
         *fmt++ = AV_PIX_FMT_VAAPI;
... ...
@@ -364,6 +365,7 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
364 364
 #endif
365 365
 #if CONFIG_HEVC_D3D11VA_HWACCEL
366 366
         *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
367
+        *fmt++ = AV_PIX_FMT_D3D11;
367 368
 #endif
368 369
 #if CONFIG_HEVC_VAAPI_HWACCEL
369 370
         *fmt++ = AV_PIX_FMT_VAAPI;
... ...
@@ -1159,6 +1159,7 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
1159 1159
 #endif
1160 1160
 #if CONFIG_MPEG2_D3D11VA_HWACCEL
1161 1161
     AV_PIX_FMT_D3D11VA_VLD,
1162
+    AV_PIX_FMT_D3D11,
1162 1163
 #endif
1163 1164
 #if CONFIG_MPEG2_VAAPI_HWACCEL
1164 1165
     AV_PIX_FMT_VAAPI,
... ...
@@ -1150,6 +1150,7 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
1150 1150
 #endif
1151 1151
 #if CONFIG_VC1_D3D11VA_HWACCEL
1152 1152
     AV_PIX_FMT_D3D11VA_VLD,
1153
+    AV_PIX_FMT_D3D11,
1153 1154
 #endif
1154 1155
 #if CONFIG_VC1_VAAPI_HWACCEL
1155 1156
     AV_PIX_FMT_VAAPI,
... ...
@@ -28,7 +28,7 @@
28 28
 #include "libavutil/version.h"
29 29
 
30 30
 #define LIBAVCODEC_VERSION_MAJOR  57
31
-#define LIBAVCODEC_VERSION_MINOR  99
31
+#define LIBAVCODEC_VERSION_MINOR 100
32 32
 #define LIBAVCODEC_VERSION_MICRO 102
33 33
 
34 34
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -113,7 +113,7 @@ fail:
113 113
 
114 114
 static int update_size(AVCodecContext *avctx, int w, int h)
115 115
 {
116
-#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL + CONFIG_VP9_VAAPI_HWACCEL)
116
+#define HWACCEL_MAX (CONFIG_VP9_DXVA2_HWACCEL + CONFIG_VP9_D3D11VA_HWACCEL * 2 + CONFIG_VP9_VAAPI_HWACCEL)
117 117
     enum AVPixelFormat pix_fmts[HWACCEL_MAX + 2], *fmtp = pix_fmts;
118 118
     VP9Context *s = avctx->priv_data;
119 119
     uint8_t *p;
... ...
@@ -132,6 +132,7 @@ static int update_size(AVCodecContext *avctx, int w, int h)
132 132
 #endif
133 133
 #if CONFIG_VP9_D3D11VA_HWACCEL
134 134
             *fmtp++ = AV_PIX_FMT_D3D11VA_VLD;
135
+            *fmtp++ = AV_PIX_FMT_D3D11;
135 136
 #endif
136 137
 #if CONFIG_VP9_VAAPI_HWACCEL
137 138
             *fmtp++ = AV_PIX_FMT_VAAPI;
... ...
@@ -65,6 +65,9 @@ typedef struct AVDXVA2FramesContext {
65 65
      *
66 66
      * If it is non-NULL, libavutil will call IDirectXVideoDecoder_Release() on
67 67
      * it just before the internal surface pool is freed.
68
+     *
69
+     * This is for convenience only. Some code uses other methods to manage the
70
+     * decoder reference.
68 71
      */
69 72
     IDirectXVideoDecoder *decoder_to_release;
70 73
 } AVDXVA2FramesContext;