[FFmpeg-devel] [PATCH] WMA: use type punning and unroll loops in decode_exp_vlc()

Mans Rullgard mans
Tue Sep 29 02:04:47 CEST 2009


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.
---
 libavcodec/wmadec.c |   22 ++++++++++++++++------
 1 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index ce2940d..a3cd034 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -33,6 +33,7 @@
  * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data.
  */
 
+#include "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "wma.h"
 
@@ -315,21 +316,26 @@ 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;
 
     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 = AV_RN32(ptab + 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 = AV_RN32(ptab + 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;
-- 
1.6.4.4




More information about the ffmpeg-devel mailing list