summaryrefslogtreecommitdiffstats
path: root/vlc/build/patches/0001-avcodec-dxva2_hevc-add-support-for-parsing-HEVC-Rang.patch
blob: 29f87258de6a2d21f4f4238a3be39d749750fe0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
From 833195704700ba3fa326473292e91524964eeeaa Mon Sep 17 00:00:00 2001
From: Steve Lhomme <robux4@ycbcr.xyz>
Date: Thu, 3 Oct 2019 14:05:40 +0200
Subject: [PATCH 1/3] avcodec/dxva2_hevc: add support for parsing HEVC Range
 Extension data

---
 libavcodec/d3d11va.h    |  1 +
 libavcodec/dxva2.h      |  1 +
 libavcodec/dxva2_hevc.c | 79 ++++++++++++++++++++++++++++++++++++++---
 3 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/libavcodec/d3d11va.h b/libavcodec/d3d11va.h
index 6816b6c1e6..68a69c372d 100644
--- a/libavcodec/d3d11va.h
+++ b/libavcodec/d3d11va.h
@@ -47,6 +47,7 @@
 
 #define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for Direct3D11 and old UVD/UVD+ ATI video cards
 #define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO    2 ///< Work around for Direct3D11 and old Intel GPUs with ClearVideo interface
+#define FF_DXVA2_WORKAROUND_HEVC_REXT           4 ///< Signal the D3D11VA decoder is using the HEVC Rext picture structure
 
 /**
  * This structure is used to provides the necessary configurations and data
diff --git a/libavcodec/dxva2.h b/libavcodec/dxva2.h
index 22c93992f2..024999239d 100644
--- a/libavcodec/dxva2.h
+++ b/libavcodec/dxva2.h
@@ -47,6 +47,7 @@
 
 #define FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG 1 ///< Work around for DXVA2 and old UVD/UVD+ ATI video cards
 #define FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO    2 ///< Work around for DXVA2 and old Intel GPUs with ClearVideo interface
+#define FF_DXVA2_WORKAROUND_HEVC_REXT           4 ///< Signal the DXVA2 decoder is using the HEVC Rext picture structure
 
 /**
  * This structure is used to provides the necessary configurations and data
diff --git a/libavcodec/dxva2_hevc.c b/libavcodec/dxva2_hevc.c
index dbb701fb1c..98b3e74bd7 100644
--- a/libavcodec/dxva2_hevc.c
+++ b/libavcodec/dxva2_hevc.c
@@ -26,10 +26,47 @@
 #include "hevc_data.h"
 #include "hevcdec.h"
 
+#pragma pack(push, 1)
+typedef struct
+{
+    DXVA_PicParams_HEVC main;
+
+    // HEVC Range Extension
+    __C89_NAMELESS union {
+        __C89_NAMELESS struct {
+            UINT32 transform_skip_rotation_enabled_flag : 1;
+            UINT32 transform_skip_context_enabled_flag : 1;
+            UINT32 implicit_rdpcm_enabled_flag : 1;
+            UINT32 explicit_rdpcm_enabled_flag : 1;
+            UINT32 extended_precision_processing_flag : 1;
+            UINT32 intra_smoothing_disabled_flag : 1;
+            UINT32 high_precision_offsets_enabled_flag : 1;
+            UINT32 persistent_rice_adaptation_enabled_flag : 1;
+            UINT32 cabac_bypass_alignment_enabled_flag : 1;
+            UINT32 cross_component_prediction_enabled_flag : 1;
+            UINT32 chroma_qp_offset_list_enabled_flag : 1;
+            UINT32 BitDepthLuma16 : 1; // TODO merge in ReservedBits5 if not needed
+            UINT32 BitDepthChroma16 : 1; // TODO merge in ReservedBits5 if not needed
+            UINT32 ReservedBits8 : 19;
+        };
+        UINT32 dwRangeExtensionFlags;
+    };
+
+    UCHAR diff_cu_chroma_qp_offset_depth;
+    UCHAR chroma_qp_offset_list_len_minus1;
+    UCHAR log2_sao_offset_scale_luma;
+    UCHAR log2_sao_offset_scale_chroma;
+    UCHAR log2_max_transform_skip_block_size_minus2;
+    CHAR cb_qp_offset_list[6];
+    CHAR cr_qp_offset_list[6];
+
+} DXVA_PicParams_HEVC_Rext;
+#pragma pack(pop)
+
 #define MAX_SLICES 256
 
 struct hevc_dxva2_picture_context {
-    DXVA_PicParams_HEVC   pp;
+    DXVA_PicParams_HEVC_Rext pp;
     DXVA_Qmatrix_HEVC     qm;
     unsigned              slice_count;
     DXVA_Slice_HEVC_Short slice_short[MAX_SLICES];
@@ -55,18 +92,48 @@ static int get_refpic_index(const DXVA_PicParams_HEVC *pp, int surface_index)
 }
 
 static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const HEVCContext *h,
-                                    DXVA_PicParams_HEVC *pp)
+                                    DXVA_PicParams_HEVC_Rext *ppext)
 {
     const HEVCFrame *current_picture = h->ref;
     const HEVCSPS *sps = h->ps.sps;
     const HEVCPPS *pps = h->ps.pps;
     int i, j;
+    DXVA_PicParams_HEVC *pp = &ppext->main;
 
-    memset(pp, 0, sizeof(*pp));
+    memset(ppext, 0, sizeof(*ppext));
 
     pp->PicWidthInMinCbsY  = sps->min_cb_width;
     pp->PicHeightInMinCbsY = sps->min_cb_height;
 
+    if (sps->sps_range_extension_flag) {
+        ppext->dwRangeExtensionFlags |= (sps->transform_skip_rotation_enabled_flag     <<  0) |
+                                        (sps->transform_skip_context_enabled_flag      <<  1) |
+                                        (sps->implicit_rdpcm_enabled_flag              <<  2) |
+                                        (sps->explicit_rdpcm_enabled_flag              <<  3) |
+                                        (sps->extended_precision_processing_flag       <<  4) |
+                                        (sps->intra_smoothing_disabled_flag            <<  5) |
+                                        (sps->high_precision_offsets_enabled_flag      <<  5) |
+                                        (sps->persistent_rice_adaptation_enabled_flag  <<  7) |
+                                        (sps->cabac_bypass_alignment_enabled_flag      <<  8);
+    }
+    if (pps->pps_range_extensions_flag) {
+        ppext->dwRangeExtensionFlags |= (pps->cross_component_prediction_enabled_flag  <<  9) |
+                                        (pps->chroma_qp_offset_list_enabled_flag       << 10);
+        if (pps->chroma_qp_offset_list_enabled_flag) {
+            ppext->diff_cu_chroma_qp_offset_depth   = pps->diff_cu_chroma_qp_offset_depth;
+            ppext->chroma_qp_offset_list_len_minus1 = pps->chroma_qp_offset_list_len_minus1;
+            for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
+                ppext->cb_qp_offset_list[i] = pps->cb_qp_offset_list[i];
+                ppext->cr_qp_offset_list[i] = pps->cr_qp_offset_list[i];
+            }
+        }
+        ppext->log2_sao_offset_scale_luma   = pps->log2_sao_offset_scale_luma;
+        ppext->log2_sao_offset_scale_chroma = pps->log2_sao_offset_scale_chroma;
+        if (pps->transform_skip_enabled_flag) {
+            ppext->log2_max_transform_skip_block_size_minus2 = pps->log2_max_transform_skip_block_size - 2;
+        }
+    }
+
     pp->wFormatAndSequenceInfoFlags = (sps->chroma_format_idc             <<  0) |
                                       (sps->separate_colour_plane_flag    <<  2) |
                                       ((sps->bit_depth - 8)               <<  3) |
@@ -402,16 +469,18 @@ static int dxva2_hevc_decode_slice(AVCodecContext *avctx,
 
 static int dxva2_hevc_end_frame(AVCodecContext *avctx)
 {
+    AVDXVAContext *ctx = DXVA_CONTEXT(avctx);
     HEVCContext *h = avctx->priv_data;
     struct hevc_dxva2_picture_context *ctx_pic = h->ref->hwaccel_picture_private;
-    int scale = ctx_pic->pp.dwCodingParamToolFlags & 1;
+    int scale = ctx_pic->pp.main.dwCodingParamToolFlags & 1;
+    int rext = (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_HEVC_REXT);
     int ret;
 
     if (ctx_pic->slice_count <= 0 || ctx_pic->bitstream_size <= 0)
         return -1;
 
     ret = ff_dxva2_common_end_frame(avctx, h->ref->frame,
-                                    &ctx_pic->pp, sizeof(ctx_pic->pp),
+                                    &ctx_pic->pp, rext ? sizeof(ctx_pic->pp) : sizeof(ctx_pic->pp.main),
                                     scale ? &ctx_pic->qm : NULL, scale ? sizeof(ctx_pic->qm) : 0,
                                     commit_bitstream_and_slice_buffer);
     return ret;
-- 
2.27.0.windows.1