Browse code

Merge commit 'd8039ef8d221ea273aa4f1e62e5df21bf618c772'

* commit 'd8039ef8d221ea273aa4f1e62e5df21bf618c772':
D3D11va: add a Direct3D11 video decoder similar to DXVA2

Conflicts:
Changelog
configure
libavcodec/Makefile
libavcodec/allcodecs.c
libavcodec/dxva2_vc1.c
libavcodec/version.h
libavutil/pixdesc.c
libavutil/pixfmt.h
libavutil/version.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2015/05/26 05:02:00
Showing 19 changed files
... ...
@@ -22,6 +22,7 @@ version <next>:
22 22
 - improved Quickdraw compatibility
23 23
 - VP9 high bit-depth and extended colorspaces decoding support
24 24
 - WebPAnimEncoder API when available for encoding and muxing WebP
25
+- Direct3D11-accelerated decoding
25 26
 
26 27
 
27 28
 version 2.6:
... ...
@@ -149,6 +149,7 @@ Component options:
149 149
   --disable-pixelutils     disable pixel utils in libavutil
150 150
 
151 151
 Hardware accelerators:
152
+  --enable-d3d11va         enable D3D11VA code
152 153
   --disable-dxva2          disable DXVA2 code [autodetect]
153 154
   --disable-vaapi          disable VAAPI code [autodetect]
154 155
   --disable-vda            disable VDA code [autodetect]
... ...
@@ -1448,6 +1449,7 @@ FEATURE_LIST="
1448 1448
 "
1449 1449
 
1450 1450
 HWACCEL_LIST="
1451
+    d3d11va
1451 1452
     dxva2
1452 1453
     vaapi
1453 1454
     vda
... ...
@@ -1670,6 +1672,7 @@ HEADERS_LIST="
1670 1670
     dev_video_meteor_ioctl_meteor_h
1671 1671
     direct_h
1672 1672
     dlfcn_h
1673
+    d3d11_h
1673 1674
     dxva_h
1674 1675
     ES2_gl_h
1675 1676
     gsm_h
... ...
@@ -1845,6 +1848,8 @@ HAVE_LIST="
1845 1845
     $TYPES_LIST
1846 1846
     atomics_native
1847 1847
     dos_paths
1848
+    d3d11_cobj
1849
+    d3d11va_lib
1848 1850
     dxva2api_cobj
1849 1851
     dxva2_lib
1850 1852
     libc_msvcrt
... ...
@@ -2314,6 +2319,7 @@ zmbv_encoder_select="zlib"
2314 2314
 
2315 2315
 # hardware accelerators
2316 2316
 crystalhd_deps="libcrystalhd_libcrystalhd_if_h"
2317
+d3d11va_deps="d3d11_h dxva_h"
2317 2318
 dxva2_deps="dxva2api_h"
2318 2319
 vaapi_deps="va_va_h"
2319 2320
 vda_deps="VideoDecodeAcceleration_VDADecoder_h pthreads"
... ...
@@ -2326,6 +2332,8 @@ h263_vaapi_hwaccel_select="h263_decoder"
2326 2326
 h263_vdpau_hwaccel_deps="vdpau"
2327 2327
 h263_vdpau_hwaccel_select="h263_decoder"
2328 2328
 h264_crystalhd_decoder_select="crystalhd h264_mp4toannexb_bsf h264_parser"
2329
+h264_d3d11va_hwaccel_deps="d3d11va"
2330
+h264_d3d11va_hwaccel_select="h264_decoder"
2329 2331
 h264_dxva2_hwaccel_deps="dxva2"
2330 2332
 h264_dxva2_hwaccel_select="h264_decoder"
2331 2333
 h264_mmal_decoder_deps="mmal"
... ...
@@ -2345,6 +2353,8 @@ h264_vdpau_decoder_deps="vdpau"
2345 2345
 h264_vdpau_decoder_select="h264_decoder"
2346 2346
 h264_vdpau_hwaccel_deps="vdpau"
2347 2347
 h264_vdpau_hwaccel_select="h264_decoder"
2348
+hevc_d3d11va_hwaccel_deps="d3d11va DXVA_PicParams_HEVC"
2349
+hevc_d3d11va_hwaccel_select="hevc_decoder"
2348 2350
 hevc_dxva2_hwaccel_deps="dxva2 DXVA_PicParams_HEVC"
2349 2351
 hevc_dxva2_hwaccel_select="hevc_decoder"
2350 2352
 mpeg_vdpau_decoder_deps="vdpau"
... ...
@@ -2358,6 +2368,8 @@ mpeg1_vdpau_hwaccel_select="mpeg1video_decoder"
2358 2358
 mpeg1_xvmc_hwaccel_deps="xvmc"
2359 2359
 mpeg1_xvmc_hwaccel_select="mpeg1video_decoder"
2360 2360
 mpeg2_crystalhd_decoder_select="crystalhd"
2361
+mpeg2_d3d11va_hwaccel_deps="d3d11va"
2362
+mpeg2_d3d11va_hwaccel_select="mpeg2video_decoder"
2361 2363
 mpeg2_dxva2_hwaccel_deps="dxva2"
2362 2364
 mpeg2_dxva2_hwaccel_select="mpeg2video_decoder"
2363 2365
 mpeg2_vaapi_hwaccel_deps="vaapi"
... ...
@@ -2375,6 +2387,8 @@ mpeg4_vdpau_hwaccel_deps="vdpau"
2375 2375
 mpeg4_vdpau_hwaccel_select="mpeg4_decoder"
2376 2376
 msmpeg4_crystalhd_decoder_select="crystalhd"
2377 2377
 vc1_crystalhd_decoder_select="crystalhd"
2378
+vc1_d3d11va_hwaccel_deps="d3d11va"
2379
+vc1_d3d11va_hwaccel_select="vc1_decoder"
2378 2380
 vc1_dxva2_hwaccel_deps="dxva2"
2379 2381
 vc1_dxva2_hwaccel_select="vc1_decoder"
2380 2382
 vc1_vaapi_hwaccel_deps="vaapi"
... ...
@@ -2384,6 +2398,7 @@ vc1_vdpau_decoder_select="vc1_decoder"
2384 2384
 vc1_vdpau_hwaccel_deps="vdpau"
2385 2385
 vc1_vdpau_hwaccel_select="vc1_decoder"
2386 2386
 wmv3_crystalhd_decoder_select="crystalhd"
2387
+wmv3_d3d11va_hwaccel_select="vc1_d3d11va_hwaccel"
2387 2388
 wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel"
2388 2389
 wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
2389 2390
 wmv3_vdpau_decoder_select="vc1_vdpau_decoder"
... ...
@@ -2814,7 +2829,7 @@ sws_max_filter_size_default=256
2814 2814
 set_default sws_max_filter_size
2815 2815
 
2816 2816
 # Enable hwaccels by default.
2817
-enable dxva2 vaapi vda vdpau xvmc
2817
+enable d3d11va dxva2 vaapi vda vdpau xvmc
2818 2818
 enable xlib
2819 2819
 
2820 2820
 # build settings
... ...
@@ -4945,6 +4960,7 @@ enabled xlib &&
4945 4945
 
4946 4946
 check_header direct.h
4947 4947
 check_header dlfcn.h
4948
+check_header d3d11.h
4948 4949
 check_header dxva.h
4949 4950
 check_header dxva2api.h -D_WIN32_WINNT=0x0600
4950 4951
 check_header io.h
... ...
@@ -5293,6 +5309,15 @@ enabled dxva2api_h &&
5293 5293
 int main(void) { IDirectXVideoDecoder *o = NULL; IDirectXVideoDecoder_Release(o); return 0; }
5294 5294
 EOF
5295 5295
 
5296
+enabled d3d11_h &&
5297
+    check_cc <<EOF && enable d3d11_cobj
5298
+#define _WIN32_WINNT 0x0600
5299
+#define COBJMACROS
5300
+#include <windows.h>
5301
+#include <d3d11.h>
5302
+int main(void) { ID3D11VideoDecoder *o = NULL; ID3D11VideoDecoder_Release(o); return 0; }
5303
+EOF
5304
+
5296 5305
 enabled vaapi &&
5297 5306
     check_lib va/va.h vaInitialize -lva ||
5298 5307
     disable vaapi
... ...
@@ -5550,6 +5575,10 @@ if test $target_os = "haiku"; then
5550 5550
     disable posix_memalign
5551 5551
 fi
5552 5552
 
5553
+enabled_all d3d11va d3d11_cobj CoTaskMemFree &&
5554
+    prepend ffmpeg_libs $($ldflags_filter "-lole32") &&
5555
+    enable d3d11va_lib
5556
+
5553 5557
 enabled_all dxva2 dxva2api_cobj CoTaskMemFree &&
5554 5558
     prepend ffmpeg_libs $($ldflags_filter "-lole32" "-luser32") &&
5555 5559
     enable dxva2_lib
... ...
@@ -5,6 +5,7 @@ NAME = avcodec
5 5
 HEADERS = avcodec.h                                                     \
6 6
           avfft.h                                                       \
7 7
           dv_profile.h                                                  \
8
+          d3d11va.h                                                     \
8 9
           dxva2.h                                                       \
9 10
           old_codec_ids.h                                               \
10 11
           qsv.h                                                         \
... ...
@@ -671,6 +672,7 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER)       += adpcmenc.o adpcm_data.o
671 671
 OBJS-$(CONFIG_VIMA_DECODER)               += vima.o adpcm_data.o
672 672
 
673 673
 # hardware accelerators
674
+OBJS-$(CONFIG_D3D11VA)                    += dxva2.o
674 675
 OBJS-$(CONFIG_DXVA2)                      += dxva2.o
675 676
 OBJS-$(CONFIG_VAAPI)                      += vaapi.o
676 677
 OBJS-$(CONFIG_VDA)                        += vda.o
... ...
@@ -678,19 +680,23 @@ OBJS-$(CONFIG_VDPAU)                      += vdpau.o
678 678
 
679 679
 OBJS-$(CONFIG_H263_VAAPI_HWACCEL)         += vaapi_mpeg4.o
680 680
 OBJS-$(CONFIG_H263_VDPAU_HWACCEL)         += vdpau_mpeg4.o
681
+OBJS-$(CONFIG_H264_D3D11VA_HWACCEL)       += dxva2_h264.o
681 682
 OBJS-$(CONFIG_H264_DXVA2_HWACCEL)         += dxva2_h264.o
682 683
 OBJS-$(CONFIG_H264_VAAPI_HWACCEL)         += vaapi_h264.o
683 684
 OBJS-$(CONFIG_H264_VDA_HWACCEL)           += vda_h264.o
684 685
 OBJS-$(CONFIG_H264_VDPAU_HWACCEL)         += vdpau_h264.o
686
+OBJS-$(CONFIG_HEVC_D3D11VA_HWACCEL)       += dxva2_hevc.o
685 687
 OBJS-$(CONFIG_HEVC_DXVA2_HWACCEL)         += dxva2_hevc.o
686 688
 OBJS-$(CONFIG_MPEG1_VDPAU_HWACCEL)        += vdpau_mpeg12.o
687 689
 OBJS-$(CONFIG_MPEG1_XVMC_HWACCEL)         += mpegvideo_xvmc.o
690
+OBJS-$(CONFIG_MPEG2_D3D11VA_HWACCEL)      += dxva2_mpeg2.o
688 691
 OBJS-$(CONFIG_MPEG2_DXVA2_HWACCEL)        += dxva2_mpeg2.o
689 692
 OBJS-$(CONFIG_MPEG2_VAAPI_HWACCEL)        += vaapi_mpeg2.o
690 693
 OBJS-$(CONFIG_MPEG2_VDPAU_HWACCEL)        += vdpau_mpeg12.o
691 694
 OBJS-$(CONFIG_MPEG2_XVMC_HWACCEL)         += mpegvideo_xvmc.o
692 695
 OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL)        += vaapi_mpeg4.o
693 696
 OBJS-$(CONFIG_MPEG4_VDPAU_HWACCEL)        += vdpau_mpeg4.o
697
+OBJS-$(CONFIG_VC1_D3D11VA_HWACCEL)        += dxva2_vc1.o
694 698
 OBJS-$(CONFIG_VC1_DXVA2_HWACCEL)          += dxva2_vc1.o
695 699
 OBJS-$(CONFIG_VC1_VAAPI_HWACCEL)          += vaapi_vc1.o
696 700
 OBJS-$(CONFIG_VC1_VDPAU_HWACCEL)          += vdpau_vc1.o
... ...
@@ -872,6 +878,7 @@ SKIPHEADERS                            += %_tablegen.h                  \
872 872
                                           tableprint_vlc.h              \
873 873
                                           $(ARCH)/vp56_arith.h          \
874 874
 
875
+SKIPHEADERS-$(CONFIG_D3D11VA)          += d3d11va.h dxva2_internal.h
875 876
 SKIPHEADERS-$(CONFIG_DXVA2)            += dxva2.h dxva2_internal.h
876 877
 SKIPHEADERS-$(CONFIG_LIBSCHROEDINGER)  += libschroedinger.h
877 878
 SKIPHEADERS-$(CONFIG_LIBUTVIDEO)       += libutvideo.h
... ...
@@ -76,6 +76,7 @@ void avcodec_register_all(void)
76 76
     /* hardware accelerators */
77 77
     REGISTER_HWACCEL(H263_VAAPI,        h263_vaapi);
78 78
     REGISTER_HWACCEL(H263_VDPAU,        h263_vdpau);
79
+    REGISTER_HWACCEL(H264_D3D11VA,      h264_d3d11va);
79 80
     REGISTER_HWACCEL(H264_DXVA2,        h264_dxva2);
80 81
     REGISTER_HWACCEL(H264_MMAL,         h264_mmal);
81 82
     REGISTER_HWACCEL(H264_QSV,          h264_qsv);
... ...
@@ -83,18 +84,22 @@ void avcodec_register_all(void)
83 83
     REGISTER_HWACCEL(H264_VDA,          h264_vda);
84 84
     REGISTER_HWACCEL(H264_VDA_OLD,      h264_vda_old);
85 85
     REGISTER_HWACCEL(H264_VDPAU,        h264_vdpau);
86
+    REGISTER_HWACCEL(HEVC_D3D11VA,      hevc_d3d11va);
86 87
     REGISTER_HWACCEL(HEVC_DXVA2,        hevc_dxva2);
87 88
     REGISTER_HWACCEL(MPEG1_XVMC,        mpeg1_xvmc);
88 89
     REGISTER_HWACCEL(MPEG1_VDPAU,       mpeg1_vdpau);
89 90
     REGISTER_HWACCEL(MPEG2_XVMC,        mpeg2_xvmc);
91
+    REGISTER_HWACCEL(MPEG2_D3D11VA,     mpeg2_d3d11va);
90 92
     REGISTER_HWACCEL(MPEG2_DXVA2,       mpeg2_dxva2);
91 93
     REGISTER_HWACCEL(MPEG2_VAAPI,       mpeg2_vaapi);
92 94
     REGISTER_HWACCEL(MPEG2_VDPAU,       mpeg2_vdpau);
93 95
     REGISTER_HWACCEL(MPEG4_VAAPI,       mpeg4_vaapi);
94 96
     REGISTER_HWACCEL(MPEG4_VDPAU,       mpeg4_vdpau);
97
+    REGISTER_HWACCEL(VC1_D3D11VA,       vc1_d3d11va);
95 98
     REGISTER_HWACCEL(VC1_DXVA2,         vc1_dxva2);
96 99
     REGISTER_HWACCEL(VC1_VAAPI,         vc1_vaapi);
97 100
     REGISTER_HWACCEL(VC1_VDPAU,         vc1_vdpau);
101
+    REGISTER_HWACCEL(WMV3_D3D11VA,      wmv3_d3d11va);
98 102
     REGISTER_HWACCEL(WMV3_DXVA2,        wmv3_dxva2);
99 103
     REGISTER_HWACCEL(WMV3_VAAPI,        wmv3_vaapi);
100 104
     REGISTER_HWACCEL(WMV3_VDPAU,        wmv3_vdpau);
101 105
new file mode 100644
... ...
@@ -0,0 +1,98 @@
0
+/*
1
+ * Direct3D11 HW acceleration
2
+ *
3
+ * copyright (c) 2009 Laurent Aimar
4
+ * copyright (c) 2015 Steve Lhomme
5
+ *
6
+ * This file is part of FFmpeg.
7
+ *
8
+ * FFmpeg is free software; you can redistribute it and/or
9
+ * modify it under the terms of the GNU Lesser General Public
10
+ * License as published by the Free Software Foundation; either
11
+ * version 2.1 of the License, or (at your option) any later version.
12
+ *
13
+ * FFmpeg is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
+ * Lesser General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU Lesser General Public
19
+ * License along with FFmpeg; if not, write to the Free Software
20
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
+ */
22
+
23
+#ifndef AVCODEC_D3D11VA_H
24
+#define AVCODEC_D3D11VA_H
25
+
26
+/**
27
+ * @file
28
+ * @ingroup lavc_codec_hwaccel_d3d11va
29
+ * Public libavcodec D3D11VA header.
30
+ */
31
+
32
+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600
33
+#undef _WIN32_WINNT
34
+#define _WIN32_WINNT 0x0600
35
+#endif
36
+
37
+#include <stdint.h>
38
+#include <d3d11.h>
39
+
40
+/**
41
+ * @defgroup lavc_codec_hwaccel_d3d11va Direct3D11
42
+ * @ingroup lavc_codec_hwaccel
43
+ *
44
+ * @{
45
+ */
46
+
47
+#define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards
48
+#define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO    2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface
49
+
50
+/**
51
+ * This structure is used to provides the necessary configurations and data
52
+ * to the Direct3D11 FFmpeg HWAccel implementation.
53
+ *
54
+ * The application must make it available as AVCodecContext.hwaccel_context.
55
+ */
56
+struct AVD3D11VAContext {
57
+    /**
58
+     * D3D11 decoder object
59
+     */
60
+    ID3D11VideoDecoder *decoder;
61
+
62
+    /**
63
+      * D3D11 VideoContext
64
+      */
65
+    ID3D11VideoContext *video_context;
66
+
67
+    /**
68
+     * D3D11 configuration used to create the decoder
69
+     */
70
+    D3D11_VIDEO_DECODER_CONFIG *cfg;
71
+
72
+    /**
73
+     * The number of surface in the surface array
74
+     */
75
+    unsigned surface_count;
76
+
77
+    /**
78
+     * The array of Direct3D surfaces used to create the decoder
79
+     */
80
+    ID3D11VideoDecoderOutputView **surface;
81
+
82
+    /**
83
+     * A bit field configuring the workarounds needed for using the decoder
84
+     */
85
+    uint64_t workaround;
86
+
87
+    /**
88
+     * Private to the FFmpeg AVHWAccel implementation
89
+     */
90
+    unsigned report_id;
91
+};
92
+
93
+/**
94
+ * @}
95
+ */
96
+
97
+#endif /* AVCODEC_D3D11VA_H */
... ...
@@ -35,14 +35,15 @@ void *ff_dxva2_get_surface(const AVFrame *frame)
35 35
     return frame->data[3];
36 36
 }
37 37
 
38
-unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
38
+unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
39
+                                    const AVDXVAContext *ctx,
39 40
                                     const AVFrame *frame)
40 41
 {
41 42
     void *surface = ff_dxva2_get_surface(frame);
42 43
     unsigned i;
43 44
 
44
-    for (i = 0; i < ctx->surface_count; i++)
45
-        if (ctx->surface[i] == surface)
45
+    for (i = 0; i < DXVA_CONTEXT_COUNT(avctx, ctx); i++)
46
+        if (DXVA_CONTEXT_SURFACE(avctx, ctx, i) == surface)
46 47
             return i;
47 48
 
48 49
     assert(0);
... ...
@@ -50,8 +51,8 @@ unsigned ff_dxva2_get_surface_index(const struct dxva_context *ctx,
50 50
 }
51 51
 
52 52
 int ff_dxva2_commit_buffer(AVCodecContext *avctx,
53
-                           struct dxva_context *ctx,
54
-                           DXVA2_DecodeBufferDesc *dsc,
53
+                           AVDXVAContext *ctx,
54
+                           DECODER_BUFFER_DESC *dsc,
55 55
                            unsigned type, const void *data, unsigned size,
56 56
                            unsigned mb_count)
57 57
 {
... ...
@@ -60,8 +61,18 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
60 60
     int      result;
61 61
     HRESULT hr;
62 62
 
63
-    hr = IDirectXVideoDecoder_GetBuffer(ctx->decoder, type,
64
-                                        &dxva_data, &dxva_size);
63
+#if CONFIG_D3D11VA
64
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
65
+        hr = ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
66
+                                                 D3D11VA_CONTEXT(ctx)->decoder,
67
+                                                 type,
68
+                                                 &dxva_size, &dxva_data);
69
+#endif
70
+#if CONFIG_DXVA2
71
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
72
+        hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, type,
73
+                                            &dxva_data, &dxva_size);
74
+#endif
65 75
     if (FAILED(hr)) {
66 76
         av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n",
67 77
                type, hr);
... ...
@@ -70,10 +81,24 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
70 70
     if (size <= dxva_size) {
71 71
         memcpy(dxva_data, data, size);
72 72
 
73
-        memset(dsc, 0, sizeof(*dsc));
74
-        dsc->CompressedBufferType = type;
75
-        dsc->DataSize             = size;
76
-        dsc->NumMBsInBuffer       = mb_count;
73
+#if CONFIG_D3D11VA
74
+        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
75
+            D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc;
76
+            memset(dsc11, 0, sizeof(*dsc11));
77
+            dsc11->BufferType           = type;
78
+            dsc11->DataSize             = size;
79
+            dsc11->NumMBsInBuffer       = mb_count;
80
+        }
81
+#endif
82
+#if CONFIG_DXVA2
83
+        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
84
+            DXVA2_DecodeBufferDesc *dsc2 = dsc;
85
+            memset(dsc2, 0, sizeof(*dsc2));
86
+            dsc2->CompressedBufferType = type;
87
+            dsc2->DataSize             = size;
88
+            dsc2->NumMBsInBuffer       = mb_count;
89
+        }
90
+#endif
77 91
 
78 92
         result = 0;
79 93
     } else {
... ...
@@ -81,7 +106,14 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx,
81 81
         result = -1;
82 82
     }
83 83
 
84
-    hr = IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder, type);
84
+#if CONFIG_D3D11VA
85
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
86
+        hr = ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type);
87
+#endif
88
+#if CONFIG_DXVA2
89
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
90
+        hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type);
91
+#endif
85 92
     if (FAILED(hr)) {
86 93
         av_log(avctx, AV_LOG_ERROR,
87 94
                "Failed to release buffer type %u: 0x%lx\n",
... ...
@@ -95,20 +127,31 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
95 95
                               const void *pp, unsigned pp_size,
96 96
                               const void *qm, unsigned qm_size,
97 97
                               int (*commit_bs_si)(AVCodecContext *,
98
-                                                  DXVA2_DecodeBufferDesc *bs,
99
-                                                  DXVA2_DecodeBufferDesc *slice))
98
+                                                  DECODER_BUFFER_DESC *bs,
99
+                                                  DECODER_BUFFER_DESC *slice))
100 100
 {
101
-    struct dxva_context *ctx = avctx->hwaccel_context;
101
+    AVDXVAContext *ctx = avctx->hwaccel_context;
102 102
     unsigned               buffer_count = 0;
103
-    DXVA2_DecodeBufferDesc buffer[4];
104
-    DXVA2_DecodeExecuteParams exec = { 0 };
103
+    D3D11_VIDEO_DECODER_BUFFER_DESC buffer11[4];
104
+    DXVA2_DecodeBufferDesc          buffer2[4];
105
+    DECODER_BUFFER_DESC             *buffer,*buffer_slice;
105 106
     int result, runs = 0;
106 107
     HRESULT hr;
108
+    unsigned type;
107 109
 
108 110
     do {
109
-        hr = IDirectXVideoDecoder_BeginFrame(ctx->decoder,
110
-                                             ff_dxva2_get_surface(frame),
111
-                                             NULL);
111
+#if CONFIG_D3D11VA
112
+        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
113
+            hr = ID3D11VideoContext_DecoderBeginFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder,
114
+                                                      ff_dxva2_get_surface(frame),
115
+                                                      0, NULL);
116
+#endif
117
+#if CONFIG_DXVA2
118
+        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
119
+            hr = IDirectXVideoDecoder_BeginFrame(DXVA2_CONTEXT(ctx)->decoder,
120
+                                                 ff_dxva2_get_surface(frame),
121
+                                                 NULL);
122
+#endif
112 123
         if (hr == E_PENDING)
113 124
             av_usleep(2000);
114 125
     } while (hr == E_PENDING && ++runs < 50);
... ...
@@ -118,8 +161,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
118 118
         return -1;
119 119
     }
120 120
 
121
-    result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
122
-                                    DXVA2_PictureParametersBufferType,
121
+#if CONFIG_D3D11VA
122
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
123
+        buffer = &buffer11[buffer_count];
124
+        type = D3D11_VIDEO_DECODER_BUFFER_PICTURE_PARAMETERS;
125
+    }
126
+#endif
127
+#if CONFIG_DXVA2
128
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
129
+        buffer = &buffer2[buffer_count];
130
+        type = DXVA2_PictureParametersBufferType;
131
+    }
132
+#endif
133
+    result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
134
+                                    type,
123 135
                                     pp, pp_size, 0);
124 136
     if (result) {
125 137
         av_log(avctx, AV_LOG_ERROR,
... ...
@@ -129,8 +184,20 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
129 129
     buffer_count++;
130 130
 
131 131
     if (qm_size > 0) {
132
-        result = ff_dxva2_commit_buffer(avctx, ctx, &buffer[buffer_count],
133
-                                        DXVA2_InverseQuantizationMatrixBufferType,
132
+#if CONFIG_D3D11VA
133
+        if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
134
+            buffer = &buffer11[buffer_count];
135
+            type = D3D11_VIDEO_DECODER_BUFFER_INVERSE_QUANTIZATION_MATRIX;
136
+        }
137
+#endif
138
+#if CONFIG_DXVA2
139
+        if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
140
+            buffer = &buffer2[buffer_count];
141
+            type = DXVA2_InverseQuantizationMatrixBufferType;
142
+        }
143
+#endif
144
+        result = ff_dxva2_commit_buffer(avctx, ctx, buffer,
145
+                                        type,
134 146
                                         qm, qm_size, 0);
135 147
         if (result) {
136 148
             av_log(avctx, AV_LOG_ERROR,
... ...
@@ -140,9 +207,22 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
140 140
         buffer_count++;
141 141
     }
142 142
 
143
+#if CONFIG_D3D11VA
144
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
145
+        buffer       = &buffer11[buffer_count + 0];
146
+        buffer_slice = &buffer11[buffer_count + 1];
147
+    }
148
+#endif
149
+#if CONFIG_DXVA2
150
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
151
+        buffer       = &buffer2[buffer_count + 0];
152
+        buffer_slice = &buffer2[buffer_count + 1];
153
+    }
154
+#endif
155
+
143 156
     result = commit_bs_si(avctx,
144
-                          &buffer[buffer_count + 0],
145
-                          &buffer[buffer_count + 1]);
157
+                          buffer,
158
+                          buffer_slice);
146 159
     if (result) {
147 160
         av_log(avctx, AV_LOG_ERROR,
148 161
                "Failed to add bitstream or slice control buffer\n");
... ...
@@ -154,17 +234,36 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame,
154 154
 
155 155
     assert(buffer_count == 1 + (qm_size > 0) + 2);
156 156
 
157
-    exec.NumCompBuffers      = buffer_count;
158
-    exec.pCompressedBuffers  = buffer;
159
-    exec.pExtensionData      = NULL;
160
-    hr = IDirectXVideoDecoder_Execute(ctx->decoder, &exec);
157
+#if CONFIG_D3D11VA
158
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
159
+        hr = ID3D11VideoContext_SubmitDecoderBuffers(D3D11VA_CONTEXT(ctx)->video_context,
160
+                                                     D3D11VA_CONTEXT(ctx)->decoder,
161
+                                                     buffer_count, buffer11);
162
+#endif
163
+#if CONFIG_DXVA2
164
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
165
+        DXVA2_DecodeExecuteParams exec = {
166
+            .NumCompBuffers     = buffer_count,
167
+            .pCompressedBuffers = buffer2,
168
+            .pExtensionData     = NULL,
169
+        };
170
+        hr = IDirectXVideoDecoder_Execute(DXVA2_CONTEXT(ctx)->decoder, &exec);
171
+    }
172
+#endif
161 173
     if (FAILED(hr)) {
162 174
         av_log(avctx, AV_LOG_ERROR, "Failed to execute: 0x%lx\n", hr);
163 175
         result = -1;
164 176
     }
165 177
 
166 178
 end:
167
-    hr = IDirectXVideoDecoder_EndFrame(ctx->decoder, NULL);
179
+#if CONFIG_D3D11VA
180
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
181
+        hr = ID3D11VideoContext_DecoderEndFrame(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder);
182
+#endif
183
+#if CONFIG_DXVA2
184
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
185
+        hr = IDirectXVideoDecoder_EndFrame(DXVA2_CONTEXT(ctx)->decoder, NULL);
186
+#endif
168 187
     if (FAILED(hr)) {
169 188
         av_log(avctx, AV_LOG_ERROR, "Failed to end frame: 0x%lx\n", hr);
170 189
         result = -1;
... ...
@@ -42,7 +42,7 @@ static void fill_picture_entry(DXVA_PicEntry_H264 *pic,
42 42
     pic->bPicEntry = index | (flag << 7);
43 43
 }
44 44
 
45
-static void fill_picture_parameters(struct dxva_context *ctx, const H264Context *h,
45
+static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h,
46 46
                                     DXVA_PicParams_H264 *pp)
47 47
 {
48 48
     const H264Picture *current_picture = h->cur_pic_ptr;
... ...
@@ -51,7 +51,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
51 51
     memset(pp, 0, sizeof(*pp));
52 52
     /* Configure current picture */
53 53
     fill_picture_entry(&pp->CurrPic,
54
-                       ff_dxva2_get_surface_index(ctx, current_picture->f),
54
+                       ff_dxva2_get_surface_index(avctx, ctx, current_picture->f),
55 55
                        h->picture_structure == PICT_BOTTOM_FIELD);
56 56
     /* Configure the set of references */
57 57
     pp->UsedForReferenceFlags  = 0;
... ...
@@ -67,7 +67,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
67 67
         }
68 68
         if (r) {
69 69
             fill_picture_entry(&pp->RefFrameList[i],
70
-                               ff_dxva2_get_surface_index(ctx, r->f),
70
+                               ff_dxva2_get_surface_index(avctx, ctx, r->f),
71 71
                                r->long_ref != 0);
72 72
 
73 73
             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
114 114
 
115 115
     pp->bit_depth_luma_minus8         = h->sps.bit_depth_luma - 8;
116 116
     pp->bit_depth_chroma_minus8       = h->sps.bit_depth_chroma - 8;
117
-    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
117
+    if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)
118 118
         pp->Reserved16Bits            = 0;
119
-    else if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
119
+    else if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
120 120
         pp->Reserved16Bits            = 0x34c;
121 121
     else
122 122
         pp->Reserved16Bits            = 3; /* FIXME is there a way to detect the right mode ? */
123
-    pp->StatusReportFeedbackNumber    = 1 + ctx->report_id++;
123
+    pp->StatusReportFeedbackNumber    = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
124 124
     pp->CurrFieldOrderCnt[0] = 0;
125 125
     if ((h->picture_structure & PICT_TOP_FIELD) &&
126 126
         current_picture->field_poc[0] != INT_MAX)
... ...
@@ -156,11 +156,11 @@ static void fill_picture_parameters(struct dxva_context *ctx, const H264Context
156 156
     //pp->SliceGroupMap[810];               /* XXX not implemented by FFmpeg */
157 157
 }
158 158
 
159
-static void fill_scaling_lists(struct dxva_context *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
159
+static void fill_scaling_lists(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h, DXVA_Qmatrix_H264 *qm)
160 160
 {
161 161
     unsigned i, j;
162 162
     memset(qm, 0, sizeof(*qm));
163
-    if (ctx->workaround & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
163
+    if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG) {
164 164
         for (i = 0; i < 6; i++)
165 165
             for (j = 0; j < 16; j++)
166 166
                 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
181 181
     }
182 182
 }
183 183
 
184
-static int is_slice_short(struct dxva_context *ctx)
184
+static int is_slice_short(const AVCodecContext *avctx, AVDXVAContext *ctx)
185 185
 {
186
-    assert(ctx->cfg->ConfigBitstreamRaw == 1 ||
187
-           ctx->cfg->ConfigBitstreamRaw == 2);
188
-    return ctx->cfg->ConfigBitstreamRaw == 2;
186
+    assert(DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 1 ||
187
+           DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2);
188
+    return DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx) == 2;
189 189
 }
190 190
 
191 191
 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,
212 212
 {
213 213
     const H264Context *h = avctx->priv_data;
214 214
     H264SliceContext *sl = &h->slice_ctx[0];
215
-    struct dxva_context *ctx = avctx->hwaccel_context;
215
+    AVDXVAContext *ctx = avctx->hwaccel_context;
216 216
     unsigned list;
217 217
 
218 218
     memset(slice, 0, sizeof(*slice));
... ...
@@ -243,10 +243,10 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
243 243
                 const H264Picture *r = sl->ref_list[list][i].parent;
244 244
                 unsigned plane;
245 245
                 unsigned index;
246
-                if (ctx->workaround & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
247
-                    index = ff_dxva2_get_surface_index(ctx, r->f);
246
+                if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)
247
+                    index = ff_dxva2_get_surface_index(avctx, ctx, r->f);
248 248
                 else
249
-                    index = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, r->f));
249
+                    index = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, r->f));
250 250
                 fill_picture_entry(&slice->RefPicList[list][i], index,
251 251
                                    r->reference == PICT_BOTTOM_FIELD);
252 252
                 for (plane = 0; plane < 3; plane++) {
... ...
@@ -289,12 +289,12 @@ static void fill_slice_long(AVCodecContext *avctx, DXVA_Slice_H264_Long *slice,
289 289
 }
290 290
 
291 291
 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
292
-                                             DXVA2_DecodeBufferDesc *bs,
293
-                                             DXVA2_DecodeBufferDesc *sc)
292
+                                             DECODER_BUFFER_DESC *bs,
293
+                                             DECODER_BUFFER_DESC *sc)
294 294
 {
295 295
     const H264Context *h = avctx->priv_data;
296 296
     const unsigned mb_count = h->mb_width * h->mb_height;
297
-    struct dxva_context *ctx = avctx->hwaccel_context;
297
+    AVDXVAContext *ctx = avctx->hwaccel_context;
298 298
     const H264Picture *current_picture = h->cur_pic_ptr;
299 299
     struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
300 300
     DXVA_Slice_H264_Short *slice = NULL;
... ...
@@ -305,12 +305,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
305 305
     unsigned slice_size;
306 306
     unsigned padding;
307 307
     unsigned i;
308
+    unsigned type;
308 309
 
309 310
     /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
310
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
311
-                                              DXVA2_BitStreamDateBufferType,
312
-                                              &dxva_data_ptr, &dxva_size)))
313
-        return -1;
311
+#if CONFIG_D3D11VA
312
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
313
+        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
314
+        if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
315
+                                                       D3D11VA_CONTEXT(ctx)->decoder,
316
+                                                       type,
317
+                                                       &dxva_size, &dxva_data_ptr)))
318
+            return -1;
319
+    }
320
+#endif
321
+#if CONFIG_DXVA2
322
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
323
+        type = DXVA2_BitStreamDateBufferType;
324
+        if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
325
+                                                  type,
326
+                                                  &dxva_data_ptr, &dxva_size)))
327
+            return -1;
328
+    }
329
+#endif
314 330
 
315 331
     dxva_data = dxva_data_ptr;
316 332
     current = dxva_data;
... ...
@@ -326,7 +342,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
326 326
         assert(offsetof(DXVA_Slice_H264_Short, SliceBytesInBuffer) ==
327 327
                offsetof(DXVA_Slice_H264_Long,  SliceBytesInBuffer));
328 328
 
329
-        if (is_slice_short(ctx))
329
+        if (is_slice_short(avctx, ctx))
330 330
             slice = &ctx_pic->slice_short[i];
331 331
         else
332 332
             slice = (DXVA_Slice_H264_Short*)&ctx_pic->slice_long[i];
... ...
@@ -341,7 +357,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
341 341
         slice->BSNALunitDataLocation = current - dxva_data;
342 342
         slice->SliceBytesInBuffer    = start_code_size + size;
343 343
 
344
-        if (!is_slice_short(ctx)) {
344
+        if (!is_slice_short(avctx, ctx)) {
345 345
             DXVA_Slice_H264_Long *slice_long = (DXVA_Slice_H264_Long*)slice;
346 346
             if (i < ctx_pic->slice_count - 1)
347 347
                 slice_long->NumMbsForSlice =
... ...
@@ -363,18 +379,43 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
363 363
 
364 364
         slice->SliceBytesInBuffer += padding;
365 365
     }
366
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
367
-                                                  DXVA2_BitStreamDateBufferType)))
368
-        return -1;
366
+#if CONFIG_D3D11VA
367
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
368
+        if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
369
+            return -1;
370
+#endif
371
+#if CONFIG_DXVA2
372
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
373
+        if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
374
+            return -1;
375
+#endif
369 376
     if (i < ctx_pic->slice_count)
370 377
         return -1;
371 378
 
372
-    memset(bs, 0, sizeof(*bs));
373
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
374
-    bs->DataSize             = current - dxva_data;
375
-    bs->NumMBsInBuffer       = mb_count;
379
+#if CONFIG_D3D11VA
380
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
381
+        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
382
+        memset(dsc11, 0, sizeof(*dsc11));
383
+        dsc11->BufferType           = type;
384
+        dsc11->DataSize             = current - dxva_data;
385
+        dsc11->NumMBsInBuffer       = mb_count;
376 386
 
377
-    if (is_slice_short(ctx)) {
387
+        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
388
+    }
389
+#endif
390
+#if CONFIG_DXVA2
391
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
392
+        DXVA2_DecodeBufferDesc *dsc2 = bs;
393
+        memset(dsc2, 0, sizeof(*dsc2));
394
+        dsc2->CompressedBufferType = type;
395
+        dsc2->DataSize             = current - dxva_data;
396
+        dsc2->NumMBsInBuffer       = mb_count;
397
+
398
+        type = DXVA2_SliceControlBufferType;
399
+    }
400
+#endif
401
+
402
+    if (is_slice_short(avctx, ctx)) {
378 403
         slice_data = ctx_pic->slice_short;
379 404
         slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
380 405
     } else {
... ...
@@ -383,7 +424,7 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
383 383
     }
384 384
     assert((bs->DataSize & 127) == 0);
385 385
     return ff_dxva2_commit_buffer(avctx, ctx, sc,
386
-                                  DXVA2_SliceControlBufferType,
386
+                                  type,
387 387
                                   slice_data, slice_size, mb_count);
388 388
 }
389 389
 
... ...
@@ -393,18 +434,20 @@ static int dxva2_h264_start_frame(AVCodecContext *avctx,
393 393
                                   av_unused uint32_t size)
394 394
 {
395 395
     const H264Context *h = avctx->priv_data;
396
-    struct dxva_context *ctx = avctx->hwaccel_context;
396
+    AVDXVAContext *ctx = avctx->hwaccel_context;
397 397
     struct dxva2_picture_context *ctx_pic = h->cur_pic_ptr->hwaccel_picture_private;
398 398
 
399
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
399
+    if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
400
+        DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
401
+        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
400 402
         return -1;
401 403
     assert(ctx_pic);
402 404
 
403 405
     /* Fill up DXVA_PicParams_H264 */
404
-    fill_picture_parameters(ctx, h, &ctx_pic->pp);
406
+    fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
405 407
 
406 408
     /* Fill up DXVA_Qmatrix_H264 */
407
-    fill_scaling_lists(ctx, h, &ctx_pic->qm);
409
+    fill_scaling_lists(avctx, ctx, h, &ctx_pic->qm);
408 410
 
409 411
     ctx_pic->slice_count    = 0;
410 412
     ctx_pic->bitstream_size = 0;
... ...
@@ -418,7 +461,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
418 418
 {
419 419
     const H264Context *h = avctx->priv_data;
420 420
     const H264SliceContext *sl = &h->slice_ctx[0];
421
-    struct dxva_context *ctx = avctx->hwaccel_context;
421
+    AVDXVAContext *ctx = avctx->hwaccel_context;
422 422
     const H264Picture *current_picture = h->cur_pic_ptr;
423 423
     struct dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
424 424
     unsigned position;
... ...
@@ -431,7 +474,7 @@ static int dxva2_h264_decode_slice(AVCodecContext *avctx,
431 431
     ctx_pic->bitstream_size += size;
432 432
 
433 433
     position = buffer - ctx_pic->bitstream;
434
-    if (is_slice_short(ctx))
434
+    if (is_slice_short(avctx, ctx))
435 435
         fill_slice_short(&ctx_pic->slice_short[ctx_pic->slice_count],
436 436
                          position, size);
437 437
     else
... ...
@@ -463,6 +506,7 @@ static int dxva2_h264_end_frame(AVCodecContext *avctx)
463 463
     return ret;
464 464
 }
465 465
 
466
+#if CONFIG_H264_DXVA2_HWACCEL
466 467
 AVHWAccel ff_h264_dxva2_hwaccel = {
467 468
     .name           = "h264_dxva2",
468 469
     .type           = AVMEDIA_TYPE_VIDEO,
... ...
@@ -473,3 +517,17 @@ AVHWAccel ff_h264_dxva2_hwaccel = {
473 473
     .end_frame      = dxva2_h264_end_frame,
474 474
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
475 475
 };
476
+#endif
477
+
478
+#if CONFIG_H264_D3D11VA_HWACCEL
479
+AVHWAccel ff_h264_d3d11va_hwaccel = {
480
+    .name           = "h264_d3d11va",
481
+    .type           = AVMEDIA_TYPE_VIDEO,
482
+    .id             = AV_CODEC_ID_H264,
483
+    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
484
+    .start_frame    = dxva2_h264_start_frame,
485
+    .decode_slice   = dxva2_h264_decode_slice,
486
+    .end_frame      = dxva2_h264_end_frame,
487
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
488
+};
489
+#endif
... ...
@@ -53,7 +53,7 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
53 53
     return 0xff;
54 54
 }
55 55
 
56
-static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext *h,
56
+static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h,
57 57
                                     DXVA_PicParams_HEVC *pp)
58 58
 {
59 59
     const HEVCFrame *current_picture = h->ref;
... ...
@@ -73,7 +73,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext
73 73
                                       (0                                  << 14) |
74 74
                                       (0                                  << 15);
75 75
 
76
-    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(ctx, current_picture->frame), 0);
76
+    fill_picture_entry(&pp->CurrPic, ff_dxva2_get_surface_index(avctx, ctx, current_picture->frame), 0);
77 77
 
78 78
     pp->sps_max_dec_pic_buffering_minus1         = h->sps->temporal_layer[h->sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
79 79
     pp->log2_min_luma_coding_block_size_minus3   = h->sps->log2_min_cb_size - 3;
... ...
@@ -165,7 +165,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext
165 165
     for (i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
166 166
         const HEVCFrame *frame = &h->DPB[i];
167 167
         if (frame != current_picture && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF | HEVC_FRAME_FLAG_SHORT_REF))) {
168
-            fill_picture_entry(&pp->RefPicList[j], ff_dxva2_get_surface_index(ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
168
+            fill_picture_entry(&pp->RefPicList[j], ff_dxva2_get_surface_index(avctx, ctx, frame->frame), !!(frame->flags & HEVC_FRAME_FLAG_LONG_REF));
169 169
             pp->PicOrderCntValList[j] = frame->poc;
170 170
             j++;
171 171
         }
... ...
@@ -176,7 +176,7 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext
176 176
         av_assert0(rpl->nb_refs <= FF_ARRAY_ELEMS(pp->ref_list)); \
177 177
         for (j = 0, k = 0; j < rpl->nb_refs; j++) { \
178 178
             if (rpl->ref[j]) { \
179
-                pp->ref_list[k] = get_refpic_index(pp, ff_dxva2_get_surface_index(ctx, rpl->ref[j]->frame)); \
179
+                pp->ref_list[k] = get_refpic_index(pp, ff_dxva2_get_surface_index(avctx, ctx, rpl->ref[j]->frame)); \
180 180
                 k++; \
181 181
             } \
182 182
         } \
... ...
@@ -187,10 +187,10 @@ static void fill_picture_parameters(struct dxva_context *ctx, const HEVCContext
187 187
     DO_REF_LIST(ST_CURR_AFT, RefPicSetStCurrAfter);
188 188
     DO_REF_LIST(LT_CURR, RefPicSetLtCurr);
189 189
 
190
-    pp->StatusReportFeedbackNumber = 1 + ctx->report_id++;
190
+    pp->StatusReportFeedbackNumber = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
191 191
 }
192 192
 
193
-static void fill_scaling_lists(struct dxva_context *ctx, const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
193
+static void fill_scaling_lists(AVDXVAContext *ctx, const HEVCContext *h, DXVA_Qmatrix_HEVC *qm)
194 194
 {
195 195
     unsigned i, j, pos;
196 196
     const ScalingList *sl = h->pps->scaling_list_data_present_flag ?
... ...
@@ -228,11 +228,11 @@ static void fill_slice_short(DXVA_Slice_HEVC_Short *slice,
228 228
 }
229 229
 
230 230
 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
231
-                                             DXVA2_DecodeBufferDesc *bs,
232
-                                             DXVA2_DecodeBufferDesc *sc)
231
+                                             DECODER_BUFFER_DESC *bs,
232
+                                             DECODER_BUFFER_DESC *sc)
233 233
 {
234 234
     const HEVCContext *h = avctx->priv_data;
235
-    struct dxva_context *ctx = avctx->hwaccel_context;
235
+    AVDXVAContext *ctx = avctx->hwaccel_context;
236 236
     const HEVCFrame *current_picture = h->ref;
237 237
     struct hevc_dxva2_picture_context *ctx_pic = current_picture->hwaccel_picture_private;
238 238
     DXVA_Slice_HEVC_Short *slice = NULL;
... ...
@@ -243,12 +243,28 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
243 243
     unsigned slice_size;
244 244
     unsigned padding;
245 245
     unsigned i;
246
+    unsigned type;
246 247
 
247 248
     /* Create an annex B bitstream buffer with only slice NAL and finalize slice */
248
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
249
-                                              DXVA2_BitStreamDateBufferType,
250
-                                              &dxva_data_ptr, &dxva_size)))
251
-        return -1;
249
+#if CONFIG_D3D11VA
250
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
251
+        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
252
+        if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
253
+                                                       D3D11VA_CONTEXT(ctx)->decoder,
254
+                                                       type,
255
+                                                       &dxva_size, &dxva_data_ptr)))
256
+            return -1;
257
+    }
258
+#endif
259
+#if CONFIG_DXVA2
260
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
261
+        type = DXVA2_BitStreamDateBufferType;
262
+        if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
263
+                                                  type,
264
+                                                  &dxva_data_ptr, &dxva_size)))
265
+            return -1;
266
+    }
267
+#endif
252 268
 
253 269
     dxva_data = dxva_data_ptr;
254 270
     current = dxva_data;
... ...
@@ -284,23 +300,48 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
284 284
 
285 285
         slice->SliceBytesInBuffer += padding;
286 286
     }
287
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
288
-                                                  DXVA2_BitStreamDateBufferType)))
289
-        return -1;
287
+#if CONFIG_D3D11VA
288
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
289
+        if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
290
+            return -1;
291
+#endif
292
+#if CONFIG_DXVA2
293
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
294
+        if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
295
+            return -1;
296
+#endif
290 297
     if (i < ctx_pic->slice_count)
291 298
         return -1;
292 299
 
293
-    memset(bs, 0, sizeof(*bs));
294
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
295
-    bs->DataSize             = current - dxva_data;
296
-    bs->NumMBsInBuffer       = 0;
300
+#if CONFIG_D3D11VA
301
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
302
+        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
303
+        memset(dsc11, 0, sizeof(*dsc11));
304
+        dsc11->BufferType           = type;
305
+        dsc11->DataSize             = current - dxva_data;
306
+        dsc11->NumMBsInBuffer       = 0;
307
+
308
+        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
309
+    }
310
+#endif
311
+#if CONFIG_DXVA2
312
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
313
+        DXVA2_DecodeBufferDesc *dsc2 = bs;
314
+        memset(dsc2, 0, sizeof(*dsc2));
315
+        dsc2->CompressedBufferType = type;
316
+        dsc2->DataSize             = current - dxva_data;
317
+        dsc2->NumMBsInBuffer       = 0;
318
+
319
+        type = DXVA2_SliceControlBufferType;
320
+    }
321
+#endif
297 322
 
298 323
     slice_data = ctx_pic->slice_short;
299 324
     slice_size = ctx_pic->slice_count * sizeof(*ctx_pic->slice_short);
300 325
 
301
-    av_assert0((bs->DataSize & 127) == 0);
326
+    av_assert0(((current - dxva_data) & 127) == 0);
302 327
     return ff_dxva2_commit_buffer(avctx, ctx, sc,
303
-                                  DXVA2_SliceControlBufferType,
328
+                                  type,
304 329
                                   slice_data, slice_size, 0);
305 330
 }
306 331
 
... ...
@@ -310,15 +351,17 @@ static int dxva2_hevc_start_frame(AVCodecContext *avctx,
310 310
                                   av_unused uint32_t size)
311 311
 {
312 312
     const HEVCContext *h = avctx->priv_data;
313
-    struct dxva_context *ctx = avctx->hwaccel_context;
313
+    AVDXVAContext *ctx = avctx->hwaccel_context;
314 314
     struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
315 315
 
316
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
316
+    if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
317
+        DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
318
+        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
317 319
         return -1;
318 320
     av_assert0(ctx_pic);
319 321
 
320 322
     /* Fill up DXVA_PicParams_HEVC */
321
-    fill_picture_parameters(ctx, h, &ctx_pic->pp);
323
+    fill_picture_parameters(avctx, ctx, h, &ctx_pic->pp);
322 324
 
323 325
     /* Fill up DXVA_Qmatrix_HEVC */
324 326
     fill_scaling_lists(ctx, h, &ctx_pic->qm);
... ...
@@ -369,6 +412,7 @@ static int dxva2_hevc_end_frame(AVCodecContext *avctx)
369 369
     return ret;
370 370
 }
371 371
 
372
+#if CONFIG_HEVC_DXVA2_HWACCEL
372 373
 AVHWAccel ff_hevc_dxva2_hwaccel = {
373 374
     .name           = "hevc_dxva2",
374 375
     .type           = AVMEDIA_TYPE_VIDEO,
... ...
@@ -379,3 +423,17 @@ AVHWAccel ff_hevc_dxva2_hwaccel = {
379 379
     .end_frame      = dxva2_hevc_end_frame,
380 380
     .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
381 381
 };
382
+#endif
383
+
384
+#if CONFIG_HEVC_D3D11VA_HWACCEL
385
+AVHWAccel ff_hevc_d3d11va_hwaccel = {
386
+    .name           = "hevc_d3d11va",
387
+    .type           = AVMEDIA_TYPE_VIDEO,
388
+    .id             = AV_CODEC_ID_HEVC,
389
+    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
390
+    .start_frame    = dxva2_hevc_start_frame,
391
+    .decode_slice   = dxva2_hevc_decode_slice,
392
+    .end_frame      = dxva2_hevc_end_frame,
393
+    .frame_priv_data_size = sizeof(struct hevc_dxva2_picture_context),
394
+};
395
+#endif
... ...
@@ -28,6 +28,7 @@
28 28
 #include "config.h"
29 29
 
30 30
 #include "dxva2.h"
31
+#include "d3d11va.h"
31 32
 #if HAVE_DXVA_H
32 33
 #include <dxva.h>
33 34
 #endif
... ...
@@ -35,13 +36,34 @@
35 35
 #include "avcodec.h"
36 36
 #include "mpegvideo.h"
37 37
 
38
+typedef void DECODER_BUFFER_DESC;
39
+
40
+typedef union {
41
+    struct AVD3D11VAContext  d3d11va;
42
+    struct dxva_context      dxva2;
43
+} AVDXVAContext;
44
+
45
+#define D3D11VA_CONTEXT(ctx) (&ctx->d3d11va)
46
+#define DXVA2_CONTEXT(ctx)   (&ctx->dxva2)
47
+
48
+#define DXVA_CONTEXT_WORKAROUND(avctx, ctx)     (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.workaround : ctx->dxva2.workaround)
49
+#define DXVA_CONTEXT_COUNT(avctx, ctx)          (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface_count : ctx->dxva2.surface_count)
50
+#define DXVA_CONTEXT_SURFACE(avctx, ctx, i)     (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.surface[i] : ctx->dxva2.surface[i])
51
+#define DXVA_CONTEXT_DECODER(avctx, ctx)        (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.decoder : ctx->dxva2.decoder)
52
+#define DXVA_CONTEXT_REPORT_ID(avctx, ctx)      (*(avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? &ctx->d3d11va.report_id : &ctx->dxva2.report_id))
53
+#define DXVA_CONTEXT_CFG(avctx, ctx)            (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg : ctx->dxva2.cfg)
54
+#define DXVA_CONTEXT_CFG_BITSTREAM(avctx, ctx)  (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigBitstreamRaw : ctx->dxva2.cfg->ConfigBitstreamRaw)
55
+#define DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigIntraResidUnsigned : ctx->dxva2.cfg->ConfigIntraResidUnsigned)
56
+#define DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD ? ctx->d3d11va.cfg->ConfigResidDiffAccelerator : ctx->dxva2.cfg->ConfigResidDiffAccelerator)
57
+
38 58
 void *ff_dxva2_get_surface(const AVFrame *frame);
39 59
 
40
-unsigned ff_dxva2_get_surface_index(const struct dxva_context *,
60
+unsigned ff_dxva2_get_surface_index(const AVCodecContext *avctx,
61
+                                    const AVDXVAContext *,
41 62
                                     const AVFrame *frame);
42 63
 
43
-int ff_dxva2_commit_buffer(AVCodecContext *, struct dxva_context *,
44
-                           DXVA2_DecodeBufferDesc *,
64
+int ff_dxva2_commit_buffer(AVCodecContext *, AVDXVAContext *,
65
+                           DECODER_BUFFER_DESC *,
45 66
                            unsigned type, const void *data, unsigned size,
46 67
                            unsigned mb_count);
47 68
 
... ...
@@ -50,7 +72,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *, AVFrame *,
50 50
                               const void *pp, unsigned pp_size,
51 51
                               const void *qm, unsigned qm_size,
52 52
                               int (*commit_bs_si)(AVCodecContext *,
53
-                                                  DXVA2_DecodeBufferDesc *bs,
54
-                                                  DXVA2_DecodeBufferDesc *slice));
53
+                                                  DECODER_BUFFER_DESC *bs,
54
+                                                  DECODER_BUFFER_DESC *slice));
55 55
 
56 56
 #endif /* AVCODEC_DXVA_INTERNAL_H */
... ...
@@ -36,7 +36,7 @@ struct dxva2_picture_context {
36 36
 };
37 37
 
38 38
 static void fill_picture_parameters(AVCodecContext *avctx,
39
-                                    struct dxva_context *ctx,
39
+                                    AVDXVAContext *ctx,
40 40
                                     const struct MpegEncContext *s,
41 41
                                     DXVA_PictureParameters *pp)
42 42
 {
... ...
@@ -44,14 +44,14 @@ static void fill_picture_parameters(AVCodecContext *avctx,
44 44
     int is_field = s->picture_structure != PICT_FRAME;
45 45
 
46 46
     memset(pp, 0, sizeof(*pp));
47
-    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(ctx, current_picture->f);
47
+    pp->wDecodedPictureIndex         = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f);
48 48
     pp->wDeblockedPictureIndex       = 0;
49 49
     if (s->pict_type != AV_PICTURE_TYPE_I)
50
-        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(ctx, s->last_picture.f);
50
+        pp->wForwardRefPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f);
51 51
     else
52 52
         pp->wForwardRefPictureIndex  = 0xffff;
53 53
     if (s->pict_type == AV_PICTURE_TYPE_B)
54
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->next_picture.f);
54
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f);
55 55
     else
56 56
         pp->wBackwardRefPictureIndex = 0xffff;
57 57
     pp->wPicWidthInMBminus1          = s->mb_width  - 1;
... ...
@@ -102,7 +102,7 @@ static void fill_picture_parameters(AVCodecContext *avctx,
102 102
 }
103 103
 
104 104
 static void fill_quantization_matrices(AVCodecContext *avctx,
105
-                                       struct dxva_context *ctx,
105
+                                       AVDXVAContext *ctx,
106 106
                                        const struct MpegEncContext *s,
107 107
                                        DXVA_QmatrixData *qm)
108 108
 {
... ...
@@ -146,11 +146,11 @@ static void fill_slice(AVCodecContext *avctx,
146 146
     slice->wMBbitOffset        = 4 * 8 + get_bits_count(&gb);
147 147
 }
148 148
 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
149
-                                             DXVA2_DecodeBufferDesc *bs,
150
-                                             DXVA2_DecodeBufferDesc *sc)
149
+                                             DECODER_BUFFER_DESC *bs,
150
+                                             DECODER_BUFFER_DESC *sc)
151 151
 {
152 152
     const struct MpegEncContext *s = avctx->priv_data;
153
-    struct dxva_context *ctx = avctx->hwaccel_context;
153
+    AVDXVAContext *ctx = avctx->hwaccel_context;
154 154
     struct dxva2_picture_context *ctx_pic =
155 155
         s->current_picture_ptr->hwaccel_picture_private;
156 156
     const int is_field = s->picture_structure != PICT_FRAME;
... ...
@@ -159,11 +159,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
159 159
     uint8_t  *dxva_data, *current, *end;
160 160
     unsigned dxva_size;
161 161
     unsigned i;
162
+    unsigned type;
162 163
 
163
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
164
-                                              DXVA2_BitStreamDateBufferType,
165
-                                              &dxva_data_ptr, &dxva_size)))
166
-        return -1;
164
+#if CONFIG_D3D11VA
165
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
166
+        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
167
+        if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
168
+                                                       D3D11VA_CONTEXT(ctx)->decoder,
169
+                                                       type,
170
+                                                       &dxva_size, &dxva_data_ptr)))
171
+            return -1;
172
+    }
173
+#endif
174
+#if CONFIG_DXVA2
175
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
176
+        type = DXVA2_BitStreamDateBufferType;
177
+        if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
178
+                                                  type,
179
+                                                  &dxva_data_ptr, &dxva_size)))
180
+            return -1;
181
+    }
182
+#endif
167 183
 
168 184
     dxva_data = dxva_data_ptr;
169 185
     current = dxva_data;
... ...
@@ -189,19 +205,44 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
189 189
         memcpy(current, &ctx_pic->bitstream[position], size);
190 190
         current += size;
191 191
     }
192
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
193
-                                                  DXVA2_BitStreamDateBufferType)))
194
-        return -1;
192
+#if CONFIG_D3D11VA
193
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
194
+        if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
195
+            return -1;
196
+#endif
197
+#if CONFIG_DXVA2
198
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
199
+        if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
200
+            return -1;
201
+#endif
195 202
     if (i < ctx_pic->slice_count)
196 203
         return -1;
197 204
 
198
-    memset(bs, 0, sizeof(*bs));
199
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
200
-    bs->DataSize             = current - dxva_data;
201
-    bs->NumMBsInBuffer       = mb_count;
205
+#if CONFIG_D3D11VA
206
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
207
+        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
208
+        memset(dsc11, 0, sizeof(*dsc11));
209
+        dsc11->BufferType           = type;
210
+        dsc11->DataSize             = current - dxva_data;
211
+        dsc11->NumMBsInBuffer       = mb_count;
212
+
213
+        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
214
+    }
215
+#endif
216
+#if CONFIG_DXVA2
217
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
218
+        DXVA2_DecodeBufferDesc *dsc2 = bs;
219
+        memset(dsc2, 0, sizeof(*dsc2));
220
+        dsc2->CompressedBufferType = type;
221
+        dsc2->DataSize             = current - dxva_data;
222
+        dsc2->NumMBsInBuffer       = mb_count;
223
+
224
+        type = DXVA2_SliceControlBufferType;
225
+    }
226
+#endif
202 227
 
203 228
     return ff_dxva2_commit_buffer(avctx, ctx, sc,
204
-                                  DXVA2_SliceControlBufferType,
229
+                                  type,
205 230
                                   ctx_pic->slice,
206 231
                                   ctx_pic->slice_count * sizeof(*ctx_pic->slice),
207 232
                                   mb_count);
... ...
@@ -212,11 +253,13 @@ static int dxva2_mpeg2_start_frame(AVCodecContext *avctx,
212 212
                                    av_unused uint32_t size)
213 213
 {
214 214
     const struct MpegEncContext *s = avctx->priv_data;
215
-    struct dxva_context *ctx = avctx->hwaccel_context;
215
+    AVDXVAContext *ctx = avctx->hwaccel_context;
216 216
     struct dxva2_picture_context *ctx_pic =
217 217
         s->current_picture_ptr->hwaccel_picture_private;
218 218
 
219
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
219
+    if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
220
+        DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
221
+        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
220 222
         return -1;
221 223
     assert(ctx_pic);
222 224
 
... ...
@@ -270,6 +313,7 @@ static int dxva2_mpeg2_end_frame(AVCodecContext *avctx)
270 270
     return ret;
271 271
 }
272 272
 
273
+#if CONFIG_MPEG2_DXVA2_HWACCEL
273 274
 AVHWAccel ff_mpeg2_dxva2_hwaccel = {
274 275
     .name           = "mpeg2_dxva2",
275 276
     .type           = AVMEDIA_TYPE_VIDEO,
... ...
@@ -280,3 +324,17 @@ AVHWAccel ff_mpeg2_dxva2_hwaccel = {
280 280
     .end_frame      = dxva2_mpeg2_end_frame,
281 281
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
282 282
 };
283
+#endif
284
+
285
+#if CONFIG_MPEG2_D3D11VA_HWACCEL
286
+AVHWAccel ff_mpeg2_d3d11va_hwaccel = {
287
+    .name           = "mpeg2_d3d11va",
288
+    .type           = AVMEDIA_TYPE_VIDEO,
289
+    .id             = AV_CODEC_ID_MPEG2VIDEO,
290
+    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
291
+    .start_frame    = dxva2_mpeg2_start_frame,
292
+    .decode_slice   = dxva2_mpeg2_decode_slice,
293
+    .end_frame      = dxva2_mpeg2_end_frame,
294
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
295
+};
296
+#endif
... ...
@@ -34,7 +34,7 @@ struct dxva2_picture_context {
34 34
 };
35 35
 
36 36
 static void fill_picture_parameters(AVCodecContext *avctx,
37
-                                    struct dxva_context *ctx, const VC1Context *v,
37
+                                    AVDXVAContext *ctx, const VC1Context *v,
38 38
                                     DXVA_PictureParameters *pp)
39 39
 {
40 40
     const MpegEncContext *s = &v->s;
... ...
@@ -51,13 +51,13 @@ static void fill_picture_parameters(AVCodecContext *avctx,
51 51
 
52 52
     memset(pp, 0, sizeof(*pp));
53 53
     pp->wDecodedPictureIndex    =
54
-    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(ctx, current_picture->f);
54
+    pp->wDeblockedPictureIndex  = ff_dxva2_get_surface_index(avctx, ctx, current_picture->f);
55 55
     if (s->pict_type != AV_PICTURE_TYPE_I && !v->bi_type)
56
-        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->last_picture.f);
56
+        pp->wForwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->last_picture.f);
57 57
     else
58 58
         pp->wForwardRefPictureIndex = 0xffff;
59 59
     if (s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type)
60
-        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(ctx, s->next_picture.f);
60
+        pp->wBackwardRefPictureIndex = ff_dxva2_get_surface_index(avctx, ctx, s->next_picture.f);
61 61
     else
62 62
         pp->wBackwardRefPictureIndex = 0xffff;
63 63
     if (v->profile == PROFILE_ADVANCED) {
... ...
@@ -82,8 +82,8 @@ static void fill_picture_parameters(AVCodecContext *avctx,
82 82
     pp->bPicIntra               = s->pict_type == AV_PICTURE_TYPE_I || v->bi_type;
83 83
     pp->bPicBackwardPrediction  = s->pict_type == AV_PICTURE_TYPE_B && !v->bi_type;
84 84
     pp->bBidirectionalAveragingMode = (1                                           << 7) |
85
-                                      ((ctx->cfg->ConfigIntraResidUnsigned != 0)   << 6) |
86
-                                      ((ctx->cfg->ConfigResidDiffAccelerator != 0) << 5) |
85
+                                      ((DXVA_CONTEXT_CFG_INTRARESID(avctx, ctx) != 0) << 6) |
86
+                                      ((DXVA_CONTEXT_CFG_RESIDACCEL(avctx, ctx) != 0) << 5) |
87 87
                                       (intcomp                                     << 4) |
88 88
                                       ((v->profile == PROFILE_ADVANCED)            << 3);
89 89
     pp->bMVprecisionAndChromaRelation = ((v->mv_mode == MV_PMODE_1MV_HPEL_BILIN) << 3) |
... ...
@@ -91,11 +91,11 @@ static void fill_picture_parameters(AVCodecContext *avctx,
91 91
                                         (0                                       << 1) |
92 92
                                         (!s->quarter_sample                          );
93 93
     pp->bChromaFormat           = v->chromaformat;
94
-    ctx->report_id++;
95
-    if (ctx->report_id >= (1 << 16))
96
-        ctx->report_id = 1;
97
-    pp->bPicScanFixed           = ctx->report_id >> 8;
98
-    pp->bPicScanMethod          = ctx->report_id & 0xff;
94
+    DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;
95
+    if (DXVA_CONTEXT_REPORT_ID(avctx, ctx) >= (1 << 16))
96
+        DXVA_CONTEXT_REPORT_ID(avctx, ctx) = 1;
97
+    pp->bPicScanFixed           = DXVA_CONTEXT_REPORT_ID(avctx, ctx) >> 8;
98
+    pp->bPicScanMethod          = DXVA_CONTEXT_REPORT_ID(avctx, ctx) & 0xff;
99 99
     pp->bPicReadbackRequests    = 0;
100 100
     pp->bRcontrol               = v->rnd;
101 101
     pp->bPicSpatialResid8       = (v->panscanflag  << 7) |
... ...
@@ -176,11 +176,11 @@ static void fill_slice(AVCodecContext *avctx, DXVA_SliceInfo *slice,
176 176
 }
177 177
 
178 178
 static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
179
-                                             DXVA2_DecodeBufferDesc *bs,
180
-                                             DXVA2_DecodeBufferDesc *sc)
179
+                                             DECODER_BUFFER_DESC *bs,
180
+                                             DECODER_BUFFER_DESC *sc)
181 181
 {
182 182
     const VC1Context *v = avctx->priv_data;
183
-    struct dxva_context *ctx = avctx->hwaccel_context;
183
+    AVDXVAContext *ctx = avctx->hwaccel_context;
184 184
     const MpegEncContext *s = &v->s;
185 185
     struct dxva2_picture_context *ctx_pic = s->current_picture_ptr->hwaccel_picture_private;
186 186
 
... ...
@@ -196,11 +196,27 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
196 196
     uint8_t  *dxva_data;
197 197
     unsigned dxva_size;
198 198
     int result;
199
+    unsigned type;
199 200
 
200
-    if (FAILED(IDirectXVideoDecoder_GetBuffer(ctx->decoder,
201
-                                              DXVA2_BitStreamDateBufferType,
202
-                                              &dxva_data_ptr, &dxva_size)))
203
-        return -1;
201
+#if CONFIG_D3D11VA
202
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
203
+        type = D3D11_VIDEO_DECODER_BUFFER_BITSTREAM;
204
+        if (FAILED(ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context,
205
+                                                       D3D11VA_CONTEXT(ctx)->decoder,
206
+                                                       type,
207
+                                                       &dxva_size, &dxva_data_ptr)))
208
+            return -1;
209
+    }
210
+#endif
211
+#if CONFIG_DXVA2
212
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
213
+        type = DXVA2_BitStreamDateBufferType;
214
+        if (FAILED(IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder,
215
+                                                  type,
216
+                                                  &dxva_data_ptr, &dxva_size)))
217
+            return -1;
218
+    }
219
+#endif
204 220
 
205 221
     dxva_data = dxva_data_ptr;
206 222
     result = data_size <= dxva_size ? 0 : -1;
... ...
@@ -216,21 +232,46 @@ static int commit_bitstream_and_slice_buffer(AVCodecContext *avctx,
216 216
             memset(dxva_data + start_code_size + slice_size, 0, padding);
217 217
         slice->dwSliceBitsInBuffer = 8 * data_size;
218 218
     }
219
-    if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(ctx->decoder,
220
-                                                  DXVA2_BitStreamDateBufferType)))
221
-        return -1;
219
+#if CONFIG_D3D11VA
220
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD)
221
+        if (FAILED(ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type)))
222
+            return -1;
223
+#endif
224
+#if CONFIG_DXVA2
225
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD)
226
+        if (FAILED(IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type)))
227
+            return -1;
228
+#endif
222 229
     if (result)
223 230
         return result;
224 231
 
225
-    memset(bs, 0, sizeof(*bs));
226
-    bs->CompressedBufferType = DXVA2_BitStreamDateBufferType;
227
-    bs->DataSize             = data_size;
228
-    bs->NumMBsInBuffer       = s->mb_width * s->mb_height;
229
-    assert((bs->DataSize & 127) == 0);
232
+#if CONFIG_D3D11VA
233
+    if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) {
234
+        D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = bs;
235
+        memset(dsc11, 0, sizeof(*dsc11));
236
+        dsc11->BufferType           = type;
237
+        dsc11->DataSize             = data_size;
238
+        dsc11->NumMBsInBuffer       = s->mb_width * s->mb_height;
239
+
240
+        type = D3D11_VIDEO_DECODER_BUFFER_SLICE_CONTROL;
241
+    }
242
+#endif
243
+#if CONFIG_DXVA2
244
+    if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) {
245
+        DXVA2_DecodeBufferDesc *dsc2 = bs;
246
+        memset(dsc2, 0, sizeof(*dsc2));
247
+        dsc2->CompressedBufferType = type;
248
+        dsc2->DataSize             = data_size;
249
+        dsc2->NumMBsInBuffer       = s->mb_width * s->mb_height;
250
+
251
+        type = DXVA2_SliceControlBufferType;
252
+    }
253
+#endif
254
+    assert((data_size & 127) == 0);
230 255
 
231 256
     return ff_dxva2_commit_buffer(avctx, ctx, sc,
232
-                                  DXVA2_SliceControlBufferType,
233
-                                  slice, sizeof(*slice), bs->NumMBsInBuffer);
257
+                                  type,
258
+                                  slice, sizeof(*slice), s->mb_width * s->mb_height);
234 259
 }
235 260
 
236 261
 static int dxva2_vc1_start_frame(AVCodecContext *avctx,
... ...
@@ -238,10 +279,12 @@ static int dxva2_vc1_start_frame(AVCodecContext *avctx,
238 238
                                  av_unused uint32_t size)
239 239
 {
240 240
     const VC1Context *v = avctx->priv_data;
241
-    struct dxva_context *ctx = avctx->hwaccel_context;
241
+    AVDXVAContext *ctx = avctx->hwaccel_context;
242 242
     struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;
243 243
 
244
-    if (!ctx->decoder || !ctx->cfg || ctx->surface_count <= 0)
244
+    if (DXVA_CONTEXT_DECODER(avctx, ctx) == NULL ||
245
+        DXVA_CONTEXT_CFG(avctx, ctx) == NULL ||
246
+        DXVA_CONTEXT_COUNT(avctx, ctx) <= 0)
245 247
         return -1;
246 248
     assert(ctx_pic);
247 249
 
... ...
@@ -307,6 +350,7 @@ AVHWAccel ff_wmv3_dxva2_hwaccel = {
307 307
 };
308 308
 #endif
309 309
 
310
+#if CONFIG_VC1_DXVA2_HWACCEL
310 311
 AVHWAccel ff_vc1_dxva2_hwaccel = {
311 312
     .name           = "vc1_dxva2",
312 313
     .type           = AVMEDIA_TYPE_VIDEO,
... ...
@@ -317,3 +361,30 @@ AVHWAccel ff_vc1_dxva2_hwaccel = {
317 317
     .end_frame      = dxva2_vc1_end_frame,
318 318
     .frame_priv_data_size = sizeof(struct dxva2_picture_context),
319 319
 };
320
+#endif
321
+
322
+#if CONFIG_WMV3_D3D11VA_HWACCEL
323
+AVHWAccel ff_wmv3_d3d11va_hwaccel = {
324
+    .name           = "wmv3_d3d11va",
325
+    .type           = AVMEDIA_TYPE_VIDEO,
326
+    .id             = AV_CODEC_ID_WMV3,
327
+    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
328
+    .start_frame    = dxva2_vc1_start_frame,
329
+    .decode_slice   = dxva2_vc1_decode_slice,
330
+    .end_frame      = dxva2_vc1_end_frame,
331
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
332
+};
333
+#endif
334
+
335
+#if CONFIG_VC1_D3D11VA_HWACCEL
336
+AVHWAccel ff_vc1_d3d11va_hwaccel = {
337
+    .name           = "vc1_d3d11va",
338
+    .type           = AVMEDIA_TYPE_VIDEO,
339
+    .id             = AV_CODEC_ID_VC1,
340
+    .pix_fmt        = AV_PIX_FMT_D3D11VA_VLD,
341
+    .start_frame    = dxva2_vc1_start_frame,
342
+    .decode_slice   = dxva2_vc1_decode_slice,
343
+    .end_frame      = dxva2_vc1_end_frame,
344
+    .frame_priv_data_size = sizeof(struct dxva2_picture_context),
345
+};
346
+#endif
... ...
@@ -935,6 +935,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
935 935
 #if CONFIG_H264_DXVA2_HWACCEL
936 936
             *fmt++ = AV_PIX_FMT_DXVA2_VLD;
937 937
 #endif
938
+#if CONFIG_H264_D3D11VA_HWACCEL
939
+            *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
940
+#endif
938 941
 #if CONFIG_H264_VAAPI_HWACCEL
939 942
             *fmt++ = AV_PIX_FMT_VAAPI_VLD;
940 943
 #endif
... ...
@@ -343,6 +343,9 @@ static int set_sps(HEVCContext *s, const HEVCSPS *sps, enum AVPixelFormat pix_fm
343 343
 #if CONFIG_HEVC_DXVA2_HWACCEL
344 344
         *fmt++ = AV_PIX_FMT_DXVA2_VLD;
345 345
 #endif
346
+#if CONFIG_HEVC_D3D11VA_HWACCEL
347
+        *fmt++ = AV_PIX_FMT_D3D11VA_VLD;
348
+#endif
346 349
     }
347 350
 
348 351
     if (pix_fmt == AV_PIX_FMT_NONE) {
... ...
@@ -1204,6 +1204,9 @@ static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
1204 1204
 #if CONFIG_MPEG2_DXVA2_HWACCEL
1205 1205
     AV_PIX_FMT_DXVA2_VLD,
1206 1206
 #endif
1207
+#if CONFIG_MPEG2_D3D11VA_HWACCEL
1208
+    AV_PIX_FMT_D3D11VA_VLD,
1209
+#endif
1207 1210
 #if CONFIG_MPEG2_VAAPI_HWACCEL
1208 1211
     AV_PIX_FMT_VAAPI_VLD,
1209 1212
 #endif
... ...
@@ -1074,6 +1074,9 @@ static const enum AVPixelFormat vc1_hwaccel_pixfmt_list_420[] = {
1074 1074
 #if CONFIG_VC1_DXVA2_HWACCEL
1075 1075
     AV_PIX_FMT_DXVA2_VLD,
1076 1076
 #endif
1077
+#if CONFIG_VC1_D3D11VA_HWACCEL
1078
+    AV_PIX_FMT_D3D11VA_VLD,
1079
+#endif
1077 1080
 #if CONFIG_VC1_VAAPI_HWACCEL
1078 1081
     AV_PIX_FMT_VAAPI_VLD,
1079 1082
 #endif
... ...
@@ -29,7 +29,7 @@
29 29
 #include "libavutil/version.h"
30 30
 
31 31
 #define LIBAVCODEC_VERSION_MAJOR 56
32
-#define LIBAVCODEC_VERSION_MINOR  40
32
+#define LIBAVCODEC_VERSION_MINOR  41
33 33
 #define LIBAVCODEC_VERSION_MICRO 100
34 34
 
35 35
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
... ...
@@ -1586,6 +1586,12 @@ const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = {
1586 1586
         },
1587 1587
         .flags = AV_PIX_FMT_FLAG_BE | AV_PIX_FMT_FLAG_PLANAR,
1588 1588
     },
1589
+    [AV_PIX_FMT_D3D11VA_VLD] = {
1590
+        .name = "d3d11va_vld",
1591
+        .log2_chroma_w = 1,
1592
+        .log2_chroma_h = 1,
1593
+        .flags = AV_PIX_FMT_FLAG_HWACCEL,
1594
+    },
1589 1595
     [AV_PIX_FMT_DXVA2_VLD] = {
1590 1596
         .name = "dxva2_vld",
1591 1597
         .log2_chroma_w = 1,
... ...
@@ -258,6 +258,8 @@ enum AVPixelFormat {
258 258
      */
259 259
     AV_PIX_FMT_MMAL,
260 260
 
261
+    AV_PIX_FMT_D3D11VA_VLD,  ///< HW decoding through Direct3D11, Picture.data[3] contains a ID3D11VideoDecoderOutputView pointer
262
+
261 263
 #ifndef AV_PIX_FMT_ABI_GIT_MASTER
262 264
     AV_PIX_FMT_RGBA64BE=0x123,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as big-endian
263 265
     AV_PIX_FMT_RGBA64LE,  ///< packed RGBA 16:16:16:16, 64bpp, 16R, 16G, 16B, 16A, the 2-byte value for each R/G/B/A component is stored as little-endian
... ...
@@ -56,8 +56,8 @@
56 56
  */
57 57
 
58 58
 #define LIBAVUTIL_VERSION_MAJOR  54
59
-#define LIBAVUTIL_VERSION_MINOR  23
60
-#define LIBAVUTIL_VERSION_MICRO 101
59
+#define LIBAVUTIL_VERSION_MINOR  24
60
+#define LIBAVUTIL_VERSION_MICRO 100
61 61
 
62 62
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
63 63
                                                LIBAVUTIL_VERSION_MINOR, \