• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
ff_init_scantable(uint8_t * permutation,ScanTable * st,const uint8_t * src_scantable)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 
ff_init_scantable_permutation(uint8_t * idct_permutation,enum idct_permutation_type perm_type)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 
ff_put_pixels_clamped_c(const int16_t * block,uint8_t * av_restrict pixels,ptrdiff_t line_size)83 void ff_put_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
84                              ptrdiff_t line_size)
85 {
86     int i;
87 
88     /* read the pixels */
89     for (i = 0; i < 8; i++) {
90         pixels[0] = av_clip_uint8(block[0]);
91         pixels[1] = av_clip_uint8(block[1]);
92         pixels[2] = av_clip_uint8(block[2]);
93         pixels[3] = av_clip_uint8(block[3]);
94         pixels[4] = av_clip_uint8(block[4]);
95         pixels[5] = av_clip_uint8(block[5]);
96         pixels[6] = av_clip_uint8(block[6]);
97         pixels[7] = av_clip_uint8(block[7]);
98 
99         pixels += line_size;
100         block  += 8;
101     }
102 }
103 
put_pixels_clamped4_c(const int16_t * block,uint8_t * av_restrict pixels,int line_size)104 static void put_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
105                                  int line_size)
106 {
107     int i;
108 
109     /* read the pixels */
110     for(i=0;i<4;i++) {
111         pixels[0] = av_clip_uint8(block[0]);
112         pixels[1] = av_clip_uint8(block[1]);
113         pixels[2] = av_clip_uint8(block[2]);
114         pixels[3] = av_clip_uint8(block[3]);
115 
116         pixels += line_size;
117         block += 8;
118     }
119 }
120 
put_pixels_clamped2_c(const int16_t * block,uint8_t * av_restrict pixels,int line_size)121 static void put_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
122                                  int line_size)
123 {
124     int i;
125 
126     /* read the pixels */
127     for(i=0;i<2;i++) {
128         pixels[0] = av_clip_uint8(block[0]);
129         pixels[1] = av_clip_uint8(block[1]);
130 
131         pixels += line_size;
132         block += 8;
133     }
134 }
135 
put_signed_pixels_clamped_c(const int16_t * block,uint8_t * av_restrict pixels,ptrdiff_t line_size)136 static void put_signed_pixels_clamped_c(const int16_t *block,
137                                         uint8_t *av_restrict pixels,
138                                         ptrdiff_t line_size)
139 {
140     int i, j;
141 
142     for (i = 0; i < 8; i++) {
143         for (j = 0; j < 8; j++) {
144             if (*block < -128)
145                 *pixels = 0;
146             else if (*block > 127)
147                 *pixels = 255;
148             else
149                 *pixels = (uint8_t) (*block + 128);
150             block++;
151             pixels++;
152         }
153         pixels += (line_size - 8);
154     }
155 }
156 
ff_add_pixels_clamped_c(const int16_t * block,uint8_t * av_restrict pixels,ptrdiff_t line_size)157 void ff_add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,
158                              ptrdiff_t line_size)
159 {
160     int i;
161 
162     /* read the pixels */
163     for (i = 0; i < 8; i++) {
164         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
165         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
166         pixels[2] = av_clip_uint8(pixels[2] + block[2]);
167         pixels[3] = av_clip_uint8(pixels[3] + block[3]);
168         pixels[4] = av_clip_uint8(pixels[4] + block[4]);
169         pixels[5] = av_clip_uint8(pixels[5] + block[5]);
170         pixels[6] = av_clip_uint8(pixels[6] + block[6]);
171         pixels[7] = av_clip_uint8(pixels[7] + block[7]);
172         pixels   += line_size;
173         block    += 8;
174     }
175 }
176 
add_pixels_clamped4_c(const int16_t * block,uint8_t * av_restrict pixels,int line_size)177 static void add_pixels_clamped4_c(const int16_t *block, uint8_t *av_restrict pixels,
178                           int line_size)
179 {
180     int i;
181 
182     /* read the pixels */
183     for(i=0;i<4;i++) {
184         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
185         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
186         pixels[2] = av_clip_uint8(pixels[2] + block[2]);
187         pixels[3] = av_clip_uint8(pixels[3] + block[3]);
188         pixels += line_size;
189         block += 8;
190     }
191 }
192 
add_pixels_clamped2_c(const int16_t * block,uint8_t * av_restrict pixels,int line_size)193 static void add_pixels_clamped2_c(const int16_t *block, uint8_t *av_restrict pixels,
194                           int line_size)
195 {
196     int i;
197 
198     /* read the pixels */
199     for(i=0;i<2;i++) {
200         pixels[0] = av_clip_uint8(pixels[0] + block[0]);
201         pixels[1] = av_clip_uint8(pixels[1] + block[1]);
202         pixels += line_size;
203         block += 8;
204     }
205 }
206 
ff_jref_idct4_put(uint8_t * dest,ptrdiff_t line_size,int16_t * block)207 static void ff_jref_idct4_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
208 {
209     ff_j_rev_dct4 (block);
210     put_pixels_clamped4_c(block, dest, line_size);
211 }
ff_jref_idct4_add(uint8_t * dest,ptrdiff_t line_size,int16_t * block)212 static void ff_jref_idct4_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
213 {
214     ff_j_rev_dct4 (block);
215     add_pixels_clamped4_c(block, dest, line_size);
216 }
217 
ff_jref_idct2_put(uint8_t * dest,ptrdiff_t line_size,int16_t * block)218 static void ff_jref_idct2_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
219 {
220     ff_j_rev_dct2 (block);
221     put_pixels_clamped2_c(block, dest, line_size);
222 }
ff_jref_idct2_add(uint8_t * dest,ptrdiff_t line_size,int16_t * block)223 static void ff_jref_idct2_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
224 {
225     ff_j_rev_dct2 (block);
226     add_pixels_clamped2_c(block, dest, line_size);
227 }
228 
ff_jref_idct1_put(uint8_t * dest,ptrdiff_t line_size,int16_t * block)229 static void ff_jref_idct1_put(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
230 {
231     dest[0] = av_clip_uint8((block[0] + 4)>>3);
232 }
ff_jref_idct1_add(uint8_t * dest,ptrdiff_t line_size,int16_t * block)233 static void ff_jref_idct1_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
234 {
235     dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3));
236 }
237 
ff_idctdsp_init(IDCTDSPContext * c,AVCodecContext * avctx)238 av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
239 {
240     const unsigned high_bit_depth = avctx->bits_per_raw_sample > 8;
241 
242     if (avctx->lowres==1) {
243         c->idct_put  = ff_jref_idct4_put;
244         c->idct_add  = ff_jref_idct4_add;
245         c->idct      = ff_j_rev_dct4;
246         c->perm_type = FF_IDCT_PERM_NONE;
247     } else if (avctx->lowres==2) {
248         c->idct_put  = ff_jref_idct2_put;
249         c->idct_add  = ff_jref_idct2_add;
250         c->idct      = ff_j_rev_dct2;
251         c->perm_type = FF_IDCT_PERM_NONE;
252     } else if (avctx->lowres==3) {
253         c->idct_put  = ff_jref_idct1_put;
254         c->idct_add  = ff_jref_idct1_add;
255         c->idct      = ff_j_rev_dct1;
256         c->perm_type = FF_IDCT_PERM_NONE;
257     } else {
258         if (avctx->bits_per_raw_sample == 10 || avctx->bits_per_raw_sample == 9) {
259             /* 10-bit MPEG-4 Simple Studio Profile requires a higher precision IDCT
260                However, it only uses idct_put */
261             if (c->mpeg4_studio_profile) {
262                 c->idct_put              = ff_simple_idct_put_int32_10bit;
263                 c->idct_add              = NULL;
264                 c->idct                  = NULL;
265             } else {
266                 c->idct_put              = ff_simple_idct_put_int16_10bit;
267                 c->idct_add              = ff_simple_idct_add_int16_10bit;
268                 c->idct                  = ff_simple_idct_int16_10bit;
269             }
270             c->perm_type             = FF_IDCT_PERM_NONE;
271         } else if (avctx->bits_per_raw_sample == 12) {
272             c->idct_put              = ff_simple_idct_put_int16_12bit;
273             c->idct_add              = ff_simple_idct_add_int16_12bit;
274             c->idct                  = ff_simple_idct_int16_12bit;
275             c->perm_type             = FF_IDCT_PERM_NONE;
276         } else {
277             if (avctx->idct_algo == FF_IDCT_INT) {
278                 c->idct_put  = ff_jref_idct_put;
279                 c->idct_add  = ff_jref_idct_add;
280                 c->idct      = ff_j_rev_dct;
281                 c->perm_type = FF_IDCT_PERM_LIBMPEG2;
282 #if CONFIG_FAANIDCT
283             } else if (avctx->idct_algo == FF_IDCT_FAAN) {
284                 c->idct_put  = ff_faanidct_put;
285                 c->idct_add  = ff_faanidct_add;
286                 c->idct      = ff_faanidct;
287                 c->perm_type = FF_IDCT_PERM_NONE;
288 #endif /* CONFIG_FAANIDCT */
289             } else { // accurate/default
290                 /* Be sure FF_IDCT_NONE will select this one, since it uses FF_IDCT_PERM_NONE */
291                 c->idct_put  = ff_simple_idct_put_int16_8bit;
292                 c->idct_add  = ff_simple_idct_add_int16_8bit;
293                 c->idct      = ff_simple_idct_int16_8bit;
294                 c->perm_type = FF_IDCT_PERM_NONE;
295             }
296         }
297     }
298 
299     c->put_pixels_clamped        = ff_put_pixels_clamped_c;
300     c->put_signed_pixels_clamped = put_signed_pixels_clamped_c;
301     c->add_pixels_clamped        = ff_add_pixels_clamped_c;
302 
303     if (CONFIG_MPEG4_DECODER && avctx->idct_algo == FF_IDCT_XVID)
304         ff_xvid_idct_init(c, avctx);
305 
306     if (ARCH_AARCH64)
307         ff_idctdsp_init_aarch64(c, avctx, high_bit_depth);
308     if (ARCH_ALPHA)
309         ff_idctdsp_init_alpha(c, avctx, high_bit_depth);
310     if (ARCH_ARM)
311         ff_idctdsp_init_arm(c, avctx, high_bit_depth);
312     if (ARCH_PPC)
313         ff_idctdsp_init_ppc(c, avctx, high_bit_depth);
314     if (ARCH_X86)
315         ff_idctdsp_init_x86(c, avctx, high_bit_depth);
316     if (ARCH_MIPS)
317         ff_idctdsp_init_mips(c, avctx, high_bit_depth);
318 
319     ff_init_scantable_permutation(c->idct_permutation,
320                                   c->perm_type);
321 }
322