Mercurial > libavcodec.hg
annotate pcm.c @ 1352:e8ff4783f188 libavcodec
1) remove TBL support in PPC performance. It's much more useful to use the
PMCs, and with Apple's CHUD it's fairly easy too. No reason to keep useless
code around
2) make the PPC perf stuff a configure option
3) make put_pixels16_altivec a bit faster by unrolling the loop by 4
patch by (Romain Dolbeau <dolbeau at irisa dot fr>)
author | michaelni |
---|---|
date | Wed, 09 Jul 2003 20:18:13 +0000 |
parents | bfc18110d4b6 |
children | d7bb818768c5 |
rev | line source |
---|---|
92 | 1 /* |
2 * PCM codecs | |
429 | 3 * Copyright (c) 2001 Fabrice Bellard. |
92 | 4 * |
429 | 5 * This library is free software; you can redistribute it and/or |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
92 | 9 * |
429 | 10 * This library is distributed in the hope that it will be useful, |
92 | 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
429 | 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 * Lesser General Public License for more details. | |
92 | 14 * |
429 | 15 * You should have received a copy of the GNU Lesser General Public |
16 * License along with this library; if not, write to the Free Software | |
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
92 | 18 */ |
1108 | 19 |
20 /** | |
21 * @file pcm.c | |
22 * PCM codecs | |
23 */ | |
24 | |
92 | 25 #include "avcodec.h" |
26 | |
27 /* from g711.c by SUN microsystems (unrestricted use) */ | |
28 | |
29 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ | |
30 #define QUANT_MASK (0xf) /* Quantization field mask. */ | |
31 #define NSEGS (8) /* Number of A-law segments. */ | |
32 #define SEG_SHIFT (4) /* Left shift for segment number. */ | |
33 #define SEG_MASK (0x70) /* Segment field mask. */ | |
34 | |
35 #define BIAS (0x84) /* Bias for linear code. */ | |
36 | |
37 /* | |
38 * alaw2linear() - Convert an A-law value to 16-bit linear PCM | |
39 * | |
40 */ | |
41 static int alaw2linear(unsigned char a_val) | |
42 { | |
43 int t; | |
44 int seg; | |
45 | |
46 a_val ^= 0x55; | |
47 | |
48 t = (a_val & QUANT_MASK) << 4; | |
49 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; | |
50 switch (seg) { | |
51 case 0: | |
52 t += 8; | |
53 break; | |
54 case 1: | |
55 t += 0x108; | |
56 break; | |
57 default: | |
58 t += 0x108; | |
59 t <<= seg - 1; | |
60 } | |
61 return ((a_val & SIGN_BIT) ? t : -t); | |
62 } | |
63 | |
64 static int ulaw2linear(unsigned char u_val) | |
65 { | |
66 int t; | |
67 | |
68 /* Complement to obtain normal u-law value. */ | |
69 u_val = ~u_val; | |
70 | |
71 /* | |
72 * Extract and bias the quantization bits. Then | |
73 * shift up by the segment number and subtract out the bias. | |
74 */ | |
75 t = ((u_val & QUANT_MASK) << 3) + BIAS; | |
76 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; | |
77 | |
78 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); | |
79 } | |
80 | |
81 /* 16384 entries per table */ | |
1064 | 82 static uint8_t *linear_to_alaw = NULL; |
92 | 83 static int linear_to_alaw_ref = 0; |
84 | |
1064 | 85 static uint8_t *linear_to_ulaw = NULL; |
92 | 86 static int linear_to_ulaw_ref = 0; |
87 | |
1064 | 88 static void build_xlaw_table(uint8_t *linear_to_xlaw, |
92 | 89 int (*xlaw2linear)(unsigned char), |
90 int mask) | |
91 { | |
92 int i, j, v, v1, v2; | |
93 | |
94 j = 0; | |
95 for(i=0;i<128;i++) { | |
96 if (i != 127) { | |
97 v1 = xlaw2linear(i ^ mask); | |
98 v2 = xlaw2linear((i + 1) ^ mask); | |
99 v = (v1 + v2 + 4) >> 3; | |
100 } else { | |
101 v = 8192; | |
102 } | |
103 for(;j<v;j++) { | |
104 linear_to_xlaw[8192 + j] = (i ^ mask); | |
105 if (j > 0) | |
106 linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80)); | |
107 } | |
108 } | |
109 linear_to_xlaw[0] = linear_to_xlaw[1]; | |
110 } | |
111 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
112 static int pcm_encode_init(AVCodecContext *avctx) |
92 | 113 { |
114 avctx->frame_size = 1; | |
115 switch(avctx->codec->id) { | |
116 case CODEC_ID_PCM_ALAW: | |
117 if (linear_to_alaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
118 linear_to_alaw = av_malloc(16384); |
92 | 119 if (!linear_to_alaw) |
120 return -1; | |
121 build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); | |
122 } | |
123 linear_to_alaw_ref++; | |
124 break; | |
125 case CODEC_ID_PCM_MULAW: | |
126 if (linear_to_ulaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
127 linear_to_ulaw = av_malloc(16384); |
92 | 128 if (!linear_to_ulaw) |
129 return -1; | |
130 build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); | |
131 } | |
132 linear_to_ulaw_ref++; | |
133 break; | |
134 default: | |
135 break; | |
136 } | |
925 | 137 |
138 avctx->coded_frame= avcodec_alloc_frame(); | |
139 avctx->coded_frame->key_frame= 1; | |
140 | |
92 | 141 return 0; |
142 } | |
143 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
144 static int pcm_encode_close(AVCodecContext *avctx) |
92 | 145 { |
925 | 146 av_freep(&avctx->coded_frame); |
147 | |
92 | 148 switch(avctx->codec->id) { |
149 case CODEC_ID_PCM_ALAW: | |
150 if (--linear_to_alaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
151 av_free(linear_to_alaw); |
92 | 152 break; |
153 case CODEC_ID_PCM_MULAW: | |
154 if (--linear_to_ulaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
155 av_free(linear_to_ulaw); |
92 | 156 break; |
157 default: | |
158 /* nothing to free */ | |
159 break; | |
160 } | |
161 return 0; | |
162 } | |
163 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
164 static int pcm_encode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
165 unsigned char *frame, int buf_size, void *data) |
92 | 166 { |
167 int n, sample_size, v; | |
168 short *samples; | |
169 unsigned char *dst; | |
170 | |
171 switch(avctx->codec->id) { | |
172 case CODEC_ID_PCM_S16LE: | |
173 case CODEC_ID_PCM_S16BE: | |
174 case CODEC_ID_PCM_U16LE: | |
175 case CODEC_ID_PCM_U16BE: | |
176 sample_size = 2; | |
177 break; | |
178 default: | |
179 sample_size = 1; | |
180 break; | |
181 } | |
182 n = buf_size / sample_size; | |
183 samples = data; | |
184 dst = frame; | |
185 | |
186 switch(avctx->codec->id) { | |
187 case CODEC_ID_PCM_S16LE: | |
188 for(;n>0;n--) { | |
189 v = *samples++; | |
190 dst[0] = v & 0xff; | |
191 dst[1] = v >> 8; | |
192 dst += 2; | |
193 } | |
194 break; | |
195 case CODEC_ID_PCM_S16BE: | |
196 for(;n>0;n--) { | |
197 v = *samples++; | |
198 dst[0] = v >> 8; | |
199 dst[1] = v; | |
200 dst += 2; | |
201 } | |
202 break; | |
203 case CODEC_ID_PCM_U16LE: | |
204 for(;n>0;n--) { | |
205 v = *samples++; | |
206 v += 0x8000; | |
207 dst[0] = v & 0xff; | |
208 dst[1] = v >> 8; | |
209 dst += 2; | |
210 } | |
211 break; | |
212 case CODEC_ID_PCM_U16BE: | |
213 for(;n>0;n--) { | |
214 v = *samples++; | |
215 v += 0x8000; | |
216 dst[0] = v >> 8; | |
217 dst[1] = v; | |
218 dst += 2; | |
219 } | |
220 break; | |
221 case CODEC_ID_PCM_S8: | |
222 for(;n>0;n--) { | |
223 v = *samples++; | |
649
5a8f80522cf8
fixing overflow in 16->8 bit conversion, patch by (Nikolai Zhubr <s001 at hotbox dot ru>)
michaelni
parents:
440
diff
changeset
|
224 dst[0] = v >> 8; |
92 | 225 dst++; |
226 } | |
227 break; | |
228 case CODEC_ID_PCM_U8: | |
229 for(;n>0;n--) { | |
230 v = *samples++; | |
649
5a8f80522cf8
fixing overflow in 16->8 bit conversion, patch by (Nikolai Zhubr <s001 at hotbox dot ru>)
michaelni
parents:
440
diff
changeset
|
231 dst[0] = (v >> 8) + 128; |
92 | 232 dst++; |
233 } | |
234 break; | |
235 case CODEC_ID_PCM_ALAW: | |
236 for(;n>0;n--) { | |
237 v = *samples++; | |
238 dst[0] = linear_to_alaw[(v + 32768) >> 2]; | |
239 dst++; | |
240 } | |
241 break; | |
242 case CODEC_ID_PCM_MULAW: | |
243 for(;n>0;n--) { | |
244 v = *samples++; | |
245 dst[0] = linear_to_ulaw[(v + 32768) >> 2]; | |
246 dst++; | |
247 } | |
248 break; | |
249 default: | |
250 return -1; | |
251 } | |
381
0d6178e4d503
* Mea culpa: it seems that I broke encoding to 8-bit pcm files. This fixes it.
philipjsg
parents:
372
diff
changeset
|
252 //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); |
372 | 253 |
92 | 254 return dst - frame; |
255 } | |
256 | |
257 typedef struct PCMDecode { | |
258 short table[256]; | |
259 } PCMDecode; | |
260 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
261 static int pcm_decode_init(AVCodecContext * avctx) |
92 | 262 { |
263 PCMDecode *s = avctx->priv_data; | |
264 int i; | |
265 | |
266 switch(avctx->codec->id) { | |
267 case CODEC_ID_PCM_ALAW: | |
268 for(i=0;i<256;i++) | |
269 s->table[i] = alaw2linear(i); | |
270 break; | |
271 case CODEC_ID_PCM_MULAW: | |
272 for(i=0;i<256;i++) | |
273 s->table[i] = ulaw2linear(i); | |
274 break; | |
275 default: | |
276 break; | |
277 } | |
278 return 0; | |
279 } | |
280 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
281 static int pcm_decode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
282 void *data, int *data_size, |
1064 | 283 uint8_t *buf, int buf_size) |
92 | 284 { |
285 PCMDecode *s = avctx->priv_data; | |
286 int n; | |
287 short *samples; | |
1064 | 288 uint8_t *src; |
92 | 289 |
290 samples = data; | |
291 src = buf; | |
292 | |
293 switch(avctx->codec->id) { | |
294 case CODEC_ID_PCM_S16LE: | |
295 n = buf_size >> 1; | |
296 for(;n>0;n--) { | |
297 *samples++ = src[0] | (src[1] << 8); | |
298 src += 2; | |
299 } | |
300 break; | |
301 case CODEC_ID_PCM_S16BE: | |
302 n = buf_size >> 1; | |
303 for(;n>0;n--) { | |
304 *samples++ = (src[0] << 8) | src[1]; | |
305 src += 2; | |
306 } | |
307 break; | |
308 case CODEC_ID_PCM_U16LE: | |
309 n = buf_size >> 1; | |
310 for(;n>0;n--) { | |
311 *samples++ = (src[0] | (src[1] << 8)) - 0x8000; | |
312 src += 2; | |
313 } | |
314 break; | |
315 case CODEC_ID_PCM_U16BE: | |
316 n = buf_size >> 1; | |
317 for(;n>0;n--) { | |
318 *samples++ = ((src[0] << 8) | src[1]) - 0x8000; | |
319 src += 2; | |
320 } | |
321 break; | |
322 case CODEC_ID_PCM_S8: | |
323 n = buf_size; | |
324 for(;n>0;n--) { | |
325 *samples++ = src[0] << 8; | |
326 src++; | |
327 } | |
328 break; | |
329 case CODEC_ID_PCM_U8: | |
330 n = buf_size; | |
331 for(;n>0;n--) { | |
332 *samples++ = ((int)src[0] - 128) << 8; | |
333 src++; | |
334 } | |
335 break; | |
336 case CODEC_ID_PCM_ALAW: | |
337 case CODEC_ID_PCM_MULAW: | |
338 n = buf_size; | |
339 for(;n>0;n--) { | |
340 *samples++ = s->table[src[0]]; | |
341 src++; | |
342 } | |
343 break; | |
344 default: | |
345 *data_size = 0; | |
346 return -1; | |
347 } | |
1064 | 348 *data_size = (uint8_t *)samples - (uint8_t *)data; |
92 | 349 return src - buf; |
350 } | |
351 | |
352 #define PCM_CODEC(id, name) \ | |
353 AVCodec name ## _encoder = { \ | |
354 #name, \ | |
355 CODEC_TYPE_AUDIO, \ | |
356 id, \ | |
357 0, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
358 pcm_encode_init, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
359 pcm_encode_frame, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
360 pcm_encode_close, \ |
92 | 361 NULL, \ |
362 }; \ | |
363 AVCodec name ## _decoder = { \ | |
364 #name, \ | |
365 CODEC_TYPE_AUDIO, \ | |
366 id, \ | |
367 sizeof(PCMDecode), \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
368 pcm_decode_init, \ |
92 | 369 NULL, \ |
370 NULL, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
371 pcm_decode_frame, \ |
1014
48349e11c9b2
C99 initializers and kill warnings patch by (mru at users dot sourceforge dot net (Mns Rullgrd))
michaelni
parents:
925
diff
changeset
|
372 } |
92 | 373 |
374 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); | |
375 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | |
376 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | |
377 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | |
378 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | |
379 PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); | |
380 PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); | |
381 PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
382 |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
383 #undef PCM_CODEC |