Mercurial > libavcodec.hg
comparison wmadec.c @ 10313:f7376a522a7e libavcodec
WMA: use type punning and unroll loops in decode_exp_vlc()
GCC does stupid things if these assignments are done using floats
directly, so fill the runs using integer operations instead. Also
unroll the loops since the length is always a multiple of 4.
author | mru |
---|---|
date | Tue, 29 Sep 2009 10:38:30 +0000 |
parents | 6aaf7c9e768b |
children | 88e1eb862abd |
comparison
equal
deleted
inserted
replaced
10312:6aaf7c9e768b | 10313:f7376a522a7e |
---|---|
313 */ | 313 */ |
314 static int decode_exp_vlc(WMACodecContext *s, int ch) | 314 static int decode_exp_vlc(WMACodecContext *s, int ch) |
315 { | 315 { |
316 int last_exp, n, code; | 316 int last_exp, n, code; |
317 const uint16_t *ptr; | 317 const uint16_t *ptr; |
318 float v, *q, max_scale, *q_end; | 318 float v, max_scale; |
319 uint32_t *q, *q_end, iv; | |
319 const float *ptab = pow_tab + 60; | 320 const float *ptab = pow_tab + 60; |
321 const uint32_t *iptab = (const uint32_t*)ptab; | |
320 | 322 |
321 ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; | 323 ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; |
322 q = s->exponents[ch]; | 324 q = (uint32_t *)s->exponents[ch]; |
323 q_end = q + s->block_len; | 325 q_end = q + s->block_len; |
324 max_scale = 0; | 326 max_scale = 0; |
325 if (s->version == 1) { | 327 if (s->version == 1) { |
326 last_exp = get_bits(&s->gb, 5) + 10; | 328 last_exp = get_bits(&s->gb, 5) + 10; |
327 v = ptab[last_exp]; | 329 v = ptab[last_exp]; |
330 iv = iptab[last_exp]; | |
328 max_scale = v; | 331 max_scale = v; |
329 n = *ptr++; | 332 n = *ptr++; |
330 do { | 333 do { |
331 *q++ = v; | 334 *q++ = iv; |
332 } while (--n); | 335 *q++ = iv; |
336 *q++ = iv; | |
337 *q++ = iv; | |
338 } while (n -= 4); | |
333 }else | 339 }else |
334 last_exp = 36; | 340 last_exp = 36; |
335 | 341 |
336 while (q < q_end) { | 342 while (q < q_end) { |
337 code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); | 343 code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); |
340 /* NOTE: this offset is the same as MPEG4 AAC ! */ | 346 /* NOTE: this offset is the same as MPEG4 AAC ! */ |
341 last_exp += code - 60; | 347 last_exp += code - 60; |
342 if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) | 348 if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) |
343 return -1; | 349 return -1; |
344 v = ptab[last_exp]; | 350 v = ptab[last_exp]; |
351 iv = iptab[last_exp]; | |
345 if (v > max_scale) | 352 if (v > max_scale) |
346 max_scale = v; | 353 max_scale = v; |
347 n = *ptr++; | 354 n = *ptr++; |
348 do { | 355 do { |
349 *q++ = v; | 356 *q++ = iv; |
350 } while (--n); | 357 *q++ = iv; |
358 *q++ = iv; | |
359 *q++ = iv; | |
360 } while (n -= 4); | |
351 } | 361 } |
352 s->max_exponent[ch] = max_scale; | 362 s->max_exponent[ch] = max_scale; |
353 return 0; | 363 return 0; |
354 } | 364 } |
355 | 365 |