Mercurial > mplayer.hg
annotate libmpeg2/idct.c @ 30088:4977e04f3a18
Add support for parsing audio streams (though should be easy to extend to video)
via libavcodec.
Parsing can be done at the demuxer stage (currently disabled) or at the decoder
(ad_ffmpeg, enabled).
Should allow using the libavcodec AAC, DTS, ... decoders independent of container
format.
author | reimar |
---|---|
date | Sun, 27 Dec 2009 15:28:01 +0000 |
parents | 25337a2147e7 |
children |
rev | line source |
---|---|
1 | 1 /* |
2 * idct.c | |
12932 | 3 * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> |
9852 | 4 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> |
1 | 5 * |
6 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. | |
9852 | 7 * See http://libmpeg2.sourceforge.net/ for updates. |
1 | 8 * |
9 * mpeg2dec is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * mpeg2dec is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
26625
5b89b42f6d50
Only compile and use libmpeg2 AltiVec code when AltiVec is available. The
diego
parents:
26619
diff
changeset
|
22 * |
27571
fd18fa10de53
libmpeg-0.4.1.diff was renamed to libmpeg2_changes.diff.
diego
parents:
27522
diff
changeset
|
23 * Modified for use with MPlayer, see libmpeg2_changes.diff for the exact changes. |
26625
5b89b42f6d50
Only compile and use libmpeg2 AltiVec code when AltiVec is available. The
diego
parents:
26619
diff
changeset
|
24 * detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/ |
5b89b42f6d50
Only compile and use libmpeg2 AltiVec code when AltiVec is available. The
diego
parents:
26619
diff
changeset
|
25 * $Id$ |
1 | 26 */ |
27 | |
28 #include "config.h" | |
29 | |
9852 | 30 #include <stdlib.h> |
1 | 31 #include <inttypes.h> |
32 | |
9852 | 33 #include "mpeg2.h" |
12932 | 34 #include "attributes.h" |
1 | 35 #include "mpeg2_internal.h" |
36 | |
12932 | 37 #define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */ |
38 #define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */ | |
39 #define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */ | |
40 #define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */ | |
41 #define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */ | |
42 #define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */ | |
1 | 43 |
36 | 44 /* idct main entry point */ |
9852 | 45 void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); |
46 void (* mpeg2_idct_add) (int last, int16_t * block, | |
47 uint8_t * dest, int stride); | |
1 | 48 |
12932 | 49 /* |
50 * In legal streams, the IDCT output should be between -384 and +384. | |
51 * In corrupted streams, it is possible to force the IDCT output to go | |
52 * to +-3826 - this is the worst case for a column IDCT where the | |
53 * column inputs are 16-bit values. | |
54 */ | |
55 uint8_t mpeg2_clip[3840 * 2 + 256]; | |
56 #define CLIP(i) ((mpeg2_clip + 3840)[i]) | |
1 | 57 |
9852 | 58 #if 0 |
59 #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ | |
60 do { \ | |
12932 | 61 t0 = W0 * d0 + W1 * d1; \ |
62 t1 = W0 * d1 - W1 * d0; \ | |
9852 | 63 } while (0) |
64 #else | |
65 #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ | |
66 do { \ | |
67 int tmp = W0 * (d0 + d1); \ | |
68 t0 = tmp + (W1 - W0) * d1; \ | |
69 t1 = tmp - (W1 + W0) * d0; \ | |
70 } while (0) | |
71 #endif | |
1 | 72 |
10392 | 73 static inline void idct_row (int16_t * const block) |
1 | 74 { |
9852 | 75 int d0, d1, d2, d3; |
76 int a0, a1, a2, a3, b0, b1, b2, b3; | |
77 int t0, t1, t2, t3; | |
1 | 78 |
79 /* shortcut */ | |
9852 | 80 if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] | |
81 ((int32_t *)block)[3]))) { | |
12932 | 82 uint32_t tmp = (uint16_t) (block[0] >> 1); |
9852 | 83 tmp |= tmp << 16; |
84 ((int32_t *)block)[0] = tmp; | |
85 ((int32_t *)block)[1] = tmp; | |
86 ((int32_t *)block)[2] = tmp; | |
87 ((int32_t *)block)[3] = tmp; | |
1 | 88 return; |
89 } | |
90 | |
12932 | 91 d0 = (block[0] << 11) + 2048; |
9852 | 92 d1 = block[1]; |
93 d2 = block[2] << 11; | |
94 d3 = block[3]; | |
95 t0 = d0 + d2; | |
96 t1 = d0 - d2; | |
97 BUTTERFLY (t2, t3, W6, W2, d3, d1); | |
98 a0 = t0 + t2; | |
99 a1 = t1 + t3; | |
100 a2 = t1 - t3; | |
101 a3 = t0 - t2; | |
1 | 102 |
9852 | 103 d0 = block[4]; |
104 d1 = block[5]; | |
105 d2 = block[6]; | |
106 d3 = block[7]; | |
107 BUTTERFLY (t0, t1, W7, W1, d3, d0); | |
108 BUTTERFLY (t2, t3, W3, W5, d1, d2); | |
109 b0 = t0 + t2; | |
110 b3 = t1 + t3; | |
111 t0 -= t2; | |
112 t1 -= t3; | |
12932 | 113 b1 = ((t0 + t1) >> 8) * 181; |
114 b2 = ((t0 - t1) >> 8) * 181; | |
9852 | 115 |
12932 | 116 block[0] = (a0 + b0) >> 12; |
117 block[1] = (a1 + b1) >> 12; | |
118 block[2] = (a2 + b2) >> 12; | |
119 block[3] = (a3 + b3) >> 12; | |
120 block[4] = (a3 - b3) >> 12; | |
121 block[5] = (a2 - b2) >> 12; | |
122 block[6] = (a1 - b1) >> 12; | |
123 block[7] = (a0 - b0) >> 12; | |
1 | 124 } |
125 | |
10392 | 126 static inline void idct_col (int16_t * const block) |
1 | 127 { |
9852 | 128 int d0, d1, d2, d3; |
129 int a0, a1, a2, a3, b0, b1, b2, b3; | |
130 int t0, t1, t2, t3; | |
1 | 131 |
9852 | 132 d0 = (block[8*0] << 11) + 65536; |
133 d1 = block[8*1]; | |
134 d2 = block[8*2] << 11; | |
135 d3 = block[8*3]; | |
136 t0 = d0 + d2; | |
137 t1 = d0 - d2; | |
138 BUTTERFLY (t2, t3, W6, W2, d3, d1); | |
139 a0 = t0 + t2; | |
140 a1 = t1 + t3; | |
141 a2 = t1 - t3; | |
142 a3 = t0 - t2; | |
1 | 143 |
9852 | 144 d0 = block[8*4]; |
145 d1 = block[8*5]; | |
146 d2 = block[8*6]; | |
147 d3 = block[8*7]; | |
148 BUTTERFLY (t0, t1, W7, W1, d3, d0); | |
149 BUTTERFLY (t2, t3, W3, W5, d1, d2); | |
150 b0 = t0 + t2; | |
151 b3 = t1 + t3; | |
12932 | 152 t0 -= t2; |
153 t1 -= t3; | |
154 b1 = ((t0 + t1) >> 8) * 181; | |
155 b2 = ((t0 - t1) >> 8) * 181; | |
9852 | 156 |
157 block[8*0] = (a0 + b0) >> 17; | |
158 block[8*1] = (a1 + b1) >> 17; | |
159 block[8*2] = (a2 + b2) >> 17; | |
160 block[8*3] = (a3 + b3) >> 17; | |
161 block[8*4] = (a3 - b3) >> 17; | |
162 block[8*5] = (a2 - b2) >> 17; | |
163 block[8*6] = (a1 - b1) >> 17; | |
164 block[8*7] = (a0 - b0) >> 17; | |
1 | 165 } |
166 | |
9852 | 167 static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, |
168 const int stride) | |
1 | 169 { |
170 int i; | |
171 | |
172 for (i = 0; i < 8; i++) | |
173 idct_row (block + 8 * i); | |
174 for (i = 0; i < 8; i++) | |
175 idct_col (block + i); | |
176 do { | |
177 dest[0] = CLIP (block[0]); | |
178 dest[1] = CLIP (block[1]); | |
179 dest[2] = CLIP (block[2]); | |
180 dest[3] = CLIP (block[3]); | |
181 dest[4] = CLIP (block[4]); | |
182 dest[5] = CLIP (block[5]); | |
183 dest[6] = CLIP (block[6]); | |
184 dest[7] = CLIP (block[7]); | |
185 | |
12932 | 186 ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0; |
187 ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0; | |
9852 | 188 |
1 | 189 dest += stride; |
190 block += 8; | |
191 } while (--i); | |
192 } | |
193 | |
9852 | 194 static void mpeg2_idct_add_c (const int last, int16_t * block, |
195 uint8_t * dest, const int stride) | |
1 | 196 { |
197 int i; | |
198 | |
12932 | 199 if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { |
9852 | 200 for (i = 0; i < 8; i++) |
201 idct_row (block + 8 * i); | |
202 for (i = 0; i < 8; i++) | |
203 idct_col (block + i); | |
204 do { | |
205 dest[0] = CLIP (block[0] + dest[0]); | |
206 dest[1] = CLIP (block[1] + dest[1]); | |
207 dest[2] = CLIP (block[2] + dest[2]); | |
208 dest[3] = CLIP (block[3] + dest[3]); | |
209 dest[4] = CLIP (block[4] + dest[4]); | |
210 dest[5] = CLIP (block[5] + dest[5]); | |
211 dest[6] = CLIP (block[6] + dest[6]); | |
212 dest[7] = CLIP (block[7] + dest[7]); | |
213 | |
12932 | 214 ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0; |
215 ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0; | |
1 | 216 |
9852 | 217 dest += stride; |
218 block += 8; | |
219 } while (--i); | |
220 } else { | |
221 int DC; | |
222 | |
12932 | 223 DC = (block[0] + 64) >> 7; |
9852 | 224 block[0] = block[63] = 0; |
225 i = 8; | |
226 do { | |
227 dest[0] = CLIP (DC + dest[0]); | |
228 dest[1] = CLIP (DC + dest[1]); | |
229 dest[2] = CLIP (DC + dest[2]); | |
230 dest[3] = CLIP (DC + dest[3]); | |
231 dest[4] = CLIP (DC + dest[4]); | |
232 dest[5] = CLIP (DC + dest[5]); | |
233 dest[6] = CLIP (DC + dest[6]); | |
234 dest[7] = CLIP (DC + dest[7]); | |
235 dest += stride; | |
236 } while (--i); | |
237 } | |
238 } | |
1 | 239 |
9852 | 240 void mpeg2_idct_init (uint32_t accel) |
241 { | |
28290 | 242 #if HAVE_SSE2 |
26393
2506f1b0bdbe
Backport SSE2-optimized IDCT routines from upstream libmpeg2.
diego
parents:
26282
diff
changeset
|
243 if (accel & MPEG2_ACCEL_X86_SSE2) { |
2506f1b0bdbe
Backport SSE2-optimized IDCT routines from upstream libmpeg2.
diego
parents:
26282
diff
changeset
|
244 mpeg2_idct_copy = mpeg2_idct_copy_sse2; |
2506f1b0bdbe
Backport SSE2-optimized IDCT routines from upstream libmpeg2.
diego
parents:
26282
diff
changeset
|
245 mpeg2_idct_add = mpeg2_idct_add_sse2; |
2506f1b0bdbe
Backport SSE2-optimized IDCT routines from upstream libmpeg2.
diego
parents:
26282
diff
changeset
|
246 mpeg2_idct_mmx_init (); |
27522
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
247 } else |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
248 #elif HAVE_MMX2 |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
249 if (accel & MPEG2_ACCEL_X86_MMXEXT) { |
9852 | 250 mpeg2_idct_copy = mpeg2_idct_copy_mmxext; |
251 mpeg2_idct_add = mpeg2_idct_add_mmxext; | |
252 mpeg2_idct_mmx_init (); | |
27522
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
253 } else |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
254 #elif HAVE_MMX |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
255 if (accel & MPEG2_ACCEL_X86_MMX) { |
9852 | 256 mpeg2_idct_copy = mpeg2_idct_copy_mmx; |
257 mpeg2_idct_add = mpeg2_idct_add_mmx; | |
258 mpeg2_idct_mmx_init (); | |
259 } else | |
260 #endif | |
28290 | 261 #if HAVE_ALTIVEC |
9852 | 262 if (accel & MPEG2_ACCEL_PPC_ALTIVEC) { |
263 mpeg2_idct_copy = mpeg2_idct_copy_altivec; | |
264 mpeg2_idct_add = mpeg2_idct_add_altivec; | |
265 mpeg2_idct_altivec_init (); | |
266 } else | |
267 #endif | |
28290 | 268 #if HAVE_MVI |
9852 | 269 if (accel & MPEG2_ACCEL_ALPHA_MVI) { |
270 mpeg2_idct_copy = mpeg2_idct_copy_mvi; | |
271 mpeg2_idct_add = mpeg2_idct_add_mvi; | |
12932 | 272 mpeg2_idct_alpha_init (); |
27522
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
273 } else |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
274 #elif ARCH_ALPHA |
1462a44ea6b9
Use preprocessor conditionals to disable CPU-extension-specific code. We cannot
diego
parents:
26625
diff
changeset
|
275 if (accel & MPEG2_ACCEL_ALPHA) { |
12932 | 276 int i; |
277 | |
9852 | 278 mpeg2_idct_copy = mpeg2_idct_copy_alpha; |
279 mpeg2_idct_add = mpeg2_idct_add_alpha; | |
12932 | 280 mpeg2_idct_alpha_init (); |
281 for (i = -3840; i < 3840 + 256; i++) | |
282 CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i); | |
9852 | 283 } else |
284 #endif | |
285 { | |
286 int i, j; | |
1 | 287 |
9852 | 288 mpeg2_idct_copy = mpeg2_idct_copy_c; |
289 mpeg2_idct_add = mpeg2_idct_add_c; | |
12932 | 290 for (i = -3840; i < 3840 + 256; i++) |
291 CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i); | |
9852 | 292 for (i = 0; i < 64; i++) { |
293 j = mpeg2_scan_norm[i]; | |
294 mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); | |
295 j = mpeg2_scan_alt[i]; | |
296 mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); | |
297 } | |
298 } | |
1 | 299 } |