Mercurial > libavcodec.hg
annotate wmaenc.c @ 7352:c2318e551ff5 libavcodec
When picking a "high utility centroid" do not pick one
that has no corresponding points. Not only it is the
worst possible pick, but also the code was written
without this case in mind.
author | vitor |
---|---|
date | Wed, 23 Jul 2008 03:55:37 +0000 |
parents | e943e1409077 |
children | 85ab7655ad4d |
rev | line source |
---|---|
4490 | 1 /* |
2 * WMA compatible encoder | |
3 * Copyright (c) 2007 Michael Niedermayer | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 #include "avcodec.h" | |
23 #include "wma.h" | |
24 | |
25 #undef NDEBUG | |
26 #include <assert.h> | |
27 | |
28 | |
29 static int encode_init(AVCodecContext * avctx){ | |
4601 | 30 WMACodecContext *s = avctx->priv_data; |
4490 | 31 int i, flags1, flags2; |
32 uint8_t *extradata; | |
33 | |
4600 | 34 s->avctx = avctx; |
35 | |
4490 | 36 if(avctx->channels > MAX_CHANNELS) |
37 return -1; | |
38 | |
4635 | 39 if(avctx->bit_rate < 24*1000) |
40 return -1; | |
41 | |
4490 | 42 /* extract flag infos */ |
43 flags1 = 0; | |
44 flags2 = 1; | |
45 if (avctx->codec->id == CODEC_ID_WMAV1) { | |
46 extradata= av_malloc(4); | |
47 avctx->extradata_size= 4; | |
5089 | 48 AV_WL16(extradata, flags1); |
49 AV_WL16(extradata+2, flags2); | |
4490 | 50 } else if (avctx->codec->id == CODEC_ID_WMAV2) { |
51 extradata= av_mallocz(10); | |
52 avctx->extradata_size= 10; | |
5089 | 53 AV_WL32(extradata, flags1); |
54 AV_WL16(extradata+4, flags2); | |
4490 | 55 }else |
56 assert(0); | |
57 avctx->extradata= extradata; | |
58 s->use_exp_vlc = flags2 & 0x0001; | |
59 s->use_bit_reservoir = flags2 & 0x0002; | |
60 s->use_variable_block_len = flags2 & 0x0004; | |
61 | |
62 ff_wma_init(avctx, flags2); | |
63 | |
64 /* init MDCT */ | |
65 for(i = 0; i < s->nb_block_sizes; i++) | |
66 ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0); | |
67 | |
68 avctx->block_align= | |
69 s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); | |
70 //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); | |
71 avctx->frame_size= s->frame_len; | |
72 | |
73 return 0; | |
74 } | |
75 | |
76 | |
77 static void apply_window_and_mdct(AVCodecContext * avctx, signed short * audio, int len) { | |
4601 | 78 WMACodecContext *s = avctx->priv_data; |
4490 | 79 int window_index= s->frame_len_bits - s->block_len_bits; |
80 int i, j, channel; | |
81 const float * win = s->windows[window_index]; | |
82 int window_len = 1 << s->block_len_bits; | |
83 float n = window_len/2; | |
84 | |
85 for (channel = 0; channel < avctx->channels; channel++) { | |
86 memcpy(s->output, s->frame_out[channel], sizeof(float)*window_len); | |
87 j = channel; | |
88 for (i = 0; i < len; i++, j += avctx->channels){ | |
4737
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4635
diff
changeset
|
89 s->output[i+window_len] = audio[j] / n * win[window_len - i - 1]; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4635
diff
changeset
|
90 s->frame_out[channel][i] = audio[j] / n * win[i]; |
4490 | 91 } |
92 ff_mdct_calc(&s->mdct_ctx[window_index], s->coefs[channel], s->output, s->mdct_tmp); | |
93 } | |
94 } | |
95 | |
96 //FIXME use for decoding too | |
5258 | 97 static void init_exp(WMACodecContext *s, int ch, const int *exp_param){ |
4490 | 98 int n; |
99 const uint16_t *ptr; | |
100 float v, *q, max_scale, *q_end; | |
101 | |
102 ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; | |
103 q = s->exponents[ch]; | |
104 q_end = q + s->block_len; | |
105 max_scale = 0; | |
106 while (q < q_end) { | |
107 /* XXX: use a table */ | |
108 v = pow(10, *exp_param++ * (1.0 / 16.0)); | |
109 max_scale= FFMAX(max_scale, v); | |
110 n = *ptr++; | |
111 do { | |
112 *q++ = v; | |
113 } while (--n); | |
114 } | |
115 s->max_exponent[ch] = max_scale; | |
116 } | |
117 | |
4601 | 118 static void encode_exp_vlc(WMACodecContext *s, int ch, const int *exp_param){ |
4490 | 119 int last_exp; |
120 const uint16_t *ptr; | |
121 float *q, *q_end; | |
122 | |
123 ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; | |
124 q = s->exponents[ch]; | |
125 q_end = q + s->block_len; | |
126 if (s->version == 1) { | |
127 last_exp= *exp_param++; | |
128 assert(last_exp-10 >= 0 && last_exp-10 < 32); | |
129 put_bits(&s->pb, 5, last_exp - 10); | |
130 q+= *ptr++; | |
131 }else | |
132 last_exp = 36; | |
133 while (q < q_end) { | |
134 int exp = *exp_param++; | |
135 int code = exp - last_exp + 60; | |
136 assert(code >= 0 && code < 120); | |
137 put_bits(&s->pb, ff_wma_scale_huffbits[code], ff_wma_scale_huffcodes[code]); | |
138 /* XXX: use a table */ | |
139 q+= *ptr++; | |
140 last_exp= exp; | |
141 } | |
142 } | |
143 | |
4601 | 144 static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], int total_gain){ |
4490 | 145 int v, bsize, ch, coef_nb_bits, parse_exponents; |
146 float mdct_norm; | |
147 int nb_coefs[MAX_CHANNELS]; | |
148 static const int fixed_exp[25]={20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}; | |
149 | |
150 //FIXME remove duplication relative to decoder | |
151 if (s->use_variable_block_len) { | |
152 assert(0); //FIXME not implemented | |
153 }else{ | |
154 /* fixed block len */ | |
155 s->next_block_len_bits = s->frame_len_bits; | |
156 s->prev_block_len_bits = s->frame_len_bits; | |
157 s->block_len_bits = s->frame_len_bits; | |
158 } | |
159 | |
160 s->block_len = 1 << s->block_len_bits; | |
161 // assert((s->block_pos + s->block_len) <= s->frame_len); | |
162 bsize = s->frame_len_bits - s->block_len_bits; | |
163 | |
164 //FIXME factor | |
165 v = s->coefs_end[bsize] - s->coefs_start; | |
166 for(ch = 0; ch < s->nb_channels; ch++) | |
167 nb_coefs[ch] = v; | |
168 { | |
169 int n4 = s->block_len / 2; | |
170 mdct_norm = 1.0 / (float)n4; | |
171 if (s->version == 1) { | |
172 mdct_norm *= sqrt(n4); | |
173 } | |
174 } | |
175 | |
176 if (s->nb_channels == 2) { | |
177 put_bits(&s->pb, 1, s->ms_stereo= 1); | |
178 } | |
179 | |
180 for(ch = 0; ch < s->nb_channels; ch++) { | |
6355
5a2c7290ddd3
silence wmaenc.c:181: warning:suggestparentheses around assignment used as truth value
banan
parents:
6035
diff
changeset
|
181 if ((s->channel_coded[ch]= 1)) { //FIXME only set channel_coded when needed, instead of always |
4490 | 182 init_exp(s, ch, fixed_exp); |
183 } | |
184 } | |
185 | |
186 for(ch = 0; ch < s->nb_channels; ch++) { | |
187 if (s->channel_coded[ch]) { | |
188 int16_t *coefs1; | |
189 float *coefs, *exponents, mult; | |
190 int i, n; | |
191 | |
192 coefs1 = s->coefs1[ch]; | |
193 exponents = s->exponents[ch]; | |
194 mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; | |
195 mult *= mdct_norm; | |
196 coefs = src_coefs[ch]; | |
197 if (s->use_noise_coding && 0) { | |
198 assert(0); //FIXME not implemented | |
199 } else { | |
200 coefs += s->coefs_start; | |
201 n = nb_coefs[ch]; | |
202 for(i = 0;i < n; i++){ | |
203 double t= *coefs++ / (exponents[i] * mult); | |
204 if(t<-32768 || t>32767) | |
205 return -1; | |
206 | |
207 coefs1[i] = lrint(t); | |
208 } | |
209 } | |
210 } | |
211 } | |
212 | |
213 v = 0; | |
214 for(ch = 0; ch < s->nb_channels; ch++) { | |
4492 | 215 int a = s->channel_coded[ch]; |
4490 | 216 put_bits(&s->pb, 1, a); |
217 v |= a; | |
218 } | |
219 | |
220 if (!v) | |
221 return 1; | |
222 | |
223 for(v= total_gain-1; v>=127; v-= 127) | |
224 put_bits(&s->pb, 7, 127); | |
225 put_bits(&s->pb, 7, v); | |
226 | |
227 coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); | |
228 | |
229 if (s->use_noise_coding) { | |
230 for(ch = 0; ch < s->nb_channels; ch++) { | |
231 if (s->channel_coded[ch]) { | |
232 int i, n; | |
233 n = s->exponent_high_sizes[bsize]; | |
234 for(i=0;i<n;i++) { | |
235 put_bits(&s->pb, 1, s->high_band_coded[ch][i]= 0); | |
236 if (0) | |
237 nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; | |
238 } | |
239 } | |
240 } | |
241 } | |
242 | |
243 parse_exponents = 1; | |
244 if (s->block_len_bits != s->frame_len_bits) { | |
245 put_bits(&s->pb, 1, parse_exponents); | |
246 } | |
247 | |
248 if (parse_exponents) { | |
249 for(ch = 0; ch < s->nb_channels; ch++) { | |
250 if (s->channel_coded[ch]) { | |
251 if (s->use_exp_vlc) { | |
252 encode_exp_vlc(s, ch, fixed_exp); | |
253 } else { | |
254 assert(0); //FIXME not implemented | |
255 // encode_exp_lsp(s, ch); | |
256 } | |
257 } | |
258 } | |
259 } else { | |
260 assert(0); //FIXME not implemented | |
261 } | |
262 | |
263 for(ch = 0; ch < s->nb_channels; ch++) { | |
264 if (s->channel_coded[ch]) { | |
265 int run, tindex; | |
266 int16_t *ptr, *eptr; | |
267 tindex = (ch == 1 && s->ms_stereo); | |
268 ptr = &s->coefs1[ch][0]; | |
269 eptr = ptr + nb_coefs[ch]; | |
270 | |
271 run=0; | |
272 for(;ptr < eptr; ptr++){ | |
273 if(*ptr){ | |
274 int level= *ptr; | |
275 int abs_level= FFABS(level); | |
276 int code= 0; | |
277 if(abs_level <= s->coef_vlcs[tindex]->max_level){ | |
278 if(run < s->coef_vlcs[tindex]->levels[abs_level-1]) | |
279 code= run + s->int_table[tindex][abs_level-1]; | |
280 } | |
281 | |
282 assert(code < s->coef_vlcs[tindex]->n); | |
283 put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[code], s->coef_vlcs[tindex]->huffcodes[code]); | |
284 | |
285 if(code == 0){ | |
286 if(1<<coef_nb_bits <= abs_level) | |
287 return -1; | |
288 | |
289 put_bits(&s->pb, coef_nb_bits, abs_level); | |
290 put_bits(&s->pb, s->frame_len_bits, run); | |
291 } | |
4493 | 292 put_bits(&s->pb, 1, level < 0); //FIXME the sign is fliped somewhere |
4490 | 293 run=0; |
294 }else{ | |
295 run++; | |
296 } | |
297 } | |
298 if(run) | |
299 put_bits(&s->pb, s->coef_vlcs[tindex]->huffbits[1], s->coef_vlcs[tindex]->huffcodes[1]); | |
300 } | |
301 if (s->version == 1 && s->nb_channels >= 2) { | |
302 align_put_bits(&s->pb); | |
303 } | |
304 } | |
305 return 0; | |
306 } | |
307 | |
4601 | 308 static int encode_frame(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], uint8_t *buf, int buf_size, int total_gain){ |
4490 | 309 init_put_bits(&s->pb, buf, buf_size); |
310 | |
311 if (s->use_bit_reservoir) { | |
312 assert(0);//FIXME not implemented | |
313 }else{ | |
314 if(encode_block(s, src_coefs, total_gain) < 0) | |
315 return INT_MAX; | |
316 } | |
317 | |
318 align_put_bits(&s->pb); | |
319 | |
320 return put_bits_count(&s->pb)/8 - s->block_align; | |
321 } | |
322 | |
323 static int encode_superframe(AVCodecContext *avctx, | |
324 unsigned char *buf, int buf_size, void *data){ | |
4601 | 325 WMACodecContext *s = avctx->priv_data; |
4490 | 326 short *samples = data; |
5258 | 327 int i, total_gain; |
4490 | 328 |
329 s->block_len_bits= s->frame_len_bits; //required by non variable block len | |
330 s->block_len = 1 << s->block_len_bits; | |
331 | |
332 apply_window_and_mdct(avctx, samples, avctx->frame_size); | |
333 | |
334 if (s->ms_stereo) { | |
335 float a, b; | |
336 int i; | |
337 | |
338 for(i = 0; i < s->block_len; i++) { | |
339 a = s->coefs[0][i]*0.5; | |
340 b = s->coefs[1][i]*0.5; | |
341 s->coefs[0][i] = a + b; | |
342 s->coefs[1][i] = a - b; | |
343 } | |
344 } | |
345 | |
346 #if 1 | |
347 total_gain= 128; | |
348 for(i=64; i; i>>=1){ | |
349 int error= encode_frame(s, s->coefs, buf, buf_size, total_gain-i); | |
350 if(error<0) | |
351 total_gain-= i; | |
352 } | |
353 #else | |
354 total_gain= 90; | |
355 best= encode_frame(s, s->coefs, buf, buf_size, total_gain); | |
356 for(i=32; i; i>>=1){ | |
357 int scoreL= encode_frame(s, s->coefs, buf, buf_size, total_gain-i); | |
358 int scoreR= encode_frame(s, s->coefs, buf, buf_size, total_gain+i); | |
359 av_log(NULL, AV_LOG_ERROR, "%d %d %d (%d)\n", scoreL, best, scoreR, total_gain); | |
360 if(scoreL < FFMIN(best, scoreR)){ | |
361 best = scoreL; | |
362 total_gain -= i; | |
363 }else if(scoreR < best){ | |
364 best = scoreR; | |
365 total_gain += i; | |
366 } | |
367 } | |
368 #endif | |
369 | |
370 encode_frame(s, s->coefs, buf, buf_size, total_gain); | |
371 assert((put_bits_count(&s->pb) & 7) == 0); | |
372 i= s->block_align - (put_bits_count(&s->pb)+7)/8; | |
373 assert(i>=0); | |
374 while(i--) | |
375 put_bits(&s->pb, 8, 'N'); | |
376 | |
377 flush_put_bits(&s->pb); | |
378 return pbBufPtr(&s->pb) - s->pb.buf; | |
379 } | |
380 | |
381 AVCodec wmav1_encoder = | |
382 { | |
383 "wmav1", | |
384 CODEC_TYPE_AUDIO, | |
385 CODEC_ID_WMAV1, | |
4601 | 386 sizeof(WMACodecContext), |
4490 | 387 encode_init, |
388 encode_superframe, | |
389 ff_wma_end, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
390 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), |
4490 | 391 }; |
392 | |
393 AVCodec wmav2_encoder = | |
394 { | |
395 "wmav2", | |
396 CODEC_TYPE_AUDIO, | |
397 CODEC_ID_WMAV2, | |
4601 | 398 sizeof(WMACodecContext), |
4490 | 399 encode_init, |
400 encode_superframe, | |
401 ff_wma_end, | |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
402 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), |
4490 | 403 }; |