diff options
author | Måns Rullgård <mans@mansr.com> | 2009-09-29 10:38:30 +0000 |
---|---|---|
committer | Måns Rullgård <mans@mansr.com> | 2009-09-29 10:38:30 +0000 |
commit | ff00b94e9d4f66922abe1830da2954a024bf87e5 (patch) | |
tree | 71992fc560075b0a73655a3e40fdefad3af9d75c | |
parent | c0d1463da71dc035776171a9165e4f65218b3654 (diff) | |
download | ffmpeg-ff00b94e9d4f66922abe1830da2954a024bf87e5.tar.gz |
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.
Originally committed as revision 20077 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/wmadec.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index ce2940d24d..e216de706b 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -315,21 +315,27 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) { int last_exp, n, code; const uint16_t *ptr; - float v, *q, max_scale, *q_end; + float v, max_scale; + uint32_t *q, *q_end, iv; const float *ptab = pow_tab + 60; + const uint32_t *iptab = (const uint32_t*)ptab; ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; - q = s->exponents[ch]; + q = (uint32_t *)s->exponents[ch]; q_end = q + s->block_len; max_scale = 0; if (s->version == 1) { last_exp = get_bits(&s->gb, 5) + 10; v = ptab[last_exp]; + iv = iptab[last_exp]; max_scale = v; n = *ptr++; do { - *q++ = v; - } while (--n); + *q++ = iv; + *q++ = iv; + *q++ = iv; + *q++ = iv; + } while (n -= 4); }else last_exp = 36; @@ -342,12 +348,16 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) return -1; v = ptab[last_exp]; + iv = iptab[last_exp]; if (v > max_scale) max_scale = v; n = *ptr++; do { - *q++ = v; - } while (--n); + *q++ = iv; + *q++ = iv; + *q++ = iv; + *q++ = iv; + } while (n -= 4); } s->max_exponent[ch] = max_scale; return 0; |