hevc: ppc: Add HEVC 4x4 IDCT for PowerPC
[ffmpeg.git] / libavcodec / hevcdsp.c
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_PPC)
249         ff_hevc_dsp_init_ppc(hevcdsp, bit_depth);
250     if (ARCH_X86)
251         ff_hevc_dsp_init_x86(hevcdsp, bit_depth);
252 }