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

ramiro subversion at mplayerhq.hu
Sat Aug 9 20:31:34 CEST 2008


Author: ramiro
Date: Sat Aug  9 20:31:34 2008
New Revision: 3095

Log:
Write filters to bitstream. To be replaced with a not-so-dumb filter.

Modified:
   mlp/mlpenc.c

Modified: mlp/mlpenc.c
==============================================================================
--- mlp/mlpenc.c	(original)
+++ mlp/mlpenc.c	Sat Aug  9 20:31:34 2008
@@ -33,6 +33,9 @@
 #define MAX_BLOCKSIZE       (40 * (MAX_SAMPLERATE / 48000))
 #define MAX_BLOCKSIZE_POW2  (64 * (MAX_SAMPLERATE / 48000))
 
+#define MAX_FILTER_ORDER    8
+#define NUM_FILTERS         2
+
 #define FIR 0
 #define IIR 1
 
@@ -80,6 +83,13 @@ typedef struct {
 } DecodingParams;
 
 typedef struct {
+    uint8_t         order;
+    uint8_t         shift;
+    int32_t         coeff[MAX_FILTER_ORDER];
+    int32_t         state[MAX_FILTER_ORDER];
+} FilterParams;
+
+typedef struct {
     AVCodecContext *avctx;
 
     int             num_substreams;
@@ -93,6 +103,8 @@ typedef struct {
 
     uint8_t         mlp_channels;
 
+    FilterParams    filter_params[MAX_CHANNELS][NUM_FILTERS];
+
     DecodingParams  decoding_params[MAX_SUBSTREAMS];
     RestartHeader   restart_header[MAX_SUBSTREAMS];
 } MLPEncodeContext;
@@ -342,8 +354,8 @@ static av_cold int mlp_encode_init(AVCod
 /*      param_presence_flags |= PARAM_MATRIX; */
 /*      param_presence_flags |= PARAM_OUTSHIFT; */
         param_presence_flags |= PARAM_QUANTSTEP;
-/*      param_presence_flags |= PARAM_FIR; */
-/*      param_presence_flags |= PARAM_IIR; */
+        param_presence_flags |= PARAM_FIR;
+        param_presence_flags |= PARAM_IIR;
         param_presence_flags |= PARAM_HUFFOFFSET;
 
         dp->param_presence_flags = param_presence_flags;
@@ -352,10 +364,73 @@ static av_cold int mlp_encode_init(AVCod
     return 0;
 }
 
+static int inline number_sbits(int number)
+{
+    int bits = 0;
+
+    if      (number > 0)
+        for (bits = 31; bits && !(number & (1<<(bits-1))); bits--);
+    else if (number < 0)
+        for (bits = 31; bits &&  (number & (1<<(bits-1))); bits--);
+
+    return bits + 1;
+}
+
+static void code_filter_coeffs(MLPEncodeContext *ctx,
+                               unsigned int channel, unsigned int filter,
+                               int *pcoeff_shift, int *pcoeff_bits)
+{
+    FilterParams *fp = &ctx->filter_params[channel][filter];
+    int min = INT_MAX, max = INT_MIN;
+    int bits, shift;
+    int or = 0;
+    int order;
+
+    for (order = 0; order < fp->order; order++) {
+        int coeff = fp->coeff[order];
+
+        if (coeff < min)
+            min = coeff;
+        if (fp->coeff[order] > max)
+            max = coeff;
+
+        or |= coeff;
+    }
+
+    bits = FFMAX(number_sbits(min), number_sbits(max));
+
+    for (shift = 0; shift < 7 && !(or & (1<<shift)); shift++);
+
+    *pcoeff_bits  = bits;
+    *pcoeff_shift = shift;
+}
+
 static void write_filter_params(MLPEncodeContext *ctx, PutBitContext *pb,
                                 unsigned int channel, unsigned int filter)
 {
-    return;
+    FilterParams *fp = &ctx->filter_params[channel][filter];
+
+    put_bits(pb, 4, fp->order);
+
+    if (fp->order > 0) {
+        int coeff_shift;
+        int coeff_bits;
+        int i;
+
+        code_filter_coeffs(ctx, channel, filter, &coeff_shift, &coeff_bits);
+
+        put_bits(pb, 4, fp->shift  );
+        put_bits(pb, 5, coeff_bits );
+        put_bits(pb, 3, coeff_shift);
+
+        for (i = 0; i < fp->order; i++) {
+            int coeff = fp->coeff[i] >> coeff_shift;
+
+            put_sbits(pb, coeff_bits, coeff);
+        }
+
+        put_bits(pb, 1, 0);
+    }
 }
 
 static void write_decoding_params(MLPEncodeContext *ctx, PutBitContext *pb,
@@ -480,6 +555,77 @@ static void input_data(MLPEncodeContext 
     }
 }
 
+static void set_filter_params(MLPEncodeContext *ctx,
+                              unsigned int channel, unsigned int filter)
+{
+    FilterParams *fp = &ctx->filter_params[channel][filter];
+
+    if (filter == FIR) {
+        fp->order    =  4;
+        fp->shift    =  0;
+        fp->coeff[0] =  1;
+        fp->coeff[1] =  0;
+        fp->coeff[2] =  0;
+        fp->coeff[3] =  0;
+    } else { /* IIR */
+        fp->order    =  4;
+        fp->shift    =  0;
+        fp->coeff[0] =  0;
+        fp->coeff[1] =  0;
+        fp->coeff[2] =  0;
+        fp->coeff[3] =  0;
+    }
+}
+
+#define MSB_MASK(bits)  (-1u << bits)
+
+static void apply_filter(MLPEncodeContext *ctx, unsigned int channel)
+{
+    int32_t filter_state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FILTER_ORDER];
+    FilterParams *fp[NUM_FILTERS] = { &ctx->filter_params[channel][FIR],
+                                      &ctx->filter_params[channel][IIR], };
+    int32_t mask = MSB_MASK(8); /* TODO quant_step_size */
+    unsigned int filter_shift = fp[FIR]->shift;
+    int index = MAX_BLOCKSIZE;
+    int filter;
+    int i;
+
+    for (filter = 0; filter < NUM_FILTERS; filter++) {
+        memcpy(&filter_state_buffer[filter][MAX_BLOCKSIZE],
+               &fp[filter]->state[0],
+               MAX_FILTER_ORDER * sizeof(int32_t));
+    }
+
+    for (i = 0; i < ctx->avctx->frame_size; i++) {
+        int32_t sample = (int32_t) ((int16_t)(ctx->sample_buffer[i][channel] >> 8)) << 8;
+        unsigned int order;
+        int64_t accum = 0;
+        int32_t residual;
+
+        for (filter = 0; filter < NUM_FILTERS; filter++)
+            for (order = 0; order < fp[filter]->order; order++)
+                accum += (int64_t)filter_state_buffer[filter][index + order] *
+                         fp[filter]->coeff[order];
+
+        accum  >>= filter_shift;
+        residual = sample - (accum & mask);
+
+        --index;
+
+        filter_state_buffer[FIR][index] = sample;
+        filter_state_buffer[IIR][index] = residual;
+
+        /* Store residual. */
+        ctx->sample_buffer[i][channel] = residual;
+    }
+
+    for (filter = 0; filter < NUM_FILTERS; filter++) {
+        memcpy(&fp[filter]->state[0],
+               &filter_state_buffer[filter][index],
+               MAX_FILTER_ORDER * sizeof(int32_t));
+    }
+}
+
 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},
@@ -782,6 +928,7 @@ static int mlp_encode_frame(AVCodecConte
     uint16_t parity_nibble = 0;
     int length, total_length;
     unsigned int substr;
+    int channel, filter;
     int write_headers;
     PutBitContext pb;
     int end = 0;
@@ -825,6 +972,12 @@ static int mlp_encode_frame(AVCodecConte
 
     input_data(ctx, data, lossless_check_data);
 
+    for (channel = 0; channel < avctx->channels; channel++) {
+        for (filter = 0; filter < NUM_FILTERS; filter++)
+            set_filter_params(ctx, channel, filter);
+        apply_filter(ctx, channel);
+    }
+
     determine_bits(ctx);
 
     for (substr = 0; substr < ctx->num_substreams; substr++) {



More information about the FFmpeg-soc mailing list