Mercurial > libavcodec.hg
annotate pcm.c @ 2956:5f51b1e0bed6 libavcodec
Cook compatibe decoder, patch by Benjamin Larsson
Add cook demucing, change rm demuxer so that it reorders audio packets
before sending them to the decoder, and send minimum decodeable sized
packets; pass only real codec extradata fo the decoder
Fix 28_8 decoder for the new demuxer strategy
author | rtognimp |
---|---|
date | Fri, 09 Dec 2005 16:08:18 +0000 |
parents | 87c11495e393 |
children | ef2149182f1c |
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" |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
26 #include "bitstream.h" // for ff_reverse |
92 | 27 |
28 /* from g711.c by SUN microsystems (unrestricted use) */ | |
29 | |
30 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ | |
31 #define QUANT_MASK (0xf) /* Quantization field mask. */ | |
32 #define NSEGS (8) /* Number of A-law segments. */ | |
33 #define SEG_SHIFT (4) /* Left shift for segment number. */ | |
34 #define SEG_MASK (0x70) /* Segment field mask. */ | |
35 | |
36 #define BIAS (0x84) /* Bias for linear code. */ | |
37 | |
38 /* | |
39 * alaw2linear() - Convert an A-law value to 16-bit linear PCM | |
40 * | |
41 */ | |
42 static int alaw2linear(unsigned char a_val) | |
43 { | |
44 int t; | |
45 int seg; | |
46 | |
47 a_val ^= 0x55; | |
48 | |
1485 | 49 t = a_val & QUANT_MASK; |
92 | 50 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; |
1485 | 51 if(seg) t= (t + t + 1 + 32) << (seg + 2); |
52 else t= (t + t + 1 ) << 3; | |
53 | |
92 | 54 return ((a_val & SIGN_BIT) ? t : -t); |
55 } | |
56 | |
57 static int ulaw2linear(unsigned char u_val) | |
58 { | |
59 int t; | |
60 | |
61 /* Complement to obtain normal u-law value. */ | |
62 u_val = ~u_val; | |
63 | |
64 /* | |
65 * Extract and bias the quantization bits. Then | |
66 * shift up by the segment number and subtract out the bias. | |
67 */ | |
68 t = ((u_val & QUANT_MASK) << 3) + BIAS; | |
69 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; | |
70 | |
71 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); | |
72 } | |
73 | |
74 /* 16384 entries per table */ | |
1064 | 75 static uint8_t *linear_to_alaw = NULL; |
92 | 76 static int linear_to_alaw_ref = 0; |
77 | |
1064 | 78 static uint8_t *linear_to_ulaw = NULL; |
92 | 79 static int linear_to_ulaw_ref = 0; |
80 | |
1064 | 81 static void build_xlaw_table(uint8_t *linear_to_xlaw, |
92 | 82 int (*xlaw2linear)(unsigned char), |
83 int mask) | |
84 { | |
85 int i, j, v, v1, v2; | |
86 | |
87 j = 0; | |
88 for(i=0;i<128;i++) { | |
89 if (i != 127) { | |
90 v1 = xlaw2linear(i ^ mask); | |
91 v2 = xlaw2linear((i + 1) ^ mask); | |
92 v = (v1 + v2 + 4) >> 3; | |
93 } else { | |
94 v = 8192; | |
95 } | |
96 for(;j<v;j++) { | |
97 linear_to_xlaw[8192 + j] = (i ^ mask); | |
98 if (j > 0) | |
99 linear_to_xlaw[8192 - j] = (i ^ (mask ^ 0x80)); | |
100 } | |
101 } | |
102 linear_to_xlaw[0] = linear_to_xlaw[1]; | |
103 } | |
104 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
105 static int pcm_encode_init(AVCodecContext *avctx) |
92 | 106 { |
107 avctx->frame_size = 1; | |
108 switch(avctx->codec->id) { | |
109 case CODEC_ID_PCM_ALAW: | |
110 if (linear_to_alaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
111 linear_to_alaw = av_malloc(16384); |
92 | 112 if (!linear_to_alaw) |
113 return -1; | |
114 build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); | |
115 } | |
116 linear_to_alaw_ref++; | |
117 break; | |
118 case CODEC_ID_PCM_MULAW: | |
119 if (linear_to_ulaw_ref == 0) { | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
120 linear_to_ulaw = av_malloc(16384); |
92 | 121 if (!linear_to_ulaw) |
122 return -1; | |
123 build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); | |
124 } | |
125 linear_to_ulaw_ref++; | |
126 break; | |
127 default: | |
128 break; | |
129 } | |
925 | 130 |
2340 | 131 switch(avctx->codec->id) { |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
132 case CODEC_ID_PCM_S32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
133 case CODEC_ID_PCM_S32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
134 case CODEC_ID_PCM_U32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
135 case CODEC_ID_PCM_U32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
136 avctx->block_align = 4 * avctx->channels; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
137 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
138 case CODEC_ID_PCM_S24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
139 case CODEC_ID_PCM_S24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
140 case CODEC_ID_PCM_U24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
141 case CODEC_ID_PCM_U24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
142 case CODEC_ID_PCM_S24DAUD: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
143 avctx->block_align = 3 * avctx->channels; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
144 break; |
2340 | 145 case CODEC_ID_PCM_S16LE: |
146 case CODEC_ID_PCM_S16BE: | |
147 case CODEC_ID_PCM_U16LE: | |
148 case CODEC_ID_PCM_U16BE: | |
149 avctx->block_align = 2 * avctx->channels; | |
150 break; | |
151 case CODEC_ID_PCM_S8: | |
152 case CODEC_ID_PCM_U8: | |
153 case CODEC_ID_PCM_MULAW: | |
154 case CODEC_ID_PCM_ALAW: | |
155 avctx->block_align = avctx->channels; | |
156 break; | |
157 default: | |
158 break; | |
159 } | |
160 | |
925 | 161 avctx->coded_frame= avcodec_alloc_frame(); |
162 avctx->coded_frame->key_frame= 1; | |
163 | |
92 | 164 return 0; |
165 } | |
166 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
167 static int pcm_encode_close(AVCodecContext *avctx) |
92 | 168 { |
925 | 169 av_freep(&avctx->coded_frame); |
170 | |
92 | 171 switch(avctx->codec->id) { |
172 case CODEC_ID_PCM_ALAW: | |
173 if (--linear_to_alaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
174 av_free(linear_to_alaw); |
92 | 175 break; |
176 case CODEC_ID_PCM_MULAW: | |
177 if (--linear_to_ulaw_ref == 0) | |
396
fce0a2520551
removed useless header includes - use av memory functions
glantau
parents:
381
diff
changeset
|
178 av_free(linear_to_ulaw); |
92 | 179 break; |
180 default: | |
181 /* nothing to free */ | |
182 break; | |
183 } | |
184 return 0; | |
185 } | |
186 | |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
187 /** |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
188 * \brief convert samples from 16 bit |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
189 * \param bps byte per sample for the destination format, must be >= 2 |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
190 * \param le 0 for big-, 1 for little-endian |
2853
87c11495e393
Document "us" parameter for PCM conversion functions.
reimar
parents:
2852
diff
changeset
|
191 * \param us 0 for signed, 1 for unsigned output |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
192 * \param samples input samples |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
193 * \param dst output samples |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
194 * \param n number of samples in samples buffer. |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
195 */ |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
196 static inline void encode_from16(int bps, int le, int us, |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
197 short **samples, uint8_t **dst, int n) { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
198 if (bps > 2) |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
199 memset(*dst, 0, n * bps); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
200 if (le) *dst += bps - 2; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
201 for(;n>0;n--) { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
202 register int v = *(*samples)++; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
203 if (us) v += 0x8000; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
204 (*dst)[le] = v >> 8; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
205 (*dst)[1 - le] = v; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
206 *dst += bps; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
207 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
208 if (le) *dst -= bps - 2; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
209 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
210 |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
211 static int pcm_encode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
212 unsigned char *frame, int buf_size, void *data) |
92 | 213 { |
214 int n, sample_size, v; | |
215 short *samples; | |
216 unsigned char *dst; | |
217 | |
218 switch(avctx->codec->id) { | |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
219 case CODEC_ID_PCM_S32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
220 case CODEC_ID_PCM_S32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
221 case CODEC_ID_PCM_U32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
222 case CODEC_ID_PCM_U32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
223 sample_size = 4; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
224 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
225 case CODEC_ID_PCM_S24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
226 case CODEC_ID_PCM_S24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
227 case CODEC_ID_PCM_U24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
228 case CODEC_ID_PCM_U24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
229 case CODEC_ID_PCM_S24DAUD: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
230 sample_size = 3; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
231 break; |
92 | 232 case CODEC_ID_PCM_S16LE: |
233 case CODEC_ID_PCM_S16BE: | |
234 case CODEC_ID_PCM_U16LE: | |
235 case CODEC_ID_PCM_U16BE: | |
236 sample_size = 2; | |
237 break; | |
238 default: | |
239 sample_size = 1; | |
240 break; | |
241 } | |
242 n = buf_size / sample_size; | |
243 samples = data; | |
244 dst = frame; | |
245 | |
246 switch(avctx->codec->id) { | |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
247 case CODEC_ID_PCM_S32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
248 encode_from16(4, 1, 0, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
249 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
250 case CODEC_ID_PCM_S32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
251 encode_from16(4, 0, 0, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
252 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
253 case CODEC_ID_PCM_U32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
254 encode_from16(4, 1, 1, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
255 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
256 case CODEC_ID_PCM_U32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
257 encode_from16(4, 0, 1, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
258 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
259 case CODEC_ID_PCM_S24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
260 encode_from16(3, 1, 0, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
261 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
262 case CODEC_ID_PCM_S24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
263 encode_from16(3, 0, 0, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
264 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
265 case CODEC_ID_PCM_U24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
266 encode_from16(3, 1, 1, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
267 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
268 case CODEC_ID_PCM_U24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
269 encode_from16(3, 0, 1, &samples, &dst, n); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
270 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
271 case CODEC_ID_PCM_S24DAUD: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
272 for(;n>0;n--) { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
273 uint32_t tmp = ff_reverse[*samples >> 8] + |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
274 (ff_reverse[*samples & 0xff] << 8); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
275 tmp <<= 4; // sync flags would go here |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
276 dst[2] = tmp & 0xff; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
277 tmp >>= 8; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
278 dst[1] = tmp & 0xff; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
279 dst[0] = tmp >> 8; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
280 samples++; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
281 dst += 3; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
282 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
283 break; |
92 | 284 case CODEC_ID_PCM_S16LE: |
285 for(;n>0;n--) { | |
286 v = *samples++; | |
287 dst[0] = v & 0xff; | |
288 dst[1] = v >> 8; | |
289 dst += 2; | |
290 } | |
291 break; | |
292 case CODEC_ID_PCM_S16BE: | |
293 for(;n>0;n--) { | |
294 v = *samples++; | |
295 dst[0] = v >> 8; | |
296 dst[1] = v; | |
297 dst += 2; | |
298 } | |
299 break; | |
300 case CODEC_ID_PCM_U16LE: | |
301 for(;n>0;n--) { | |
302 v = *samples++; | |
303 v += 0x8000; | |
304 dst[0] = v & 0xff; | |
305 dst[1] = v >> 8; | |
306 dst += 2; | |
307 } | |
308 break; | |
309 case CODEC_ID_PCM_U16BE: | |
310 for(;n>0;n--) { | |
311 v = *samples++; | |
312 v += 0x8000; | |
313 dst[0] = v >> 8; | |
314 dst[1] = v; | |
315 dst += 2; | |
316 } | |
317 break; | |
318 case CODEC_ID_PCM_S8: | |
319 for(;n>0;n--) { | |
320 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
|
321 dst[0] = v >> 8; |
92 | 322 dst++; |
323 } | |
324 break; | |
325 case CODEC_ID_PCM_U8: | |
326 for(;n>0;n--) { | |
327 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
|
328 dst[0] = (v >> 8) + 128; |
92 | 329 dst++; |
330 } | |
331 break; | |
332 case CODEC_ID_PCM_ALAW: | |
333 for(;n>0;n--) { | |
334 v = *samples++; | |
335 dst[0] = linear_to_alaw[(v + 32768) >> 2]; | |
336 dst++; | |
337 } | |
338 break; | |
339 case CODEC_ID_PCM_MULAW: | |
340 for(;n>0;n--) { | |
341 v = *samples++; | |
342 dst[0] = linear_to_ulaw[(v + 32768) >> 2]; | |
343 dst++; | |
344 } | |
345 break; | |
346 default: | |
347 return -1; | |
348 } | |
381
0d6178e4d503
* Mea culpa: it seems that I broke encoding to 8-bit pcm files. This fixes it.
philipjsg
parents:
372
diff
changeset
|
349 //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); |
372 | 350 |
92 | 351 return dst - frame; |
352 } | |
353 | |
354 typedef struct PCMDecode { | |
355 short table[256]; | |
356 } PCMDecode; | |
357 | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
358 static int pcm_decode_init(AVCodecContext * avctx) |
92 | 359 { |
360 PCMDecode *s = avctx->priv_data; | |
361 int i; | |
362 | |
363 switch(avctx->codec->id) { | |
364 case CODEC_ID_PCM_ALAW: | |
365 for(i=0;i<256;i++) | |
366 s->table[i] = alaw2linear(i); | |
367 break; | |
368 case CODEC_ID_PCM_MULAW: | |
369 for(i=0;i<256;i++) | |
370 s->table[i] = ulaw2linear(i); | |
371 break; | |
372 default: | |
373 break; | |
374 } | |
375 return 0; | |
376 } | |
377 | |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
378 /** |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
379 * \brief convert samples to 16 bit |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
380 * \param bps byte per sample for the source format, must be >= 2 |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
381 * \param le 0 for big-, 1 for little-endian |
2853
87c11495e393
Document "us" parameter for PCM conversion functions.
reimar
parents:
2852
diff
changeset
|
382 * \param us 0 for signed, 1 for unsigned input |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
383 * \param src input samples |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
384 * \param samples output samples |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
385 * \param src_len number of bytes in src |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
386 */ |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
387 static inline void decode_to16(int bps, int le, int us, |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
388 uint8_t **src, short **samples, int src_len) |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
389 { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
390 register int n = src_len / bps; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
391 if (le) *src += bps - 2; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
392 for(;n>0;n--) { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
393 *(*samples)++ = ((*src)[le] << 8 | (*src)[1 - le]) - (us?0x8000:0); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
394 *src += bps; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
395 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
396 if (le) *src -= bps - 2; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
397 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
398 |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
399 static int pcm_decode_frame(AVCodecContext *avctx, |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
400 void *data, int *data_size, |
1064 | 401 uint8_t *buf, int buf_size) |
92 | 402 { |
403 PCMDecode *s = avctx->priv_data; | |
404 int n; | |
405 short *samples; | |
1064 | 406 uint8_t *src; |
92 | 407 |
408 samples = data; | |
409 src = buf; | |
410 | |
2506 | 411 if(buf_size > AVCODEC_MAX_AUDIO_FRAME_SIZE/2) |
412 buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE/2; | |
413 | |
92 | 414 switch(avctx->codec->id) { |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
415 case CODEC_ID_PCM_S32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
416 decode_to16(4, 1, 0, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
417 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
418 case CODEC_ID_PCM_S32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
419 decode_to16(4, 0, 0, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
420 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
421 case CODEC_ID_PCM_U32LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
422 decode_to16(4, 1, 1, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
423 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
424 case CODEC_ID_PCM_U32BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
425 decode_to16(4, 0, 1, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
426 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
427 case CODEC_ID_PCM_S24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
428 decode_to16(3, 1, 0, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
429 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
430 case CODEC_ID_PCM_S24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
431 decode_to16(3, 0, 0, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
432 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
433 case CODEC_ID_PCM_U24LE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
434 decode_to16(3, 1, 1, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
435 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
436 case CODEC_ID_PCM_U24BE: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
437 decode_to16(3, 0, 1, &src, &samples, buf_size); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
438 break; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
439 case CODEC_ID_PCM_S24DAUD: |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
440 n = buf_size / 3; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
441 for(;n>0;n--) { |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
442 uint32_t v = src[0] << 16 | src[1] << 8 | src[2]; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
443 v >>= 4; // sync flags are here |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
444 *samples++ = ff_reverse[(v >> 8) & 0xff] + |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
445 (ff_reverse[v & 0xff] << 8); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
446 src += 3; |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
447 } |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
448 break; |
92 | 449 case CODEC_ID_PCM_S16LE: |
450 n = buf_size >> 1; | |
451 for(;n>0;n--) { | |
452 *samples++ = src[0] | (src[1] << 8); | |
453 src += 2; | |
454 } | |
455 break; | |
456 case CODEC_ID_PCM_S16BE: | |
457 n = buf_size >> 1; | |
458 for(;n>0;n--) { | |
459 *samples++ = (src[0] << 8) | src[1]; | |
460 src += 2; | |
461 } | |
462 break; | |
463 case CODEC_ID_PCM_U16LE: | |
464 n = buf_size >> 1; | |
465 for(;n>0;n--) { | |
466 *samples++ = (src[0] | (src[1] << 8)) - 0x8000; | |
467 src += 2; | |
468 } | |
469 break; | |
470 case CODEC_ID_PCM_U16BE: | |
471 n = buf_size >> 1; | |
472 for(;n>0;n--) { | |
473 *samples++ = ((src[0] << 8) | src[1]) - 0x8000; | |
474 src += 2; | |
475 } | |
476 break; | |
477 case CODEC_ID_PCM_S8: | |
478 n = buf_size; | |
479 for(;n>0;n--) { | |
480 *samples++ = src[0] << 8; | |
481 src++; | |
482 } | |
483 break; | |
484 case CODEC_ID_PCM_U8: | |
485 n = buf_size; | |
486 for(;n>0;n--) { | |
487 *samples++ = ((int)src[0] - 128) << 8; | |
488 src++; | |
489 } | |
490 break; | |
491 case CODEC_ID_PCM_ALAW: | |
492 case CODEC_ID_PCM_MULAW: | |
493 n = buf_size; | |
494 for(;n>0;n--) { | |
495 *samples++ = s->table[src[0]]; | |
496 src++; | |
497 } | |
498 break; | |
499 default: | |
500 return -1; | |
501 } | |
1064 | 502 *data_size = (uint8_t *)samples - (uint8_t *)data; |
92 | 503 return src - buf; |
504 } | |
505 | |
506 #define PCM_CODEC(id, name) \ | |
507 AVCodec name ## _encoder = { \ | |
508 #name, \ | |
509 CODEC_TYPE_AUDIO, \ | |
510 id, \ | |
511 0, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
512 pcm_encode_init, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
513 pcm_encode_frame, \ |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
514 pcm_encode_close, \ |
92 | 515 NULL, \ |
516 }; \ | |
517 AVCodec name ## _decoder = { \ | |
518 #name, \ | |
519 CODEC_TYPE_AUDIO, \ | |
520 id, \ | |
521 sizeof(PCMDecode), \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
522 pcm_decode_init, \ |
92 | 523 NULL, \ |
524 NULL, \ | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
525 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
|
526 } |
92 | 527 |
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
528 PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
529 PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
530 PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
531 PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
532 PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
533 PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
534 PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
535 PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); |
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
536 PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); |
92 | 537 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); |
538 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | |
539 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | |
540 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | |
541 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | |
542 PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); | |
543 PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); | |
544 PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); | |
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
545 |
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
546 #undef PCM_CODEC |