Libav
hevcdsp.c
Go to the documentation of this file.
1 /*
2  * HEVC video decoder
3  *
4  * Copyright (C) 2012 - 2013 Guillaume Martres
5  *
6  * This file is part of Libav.
7  *
8  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "hevcdsp.h"
24 
25 static const int8_t transform[32][32] = {
26  { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
27  64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64 },
28  { 90, 90, 88, 85, 82, 78, 73, 67, 61, 54, 46, 38, 31, 22, 13, 4,
29  -4, -13, -22, -31, -38, -46, -54, -61, -67, -73, -78, -82, -85, -88, -90, -90 },
30  { 90, 87, 80, 70, 57, 43, 25, 9, -9, -25, -43, -57, -70, -80, -87, -90,
31  -90, -87, -80, -70, -57, -43, -25, -9, 9, 25, 43, 57, 70, 80, 87, 90 },
32  { 90, 82, 67, 46, 22, -4, -31, -54, -73, -85, -90, -88, -78, -61, -38, -13,
33  13, 38, 61, 78, 88, 90, 85, 73, 54, 31, 4, -22, -46, -67, -82, -90 },
34  { 89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89,
35  89, 75, 50, 18, -18, -50, -75, -89, -89, -75, -50, -18, 18, 50, 75, 89 },
36  { 88, 67, 31, -13, -54, -82, -90, -78, -46, -4, 38, 73, 90, 85, 61, 22,
37  -22, -61, -85, -90, -73, -38, 4, 46, 78, 90, 82, 54, 13, -31, -67, -88 },
38  { 87, 57, 9, -43, -80, -90, -70, -25, 25, 70, 90, 80, 43, -9, -57, -87,
39  -87, -57, -9, 43, 80, 90, 70, 25, -25, -70, -90, -80, -43, 9, 57, 87 },
40  { 85, 46, -13, -67, -90, -73, -22, 38, 82, 88, 54, -4, -61, -90, -78, -31,
41  31, 78, 90, 61, 4, -54, -88, -82, -38, 22, 73, 90, 67, 13, -46, -85 },
42  { 83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83,
43  83, 36, -36, -83, -83, -36, 36, 83, 83, 36, -36, -83, -83, -36, 36, 83 },
44  { 82, 22, -54, -90, -61, 13, 78, 85, 31, -46, -90, -67, 4, 73, 88, 38,
45  -38, -88, -73, -4, 67, 90, 46, -31, -85, -78, -13, 61, 90, 54, -22, -82 },
46  { 80, 9, -70, -87, -25, 57, 90, 43, -43, -90, -57, 25, 87, 70, -9, -80,
47  -80, -9, 70, 87, 25, -57, -90, -43, 43, 90, 57, -25, -87, -70, 9, 80 },
48  { 78, -4, -82, -73, 13, 85, 67, -22, -88, -61, 31, 90, 54, -38, -90, -46,
49  46, 90, 38, -54, -90, -31, 61, 88, 22, -67, -85, -13, 73, 82, 4, -78 },
50  { 75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75,
51  75, -18, -89, -50, 50, 89, 18, -75, -75, 18, 89, 50, -50, -89, -18, 75 },
52  { 73, -31, -90, -22, 78, 67, -38, -90, -13, 82, 61, -46, -88, -4, 85, 54,
53  -54, -85, 4, 88, 46, -61, -82, 13, 90, 38, -67, -78, 22, 90, 31, -73 },
54  { 70, -43, -87, 9, 90, 25, -80, -57, 57, 80, -25, -90, -9, 87, 43, -70,
55  -70, 43, 87, -9, -90, -25, 80, 57, -57, -80, 25, 90, 9, -87, -43, 70 },
56  { 67, -54, -78, 38, 85, -22, -90, 4, 90, 13, -88, -31, 82, 46, -73, -61,
57  61, 73, -46, -82, 31, 88, -13, -90, -4, 90, 22, -85, -38, 78, 54, -67 },
58  { 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64,
59  64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64, 64, -64, -64, 64 },
60  { 61, -73, -46, 82, 31, -88, -13, 90, -4, -90, 22, 85, -38, -78, 54, 67,
61  -67, -54, 78, 38, -85, -22, 90, 4, -90, 13, 88, -31, -82, 46, 73, -61 },
62  { 57, -80, -25, 90, -9, -87, 43, 70, -70, -43, 87, 9, -90, 25, 80, -57,
63  -57, 80, 25, -90, 9, 87, -43, -70, 70, 43, -87, -9, 90, -25, -80, 57 },
64  { 54, -85, -4, 88, -46, -61, 82, 13, -90, 38, 67, -78, -22, 90, -31, -73,
65  73, 31, -90, 22, 78, -67, -38, 90, -13, -82, 61, 46, -88, 4, 85, -54 },
66  { 50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50,
67  50, -89, 18, 75, -75, -18, 89, -50, -50, 89, -18, -75, 75, 18, -89, 50 },
68  { 46, -90, 38, 54, -90, 31, 61, -88, 22, 67, -85, 13, 73, -82, 4, 78,
69  -78, -4, 82, -73, -13, 85, -67, -22, 88, -61, -31, 90, -54, -38, 90, -46 },
70  { 43, -90, 57, 25, -87, 70, 9, -80, 80, -9, -70, 87, -25, -57, 90, -43,
71  -43, 90, -57, -25, 87, -70, -9, 80, -80, 9, 70, -87, 25, 57, -90, 43 },
72  { 38, -88, 73, -4, -67, 90, -46, -31, 85, -78, 13, 61, -90, 54, 22, -82,
73  82, -22, -54, 90, -61, -13, 78, -85, 31, 46, -90, 67, 4, -73, 88, -38 },
74  { 36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36,
75  36, -83, 83, -36, -36, 83, -83, 36, 36, -83, 83, -36, -36, 83, -83, 36 },
76  { 31, -78, 90, -61, 4, 54, -88, 82, -38, -22, 73, -90, 67, -13, -46, 85,
77  -85, 46, 13, -67, 90, -73, 22, 38, -82, 88, -54, -4, 61, -90, 78, -31 },
78  { 25, -70, 90, -80, 43, 9, -57, 87, -87, 57, -9, -43, 80, -90, 70, -25,
79  -25, 70, -90, 80, -43, -9, 57, -87, 87, -57, 9, 43, -80, 90, -70, 25 },
80  { 22, -61, 85, -90, 73, -38, -4, 46, -78, 90, -82, 54, -13, -31, 67, -88,
81  88, -67, 31, 13, -54, 82, -90, 78, -46, 4, 38, -73, 90, -85, 61, -22 },
82  { 18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18,
83  18, -50, 75, -89, 89, -75, 50, -18, -18, 50, -75, 89, -89, 75, -50, 18 },
84  { 13, -38, 61, -78, 88, -90, 85, -73, 54, -31, 4, 22, -46, 67, -82, 90,
85  -90, 82, -67, 46, -22, -4, 31, -54, 73, -85, 90, -88, 78, -61, 38, -13 },
86  { 9, -25, 43, -57, 70, -80, 87, -90, 90, -87, 80, -70, 57, -43, 25, -9,
87  -9, 25, -43, 57, -70, 80, -87, 90, -90, 87, -80, 70, -57, 43, -25, 9 },
88  { 4, -13, 22, -31, 38, -46, 54, -61, 67, -73, 78, -82, 85, -88, 90, -90,
89  90, -90, 88, -85, 82, -78, 73, -67, 61, -54, 46, -38, 31, -22, 13, -4 },
90 };
91 
92 DECLARE_ALIGNED(16, const int16_t, ff_hevc_epel_coeffs[7][16]) = {
93  { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 },
94  { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 },
95  { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 },
96  { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 },
97  { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 },
98  { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 },
99  { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 },
100 };
101 
102 DECLARE_ALIGNED(16, const int8_t, ff_hevc_epel_coeffs8[7][16]) = {
103  { -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2, -2, 58, 10, -2 },
104  { -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2, -4, 54, 16, -2 },
105  { -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4, -6, 46, 28, -4 },
106  { -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4, -4, 36, 36, -4 },
107  { -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6, -4, 28, 46, -6 },
108  { -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4, -2, 16, 54, -4 },
109  { -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2, -2, 10, 58, -2 },
110 };
111 
112 DECLARE_ALIGNED(16, const int16_t, ff_hevc_qpel_coeffs[3][8]) = {
113  { -1, 4, -10, 58, 17, -5, 1, 0 },
114  { -1, 4, -11, 40, 40, -11, 4, -1 },
115  { 0, 1, -5, 17, 58, -10, 4, -1 },
116 };
117 
118 DECLARE_ALIGNED(16, const int8_t, ff_hevc_qpel_coeffs8[3][16]) = {
119  { -1, 4, -10, 58, 17, -5, 1, 0, -1, 4, -10, 58, 17, -5, 1, 0 },
120  { -1, 4, -11, 40, 40, -11, 4, -1, -1, 4, -11, 40, 40, -11, 4, -1 },
121  { 0, 1, -5, 17, 58, -10, 4, -1, 0, 1, -5, 17, 58, -10, 4, -1 },
122 };
123 
124 #define BIT_DEPTH 8
125 #include "hevcdsp_template.c"
126 #undef BIT_DEPTH
127 
128 #define BIT_DEPTH 9
129 #include "hevcdsp_template.c"
130 #undef BIT_DEPTH
131 
132 #define BIT_DEPTH 10
133 #include "hevcdsp_template.c"
134 #undef BIT_DEPTH
135 
136 void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth)
137 {
138 #undef FUNC
139 #define FUNC(a, depth) a ## _ ## depth
140 
141 #define QPEL_FUNC(i, width, depth) \
142  hevcdsp->put_hevc_qpel[0][0][i] = FUNC(put_hevc_qpel_pixels_ ## width, depth); \
143  hevcdsp->put_hevc_qpel[0][1][i] = FUNC(put_hevc_qpel_h_ ## width, depth); \
144  hevcdsp->put_hevc_qpel[1][0][i] = FUNC(put_hevc_qpel_v_ ## width, depth); \
145  hevcdsp->put_hevc_qpel[1][1][i] = FUNC(put_hevc_qpel_hv_ ## width, depth); \
146 
147 #define EPEL_FUNC(i, width, depth) \
148  hevcdsp->put_hevc_epel[0][0][i] = FUNC(put_hevc_epel_pixels_ ## width, depth); \
149  hevcdsp->put_hevc_epel[0][1][i] = FUNC(put_hevc_epel_h_ ## width, depth); \
150  hevcdsp->put_hevc_epel[1][0][i] = FUNC(put_hevc_epel_v_ ## width, depth); \
151  hevcdsp->put_hevc_epel[1][1][i] = FUNC(put_hevc_epel_hv_ ## width, depth); \
152 
153 #define PRED_FUNC(i, width, depth) \
154  hevcdsp->put_unweighted_pred[i] = FUNC(put_unweighted_pred_ ## width, depth); \
155  hevcdsp->put_unweighted_pred_avg[i] = FUNC(put_unweighted_pred_avg_ ## width, depth); \
156  hevcdsp->weighted_pred[i] = FUNC(put_weighted_pred_ ## width, depth); \
157  hevcdsp->weighted_pred_avg[i] = FUNC(put_weighted_pred_avg_ ## width, depth); \
158 
159 #define PRED_FUNC_CHROMA(i, width, depth) \
160  hevcdsp->put_unweighted_pred_chroma[i] = FUNC(put_unweighted_pred_ ## width, depth); \
161  hevcdsp->put_unweighted_pred_avg_chroma[i] = FUNC(put_unweighted_pred_avg_ ## width, depth); \
162  hevcdsp->weighted_pred_chroma[i] = FUNC(put_weighted_pred_ ## width, depth); \
163  hevcdsp->weighted_pred_avg_chroma[i] = FUNC(put_weighted_pred_avg_ ## width, depth); \
164 
165 #define HEVC_DSP(depth) \
166  hevcdsp->put_pcm = FUNC(put_pcm, depth); \
167  hevcdsp->add_residual[0] = FUNC(add_residual4x4, depth); \
168  hevcdsp->add_residual[1] = FUNC(add_residual8x8, depth); \
169  hevcdsp->add_residual[2] = FUNC(add_residual16x16, depth); \
170  hevcdsp->add_residual[3] = FUNC(add_residual32x32, depth); \
171  hevcdsp->dequant = FUNC(dequant, depth); \
172  hevcdsp->transform_4x4_luma = FUNC(transform_4x4_luma, depth); \
173  hevcdsp->idct[0] = FUNC(idct_4x4, depth); \
174  hevcdsp->idct[1] = FUNC(idct_8x8, depth); \
175  hevcdsp->idct[2] = FUNC(idct_16x16, depth); \
176  hevcdsp->idct[3] = FUNC(idct_32x32, depth); \
177  \
178  hevcdsp->idct_dc[0] = FUNC(idct_4x4_dc, depth); \
179  hevcdsp->idct_dc[1] = FUNC(idct_8x8_dc, depth); \
180  hevcdsp->idct_dc[2] = FUNC(idct_16x16_dc, depth); \
181  hevcdsp->idct_dc[3] = FUNC(idct_32x32_dc, depth); \
182  hevcdsp->sao_band_filter[0] = FUNC(sao_band_filter_0, depth); \
183  hevcdsp->sao_band_filter[1] = FUNC(sao_band_filter_1, depth); \
184  hevcdsp->sao_band_filter[2] = FUNC(sao_band_filter_2, depth); \
185  hevcdsp->sao_band_filter[3] = FUNC(sao_band_filter_3, depth); \
186  \
187  hevcdsp->sao_edge_filter[0] = FUNC(sao_edge_filter_0, depth); \
188  hevcdsp->sao_edge_filter[1] = FUNC(sao_edge_filter_1, depth); \
189  hevcdsp->sao_edge_filter[2] = FUNC(sao_edge_filter_2, depth); \
190  hevcdsp->sao_edge_filter[3] = FUNC(sao_edge_filter_3, depth); \
191  \
192  QPEL_FUNC(0, 4, depth); \
193  QPEL_FUNC(1, 8, depth); \
194  QPEL_FUNC(2, 12, depth); \
195  QPEL_FUNC(3, 16, depth); \
196  QPEL_FUNC(4, 24, depth); \
197  QPEL_FUNC(5, 32, depth); \
198  QPEL_FUNC(6, 48, depth); \
199  QPEL_FUNC(7, 64, depth); \
200  \
201  EPEL_FUNC(0, 2, depth); \
202  EPEL_FUNC(1, 4, depth); \
203  EPEL_FUNC(2, 6, depth); \
204  EPEL_FUNC(3, 8, depth); \
205  EPEL_FUNC(4, 12, depth); \
206  EPEL_FUNC(5, 16, depth); \
207  EPEL_FUNC(6, 24, depth); \
208  EPEL_FUNC(7, 32, depth); \
209  \
210  PRED_FUNC(0, 4, depth); \
211  PRED_FUNC(1, 8, depth); \
212  PRED_FUNC(2, 12, depth); \
213  PRED_FUNC(3, 16, depth); \
214  PRED_FUNC(4, 24, depth); \
215  PRED_FUNC(5, 32, depth); \
216  PRED_FUNC(6, 48, depth); \
217  PRED_FUNC(7, 64, depth); \
218  PRED_FUNC_CHROMA(0, 2, depth); \
219  PRED_FUNC_CHROMA(1, 4, depth); \
220  PRED_FUNC_CHROMA(2, 6, depth); \
221  PRED_FUNC_CHROMA(3, 8, depth); \
222  PRED_FUNC_CHROMA(4, 12, depth); \
223  PRED_FUNC_CHROMA(5, 16, depth); \
224  PRED_FUNC_CHROMA(6, 24, depth); \
225  PRED_FUNC_CHROMA(7, 32, depth); \
226  \
227  hevcdsp->hevc_h_loop_filter_luma = FUNC(hevc_h_loop_filter_luma, depth); \
228  hevcdsp->hevc_v_loop_filter_luma = FUNC(hevc_v_loop_filter_luma, depth); \
229  hevcdsp->hevc_h_loop_filter_chroma = FUNC(hevc_h_loop_filter_chroma, depth); \
230  hevcdsp->hevc_v_loop_filter_chroma = FUNC(hevc_v_loop_filter_chroma, depth); \
231  hevcdsp->hevc_h_loop_filter_luma_c = FUNC(hevc_h_loop_filter_luma, depth); \
232  hevcdsp->hevc_v_loop_filter_luma_c = FUNC(hevc_v_loop_filter_luma, depth); \
233  hevcdsp->hevc_h_loop_filter_chroma_c = FUNC(hevc_h_loop_filter_chroma, depth); \
234  hevcdsp->hevc_v_loop_filter_chroma_c = FUNC(hevc_v_loop_filter_chroma, depth);
235 
236  switch (bit_depth) {
237  case 9:
238  HEVC_DSP(9);
239  break;
240  case 10:
241  HEVC_DSP(10);
242  break;
243  default:
244  HEVC_DSP(8);
245  break;
246  }
247 
248  if (ARCH_X86)
249  ff_hevc_dsp_init_x86(hevcdsp, bit_depth);
250 }
#define HEVC_DSP(depth)
#define DECLARE_ALIGNED(n, t, v)
Definition: mem.h:58
const int16_t ff_hevc_epel_coeffs[7][16]
Definition: hevcdsp.c:92
#define ARCH_X86
Definition: config.h:33
const int8_t ff_hevc_epel_coeffs8[7][16]
Definition: hevcdsp.c:102
void ff_hevc_dsp_init_x86(HEVCDSPContext *c, const int bit_depth)
Definition: hevcdsp_init.c:239
static const int8_t transform[32][32]
Definition: hevcdsp.c:25
void ff_hevc_dsp_init(HEVCDSPContext *hevcdsp, int bit_depth)
Definition: hevcdsp.c:136
const int16_t ff_hevc_qpel_coeffs[3][8]
Definition: hevcdsp.c:112
const int8_t ff_hevc_qpel_coeffs8[3][16]
Definition: hevcdsp.c:118