[FFmpeg-cvslog] r19234 - trunk/libavcodec/wma.c

faust3 subversion
Sat Jun 20 13:06:48 CEST 2009


Author: faust3
Date: Sat Jun 20 13:06:48 2009
New Revision: 19234

Log:
Simplify run level decoding:
- remove unneeded vlc code < 0 check
- reorder vlc code handling so that the unlikely escape decoding
  part comes last
- move overflow check out of the decode loop
- branchless sign conversion

Modified:
   trunk/libavcodec/wma.c

Modified: trunk/libavcodec/wma.c
==============================================================================
--- trunk/libavcodec/wma.c	Sat Jun 20 12:33:18 2009	(r19233)
+++ trunk/libavcodec/wma.c	Sat Jun 20 13:06:48 2009	(r19234)
@@ -470,23 +470,24 @@ int ff_wma_run_level_decode(AVCodecConte
                             int num_coefs, int block_len, int frame_len_bits,
                             int coef_nb_bits)
 {
-    int code, run, level, sign;
-    WMACoef* eptr = ptr + num_coefs;
-    ptr += offset;
-    for(;;) {
+    int code, level, sign;
+    const unsigned int coef_mask = block_len - 1;
+    for (; offset < num_coefs; offset++) {
         code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX);
-        if (code < 0)
-            return -1;
-        if (code == 1) {
+        if (code > 1) {
+            /** normal code */
+            offset += run_table[code];
+            level = level_table[code];
+        } else if (code == 1) {
             /* EOB */
             break;
-        } else if (code == 0) {
+        } else {
             /* escape */
             if (!version) {
                 level = get_bits(gb, coef_nb_bits);
                 /* NOTE: this is rather suboptimal. reading
                    block_len_bits would be better */
-                run = get_bits(gb, frame_len_bits);
+                offset += get_bits(gb, frame_len_bits);
             } else {
                 level = ff_wma_get_large_val(gb);
                 /** escape decode */
@@ -497,31 +498,21 @@ int ff_wma_run_level_decode(AVCodecConte
                                 "broken escape sequence\n");
                             return -1;
                         } else
-                            run = get_bits(gb, frame_len_bits) + 4;
+                            offset += get_bits(gb, frame_len_bits) + 4;
                     } else
-                        run = get_bits(gb, 2) + 1;
-                } else
-                     run = 0;
+                        offset += get_bits(gb, 2) + 1;
+                }
             }
-        } else {
-            /* normal code */
-            run = run_table[code];
-            level = level_table[code];
-        }
-        sign = get_bits1(gb);
-        if (!sign)
-             level = -level;
-        ptr += run;
-        if (ptr >= eptr)
-        {
-            av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
-            break;
         }
-        *ptr++ = level;
-        /* NOTE: EOB can be omitted */
-        if (ptr >= eptr)
-            break;
+        sign = get_bits1(gb) - 1;
+        ptr[offset & coef_mask] = (level^sign) - sign;
     }
+    /** NOTE: EOB can be omitted */
+    if (offset > num_coefs) {
+        av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
+        return -1;
+    }
+
     return 0;
 }
 



More information about the ffmpeg-cvslog mailing list