[FFmpeg-soc] [soc]: r4840 - in als: als_data.h alsdec.c

thilo.borgmann subversion at mplayerhq.hu
Thu Jul 30 00:22:36 CEST 2009


Author: thilo.borgmann
Date: Thu Jul 30 00:22:36 2009
New Revision: 4840

Log:
Added functionality for short-term prediction.

Added:
   als/als_data.h
Modified:
   als/alsdec.c

Added: als/als_data.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ als/als_data.h	Thu Jul 30 00:22:36 2009	(r4840)
@@ -0,0 +1,147 @@
+/*
+ * ALS header file for common data
+ * Copyright (c) 2009 Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file libavcodec/als_data.h
+ * MPEG-4 ALS header file for common data
+ * @author Thilo Borgmann <thilo.borgmann _at_ googlemail.com>
+ */
+
+
+#ifndef AVCODEC_ALS_DATA_H
+#define AVCODEC_ALS_DATA_H
+
+
+#include <inttypes.h>
+
+/** Rice parameters and corresponding index offsets for decoding the
+ *  indices of scaled PARCOR values. The table choosen is set globally
+ *  by the encoder and.
+ */
+int8_t parcor_rice_table[3][20][2] = {
+                        {
+                        {-52, 4},
+                        {-29, 5},
+                        {-31, 4},
+                        { 19, 4},
+                        {-16, 4},
+                        { 12, 3},
+                        { -7, 3},
+                        {  9, 3},
+                        { -5, 3},
+                        {  6, 3},
+                        { -4, 3},
+                        {  3, 3},
+                        { -3, 2},
+                        {  3, 2},
+                        { -2, 2},
+                        {  3, 2},
+                        { -1, 2},
+                        {  2, 2},
+                        { -1, 2},
+                        {  2, 2}
+                        },
+                        {
+                        {-58, 3},
+                        {-42, 4},
+                        {-46, 4},
+                        { 37, 5},
+                        {-36, 4},
+                        { 29, 4},
+                        {-29, 4},
+                        { 25, 4},
+                        {-23, 4},
+                        { 20, 4},
+                        {-17, 4},
+                        { 16, 4},
+                        {-12, 4},
+                        { 12, 3},
+                        {-10, 4},
+                        {  7, 3},
+                        { -4, 4},
+                        {  3, 3},
+                        { -1, 3},
+                        {  1, 3}
+                        },
+                        {
+                        {-59, 3},
+                        {-45, 5},
+                        {-50, 4},
+                        { 38, 4},
+                        {-39, 4},
+                        { 32, 4},
+                        {-30, 4},
+                        { 25, 3},
+                        {-23, 3},
+                        { 20, 3},
+                        {-20, 3},
+                        { 16, 3},
+                        {-13, 3},
+                        { 10, 3},
+                        { -7, 3},
+                        {  3, 3},
+                        {  0, 3},
+                        { -1, 3},
+                        {  2, 3},
+                        { -1, 2}
+                        }
+                        };
+
+
+/** Scaled PARCOR values used for the first two PARCOR coefficients.
+ *  To be indexed by the Rice coded indices.
+ *  Generated by: parcor_scaled_values[i] = 32 + ((i * (i+1)) << 7) - (1 << 20)
+ */
+int32_t parcor_scaled_values[] = {-1048544, -1048288, -1047776, -1047008,
+                                  -1045984, -1044704, -1043168, -1041376,
+                                  -1039328, -1037024, -1034464, -1031648,
+                                  -1028576, -1025248, -1021664, -1017824,
+                                  -1013728, -1009376, -1004768,  -999904,
+                                   -994784,  -989408,  -983776,  -977888,
+                                   -971744,  -965344,  -958688,  -951776,
+                                   -944608,  -937184,  -929504,  -921568,
+                                   -913376,  -904928,  -896224,  -887264,
+                                   -878048,  -868576,  -858848,  -848864,
+                                   -838624,  -828128,  -817376,  -806368,
+                                   -795104,  -783584,  -771808,  -759776,
+                                   -747488,  -734944,  -722144,  -709088,
+                                   -695776,  -682208,  -668384,  -654304,
+                                   -639968,  -625376,  -610528,  -595424,
+                                   -580064,  -564448,  -548576,  -532448,
+                                   -516064,  -499424,  -482528,  -465376,
+                                   -447968,  -430304,  -412384,  -394208,
+                                   -375776,  -357088,  -338144,  -318944,
+                                   -299488,  -279776,  -259808,  -239584,
+                                   -219104,  -198368,  -177376,  -156128,
+                                   -134624,  -112864,   -90848,   -68576,
+                                    -46048,   -23264,     -224,    23072,
+                                     46624,    70432,    94496,   118816,
+                                    143392,   168224,   193312,   218656,
+                                    244256,   270112,   296224,   322592,
+                                    349216,   376096,   403232,   430624,
+                                    458272,   486176,   514336,   542752,
+                                    571424,   600352,   629536,   658976,
+                                    688672,   718624,   748832,   779296,
+                                    810016,   840992,   872224,   903712,
+                                    935456,   967456,   999712,  1032224};
+
+
+#endif

Modified: als/alsdec.c
==============================================================================
--- als/alsdec.c	Wed Jul 29 19:52:24 2009	(r4839)
+++ als/alsdec.c	Thu Jul 30 00:22:36 2009	(r4840)
@@ -33,6 +33,7 @@
 #include "get_bits.h"
 #include "unary.h"
 
+#include "als_data.h"
 
 typedef struct {
     uint32_t als_id;                 ///< ALS identifier
@@ -77,6 +78,7 @@ typedef struct {
     unsigned int      frame_id;          ///< The frame id / number of the current frame.
     unsigned int      js_switch;         ///< If true, joint-stereo decoding is enforced.
     unsigned int      num_blocks;        ///< Number of blocks used in the current frame.
+    int64_t           *residuals;        ///< Decoded residuals of the current block.
     int64_t           **raw_samples;     ///< Decoded raw samples for each channel.
 } ALSDecContext;
 
@@ -324,6 +326,36 @@ static int64_t decode_rice(GetBitContext
 }
 
 
+/** Converts PARCOR coefficient k to direct filter coefficient.
+ */
+static void parcor_to_lpc(unsigned int k, int64_t *par, int64_t *cof)
+{
+    int i;
+    int64_t tmp1, tmp2;
+
+    for (i = 0; i < ((k+1) >> 1); i++) {
+        tmp1 = cof[    i    ] + ((par[k] * cof[k - i - 1] + (1 << 19)) >> 20);
+        tmp2 = cof[k - i - 1] + ((par[k] * cof[    i    ] + (1 << 19)) >> 20);
+        cof[k - i - 1] = tmp2;
+        cof[    i    ] = tmp1;
+    }
+
+    cof[k] = par[k];
+}
+
+
+/** Converts all PARCOR coefficients to direct filter coefficients.
+ */
+static void all_parcor_to_lpc(unsigned int num, int64_t *par, int64_t *cof)
+{
+    int k;
+
+    for (k = 0; k < num; k++) {
+        parcor_to_lpc(k, par, cof);
+    }
+}
+
+
 /** Reads the block data.
  */
 static int read_block_data(ALSDecContext *ctx, unsigned int ra_block,
@@ -369,8 +401,10 @@ static int read_block_data(ALSDecContext
         unsigned int s[8];
         unsigned int sub_blocks, sb_length, shift_lsbs;
         unsigned int opt_order = 1;
+        int64_t      quant_cof[sconf->max_order];
+        int64_t      lpc_cof[sconf->max_order];
         unsigned int start = 0;
-        int64_t      res[block_length];
+        int64_t      *res = ctx->residuals;
         unsigned int sb, smp;
 
 
@@ -407,6 +441,8 @@ static int read_block_data(ALSDecContext
 
 
         if (!sconf->RLSLMS) {
+            int64_t quant_index;
+
             if (sconf->adapt_order) {
                 int opt_order_length =
                         FFMIN(
@@ -418,8 +454,62 @@ static int read_block_data(ALSDecContext
                 opt_order = sconf->max_order;
             }
 
-            for (k = 0; k < opt_order; k++) {
-                // TODO: prediction
+            if (opt_order) {
+                if (sconf->coef_table == 3) {
+                    // read coefficient 0
+                    quant_index = get_bits(gb, 7) - 64;
+                    quant_cof[0] = parcor_scaled_values[quant_index + 64];
+
+                    // read coefficient 1
+                    quant_index = get_bits(gb, 7) - 64;
+                    quant_cof[1] = -parcor_scaled_values[quant_index + 64];
+
+                    // read coefficients 2 - opt_order
+                    for (k = 2; k < opt_order; k++) {
+                        quant_index = get_bits(gb, 7) - 64;
+                        quant_cof[k] = (quant_index << 14) + (1 << 13);
+                    }
+                } else {
+                    int offset, rice_param, k_max;
+
+                    // read coefficient 0
+                    offset       = parcor_rice_table[sconf->coef_table][0][0];
+                    rice_param   = parcor_rice_table[sconf->coef_table][0][1];
+                    quant_index  = decode_rice(gb, rice_param) + offset;
+                    quant_cof[0] = parcor_scaled_values[quant_index + 64];
+
+                    // read coefficient 1
+                    offset       = parcor_rice_table[sconf->coef_table][1][0];
+                    rice_param   = parcor_rice_table[sconf->coef_table][1][1];
+                    quant_index  = decode_rice(gb, rice_param) + offset;
+                    quant_cof[1] = -parcor_scaled_values[quant_index + 64];
+
+                    // read coefficients 2 - 20
+                    k_max = FFMIN(20, opt_order);
+                    for (k = 2; k < k_max; k++) {
+                        offset       = parcor_rice_table[sconf->coef_table][k][0];
+                        rice_param   = parcor_rice_table[sconf->coef_table][k][1];
+                        quant_index  = decode_rice(gb, rice_param) + offset;
+                        quant_cof[k] = (quant_index << 14) + (1 << 13);
+                    }
+
+                    // read coefficients 20 - 128
+                    k_max = FFMIN(127, opt_order);
+                    for (k = 20; k < k_max; k++) {
+                        offset       = k & 1;
+                        rice_param   = 2;
+                        quant_index  = decode_rice(gb, rice_param) + offset;
+                        quant_cof[k] = (quant_index << 14) + (1 << 13);
+                    }
+
+                    // read coefficients 128 - opt_order
+                    for (k = 127; k < opt_order; k++) {
+                        offset       = 0;
+                        rice_param   = 1;
+                        quant_index  = decode_rice(gb, rice_param) + offset;
+                        quant_cof[k] = (quant_index << 14) + (1 << 13);
+                    }
+                }
             }
         }
 
@@ -442,10 +532,12 @@ static int read_block_data(ALSDecContext
 
             start = FFMIN(opt_order, 3);
         } else {
-            // TODO: Non random access blocks
+            // TODO: check if this has to be a function after features are implemented.
+            all_parcor_to_lpc(opt_order, quant_cof, lpc_cof);
         }
 
         // read all residuals
+        // TODO: decode directly into ctx->raw_samples[] instead of storing the residuals
         if (sconf->bgmc_mode) {
             // TODO: BGMC mode
         } else {
@@ -463,17 +555,27 @@ static int read_block_data(ALSDecContext
         // reconstruct all samples from residuals
         if (ra_block) {
             unsigned int progressive = FFMIN(block_length, opt_order);
+            int64_t y = 0;
 
             for (smp = 0; smp < progressive; smp++) {
-                // TODO: prediction
+                y = 1 << 19;
+
+                for (sb = 0; sb < smp; sb++) {
+                    y += lpc_cof[sb] * raw_samples[smp - (sb + 1)];
+                }
+
+                raw_samples[smp] = res[smp] - (y >> 20);
+                parcor_to_lpc(smp, quant_cof, lpc_cof);
             }
 
             for (; smp < block_length; smp++) {
+                y = 1 << 19;
+
                 for (sb = 0; sb < progressive; sb++) {
-                    // TODO: prediction
+                    y += lpc_cof[sb] * raw_samples[smp - (sb + 1)];
                 }
 
-                raw_samples[smp] = res[smp];
+                raw_samples[smp] = res[smp] - (y >> 20);
             }
         } else {
             // TODO: non random access blocks
@@ -651,6 +753,7 @@ static av_cold int decode_end(AVCodecCon
     unsigned int c;
 
     av_freep(&ctx->sconf.chan_pos);
+    av_freep(&ctx->residuals);
 
     if (ctx->raw_samples)
         for (c = 0; c < sconf->channels; c++)
@@ -696,12 +799,21 @@ static av_cold int decode_init(AVCodecCo
 
     avctx->frame_size = ctx->sconf.frame_length;
 
+    // allocate residual buffer
+    if (!(ctx->residuals = av_malloc(sizeof(int64_t) * ctx->sconf.frame_length))) {
+        av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n");
+        decode_end(avctx);
+        return AVERROR_NOMEM;
+    }
+
+    // allocate raw sample array buffer
     if (!(ctx->raw_samples = av_malloc(sizeof(int64_t*) * avctx->channels))) {
         av_log(avctx, AV_LOG_ERROR, "Allocating buffer array failed.\n");
         decode_end(avctx);
         return AVERROR_NOMEM;
     }
 
+    // allocate raw sample buffers
     for (c = 0; c < avctx->channels; c++) {
         if(!(ctx->raw_samples[c] = av_malloc(sizeof(int64_t)
                                              * ctx->sconf.frame_length))) {


More information about the FFmpeg-soc mailing list