aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMåns Rullgård <mans@mansr.com>2009-09-29 10:38:30 +0000
committerMåns Rullgård <mans@mansr.com>2009-09-29 10:38:30 +0000
commitff00b94e9d4f66922abe1830da2954a024bf87e5 (patch)
tree71992fc560075b0a73655a3e40fdefad3af9d75c
parentc0d1463da71dc035776171a9165e4f65218b3654 (diff)
downloadffmpeg-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.c22
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;