[FFmpeg-soc] [soc]: r3076 - mlp/mlpenc.c

ramiro subversion at mplayerhq.hu
Fri Aug 8 05:27:16 CEST 2008


Author: ramiro
Date: Fri Aug  8 05:27:16 2008
New Revision: 3076

Log:
Support codebooks 1 and 2. Brute-forces for best offset.
Ridiculously slow.

Modified:
   mlp/mlpenc.c

Modified: mlp/mlpenc.c
==============================================================================
--- mlp/mlpenc.c	(original)
+++ mlp/mlpenc.c	Fri Aug  8 05:27:16 2008
@@ -480,6 +480,30 @@ static void input_data(MLPEncodeContext 
     }
 }
 
+static const uint8_t huffman_tables[3][18][2] = {
+    {    /* huffman table 0, -7 - +10 */
+        {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3},
+        {0x04, 3}, {0x05, 3}, {0x06, 3}, {0x07, 3},
+        {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9},
+    }, { /* huffman table 1, -7 - +8 */
+        {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3},
+        {0x02, 2}, {0x03, 2},
+        {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9},
+    }, { /* huffman table 2, -7 - +7 */
+        {0x01, 9}, {0x01, 8}, {0x01, 7}, {0x01, 6}, {0x01, 5}, {0x01, 4}, {0x01, 3},
+        {0x01, 1},
+        {0x03, 3}, {0x05, 4}, {0x09, 5}, {0x11, 6}, {0x21, 7}, {0x41, 8}, {0x81, 9},
+    }
+};
+
+static int codebook_extremes[3][2] = {
+    {-9, 8}, {-8, 7}, {-7, 7},
+};
+
+static int codebook_offsets[3] = {
+    9, 8, 7,
+};
+
 static int no_codebook_bits(MLPEncodeContext *ctx, unsigned int substr,
                             unsigned int channel,
                             int16_t min, int16_t max,
@@ -525,6 +549,77 @@ static int no_codebook_bits(MLPEncodeCon
     return lsb_bits * dp->blocksize;
 }
 
+static void codebook_bits_offset(MLPEncodeContext *ctx, unsigned int substr,
+                                 unsigned int channel, int codebook,
+                                 int32_t min, int32_t max, int16_t offset,
+                                 int *plsb_bits, int *pcount)
+{
+    DecodingParams *dp = &ctx->decoding_params[substr];
+    int codebook_offset  = codebook_offsets[codebook];
+    int32_t codebook_min = codebook_extremes[codebook][0];
+    int32_t codebook_max = codebook_extremes[codebook][1];
+    int lsb_bits = 0, bitcount = 0;
+    int i;
+
+    min -= offset;
+    max -= offset;
+
+    while (min < codebook_min || max > codebook_max) {
+        lsb_bits++;
+        min >>= 1;
+        max >>= 1;
+    }
+
+    for (i = 0; i < dp->blocksize; i++) {
+        int32_t sample = (int16_t) (ctx->sample_buffer[i][channel] >> 8);
+
+        sample  -= offset;
+        sample >>= lsb_bits;
+
+        bitcount += huffman_tables[codebook][sample + codebook_offset][1];
+    }
+
+    if (codebook == 2)
+        lsb_bits++;
+
+    *plsb_bits = lsb_bits;
+    *pcount    = lsb_bits * dp->blocksize + bitcount;
+}
+
+static int codebook_bits(MLPEncodeContext *ctx, unsigned int substr,
+                         unsigned int channel, int codebook,
+                         int16_t min, int16_t max,
+                         int16_t *poffset, int *plsb_bits)
+{
+    int best_count = INT_MAX;
+    int16_t best_offset = 0;
+    int best_lsb_bits = 0;
+    int offset;
+    int offset_min, offset_max;
+
+    offset_min = FFMAX(min, HUFF_OFFSET_MIN);
+    offset_max = FFMIN(max, HUFF_OFFSET_MAX);
+
+    for (offset = offset_min; offset <= offset_max; offset++) {
+        int lsb_bits, count;
+
+        codebook_bits_offset(ctx, substr, channel, codebook,
+                             min, max, offset,
+                             &lsb_bits, &count);
+
+        if (count < best_count) {
+            best_lsb_bits = lsb_bits;
+            best_offset   = offset;
+            best_count    = count;
+         }
+    }
+
+    *plsb_bits = best_lsb_bits;
+    *poffset   = best_offset;
+
+    return best_count;
+}
+
 static void determine_bits(MLPEncodeContext *ctx)
 {
     unsigned int substr;
@@ -536,9 +631,11 @@ static void determine_bits(MLPEncodeCont
 
         for (channel = 0; channel <= rh->max_channel; channel++) {
             int16_t min = INT16_MAX, max = INT16_MIN;
-            int16_t offset;
-            int bitcount;
-            int lsb_bits, i;
+            int best_bitcount = INT_MAX;
+            int best_codebook = 0;
+            int16_t offset[3];
+            int bitcount[3];
+            int lsb_bits[3], i;
 
             /* Determine extremes. */
             for (i = 0; i < dp->blocksize; i++) {
@@ -549,12 +646,26 @@ static void determine_bits(MLPEncodeCont
                     max = sample;
             }
 
-            bitcount = no_codebook_bits(ctx, substr, channel,
-                                        min, max, &offset, &lsb_bits);
+            bitcount[0] = no_codebook_bits(ctx, substr, channel,
+                                           min, max, &offset[0], &lsb_bits[0]);
+
+            for (i = 1; i < 3; i++) {
+                bitcount[i] = codebook_bits(ctx, substr, channel, i - 1,
+                                            min, max, &offset[i], &lsb_bits[i]);
+            }
+
+            /* Choose best codebook. */
+            for (i = 0; i < 3; i++) {
+                if (bitcount[i] < best_bitcount) {
+                    best_bitcount = bitcount[i];
+                    best_codebook = i;
+                }
+            }
 
             /* Update context. */
-            dp->huff_offset[channel] = offset;
-            dp->huff_lsbs  [channel] = lsb_bits + 8;
+            dp->huff_offset[channel] = offset  [best_codebook];
+            dp->huff_lsbs  [channel] = lsb_bits[best_codebook] + 8;
+            dp->codebook   [channel] = best_codebook;
         }
     }
 }
@@ -564,6 +675,8 @@ static void write_block_data(MLPEncodeCo
 {
     DecodingParams *dp = &ctx->decoding_params[substr];
     RestartHeader  *rh = &ctx->restart_header [substr];
+    int codebook_offset[MAX_CHANNELS];
+    int codebook[MAX_CHANNELS];
     int16_t unsign[MAX_CHANNELS];
     int16_t offset[MAX_CHANNELS];
     int lsb_bits[MAX_CHANNELS];
@@ -571,8 +684,15 @@ static void write_block_data(MLPEncodeCo
 
     for (ch = rh->min_channel; ch <= rh->max_channel; ch++) {
         lsb_bits[ch] = dp->huff_lsbs[ch] - dp->quant_step_size[ch];
+        codebook       [ch] = dp->codebook   [ch] - 1;
         offset  [ch] = dp->huff_offset[ch];
+        codebook_offset[ch] = codebook_offsets[codebook[ch]];
+
+        /* Unsign if needed. */
+        if (codebook[ch] == -1 || codebook[ch] == 2)
         unsign  [ch] = 1 << (lsb_bits[ch] - 1);
+        else
+            unsign[ch] = 0;
     }
 
     for (i = 0; i < dp->blocksize; i++) {
@@ -582,6 +702,12 @@ static void write_block_data(MLPEncodeCo
             sample -= offset[ch];
             sample += unsign[ch];
 
+            if (codebook[ch] >= 0) {
+                int8_t vlc = (sample >> lsb_bits[ch]) + codebook_offset[ch];
+                put_bits(pb, huffman_tables[codebook[ch]][vlc][1],
+                             huffman_tables[codebook[ch]][vlc][0]);
+            }
+
             put_sbits(pb, lsb_bits[ch], sample);
         }
     }



More information about the FFmpeg-soc mailing list