lavc/aarch64: add ff_simple_idct{,_add,_put}_neon functions
[ffmpeg.git] / libavcodec / idctdsp.c
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include "config.h"
20 #include "libavutil/attributes.h"
21 #include "libavutil/common.h"
22 #include "avcodec.h"
23 #include "dct.h"
24 #include "faanidct.h"
25 #include "idctdsp.h"
26 #include "simple_idct.h"
27 #include "xvididct.h"
28
29 av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st,
30                                const uint8_t *src_scantable)
31 {
32     int i, end;
33
34     st->scantable = src_scantable;
35
36     for (i = 0; i < 64; i++) {
37         int j = src_scantable[i];
38         st->permutated[i] = permutation[j];
39     }
40
41     end = -1;
42     for (i = 0; i < 64; i++) {
43         int j = st->permutated[i];
44         if (j > end)
45             end = j;
46         st->raster_end[i] = end;
47     }
48 }
49
50 av_cold void ff_init_scantable_permutation(uint8_t *idct_permutation,
51                                            enum idct_permutation_type perm_type)
52 {
53     int i;
54
55     if (ARCH_X86)
56         if (ff_init_scantable_permutation_x86(idct_permutation,
57                                               perm_type))
58             return;
59
60     switch (perm_type) {
61     case FF_IDCT_PERM_NONE:
62         for (i = 0; i < 64; i++)
63             idct_permutation[i] = i;
64         break;
65     case FF_IDCT_PERM_LIBMPEG2:
66         for (i = 0; i < 64; i++)
67             idct_permutation[i] = (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);
68         break;
69     case FF_IDCT_PERM_TRANSPOSE:
70         for (i = 0; i < 64; i++)
71             idct_permutation[i] = ((i & 7) << 3) | (i >> 3);
72         break;
73     case FF_IDCT_PERM_PARTTRANS:
74         for (i = 0; i < 64; i++)
75             idct_permutation[i] = (i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3);
76         break;
77     default:
78         av_log(NULL, AV_LOG_ERROR,
79                "Internal error, IDCT permutation not set\n");
80     }
81 }
82
83 void (*ff_put_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
84 void (*ff_add_pixels_clamped)(const int16_t *block, uint8_t *pixels, ptrdiff_t line_size);
85
86 static void put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
87                                  ptrdiff_t line_size)
88 {
89     int i;
90
91     /* read the pixels */
92     for (i = 0; i < 8; i++) {
93         pixels[0] = av_clip_uint8(block[0]);
94         pixels[1] = av_clip_uint8(block[1]);
95         pixels[2] = av_clip_uint8(block[2]);
96         pixels[3] = av_clip_uint8(block[3]);
97         pixels[4] = av_clip_uint8(block[4]);
98         pixels[5] = av_clip_uint8(block[5]);
99         pixels[6] = av_clip_uint8(block[6]);
100         pixels[7] = av_clip_uint8(block[7]);
101
102         pixels += line_size;
103         block  += 8;
104     }
105 }
106
107 static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
108                                  int line_size)
109 {
110     int i;
111
112     /* read the pixels */
113     for(i=0;i<4;i++) {
114         pixels[0] = av_clip_uint8(block[0]);
115         pixels[1] = av_clip_uint8(block[1]);
116         pixels[2] = av_clip_uint8(block[2]);
117         pixels[3] = av_clip_uint8(block[3]);
118
119         pixels += line_size;
120         block += 8;
121     }
122 }
123
124 static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
125                                  int line_size)
126 {
127     int i;
128
129     /* read the pixels */
130     for(i=0;i<2;i++) {
131         pixels[0] = av_clip_uint8(block[0]);
132         pixels[1] = av_clip_uint8(block[1]);
133
134         pixels += line_size;
135         block += 8;
136     }
137 }
138
139 static void put_signed_pixels_clamped_c(const int16_t *block,
140                                         uint8_t *av_restrict pixels,
141                                         ptrdiff_t line_size)
142 {
143     int i, j;
144
145     for (i = 0; i < 8; i++) {
146         for (j = 0; j < 8; j++) {
147             if (*block < -128)
148                 *pixels = 0;
149             else if (*block > 127)
150                 *pixels = 255;
151             else
152                 *pixels = (uint8_t) (*block + 128);
153             block++;
154             pixels++;
155         }
156         pixels += (line_size - 8);
157     }
158 }
159
160 static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
161                                  ptrdiff_t line_size)
162 {
163     int i;
164
165     /* read the pixels */
166     for (i = 0; i < 8; i++) {
167         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
168         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
169         pixels[2] = av_clip_uint8(pixels[2] + block[2]);
170         pixels[3] = av_clip_uint8(pixels[3] + block[3]);
171         pixels[4] = av_clip_uint8(pixels[4] + block[4]);
172         pixels[5] = av_clip_uint8(pixels[5] + block[5]);
173         pixels[6] = av_clip_uint8(pixels[6] + block[6]);
174         pixels[7] = av_clip_uint8(pixels[7] + block[7]);
175         pixels   += line_size;
176         block    += 8;
177     }
178 }
179
180 static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
181                           int line_size)
182 {
183     int i;
184
185     /* read the pixels */
186     for(i=0;i<4;i++) {
187         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
188         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
189         pixels[2] = av_clip_uint8(pixels[2] + block[2]);
190         pixels[3] = av_clip_uint8(pixels[3] + block[3]);
191         pixels += line_size;
192         block += 8;
193     }
194 }
195
196 static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
197                           int line_size)
198 {
199     int i;
200
201     /* read the pixels */
202     for(i=0;i<2;i++) {
203         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
204         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
205         pixels += line_size;
206         block += 8;
207     }
208 }
209
210 static void ff_jref_idct4_put(uint8_t *dest, int line_size, int16_t *block)
211 {
212     ff_j_rev_dct4 (block);
213     put_pixels_clamped4_c(block, dest, line_size);
214 }
215 static void ff_jref_idct4_add(uint8_t *dest, int line_size, int16_t *block)
216 {
217     ff_j_rev_dct4 (block);
218     add_pixels_clamped4_c(block, dest, line_size);
219 }
220
221 static void ff_jref_idct2_put(uint8_t *dest, int line_size, int16_t *block)
222 {
223     ff_j_rev_dct2 (block);
224     put_pixels_clamped2_c(block, dest, line_size);
225 }
226 static void ff_jref_idct2_add(uint8_t *dest, int line_size, int16_t *block)
227 {
228     ff_j_rev_dct2 (block);
229     add_pixels_clamped2_c(block, dest, line_size);
230 }
231
232 static void ff_jref_idct1_put(uint8_t *dest, int line_size, int16_t *block)
233 {
234     dest[0] = av_clip_uint8((block[0] + 4)>>3);
235 }
236 static void ff_jref_idct1_add(uint8_t *dest, int line_size, int16_t *block)
237 {
238     dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3));
239 }
240
241 av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
242 {
243     const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;
244
245     if (avctx->lowres==1) {
246         c->idct_put  = ff_jref_idct4_put;
247         c->idct_add  = ff_jref_idct4_add;
248         c->idct      = ff_j_rev_dct4;
249         c->perm_type = FF_IDCT_PERM_NONE;
250     } else if (avctx->lowres==2) {
251         c->idct_put  = ff_jref_idct2_put;
252         c->idct_add  = ff_jref_idct2_add;
253         c->idct      = ff_j_rev_dct2;
254         c->perm_type = FF_IDCT_PERM_NONE;
255     } else if (avctx->lowres==3) {
256         c->idct_put  = ff_jref_idct1_put;
257         c->idct_add  = ff_jref_idct1_add;
258         c->idct      = ff_j_rev_dct1;
259         c->perm_type = FF_IDCT_PERM_NONE;
260     } else {
261         if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) {
262             c->idct_put              = ff_simple_idct_put_10;
263             c->idct_add              = ff_simple_idct_add_10;
264             c->idct                  = ff_simple_idct_10;
265             c->perm_type             = FF_IDCT_PERM_NONE;
266         } else if (avctx->bits_per_raw_sample == 12) {
267             c->idct_put              = ff_simple_idct_put_12;
268             c->idct_add              = ff_simple_idct_add_12;
269             c->idct                  = ff_simple_idct_12;
270             c->perm_type             = FF_IDCT_PERM_NONE;
271         } else {
272             if (avctx->idct_algo == FF_IDCT_INT) {
273                 c->idct_put  = ff_jref_idct_put;
274                 c->idct_add  = ff_jref_idct_add;
275                 c->idct      = ff_j_rev_dct;
276                 c->perm_type = FF_IDCT_PERM_LIBMPEG2;
277 #if CONFIG_FAANIDCT
278             } else if (avctx->idct_algo == FF_IDCT_FAAN) {
279                 c->idct_put  = ff_faanidct_put;
280                 c->idct_add  = ff_faanidct_add;
281                 c->idct      = ff_faanidct;
282                 c->perm_type = FF_IDCT_PERM_NONE;
283 #endif /* CONFIG_FAANIDCT */
284             } else { // accurate/default
285                 c->idct_put  = ff_simple_idct_put_8;
286                 c->idct_add  = ff_simple_idct_add_8;
287                 c->idct      = ff_simple_idct_8;
288                 c->perm_type = FF_IDCT_PERM_NONE;
289             }
290         }
291     }
292
293     c->put_pixels_clamped        = put_pixels_clamped_c;
294     c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;
295     c->add_pixels_clamped        = add_pixels_clamped_c;
296
297     if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID)
298         ff_xvid_idct_init(c, avctx);
299
300     if (ARCH_AARCH64)
301         ff_idctdsp_init_aarch64(c, avctx, high_bit_depth);
302     if (ARCH_ALPHA)
303         ff_idctdsp_init_alpha(c, avctx, high_bit_depth);
304     if (ARCH_ARM)
305         ff_idctdsp_init_arm(c, avctx, high_bit_depth);
306     if (ARCH_PPC)
307         ff_idctdsp_init_ppc(c, avctx, high_bit_depth);
308     if (ARCH_X86)
309         ff_idctdsp_init_x86(c, avctx, high_bit_depth);
310     if (ARCH_MIPS)
311         ff_idctdsp_init_mips(c, avctx, high_bit_depth);
312
313     ff_put_pixels_clamped = c->put_pixels_clamped;
314     ff_add_pixels_clamped = c->add_pixels_clamped;
315
316     ff_init_scantable_permutation(c->idct_permutation,
317                                   c->perm_type);
318 }