Mercurial > libavcodec.hg
annotate pcm.c @ 2497:69adfbbdcdeb libavcodec
- samples from mplayer ftp in the "adv" profile seem to have profile=2,
which isn't the advanced one; and indeed, using adv. profile parser fails.
Using normal parser works, and that's what is done
- attempt at taking care of stride for NORM2 bitplane decoding
- duplication of much code from msmpeg4.c; this code isn't yet used, but
goes down as far as the block layer (mainly Transform Type stuff, the
remains are wild editing without checking). Unusable yet, and lacks the AC
decoding (but a step further in bitstream parsing)
patch by anonymous
author | michael |
---|---|
date | Fri, 04 Feb 2005 02:20:38 +0000 |
parents | a2073e67cb19 |
children | 9404bbf9de07 |
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 | |
1485 | 48 t = a_val & QUANT_MASK; |
92 | 49 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; |
1485 | 50 if(seg) t= (t + t + 1 + 32) << (seg + 2); |
51 else t= (t + t + 1 ) << 3; | |
52 | |
92 | 53 return ((a_val & SIGN_BIT) ? t : -t); |
54 } | |
55 | |
56 static int ulaw2linear(unsigned char u_val) | |
57 { | |
58 int t; | |
59 | |
60 /* Complement to obtain normal u-law value. */ | |
61 u_val = ~u_val; | |
62 | |
63 /* | |
64 * Extract and bias the quantization bits. Then | |
65 * shift up by the segment number and subtract out the bias. | |
66 */ | |
67 t = ((u_val & QUANT_MASK) << 3) + BIAS; | |
68 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; | |
69 | |
70 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); | |
71 } | |
72 | |
73 /* 16384 entries per table */ | |
1064 | 74 static uint8_t *linear_to_alaw = NULL; |
92 | 75 static int linear_to_alaw_ref = 0; |
76 | |
1064 | 77 static uint8_t *linear_to_ulaw = NULL; |
92 | 78 static int linear_to_ulaw_ref = 0; |
79 | |
1064 | 80 static void build_xlaw_table(uint8_t *linear_to_xlaw, |
92 | 81 int (*xlaw2linear)(unsigned char), |
82 int mask) | |
83 { | |
84 int i, j, v, v1, v2; | |
85 | |
86 j = 0; | |
87 for(i=0;i<128;i++) { | |
88 if (i != 127) { | |
89 v1 = xlaw2linear(i ^ mask); | |
90 v2 = xlaw2linear((i + 1) ^ mask); | |
91 v = (v1 + v2 + 4) >> 3; | |
92 } else { | |
93 v = 8192; | |
94 } | |
95 for(;j<v;j++) { | |
96 linear_to_xlaw[8192 + j] = (i ^ mask); | |
97 if (j > 0) | |
98 linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80)); | |
99 } | |
100 } | |
101 linear_to_xlaw[0] = linear_to_xlaw[1]; | |
102 } | |
103 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
104 static int pcm_encode_init(AVCodecContext *avctx) |
92 | 105 { |
106 avctx->frame_size = 1; | |
107 switch(avctx->codec->id) { | |
108 case CODEC_ID_PCM_ALAW: | |
109 if (linear_to_alaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
110 linear_to_alaw = av_malloc(16384); |
92 | 111 if (!linear_to_alaw) |
112 return -1; | |
113 build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); | |
114 } | |
115 linear_to_alaw_ref++; | |
116 break; | |
117 case CODEC_ID_PCM_MULAW: | |
118 if (linear_to_ulaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
119 linear_to_ulaw = av_malloc(16384); |
92 | 120 if (!linear_to_ulaw) |
121 return -1; | |
122 build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); | |
123 } | |
124 linear_to_ulaw_ref++; | |
125 break; | |
126 default: | |
127 break; | |
128 } | |
925 | 129 |
2340 | 130 switch(avctx->codec->id) { |
131 case CODEC_ID_PCM_S16LE: | |
132 case CODEC_ID_PCM_S16BE: | |
133 case CODEC_ID_PCM_U16LE: | |
134 case CODEC_ID_PCM_U16BE: | |
135 avctx->block_align = 2 * avctx->channels; | |
136 break; | |
137 case CODEC_ID_PCM_S8: | |
138 case CODEC_ID_PCM_U8: | |
139 case CODEC_ID_PCM_MULAW: | |
140 case CODEC_ID_PCM_ALAW: | |
141 avctx->block_align = avctx->channels; | |
142 break; | |
143 default: | |
144 break; | |
145 } | |
146 | |
925 | 147 avctx->coded_frame= avcodec_alloc_frame(); |
148 avctx->coded_frame->key_frame= 1; | |
149 | |
92 | 150 return 0; |
151 } | |
152 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
153 static int pcm_encode_close(AVCodecContext *avctx) |
92 | 154 { |
925 | 155 av_freep(&avctx->coded_frame); |
156 | |
92 | 157 switch(avctx->codec->id) { |
158 case CODEC_ID_PCM_ALAW: | |
159 if (--linear_to_alaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
160 av_free(linear_to_alaw); |
92 | 161 break; |
162 case CODEC_ID_PCM_MULAW: | |
163 if (--linear_to_ulaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
164 av_free(linear_to_ulaw); |
92 | 165 break; |
166 default: | |
167 /* nothing to free */ | |
168 break; | |
169 } | |
170 return 0; | |
171 } | |
172 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
173 static int pcm_encode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
174 unsigned char *frame, int buf_size, void *data) |
92 | 175 { |
176 int n, sample_size, v; | |
177 short *samples; | |
178 unsigned char *dst; | |
179 | |
180 switch(avctx->codec->id) { | |
181 case CODEC_ID_PCM_S16LE: | |
182 case CODEC_ID_PCM_S16BE: | |
183 case CODEC_ID_PCM_U16LE: | |
184 case CODEC_ID_PCM_U16BE: | |
185 sample_size = 2; | |
186 break; | |
187 default: | |
188 sample_size = 1; | |
189 break; | |
190 } | |
191 n = buf_size / sample_size; | |
192 samples = data; | |
193 dst = frame; | |
194 | |
195 switch(avctx->codec->id) { | |
196 case CODEC_ID_PCM_S16LE: | |
197 for(;n>0;n--) { | |
198 v = *samples++; | |
199 dst[0] = v & 0xff; | |
200 dst[1] = v >> 8; | |
201 dst += 2; | |
202 } | |
203 break; | |
204 case CODEC_ID_PCM_S16BE: | |
205 for(;n>0;n--) { | |
206 v = *samples++; | |
207 dst[0] = v >> 8; | |
208 dst[1] = v; | |
209 dst += 2; | |
210 } | |
211 break; | |
212 case CODEC_ID_PCM_U16LE: | |
213 for(;n>0;n--) { | |
214 v = *samples++; | |
215 v += 0x8000; | |
216 dst[0] = v & 0xff; | |
217 dst[1] = v >> 8; | |
218 dst += 2; | |
219 } | |
220 break; | |
221 case CODEC_ID_PCM_U16BE: | |
222 for(;n>0;n--) { | |
223 v = *samples++; | |
224 v += 0x8000; | |
225 dst[0] = v >> 8; | |
226 dst[1] = v; | |
227 dst += 2; | |
228 } | |
229 break; | |
230 case CODEC_ID_PCM_S8: | |
231 for(;n>0;n--) { | |
232 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
|
233 dst[0] = v >> 8; |
92 | 234 dst++; |
235 } | |
236 break; | |
237 case CODEC_ID_PCM_U8: | |
238 for(;n>0;n--) { | |
239 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
|
240 dst[0] = (v >> 8) + 128; |
92 | 241 dst++; |
242 } | |
243 break; | |
244 case CODEC_ID_PCM_ALAW: | |
245 for(;n>0;n--) { | |
246 v = *samples++; | |
247 dst[0] = linear_to_alaw[(v + 32768) >> 2]; | |
248 dst++; | |
249 } | |
250 break; | |
251 case CODEC_ID_PCM_MULAW: | |
252 for(;n>0;n--) { | |
253 v = *samples++; | |
254 dst[0] = linear_to_ulaw[(v + 32768) >> 2]; | |
255 dst++; | |
256 } | |
257 break; | |
258 default: | |
259 return -1; | |
260 } | |
381
0d6178e4d503
* Mea culpa: it seems that I broke encoding to 8-bit pcm files. This fixes it.
philipjsg
parents:
372
diff
changeset
|
261 //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); |
372 | 262 |
92 | 263 return dst - frame; |
264 } | |
265 | |
266 typedef struct PCMDecode { | |
267 short table[256]; | |
268 } PCMDecode; | |
269 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
270 static int pcm_decode_init(AVCodecContext * avctx) |
92 | 271 { |
272 PCMDecode *s = avctx->priv_data; | |
273 int i; | |
274 | |
275 switch(avctx->codec->id) { | |
276 case CODEC_ID_PCM_ALAW: | |
277 for(i=0;i<256;i++) | |
278 s->table[i] = alaw2linear(i); | |
279 break; | |
280 case CODEC_ID_PCM_MULAW: | |
281 for(i=0;i<256;i++) | |
282 s->table[i] = ulaw2linear(i); | |
283 break; | |
284 default: | |
285 break; | |
286 } | |
287 return 0; | |
288 } | |
289 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
290 static int pcm_decode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
291 void *data, int *data_size, |
1064 | 292 uint8_t *buf, int buf_size) |
92 | 293 { |
294 PCMDecode *s = avctx->priv_data; | |
295 int n; | |
296 short *samples; | |
1064 | 297 uint8_t *src; |
92 | 298 |
299 samples = data; | |
300 src = buf; | |
301 | |
302 switch(avctx->codec->id) { | |
303 case CODEC_ID_PCM_S16LE: | |
304 n = buf_size >> 1; | |
305 for(;n>0;n--) { | |
306 *samples++ = src[0] | (src[1] << 8); | |
307 src += 2; | |
308 } | |
309 break; | |
310 case CODEC_ID_PCM_S16BE: | |
311 n = buf_size >> 1; | |
312 for(;n>0;n--) { | |
313 *samples++ = (src[0] << 8) | src[1]; | |
314 src += 2; | |
315 } | |
316 break; | |
317 case CODEC_ID_PCM_U16LE: | |
318 n = buf_size >> 1; | |
319 for(;n>0;n--) { | |
320 *samples++ = (src[0] | (src[1] << 8)) - 0x8000; | |
321 src += 2; | |
322 } | |
323 break; | |
324 case CODEC_ID_PCM_U16BE: | |
325 n = buf_size >> 1; | |
326 for(;n>0;n--) { | |
327 *samples++ = ((src[0] << 8) | src[1]) - 0x8000; | |
328 src += 2; | |
329 } | |
330 break; | |
331 case CODEC_ID_PCM_S8: | |
332 n = buf_size; | |
333 for(;n>0;n--) { | |
334 *samples++ = src[0] << 8; | |
335 src++; | |
336 } | |
337 break; | |
338 case CODEC_ID_PCM_U8: | |
339 n = buf_size; | |
340 for(;n>0;n--) { | |
341 *samples++ = ((int)src[0] - 128) << 8; | |
342 src++; | |
343 } | |
344 break; | |
345 case CODEC_ID_PCM_ALAW: | |
346 case CODEC_ID_PCM_MULAW: | |
347 n = buf_size; | |
348 for(;n>0;n--) { | |
349 *samples++ = s->table[src[0]]; | |
350 src++; | |
351 } | |
352 break; | |
353 default: | |
354 return -1; | |
355 } | |
1064 | 356 *data_size = (uint8_t *)samples - (uint8_t *)data; |
92 | 357 return src - buf; |
358 } | |
359 | |
360 #define PCM_CODEC(id, name) \ | |
361 AVCodec name ## _encoder = { \ | |
362 #name, \ | |
363 CODEC_TYPE_AUDIO, \ | |
364 id, \ | |
365 0, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
366 pcm_encode_init, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
367 pcm_encode_frame, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
368 pcm_encode_close, \ |
92 | 369 NULL, \ |
370 }; \ | |
371 AVCodec name ## _decoder = { \ | |
372 #name, \ | |
373 CODEC_TYPE_AUDIO, \ | |
374 id, \ | |
375 sizeof(PCMDecode), \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
376 pcm_decode_init, \ |
92 | 377 NULL, \ |
378 NULL, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
379 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
|
380 } |
92 | 381 |
382 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); | |
383 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | |
384 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | |
385 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | |
386 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | |
387 PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); | |
388 PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); | |
389 PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
390 |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
391 #undef PCM_CODEC |