[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