Browse code

WMA: store level_table as floats, use type punning for sign flip in decode

Originally committed as revision 20078 to svn://svn.ffmpeg.org/ffmpeg/trunk

Måns Rullgård authored on 2009/09/29 19:38:34
Showing 4 changed files
... ...
@@ -29,7 +29,7 @@
29 29
 /* XXX: use same run/length optimization as mpeg decoders */
30 30
 //FIXME maybe split decode / encode or pass flag
31 31
 static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
32
-                          uint16_t **plevel_table, uint16_t **pint_table,
32
+                          float **plevel_table, uint16_t **pint_table,
33 33
                           const CoefVLCTable *vlc_table)
34 34
 {
35 35
     int n = vlc_table->n;
... ...
@@ -37,12 +37,14 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
37 37
     const uint32_t *table_codes  = vlc_table->huffcodes;
38 38
     const uint16_t *levels_table = vlc_table->levels;
39 39
     uint16_t *run_table, *level_table, *int_table;
40
+    float *flevel_table;
40 41
     int i, l, j, k, level;
41 42
 
42 43
     init_vlc(vlc, VLCBITS, n, table_bits, 1, 1, table_codes, 4, 4, 0);
43 44
 
44 45
     run_table   = av_malloc(n * sizeof(uint16_t));
45 46
     level_table = av_malloc(n * sizeof(uint16_t));
47
+    flevel_table= av_malloc(n * sizeof(*flevel_table));
46 48
     int_table   = av_malloc(n * sizeof(uint16_t));
47 49
     i = 2;
48 50
     level = 1;
... ...
@@ -53,13 +55,15 @@ static void init_coef_vlc(VLC *vlc, uint16_t **prun_table,
53 53
         for (j = 0; j < l; j++) {
54 54
             run_table[i]   = j;
55 55
             level_table[i] = level;
56
+            flevel_table[i]= level;
56 57
             i++;
57 58
         }
58 59
         level++;
59 60
     }
60 61
     *prun_table   = run_table;
61
-    *plevel_table = level_table;
62
+    *plevel_table = flevel_table;
62 63
     *pint_table   = int_table;
64
+    av_free(level_table);
63 65
 }
64 66
 
65 67
 /**
... ...
@@ -465,19 +469,22 @@ unsigned int ff_wma_get_large_val(GetBitContext* gb)
465 465
  */
466 466
 int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
467 467
                             VLC *vlc,
468
-                            const uint16_t *level_table, const uint16_t *run_table,
468
+                            const float *level_table, const uint16_t *run_table,
469 469
                             int version, WMACoef *ptr, int offset,
470 470
                             int num_coefs, int block_len, int frame_len_bits,
471 471
                             int coef_nb_bits)
472 472
 {
473 473
     int code, level, sign;
474
+    const uint32_t *ilvl = (const uint32_t*)level_table;
475
+    uint32_t *iptr = (uint32_t*)ptr;
474 476
     const unsigned int coef_mask = block_len - 1;
475 477
     for (; offset < num_coefs; offset++) {
476 478
         code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX);
477 479
         if (code > 1) {
478 480
             /** normal code */
479 481
             offset += run_table[code];
480
-            level = level_table[code];
482
+            sign = get_bits1(gb) - 1;
483
+            iptr[offset & coef_mask] = ilvl[code] ^ sign<<31;
481 484
         } else if (code == 1) {
482 485
             /** EOB */
483 486
             break;
... ...
@@ -503,9 +510,9 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
503 503
                         offset += get_bits(gb, 2) + 1;
504 504
                 }
505 505
             }
506
+            sign = get_bits1(gb) - 1;
507
+            ptr[offset & coef_mask] = (level^sign) - sign;
506 508
         }
507
-        sign = get_bits1(gb) - 1;
508
-        ptr[offset & coef_mask] = (level^sign) - sign;
509 509
     }
510 510
     /** NOTE: EOB can be omitted */
511 511
     if (offset > num_coefs) {
... ...
@@ -93,7 +93,7 @@ typedef struct WMACodecContext {
93 93
 //FIXME the following 3 tables should be shared between decoders
94 94
     VLC coef_vlc[2];
95 95
     uint16_t *run_table[2];
96
-    uint16_t *level_table[2];
96
+    float *level_table[2];
97 97
     uint16_t *int_table[2];
98 98
     const CoefVLCTable *coef_vlcs[2];
99 99
     /* frame info */
... ...
@@ -153,7 +153,7 @@ int ff_wma_end(AVCodecContext *avctx);
153 153
 unsigned int ff_wma_get_large_val(GetBitContext* gb);
154 154
 int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
155 155
                             VLC *vlc,
156
-                            const uint16_t *level_table, const uint16_t *run_table,
156
+                            const float *level_table, const uint16_t *run_table,
157 157
                             int version, WMACoef *ptr, int offset,
158 158
                             int num_coefs, int block_len, int frame_len_bits,
159 159
                             int coef_nb_bits);
... ...
@@ -352,7 +352,7 @@ static const uint16_t coef0_run[HUFF_COEF0_SIZE] = {
352 352
       1,   0,   1,   0,   1,   0,
353 353
 };
354 354
 
355
-static const uint16_t coef0_level[HUFF_COEF0_SIZE] = {
355
+static const float coef0_level[HUFF_COEF0_SIZE] = {
356 356
       0,   0,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
357 357
       1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
358 358
       1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
... ...
@@ -393,7 +393,7 @@ static const uint16_t coef1_run[HUFF_COEF1_SIZE] = {
393 393
      1,  0,  1,  0,  1,  0,  1,  0,  0,  0,
394 394
 };
395 395
 
396
-static const uint16_t coef1_level[HUFF_COEF1_SIZE] = {
396
+static const float coef1_level[HUFF_COEF1_SIZE] = {
397 397
      0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
398 398
      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
399 399
      1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
... ...
@@ -769,7 +769,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c)
769 769
     int cur_coeff = 0;
770 770
     int num_zeros = 0;
771 771
     const uint16_t* run;
772
-    const uint16_t* level;
772
+    const float* level;
773 773
 
774 774
     dprintf(s->avctx, "decode coefficients for channel %i\n", c);
775 775