Mercurial > libavcodec.hg
annotate pcm.c @ 5319:40af705cef7e libavcodec
AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9
Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.
2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.
| author | jbr |
|---|---|
| date | Sat, 14 Jul 2007 16:03:14 +0000 |
| parents | 91015dc624ad |
| children | ad384eda0cb7 |
| rev | line source |
|---|---|
| 92 | 1 /* |
| 2 * PCM codecs | |
| 429 | 3 * Copyright (c) 2001 Fabrice Bellard. |
| 92 | 4 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
5 * This file is part of FFmpeg. |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
6 * |
|
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
| 429 | 8 * modify it under the terms of the GNU Lesser General Public |
| 9 * License as published by the Free Software Foundation; either | |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
| 92 | 11 * |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
| 92 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 429 | 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 * Lesser General Public License for more details. | |
| 92 | 16 * |
| 429 | 17 * You should have received a copy of the GNU Lesser General Public |
|
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3036
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
|
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2979
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 92 | 20 */ |
| 2967 | 21 |
| 1108 | 22 /** |
| 23 * @file pcm.c | |
| 24 * PCM codecs | |
| 25 */ | |
| 2967 | 26 |
| 92 | 27 #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
|
28 #include "bitstream.h" // for ff_reverse |
| 4959 | 29 #include "bytestream.h" |
| 92 | 30 |
| 31 /* from g711.c by SUN microsystems (unrestricted use) */ | |
| 32 | |
| 2979 | 33 #define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ |
| 34 #define QUANT_MASK (0xf) /* Quantization field mask. */ | |
| 35 #define NSEGS (8) /* Number of A-law segments. */ | |
| 36 #define SEG_SHIFT (4) /* Left shift for segment number. */ | |
| 37 #define SEG_MASK (0x70) /* Segment field mask. */ | |
| 92 | 38 |
| 2979 | 39 #define BIAS (0x84) /* Bias for linear code. */ |
| 92 | 40 |
| 41 /* | |
| 42 * alaw2linear() - Convert an A-law value to 16-bit linear PCM | |
| 43 * | |
| 44 */ | |
| 2979 | 45 static int alaw2linear(unsigned char a_val) |
| 92 | 46 { |
| 2979 | 47 int t; |
| 48 int seg; | |
| 92 | 49 |
| 2979 | 50 a_val ^= 0x55; |
| 92 | 51 |
| 2979 | 52 t = a_val & QUANT_MASK; |
| 53 seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; | |
| 54 if(seg) t= (t + t + 1 + 32) << (seg + 2); | |
| 55 else t= (t + t + 1 ) << 3; | |
| 1485 | 56 |
| 2979 | 57 return ((a_val & SIGN_BIT) ? t : -t); |
| 92 | 58 } |
| 59 | |
| 2979 | 60 static int ulaw2linear(unsigned char u_val) |
| 92 | 61 { |
| 2979 | 62 int t; |
| 92 | 63 |
| 2979 | 64 /* Complement to obtain normal u-law value. */ |
| 65 u_val = ~u_val; | |
| 92 | 66 |
| 2979 | 67 /* |
| 68 * Extract and bias the quantization bits. Then | |
| 69 * shift up by the segment number and subtract out the bias. | |
| 70 */ | |
| 71 t = ((u_val & QUANT_MASK) << 3) + BIAS; | |
| 72 t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; | |
| 92 | 73 |
| 2979 | 74 return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); |
| 92 | 75 } |
| 76 | |
| 77 /* 16384 entries per table */ | |
| 4660 | 78 static uint8_t linear_to_alaw[16384]; |
| 79 static uint8_t linear_to_ulaw[16384]; | |
| 92 | 80 |
| 2967 | 81 static void build_xlaw_table(uint8_t *linear_to_xlaw, |
| 92 | 82 int (*xlaw2linear)(unsigned char), |
| 2967 | 83 int mask) |
| 92 | 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: | |
| 4660 | 110 build_xlaw_table(linear_to_alaw, alaw2linear, 0xd5); |
| 92 | 111 break; |
| 112 case CODEC_ID_PCM_MULAW: | |
| 4660 | 113 build_xlaw_table(linear_to_ulaw, ulaw2linear, 0xff); |
| 92 | 114 break; |
| 115 default: | |
| 116 break; | |
| 117 } | |
| 2967 | 118 |
| 2340 | 119 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
|
120 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
|
121 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
|
122 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
|
123 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
|
124 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
|
125 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
126 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
|
127 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
|
128 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
|
129 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
|
130 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
|
131 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
|
132 break; |
| 2340 | 133 case CODEC_ID_PCM_S16LE: |
| 134 case CODEC_ID_PCM_S16BE: | |
| 135 case CODEC_ID_PCM_U16LE: | |
| 136 case CODEC_ID_PCM_U16BE: | |
| 137 avctx->block_align = 2 * avctx->channels; | |
| 138 break; | |
| 139 case CODEC_ID_PCM_S8: | |
| 140 case CODEC_ID_PCM_U8: | |
| 141 case CODEC_ID_PCM_MULAW: | |
| 142 case CODEC_ID_PCM_ALAW: | |
| 143 avctx->block_align = avctx->channels; | |
| 144 break; | |
| 145 default: | |
| 146 break; | |
| 147 } | |
| 148 | |
| 925 | 149 avctx->coded_frame= avcodec_alloc_frame(); |
| 150 avctx->coded_frame->key_frame= 1; | |
| 2967 | 151 |
| 92 | 152 return 0; |
| 153 } | |
| 154 | |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
155 static int pcm_encode_close(AVCodecContext *avctx) |
| 92 | 156 { |
| 925 | 157 av_freep(&avctx->coded_frame); |
| 158 | |
| 92 | 159 return 0; |
| 160 } | |
| 161 | |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
162 /** |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
163 * \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
|
164 * \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
|
165 * \param le 0 for big-, 1 for little-endian |
|
2853
87c11495e393
Document "us" parameter for PCM conversion functions.
reimar
parents:
2852
diff
changeset
|
166 * \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
|
167 * \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
|
168 * \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
|
169 * \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
|
170 */ |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
171 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
|
172 short **samples, uint8_t **dst, int n) { |
| 4956 | 173 int usum = us ? 0x8000 : 0; |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
174 if (bps > 2) |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
175 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
|
176 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
|
177 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
|
178 register int v = *(*samples)++; |
| 4956 | 179 v += usum; |
| 4973 | 180 if (le) AV_WL16(*dst, v); |
| 181 else AV_WB16(*dst, v); | |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
182 *dst += bps; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
183 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
184 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
|
185 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
186 |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
187 static int pcm_encode_frame(AVCodecContext *avctx, |
| 2979 | 188 unsigned char *frame, int buf_size, void *data) |
| 92 | 189 { |
| 190 int n, sample_size, v; | |
| 191 short *samples; | |
| 192 unsigned char *dst; | |
| 193 | |
| 194 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
|
195 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
|
196 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
|
197 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
|
198 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
|
199 sample_size = 4; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
200 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
201 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
|
202 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
|
203 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
|
204 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
|
205 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
|
206 sample_size = 3; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
207 break; |
| 92 | 208 case CODEC_ID_PCM_S16LE: |
| 209 case CODEC_ID_PCM_S16BE: | |
| 210 case CODEC_ID_PCM_U16LE: | |
| 211 case CODEC_ID_PCM_U16BE: | |
| 212 sample_size = 2; | |
| 213 break; | |
| 214 default: | |
| 215 sample_size = 1; | |
| 216 break; | |
| 217 } | |
| 218 n = buf_size / sample_size; | |
| 219 samples = data; | |
| 220 dst = frame; | |
| 221 | |
| 222 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
|
223 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
|
224 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
|
225 break; |
|
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_S32BE: |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
227 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
|
228 break; |
|
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_U32LE: |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
230 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
|
231 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
232 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
|
233 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
|
234 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
235 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
|
236 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
|
237 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
238 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
|
239 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
|
240 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
241 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
|
242 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
|
243 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
244 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
|
245 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
|
246 break; |
|
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_S24DAUD: |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
248 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
|
249 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
|
250 (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
|
251 tmp <<= 4; // sync flags would go here |
| 4959 | 252 bytestream_put_be24(&dst, tmp); |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
253 samples++; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
254 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
255 break; |
| 92 | 256 case CODEC_ID_PCM_S16LE: |
| 257 for(;n>0;n--) { | |
| 258 v = *samples++; | |
| 4959 | 259 bytestream_put_le16(&dst, v); |
| 92 | 260 } |
| 261 break; | |
| 262 case CODEC_ID_PCM_S16BE: | |
| 263 for(;n>0;n--) { | |
| 264 v = *samples++; | |
| 4959 | 265 bytestream_put_be16(&dst, v); |
| 92 | 266 } |
| 267 break; | |
| 268 case CODEC_ID_PCM_U16LE: | |
| 269 for(;n>0;n--) { | |
| 270 v = *samples++; | |
| 271 v += 0x8000; | |
| 4959 | 272 bytestream_put_le16(&dst, v); |
| 92 | 273 } |
| 274 break; | |
| 275 case CODEC_ID_PCM_U16BE: | |
| 276 for(;n>0;n--) { | |
| 277 v = *samples++; | |
| 278 v += 0x8000; | |
| 4959 | 279 bytestream_put_be16(&dst, v); |
| 92 | 280 } |
| 281 break; | |
| 282 case CODEC_ID_PCM_S8: | |
| 283 for(;n>0;n--) { | |
| 284 v = *samples++; | |
| 4960 | 285 *dst++ = v >> 8; |
| 92 | 286 } |
| 287 break; | |
| 288 case CODEC_ID_PCM_U8: | |
| 289 for(;n>0;n--) { | |
| 290 v = *samples++; | |
| 4960 | 291 *dst++ = (v >> 8) + 128; |
| 92 | 292 } |
| 293 break; | |
| 294 case CODEC_ID_PCM_ALAW: | |
| 295 for(;n>0;n--) { | |
| 296 v = *samples++; | |
| 4960 | 297 *dst++ = linear_to_alaw[(v + 32768) >> 2]; |
| 92 | 298 } |
| 299 break; | |
| 300 case CODEC_ID_PCM_MULAW: | |
| 301 for(;n>0;n--) { | |
| 302 v = *samples++; | |
| 4960 | 303 *dst++ = linear_to_ulaw[(v + 32768) >> 2]; |
| 92 | 304 } |
| 305 break; | |
| 306 default: | |
| 307 return -1; | |
| 308 } | |
|
381
0d6178e4d503
* Mea culpa: it seems that I broke encoding to 8-bit pcm files. This fixes it.
philipjsg
parents:
372
diff
changeset
|
309 //avctx->frame_size = (dst - frame) / (sample_size * avctx->channels); |
| 372 | 310 |
| 92 | 311 return dst - frame; |
| 312 } | |
| 313 | |
| 314 typedef struct PCMDecode { | |
| 315 short table[256]; | |
| 316 } PCMDecode; | |
| 317 | |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
318 static int pcm_decode_init(AVCodecContext * avctx) |
| 92 | 319 { |
| 320 PCMDecode *s = avctx->priv_data; | |
| 321 int i; | |
| 322 | |
| 323 switch(avctx->codec->id) { | |
| 324 case CODEC_ID_PCM_ALAW: | |
| 325 for(i=0;i<256;i++) | |
| 326 s->table[i] = alaw2linear(i); | |
| 327 break; | |
| 328 case CODEC_ID_PCM_MULAW: | |
| 329 for(i=0;i<256;i++) | |
| 330 s->table[i] = ulaw2linear(i); | |
| 331 break; | |
| 332 default: | |
| 333 break; | |
| 334 } | |
| 335 return 0; | |
| 336 } | |
| 337 | |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
338 /** |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
339 * \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
|
340 * \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
|
341 * \param le 0 for big-, 1 for little-endian |
|
2853
87c11495e393
Document "us" parameter for PCM conversion functions.
reimar
parents:
2852
diff
changeset
|
342 * \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
|
343 * \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
|
344 * \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
|
345 * \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
|
346 */ |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
347 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
|
348 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
|
349 { |
| 4956 | 350 int usum = us ? -0x8000 : 0; |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
351 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
|
352 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
|
353 for(;n>0;n--) { |
| 4958 | 354 register int v; |
| 355 if (le) v = AV_RL16(*src); | |
| 356 else v = AV_RB16(*src); | |
| 357 v += usum; | |
| 358 *(*samples)++ = v; | |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
359 *src += bps; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
360 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
361 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
|
362 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
363 |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
364 static int pcm_decode_frame(AVCodecContext *avctx, |
| 2979 | 365 void *data, int *data_size, |
| 366 uint8_t *buf, int buf_size) | |
| 92 | 367 { |
| 368 PCMDecode *s = avctx->priv_data; | |
| 369 int n; | |
| 370 short *samples; | |
| 1064 | 371 uint8_t *src; |
| 92 | 372 |
| 373 samples = data; | |
| 374 src = buf; | |
| 375 | |
| 4506 | 376 n= av_get_bits_per_sample(avctx->codec_id)/8; |
| 377 if(n && buf_size % n){ | |
| 378 av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n"); | |
| 379 return -1; | |
| 380 } | |
| 381 | |
| 4351 | 382 buf_size= FFMIN(buf_size, *data_size/2); |
| 383 *data_size=0; | |
| 2506 | 384 |
| 92 | 385 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
|
386 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
|
387 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
|
388 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
389 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
|
390 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
|
391 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
392 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
|
393 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
|
394 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
395 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
|
396 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
|
397 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
398 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
|
399 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
|
400 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
401 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
|
402 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
|
403 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
404 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
|
405 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
|
406 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
407 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
|
408 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
|
409 break; |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
410 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
|
411 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
|
412 for(;n>0;n--) { |
| 4959 | 413 uint32_t v = bytestream_get_be24(&src); |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
414 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
|
415 *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
|
416 (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
|
417 } |
|
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
418 break; |
| 92 | 419 case CODEC_ID_PCM_S16LE: |
| 420 n = buf_size >> 1; | |
| 421 for(;n>0;n--) { | |
| 4959 | 422 *samples++ = bytestream_get_le16(&src); |
| 92 | 423 } |
| 424 break; | |
| 425 case CODEC_ID_PCM_S16BE: | |
| 426 n = buf_size >> 1; | |
| 427 for(;n>0;n--) { | |
| 4959 | 428 *samples++ = bytestream_get_be16(&src); |
| 92 | 429 } |
| 430 break; | |
| 431 case CODEC_ID_PCM_U16LE: | |
| 432 n = buf_size >> 1; | |
| 433 for(;n>0;n--) { | |
| 4959 | 434 *samples++ = bytestream_get_le16(&src) - 0x8000; |
| 92 | 435 } |
| 436 break; | |
| 437 case CODEC_ID_PCM_U16BE: | |
| 438 n = buf_size >> 1; | |
| 439 for(;n>0;n--) { | |
| 4959 | 440 *samples++ = bytestream_get_be16(&src) - 0x8000; |
| 92 | 441 } |
| 442 break; | |
| 443 case CODEC_ID_PCM_S8: | |
| 444 n = buf_size; | |
| 445 for(;n>0;n--) { | |
| 4960 | 446 *samples++ = *src++ << 8; |
| 92 | 447 } |
| 448 break; | |
| 449 case CODEC_ID_PCM_U8: | |
| 450 n = buf_size; | |
| 451 for(;n>0;n--) { | |
| 4960 | 452 *samples++ = ((int)*src++ - 128) << 8; |
| 92 | 453 } |
| 454 break; | |
| 455 case CODEC_ID_PCM_ALAW: | |
| 456 case CODEC_ID_PCM_MULAW: | |
| 457 n = buf_size; | |
| 458 for(;n>0;n--) { | |
| 4960 | 459 *samples++ = s->table[*src++]; |
| 92 | 460 } |
| 461 break; | |
| 462 default: | |
| 463 return -1; | |
| 464 } | |
| 1064 | 465 *data_size = (uint8_t *)samples - (uint8_t *)data; |
| 92 | 466 return src - buf; |
| 467 } | |
| 468 | |
| 469 #define PCM_CODEC(id, name) \ | |
| 470 AVCodec name ## _encoder = { \ | |
| 471 #name, \ | |
| 472 CODEC_TYPE_AUDIO, \ | |
| 473 id, \ | |
| 474 0, \ | |
| 2979 | 475 pcm_encode_init, \ |
| 476 pcm_encode_frame, \ | |
| 477 pcm_encode_close, \ | |
| 92 | 478 NULL, \ |
| 479 }; \ | |
| 480 AVCodec name ## _decoder = { \ | |
| 481 #name, \ | |
| 482 CODEC_TYPE_AUDIO, \ | |
| 483 id, \ | |
| 484 sizeof(PCMDecode), \ | |
| 2979 | 485 pcm_decode_init, \ |
| 92 | 486 NULL, \ |
| 487 NULL, \ | |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
488 pcm_decode_frame, \ |
|
1014
48349e11c9b2
C99 initializers and kill warnings patch by (mru at users dot sourceforge dot net (M?ns Rullg?rd))
michaelni
parents:
925
diff
changeset
|
489 } |
| 92 | 490 |
|
2852
6f7428adc6ad
Support de-/encoding of 24 and 32 bit PCM (from and to internal 16 bit).
reimar
parents:
2506
diff
changeset
|
491 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
|
492 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
|
493 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
|
494 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
|
495 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
|
496 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
|
497 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
|
498 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
|
499 PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); |
| 92 | 500 PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); |
| 501 PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); | |
| 502 PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); | |
| 503 PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); | |
| 504 PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); | |
| 505 PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); | |
| 506 PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); | |
| 507 PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); | |
|
440
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
508 |
|
000aeeac27a2
* started to cleanup name clashes for onetime compilation
kabi
parents:
429
diff
changeset
|
509 #undef PCM_CODEC |
