[FFmpeg-soc] [soc]: r339 - in eac3: ac3.c ac3.h ac3tab.c ac3tab.h eac3.h eac3_parser.c eac3dec.c ffmpeg.patch
bwolowiec
subversion at mplayerhq.hu
Sat Jul 7 16:04:27 CEST 2007
Author: bwolowiec
Date: Sat Jul 7 16:04:27 2007
New Revision: 339
Log:
This is main code of the E-AC3 decoder. It plays available from hd-dvd samples (http://www1.mplayerhq.hu/MPlayer/samples/evob/). Few extensions are lacking: AHT, Channel coupling, spectral extension and few smaller parts of code (because there are no samples).
Added:
eac3/ac3.c
eac3/ac3.h
eac3/ac3tab.c
eac3/ac3tab.h
eac3/eac3.h
eac3/eac3_parser.c
eac3/eac3dec.c
eac3/ffmpeg.patch
Added: eac3/ac3.c
==============================================================================
--- (empty file)
+++ eac3/ac3.c Sat Jul 7 16:04:27 2007
@@ -0,0 +1,556 @@
+/*
+ * Common code between AC3 encoder and decoder
+ * Copyright (c) 2000 Fabrice Bellard.
+ * Copyright (c) 2007 Bartlomiej Wolowiec
+ *
+ * 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 ac3.c
+ * Common code between AC3 encoder and decoder.
+ */
+#define DEBUG
+
+#include "avcodec.h"
+#include "ac3.h"
+#include "bitstream.h"
+#include "random.h"
+
+uint8_t bndtab[51];
+uint8_t masktab[253];
+
+/** tables for ungrouping mantissas */
+float ff_ac3_b1_mantissas[ 32][3];
+float ff_ac3_b2_mantissas[128][3];
+float ff_ac3_b3_mantissas[8];
+float ff_ac3_b4_mantissas[128][2];
+float ff_ac3_b5_mantissas[16];
+
+/** dynamic range table. converts codes to scale factors. */
+float ff_ac3_dynrng_tbl[256];
+
+/** dialogue normalization table */
+float ff_ac3_dialnorm_tbl[32];
+
+/** table for exponent to scale_factor mapping */
+float ff_ac3_scale_factors[25];
+
+/** table for grouping exponents */
+uint8_t ff_ac3_exp_ungroup_tbl[128][3];
+
+/**
+ * Table for number of exponent groups
+ * format: nexpgrp_tbl[cplinu][expstr-1][nmant]
+ */
+uint8_t ff_ac3_nexpgrp_tbl[2][3][256];
+
+static inline int calc_lowcomp1(int a, int b0, int b1, int c)
+{
+ if ((b0 + 256) == b1) {
+ a = c;
+ } else if (b0 > b1) {
+ a = FFMAX(a - 64, 0);
+ }
+ return a;
+}
+
+static inline int calc_lowcomp(int a, int b0, int b1, int bin)
+{
+ if (bin < 7) {
+ return calc_lowcomp1(a, b0, b1, 384);
+ } else if (bin < 20) {
+ return calc_lowcomp1(a, b0, b1, 320);
+ } else {
+ return FFMAX(a - 128, 0);
+ }
+}
+
+void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd,
+ int16_t *bndpsd)
+{
+ int bin, i, j, k, end1, v;
+
+ /* exponent mapping to PSD */
+ for(bin=start;bin<end;bin++) {
+ psd[bin]=(3072 - (exp[bin] << 7));
+ }
+
+ /* PSD integration */
+ j=start;
+ k=masktab[start];
+ do {
+ v=psd[j];
+ j++;
+ end1 = FFMIN(bndtab[k+1], end);
+ for(i=j;i<end1;i++) {
+ /* logadd */
+ int adr = FFMIN(FFABS(v - psd[j]) >> 1, 255);
+ v = FFMAX(v, psd[j]) + ff_ac3_latab[adr];
+ j++;
+ }
+ bndpsd[k]=v;
+ k++;
+ } while (end > bndtab[k]);
+}
+
+void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd,
+ int start, int end, int fgain, int is_lfe,
+ int deltbae, int deltnseg, uint8_t *deltoffst,
+ uint8_t *deltlen, uint8_t *deltba,
+ int16_t *mask)
+{
+ int16_t excite[50]; /* excitation */
+ int bin, k;
+ int bndstrt, bndend, begin, end1, tmp;
+ int lowcomp, fastleak, slowleak;
+
+ /* excitation function */
+ bndstrt = masktab[start];
+ bndend = masktab[end-1] + 1;
+
+ if (bndstrt == 0) {
+ lowcomp = 0;
+ lowcomp = calc_lowcomp1(lowcomp, bndpsd[0], bndpsd[1], 384);
+ excite[0] = bndpsd[0] - fgain - lowcomp;
+ lowcomp = calc_lowcomp1(lowcomp, bndpsd[1], bndpsd[2], 384);
+ excite[1] = bndpsd[1] - fgain - lowcomp;
+ begin = 7;
+ for (bin = 2; bin < 7; bin++) {
+ if (!(is_lfe && bin == 6))
+ lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1], 384);
+ fastleak = bndpsd[bin] - fgain;
+ slowleak = bndpsd[bin] - s->sgain;
+ excite[bin] = fastleak - lowcomp;
+ if (!(is_lfe && bin == 6)) {
+ if (bndpsd[bin] <= bndpsd[bin+1]) {
+ begin = bin + 1;
+ break;
+ }
+ }
+ }
+
+ end1=bndend;
+ if (end1 > 22) end1=22;
+
+ for (bin = begin; bin < end1; bin++) {
+ if (!(is_lfe && bin == 6))
+ lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin);
+
+ fastleak = FFMAX(fastleak - s->fdecay, bndpsd[bin] - fgain);
+ slowleak = FFMAX(slowleak - s->sdecay, bndpsd[bin] - s->sgain);
+ excite[bin] = FFMAX(fastleak - lowcomp, slowleak);
+ }
+ begin = 22;
+ } else {
+ /* coupling channel */
+ begin = bndstrt;
+
+ fastleak = (s->cplfleak << 8) + 768;
+ slowleak = (s->cplsleak << 8) + 768;
+ }
+
+ for (bin = begin; bin < bndend; bin++) {
+ fastleak = FFMAX(fastleak - s->fdecay, bndpsd[bin] - fgain);
+ slowleak = FFMAX(slowleak - s->sdecay, bndpsd[bin] - s->sgain);
+ excite[bin] = FFMAX(fastleak, slowleak);
+ }
+
+ /* compute masking curve */
+
+ for (bin = bndstrt; bin < bndend; bin++) {
+ tmp = s->dbknee - bndpsd[bin];
+ if (tmp > 0) {
+ excite[bin] += tmp >> 2;
+ }
+ mask[bin] = FFMAX(ff_ac3_hth[bin >> s->halfratecod][s->fscod], excite[bin]);
+ }
+
+ /* delta bit allocation */
+
+ if (deltbae == 0 || deltbae == 1) {
+ int band, seg, delta;
+ band = 0;
+ for (seg = 0; seg < deltnseg; seg++) {
+ band += deltoffst[seg];
+ if (deltba[seg] >= 4) {
+ delta = (deltba[seg] - 3) << 7;
+ } else {
+ delta = (deltba[seg] - 4) << 7;
+ }
+ for (k = 0; k < deltlen[seg]; k++) {
+ mask[band] += delta;
+ band++;
+ }
+ }
+ }
+}
+
+void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
+ int snroffset, int floor, uint8_t *bap)
+{
+ int i, j, k, end1, v, address;
+
+ /* special case, if snroffset is -960, set all bap's to zero */
+ if(snroffset == -960) {
+ memset(bap, 0, 256);
+ return;
+ }
+ memset(bap, 0, 256);
+
+ i = start;
+ j = masktab[start];
+ do {
+ v = (FFMAX(mask[j] - snroffset - floor, 0) & 0x1FE0) + floor;
+ end1 = FFMIN(bndtab[j] + ff_ac3_bndsz[j], end);
+ for (k = i; k < end1; k++) {
+ address = av_clip((psd[i] - v) >> 5, 0, 63);
+ bap[i] = ff_ac3_baptab[address];
+ assert(bap[i]<16);
+ i++;
+ }
+ } while (end > bndtab[j++]);
+}
+
+/* AC3 bit allocation. The algorithm is the one described in the AC3
+ spec. */
+void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
+ int8_t *exp, int start, int end,
+ int snroffset, int fgain, int is_lfe,
+ int deltbae,int deltnseg,
+ uint8_t *deltoffst, uint8_t *deltlen,
+ uint8_t *deltba)
+{
+ int16_t psd[256]; /* scaled exponents */
+ int16_t bndpsd[50]; /* interpolated exponents */
+ int16_t mask[50]; /* masking value */
+
+ ff_ac3_bit_alloc_calc_psd(exp, start, end, psd, bndpsd);
+
+ ff_ac3_bit_alloc_calc_mask(s, bndpsd, start, end, fgain, is_lfe,
+ deltbae, deltnseg, deltoffst, deltlen, deltba,
+ mask);
+
+ ff_ac3_bit_alloc_calc_bap(mask, psd, start, end, snroffset, s->floor, bap);
+}
+
+/**
+ * Initializes some tables.
+ * note: This function must remain thread safe because it is called by the
+ * AVParser init code.
+ */
+void ac3_common_init(void)
+{
+ int i, j, k, l, v;
+ /* compute bndtab and masktab from bandsz */
+ k = 0;
+ l = 0;
+ for(i=0;i<50;i++) {
+ bndtab[i] = l;
+ v = ff_ac3_bndsz[i];
+ for(j=0;j<v;j++) masktab[k++]=i;
+ l += v;
+ }
+ bndtab[50] = l;
+}
+
+/**
+ * Generates a Kaiser-Bessel Derived Window.
+ */
+void ff_ac3_window_init(float *window)
+{
+ int i, j;
+ double sum = 0.0, bessel, tmp;
+ double local_window[256];
+ double alpha2 = (5.0 * M_PI / 256.0) * (5.0 * M_PI / 256.0);
+
+ for(i=0; i<256; i++) {
+ tmp = i * (256 - i) * alpha2;
+ bessel = 1.0;
+ for(j=100; j>0; j--) /* default to 100 iterations */
+ bessel = bessel * tmp / (j * j) + 1;
+ sum += bessel;
+ local_window[i] = sum;
+ }
+
+ sum++;
+ for(i=0; i<256; i++)
+ window[i] = sqrt(local_window[i] / sum);
+}
+
+static inline float
+symmetric_dequant(int code, int levels)
+{
+ return (code - (levels >> 1)) * (2.0f / levels);
+}
+
+void ff_ac3_decoder_tables_init(void)
+{
+ int i, expstr, cplinu;
+
+ /* generate grouped mantissa tables
+ reference: Section 7.3.5 Ungrouping of Mantissas */
+ for(i=0; i<32; i++) {
+ /* bap=1 mantissas */
+ ff_ac3_b1_mantissas[i][0] = symmetric_dequant( i / 9 , 3);
+ ff_ac3_b1_mantissas[i][1] = symmetric_dequant((i % 9) / 3, 3);
+ ff_ac3_b1_mantissas[i][2] = symmetric_dequant((i % 9) % 3, 3);
+ }
+ for(i=0; i<128; i++) {
+ /* bap=2 mantissas */
+ ff_ac3_b2_mantissas[i][0] = symmetric_dequant( i / 25 , 5);
+ ff_ac3_b2_mantissas[i][1] = symmetric_dequant((i % 25) / 5, 5);
+ ff_ac3_b2_mantissas[i][2] = symmetric_dequant((i % 25) % 5, 5);
+
+ /* bap=4 mantissas */
+ ff_ac3_b4_mantissas[i][0] = symmetric_dequant(i / 11, 11);
+ ff_ac3_b4_mantissas[i][1] = symmetric_dequant(i % 11, 11);
+ }
+ /* generate ungrouped mantissa tables
+ reference: Tables 7.21 and 7.23 */
+ for(i=0; i<7; i++) {
+ /* bap=3 mantissas */
+ ff_ac3_b3_mantissas[i] = symmetric_dequant(i, 7);
+ }
+ for(i=0; i<15; i++) {
+ /* bap=5 mantissas */
+ ff_ac3_b5_mantissas[i] = symmetric_dequant(i, 15);
+ }
+
+ /* generate dynamic range table
+ reference: Section 7.7.1 Dynamic Range Control */
+ for(i=0; i<256; i++) {
+ int v = (i >> 5) - ((i >> 7) << 3) - 5;
+ ff_ac3_dynrng_tbl[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
+ }
+
+ /* generate dialogue normalization table
+ references: Section 5.4.2.8 dialnorm
+ Section 7.6 Dialogue Normalization */
+ for(i=1; i<32; i++) {
+ ff_ac3_dialnorm_tbl[i] = expf((i-31) * M_LN10 / 20.0f);
+ }
+ ff_ac3_dialnorm_tbl[0] = ff_ac3_dialnorm_tbl[31];
+
+ /* generate scale factors */
+ for(i=0; i<25; i++)
+ ff_ac3_scale_factors[i] = pow(2.0, -i);
+
+ /* generate exponent tables
+ reference: Section 7.1.3 Exponent Decoding */
+ for(i=0; i<128; i++) {
+ ff_ac3_exp_ungroup_tbl[i][0] = i / 25;
+ ff_ac3_exp_ungroup_tbl[i][1] = (i % 25) / 5;
+ ff_ac3_exp_ungroup_tbl[i][2] = (i % 25) % 5;
+ }
+
+ /** generate table for number of exponent groups
+ reference: Section 7.1.3 Exponent Decoding */
+ for(cplinu=0; cplinu<=1; cplinu++) {
+ for(expstr=EXP_D15; expstr<=EXP_D45; expstr++) {
+ for(i=0; i<256; i++) {
+ int grpsize = expstr + (expstr == EXP_D45);
+ int ngrps = 0;
+ if(cplinu) {
+ ngrps = i / (3 * grpsize);
+ } else {
+ if(i == 7)
+ ngrps = 2;
+ else
+ ngrps = (i + (grpsize * 3) - 4) / (3 * grpsize);
+ }
+ ff_ac3_nexpgrp_tbl[cplinu][expstr-1][i] = ngrps;
+ }
+ }
+ }
+}
+
+
+/** ungrouped mantissas */
+typedef struct {
+ float b1_mant[3];
+ float b2_mant[3];
+ float b4_mant[2];
+ int b1ptr;
+ int b2ptr;
+ int b4ptr;
+} mant_groups;
+
+/** Gets the transform coefficients for particular channel */
+//TODO add @param
+static void get_transform_coeffs_ch(
+ GetBitContext *gb, uint8_t *bap, uint8_t *dexps, mant_groups *m,
+ int dithflag, float *transform_coeffs, int strmant, int endmant
+ )
+{
+// GetBitContext *gb = &ctx->gb;
+ int i, gcode ;
+
+ for(i=strmant; i<endmant; i++) {
+ // int tbap = ctx->bap[ch][i];
+ int tbap = bap[i];
+ assert(tbap>=0 && tbap<=15);
+ switch(tbap) {
+ case 0:
+ if(!dithflag) {
+ transform_coeffs[i] = 0.0f;
+ } else {
+ transform_coeffs[i] = LEVEL_MINUS_3DB;
+ }
+ break;
+ case 1:
+ if(m->b1ptr > 2) {
+ gcode = get_bits(gb, 5);
+ m->b1_mant[0] = ff_ac3_b1_mantissas[gcode][0];
+ m->b1_mant[1] = ff_ac3_b1_mantissas[gcode][1];
+ m->b1_mant[2] = ff_ac3_b1_mantissas[gcode][2];
+ m->b1ptr = 0;
+ }
+ transform_coeffs[i] = m->b1_mant[m->b1ptr++];
+ break;
+ case 2:
+ if(m->b2ptr > 2) {
+ gcode = get_bits(gb, 7);
+ m->b2_mant[0] = ff_ac3_b2_mantissas[gcode][0];
+ m->b2_mant[1] = ff_ac3_b2_mantissas[gcode][1];
+ m->b2_mant[2] = ff_ac3_b2_mantissas[gcode][2];
+ m->b2ptr = 0;
+ }
+ transform_coeffs[i] = m->b2_mant[m->b2ptr++];
+ break;
+ case 3:
+ transform_coeffs[i] = ff_ac3_b3_mantissas[get_bits(gb, 3)];
+ break;
+ case 4:
+ if(m->b4ptr > 1) {
+ gcode = get_bits(gb, 7);
+ m->b4_mant[0] = ff_ac3_b4_mantissas[gcode][0];
+ m->b4_mant[1] = ff_ac3_b4_mantissas[gcode][1];
+ m->b4ptr = 0;
+ }
+ transform_coeffs[i] = m->b4_mant[m->b4ptr++];
+ break;
+ case 5:
+ transform_coeffs[i] = ff_ac3_b5_mantissas[get_bits(gb, 4)];
+ break;
+ default:
+ /* asymmetric dequantization */
+ transform_coeffs[i] = get_sbits(gb, ff_qntztab[tbap]) * ff_ac3_scale_factors[ff_qntztab[tbap]-1];
+ break;
+ }
+ transform_coeffs[i] *= ff_ac3_scale_factors[dexps[i]];
+ //av_log(NULL, AV_LOG_INFO, "dexps[%i] = %i transform_coeffs[%i] = %f\n", i, dexps[i], i, transform_coeffs[i]);
+ }
+}
+
+/**
+ * Applies random dithering to coefficients
+ * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0)
+ */
+static void apply_dithering(int nchans, int *endmant, int *dithflag, float (*transform_coeffs)[AC3_MAX_COEFS],int *chincpl, AVRandomState *dith_state, uint8_t (*bap)[AC3_MAX_COEFS]) {
+ int ch, i;
+ int end=0;
+ float *coeffs;
+
+ for(ch=1; ch<=nchans; ch++) {
+ coeffs = transform_coeffs[ch];
+ if(chincpl[ch])
+ end = endmant[CPL_CH];
+ else
+ end = endmant[ch];
+ if(dithflag[ch]) {
+ for(i=0; i<end; i++) {
+ if(bap[ch][i] == 0) {
+ coeffs[i] *= (av_random(dith_state) & 0xFFFF) / 32768.0f;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Gets the transform coefficients.
+ * This function extracts the tranform coefficients from the AC-3 bitstream
+ * using the previously decoded bit allocation pointers. If coupling is in
+ * use, coupled coefficients are also reconstructed here.
+ */
+
+void ff_ac3_get_transform_coeffs(GetBitContext *gb, uint8_t (*bap)[AC3_MAX_COEFS], uint8_t (*dexps)[AC3_MAX_COEFS], int nchans, int *chincpl, int *dithflag, float (*transform_coeffs)[AC3_MAX_COEFS], int *strtmant, int *endmant, AVRandomState *dith_state)
+{
+ int ch, end;
+ int got_cplch = 0;
+ mant_groups m;
+
+ m.b1ptr = m.b2ptr = m.b4ptr = 3;
+
+ for(ch=1; ch<=nchans; ch++) {
+ /* transform coefficients for individual channel */
+ get_transform_coeffs_ch(gb, bap[ch], dexps[ch], &m, dithflag[ch], transform_coeffs[ch], strtmant[ch],endmant[ch]);
+
+ /* tranform coefficients for coupling channel */
+ if(chincpl[ch]) {
+ if(!got_cplch) {
+ assert(0);
+ // TODO
+ // get_transform_coeffs_ch(ctx, CPL_CH, &m);
+ // uncouple_channels(ctx);
+ got_cplch = 1;
+ }
+ end = endmant[CPL_CH];
+ } else {
+ end = endmant[ch];
+ }
+ memset(&transform_coeffs[ch][end], 0, (256-end)*sizeof(float));
+ }
+ // TODO
+//static void apply_dithering(int nfchans, int *endmant, int *dithflag, float (*transform_coeffs)[AC3_MAX_COEFS],int *chincpl, AVRandomState *dith_state, uint8_t *bap) {
+ apply_dithering(nchans, endmant, dithflag, transform_coeffs,chincpl, dith_state, bap);
+}
+
+
+/**
+ * Decodes the grouped exponents.
+ * This function decodes the coded exponents according to exponent strategy
+ * and stores them in the decoded exponents buffer.
+ */
+void ff_ac3_decode_exponents(GetBitContext *gb, int expstr, int ngrps,
+ uint8_t absexp, uint8_t *dexps)
+{
+ int i, j, grp, grpsize;
+ int dexp[256];
+ int expacc, prevexp;
+
+ /* unpack groups */
+ grpsize = expstr + (expstr == EXP_D45);
+ for(grp=0,i=0; grp<ngrps; grp++) {
+ expacc = get_bits(gb, 7);
+ dexp[i++] = ff_ac3_exp_ungroup_tbl[expacc][0];
+ dexp[i++] = ff_ac3_exp_ungroup_tbl[expacc][1];
+ dexp[i++] = ff_ac3_exp_ungroup_tbl[expacc][2];
+ }
+
+ /* convert to absolute exps and expand groups */
+ prevexp = absexp;
+ for(i=0; i<ngrps*3; i++) {
+ prevexp = av_clip(prevexp + dexp[i]-2, 0, 24);
+ for(j=0; j<grpsize; j++) {
+ dexps[(i*grpsize)+j] = prevexp;
+ }
+ }
+}
+
+
Added: eac3/ac3.h
==============================================================================
--- (empty file)
+++ eac3/ac3.h Sat Jul 7 16:04:27 2007
@@ -0,0 +1,201 @@
+/*
+ * Common code between AC3 encoder and decoder
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
+ *
+ * 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 ac3.h
+ * Common code between AC3 encoder and decoder.
+ */
+
+#ifndef AC3_H
+#define AC3_H
+
+#include "ac3tab.h"
+#include "bitstream.h"
+#include "random.h"
+
+#define AC3_MAX_COEFS 256
+
+#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */
+// TODO
+#define AC3_MAX_CHANNELS 8 /* including LFE channel */
+
+#define NB_BLOCKS 6 /* number of PCM blocks inside an AC3 frame */
+#define AC3_FRAME_SIZE (NB_BLOCKS * 256)
+#define CPL_CH 0
+
+/* exponent encoding strategy */
+#define EXP_REUSE 0
+#define EXP_NEW 1
+
+#define EXP_D15 1
+#define EXP_D25 2
+#define EXP_D45 3
+
+typedef struct AC3BitAllocParameters {
+ int fscod; /* frequency */
+ int halfratecod;
+ int sgain, sdecay, fdecay, dbknee, floor;
+ int cplfleak, cplsleak;
+} AC3BitAllocParameters;
+
+/**
+ * @struct AC3HeaderInfo
+ * Coded AC-3 header values up to the lfeon element, plus derived values.
+ */
+typedef struct {
+ /** @defgroup coded Coded elements
+ * @{
+ */
+ uint16_t sync_word;
+ uint16_t crc1;
+ uint8_t fscod;
+ uint8_t frmsizecod;
+ uint8_t bsid;
+ uint8_t bsmod;
+ uint8_t acmod;
+ uint8_t cmixlev;
+ uint8_t surmixlev;
+ uint8_t dsurmod;
+ uint8_t lfeon;
+ /** @} */
+
+ /** @defgroup derived Derived values
+ * @{
+ */
+ uint8_t halfratecod;
+ uint16_t sample_rate;
+ uint32_t bit_rate;
+ uint8_t channels;
+ uint16_t frame_size;
+ /** @} */
+} AC3HeaderInfo;
+
+
+void ac3_common_init(void);
+
+/** dynamic range table. converts codes to scale factors. */
+extern float ff_ac3_dynrng_tbl[256];
+
+/** dialogue normalization table */
+extern float ff_ac3_dialnorm_tbl[32];
+
+/** table for exponent to scale_factor mapping */
+extern float ff_ac3_scale_factors[25];
+
+/** table for grouping exponents */
+extern uint8_t ff_ac3_exp_ungroup_tbl[128][3];
+
+/**
+ * Table for number of exponent groups
+ * format: nexpgrp_tbl[cplinu][expstr-1][nmant]
+ */
+extern uint8_t ff_ac3_nexpgrp_tbl[2][3][256];
+
+extern float ff_ac3_b1_mantissas[ 32][3];
+extern float ff_ac3_b2_mantissas[128][3];
+extern float ff_ac3_b3_mantissas[8];
+extern float ff_ac3_b4_mantissas[128][2];
+extern float ff_ac3_b5_mantissas[16];
+
+/**
+ * Calculates the log power-spectral density of the input signal.
+ * This gives a rough estimate of signal power in the frequency domain by using
+ * the spectral envelope (exponents). The psd is also separately grouped
+ * into critical bands for use in the calculating the masking curve.
+ * 128 units in psd = -6 dB. The dbknee parameter in AC3BitAllocParameters
+ * determines the reference level.
+ *
+ * @param[in] exp frequency coefficient exponents
+ * @param[in] start starting bin location
+ * @param[in] end ending bin location
+ * @param[out] psd signal power for each frequency bin
+ * @param[out] bndpsd signal power for each critical band
+ */
+void ff_ac3_bit_alloc_calc_psd(int8_t *exp, int start, int end, int16_t *psd,
+ int16_t *bndpsd);
+
+/**
+ * Calculates the masking curve.
+ * First, the excitation is calculated using parameters in \p s and the signal
+ * power in each critical band. The excitation is compared with a predefined
+ * hearing threshold table to produce the masking curve. If delta bit
+ * allocation information is provided, it is used for adjusting the masking
+ * curve, usually to give a closer match to a better psychoacoustic model.
+ *
+ * @param[in] s adjustable bit allocation parameters
+ * @param[in] bndpsd signal power for each critical band
+ * @param[in] start starting bin location
+ * @param[in] end ending bin location
+ * @param[in] fgain fast gain (estimated signal-to-mask ratio)
+ * @param[in] is_lfe whether or not the channel being processed is the LFE
+ * @param[in] deltbae delta bit allocation exists (none, reuse, or new)
+ * @param[in] deltnseg number of delta segments
+ * @param[in] deltoffst location offsets for each segment
+ * @param[in] deltlen length of each segment
+ * @param[in] deltba delta bit allocation for each segment
+ * @param[out] mask calculated masking curve
+ */
+void ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *bndpsd,
+ int start, int end, int fgain, int is_lfe,
+ int deltbae, int deltnseg, uint8_t *deltoffst,
+ uint8_t *deltlen, uint8_t *deltba,
+ int16_t *mask);
+
+/**
+ * Calculates bit allocation pointers.
+ * The SNR is the difference between the masking curve and the signal. AC-3
+ * uses this value for each frequency bin to allocate bits. The \p snroffset
+ * parameter is a global adjustment to the SNR for all bins.
+ *
+ * @param[in] mask masking curve
+ * @param[in] psd signal power for each frequency bin
+ * @param[in] start starting bin location
+ * @param[in] end ending bin location
+ * @param[in] snroffset SNR adjustment
+ * @param[in] floor noise floor
+ * @param[out] bap bit allocation pointers
+ */
+void ff_ac3_bit_alloc_calc_bap(int16_t *mask, int16_t *psd, int start, int end,
+ int snroffset, int floor, uint8_t *bap);
+
+void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, uint8_t *bap,
+ int8_t *exp, int start, int end,
+ int snroffset, int fgain, int is_lfe,
+ int deltbae,int deltnseg,
+ uint8_t *deltoffst, uint8_t *deltlen, uint8_t *deltba);
+
+void ff_ac3_window_init(float *window);
+void ff_ac3_decoder_tables_init(void);
+
+void ff_ac3_get_transform_coeffs(GetBitContext *gb, uint8_t (*bap)[AC3_MAX_COEFS], uint8_t (*dexps)[AC3_MAX_COEFS], int nchans, int *chincpl, int *dithflag, float (*transform_coeffs)[AC3_MAX_COEFS], int *strtmant, int *endmant, AVRandomState *dith_state);
+
+void ff_ac3_decode_exponents(GetBitContext *gb, int expstr, int ngrps,
+ uint8_t absexp, uint8_t *dexps);
+
+/** adjustments in dB gain */
+#define LEVEL_ZERO (0.0000000000000000f)
+#define LEVEL_ONE (1.0000000000000000f)
+#define LEVEL_MINUS_3DB (0.7071067811865476f) /* sqrt(2)/2 */
+#define LEVEL_MINUS_4POINT5DB (0.5946035575013605f) /* fourth-root(2)/2 */
+#define LEVEL_MINUS_6DB (0.5000000000000000f)
+#define LEVEL_MINUS_9DB (0.3535533905932738f) /* sqrt(2)/4 */
+
+#endif /* AC3_H */
Added: eac3/ac3tab.c
==============================================================================
--- (empty file)
+++ eac3/ac3tab.c Sat Jul 7 16:04:27 2007
@@ -0,0 +1,265 @@
+/*
+ * AC3 tables
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * 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 ac3tab.c
+ * tables taken directly from AC3 spec.
+ */
+
+#include "ac3tab.h"
+
+/**
+ * Possible frame sizes.
+ * from ATSC A/52 Table 5.18 Frame Size Code Table.
+ */
+const uint16_t ff_ac3_frame_sizes[38][3] = {
+ { 64, 69, 96 },
+ { 64, 70, 96 },
+ { 80, 87, 120 },
+ { 80, 88, 120 },
+ { 96, 104, 144 },
+ { 96, 105, 144 },
+ { 112, 121, 168 },
+ { 112, 122, 168 },
+ { 128, 139, 192 },
+ { 128, 140, 192 },
+ { 160, 174, 240 },
+ { 160, 175, 240 },
+ { 192, 208, 288 },
+ { 192, 209, 288 },
+ { 224, 243, 336 },
+ { 224, 244, 336 },
+ { 256, 278, 384 },
+ { 256, 279, 384 },
+ { 320, 348, 480 },
+ { 320, 349, 480 },
+ { 384, 417, 576 },
+ { 384, 418, 576 },
+ { 448, 487, 672 },
+ { 448, 488, 672 },
+ { 512, 557, 768 },
+ { 512, 558, 768 },
+ { 640, 696, 960 },
+ { 640, 697, 960 },
+ { 768, 835, 1152 },
+ { 768, 836, 1152 },
+ { 896, 975, 1344 },
+ { 896, 976, 1344 },
+ { 1024, 1114, 1536 },
+ { 1024, 1115, 1536 },
+ { 1152, 1253, 1728 },
+ { 1152, 1254, 1728 },
+ { 1280, 1393, 1920 },
+ { 1280, 1394, 1920 },
+};
+
+/**
+ * Maps audio coding mode (acmod) to number of full-bandwidth channels.
+ * from ATSC A/52 Table 5.8 Audio Coding Mode
+ */
+const uint8_t ff_ac3_channels[8] = {
+ 2, 1, 2, 3, 3, 4, 4, 5
+};
+
+/* possible frequencies */
+const uint16_t ff_ac3_freqs[3] = { 48000, 44100, 32000 };
+
+/* possible bitrates */
+const uint16_t ff_ac3_bitratetab[19] = {
+ 32, 40, 48, 56, 64, 80, 96, 112, 128,
+ 160, 192, 224, 256, 320, 384, 448, 512, 576, 640
+};
+
+/* AC3 MDCT window */
+
+/* MDCT window */
+const int16_t ff_ac3_window[256] = {
+ 4, 7, 12, 16, 21, 28, 34, 42,
+ 51, 61, 72, 84, 97, 111, 127, 145,
+ 164, 184, 207, 231, 257, 285, 315, 347,
+ 382, 419, 458, 500, 544, 591, 641, 694,
+ 750, 810, 872, 937, 1007, 1079, 1155, 1235,
+ 1318, 1406, 1497, 1593, 1692, 1796, 1903, 2016,
+ 2132, 2253, 2379, 2509, 2644, 2783, 2927, 3076,
+ 3230, 3389, 3552, 3721, 3894, 4072, 4255, 4444,
+ 4637, 4835, 5038, 5246, 5459, 5677, 5899, 6127,
+ 6359, 6596, 6837, 7083, 7334, 7589, 7848, 8112,
+ 8380, 8652, 8927, 9207, 9491, 9778,10069,10363,
+10660,10960,11264,11570,11879,12190,12504,12820,
+13138,13458,13780,14103,14427,14753,15079,15407,
+15735,16063,16392,16720,17049,17377,17705,18032,
+18358,18683,19007,19330,19651,19970,20287,20602,
+20914,21225,21532,21837,22139,22438,22733,23025,
+23314,23599,23880,24157,24430,24699,24964,25225,
+25481,25732,25979,26221,26459,26691,26919,27142,
+27359,27572,27780,27983,28180,28373,28560,28742,
+28919,29091,29258,29420,29577,29729,29876,30018,
+30155,30288,30415,30538,30657,30771,30880,30985,
+31086,31182,31274,31363,31447,31528,31605,31678,
+31747,31814,31877,31936,31993,32046,32097,32145,
+32190,32232,32272,32310,32345,32378,32409,32438,
+32465,32490,32513,32535,32556,32574,32592,32608,
+32623,32636,32649,32661,32671,32681,32690,32698,
+32705,32712,32718,32724,32729,32733,32737,32741,
+32744,32747,32750,32752,32754,32756,32757,32759,
+32760,32761,32762,32763,32764,32764,32765,32765,
+32766,32766,32766,32766,32767,32767,32767,32767,
+32767,32767,32767,32767,32767,32767,32767,32767,
+32767,32767,32767,32767,32767,32767,32767,32767,
+};
+
+const uint8_t ff_ac3_latab[260]= {
+0x0040,0x003f,0x003e,0x003d,0x003c,0x003b,0x003a,0x0039,0x0038,0x0037,
+0x0036,0x0035,0x0034,0x0034,0x0033,0x0032,0x0031,0x0030,0x002f,0x002f,
+0x002e,0x002d,0x002c,0x002c,0x002b,0x002a,0x0029,0x0029,0x0028,0x0027,
+0x0026,0x0026,0x0025,0x0024,0x0024,0x0023,0x0023,0x0022,0x0021,0x0021,
+0x0020,0x0020,0x001f,0x001e,0x001e,0x001d,0x001d,0x001c,0x001c,0x001b,
+0x001b,0x001a,0x001a,0x0019,0x0019,0x0018,0x0018,0x0017,0x0017,0x0016,
+0x0016,0x0015,0x0015,0x0015,0x0014,0x0014,0x0013,0x0013,0x0013,0x0012,
+0x0012,0x0012,0x0011,0x0011,0x0011,0x0010,0x0010,0x0010,0x000f,0x000f,
+0x000f,0x000e,0x000e,0x000e,0x000d,0x000d,0x000d,0x000d,0x000c,0x000c,
+0x000c,0x000c,0x000b,0x000b,0x000b,0x000b,0x000a,0x000a,0x000a,0x000a,
+0x000a,0x0009,0x0009,0x0009,0x0009,0x0009,0x0008,0x0008,0x0008,0x0008,
+0x0008,0x0008,0x0007,0x0007,0x0007,0x0007,0x0007,0x0007,0x0006,0x0006,
+0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0005,0x0005,0x0005,0x0005,
+0x0005,0x0005,0x0005,0x0005,0x0004,0x0004,0x0004,0x0004,0x0004,0x0004,
+0x0004,0x0004,0x0004,0x0004,0x0004,0x0003,0x0003,0x0003,0x0003,0x0003,
+0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0003,0x0002,
+0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,
+0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0002,0x0001,0x0001,
+0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
+0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
+0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,0x0001,
+0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+};
+
+const uint16_t ff_ac3_hth[50][3]= {
+{ 0x04d0,0x04f0,0x0580 },
+{ 0x04d0,0x04f0,0x0580 },
+{ 0x0440,0x0460,0x04b0 },
+{ 0x0400,0x0410,0x0450 },
+{ 0x03e0,0x03e0,0x0420 },
+{ 0x03c0,0x03d0,0x03f0 },
+{ 0x03b0,0x03c0,0x03e0 },
+{ 0x03b0,0x03b0,0x03d0 },
+{ 0x03a0,0x03b0,0x03c0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03b0 },
+{ 0x03a0,0x03a0,0x03a0 },
+{ 0x0390,0x03a0,0x03a0 },
+{ 0x0390,0x0390,0x03a0 },
+{ 0x0390,0x0390,0x03a0 },
+{ 0x0380,0x0390,0x03a0 },
+{ 0x0380,0x0380,0x03a0 },
+{ 0x0370,0x0380,0x03a0 },
+{ 0x0370,0x0380,0x03a0 },
+{ 0x0360,0x0370,0x0390 },
+{ 0x0360,0x0370,0x0390 },
+{ 0x0350,0x0360,0x0390 },
+{ 0x0350,0x0360,0x0390 },
+{ 0x0340,0x0350,0x0380 },
+{ 0x0340,0x0350,0x0380 },
+{ 0x0330,0x0340,0x0380 },
+{ 0x0320,0x0340,0x0370 },
+{ 0x0310,0x0320,0x0360 },
+{ 0x0300,0x0310,0x0350 },
+{ 0x02f0,0x0300,0x0340 },
+{ 0x02f0,0x02f0,0x0330 },
+{ 0x02f0,0x02f0,0x0320 },
+{ 0x02f0,0x02f0,0x0310 },
+{ 0x0300,0x02f0,0x0300 },
+{ 0x0310,0x0300,0x02f0 },
+{ 0x0340,0x0320,0x02f0 },
+{ 0x0390,0x0350,0x02f0 },
+{ 0x03e0,0x0390,0x0300 },
+{ 0x0420,0x03e0,0x0310 },
+{ 0x0460,0x0420,0x0330 },
+{ 0x0490,0x0450,0x0350 },
+{ 0x04a0,0x04a0,0x03c0 },
+{ 0x0460,0x0490,0x0410 },
+{ 0x0440,0x0460,0x0470 },
+{ 0x0440,0x0440,0x04a0 },
+{ 0x0520,0x0480,0x0460 },
+{ 0x0800,0x0630,0x0440 },
+{ 0x0840,0x0840,0x0450 },
+{ 0x0840,0x0840,0x04e0 },
+};
+
+const uint8_t ff_ac3_baptab[64]= {
+ 0, 1, 1, 1, 1, 1, 2, 2, 3, 3,
+ 3, 4, 4, 5, 5, 6, 6, 6, 6, 7,
+ 7, 7, 7, 8, 8, 8, 8, 9, 9, 9,
+ 9, 10, 10, 10, 10, 11, 11, 11, 11, 12,
+ 12, 12, 12, 13, 13, 13, 13, 14, 14, 14,
+ 14, 14, 14, 14, 14, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15,
+};
+
+const uint8_t ff_sdecaytab[4]={
+ 0x0f, 0x11, 0x13, 0x15,
+};
+
+const uint8_t ff_fdecaytab[4]={
+ 0x3f, 0x53, 0x67, 0x7b,
+};
+
+const uint16_t ff_sgaintab[4]= {
+ 0x540, 0x4d8, 0x478, 0x410,
+};
+
+const uint16_t ff_dbkneetab[4]= {
+ 0x000, 0x700, 0x900, 0xb00,
+};
+
+const int16_t ff_floortab[8]= {
+ 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800,
+};
+
+const uint16_t ff_fgaintab[8]= {
+ 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400,
+};
+
+const uint8_t ff_ac3_bndsz[50]={
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3,
+ 3, 6, 6, 6, 6, 6, 6, 12, 12, 12, 12, 24, 24, 24, 24, 24
+};
+
+/**
+ * Quantization table: levels for symmetric. bits for asymmetric.
+ * reference: Table 7.18 Mapping of bap to Quantizer
+ */
+const uint8_t ff_qntztab[16] = {
+ 0, 3, 5, 7, 11, 15,
+ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
+};
+
+const uint8_t ff_eac3_blocks[4] = {
+ 1, 2, 3, 6
+};
+
+const uint8_t ff_nfchans_tbl[8] = { 2, 1, 2, 3, 3, 4, 4, 5 };
+
Added: eac3/ac3tab.h
==============================================================================
--- (empty file)
+++ eac3/ac3tab.h Sat Jul 7 16:04:27 2007
@@ -0,0 +1,46 @@
+/*
+ * AC3 tables
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard.
+ *
+ * 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
+ */
+
+#ifndef AC3TAB_H
+#define AC3TAB_H
+
+#include "common.h"
+
+extern const uint16_t ff_ac3_frame_sizes[38][3];
+extern const uint8_t ff_ac3_channels[8];
+extern const uint16_t ff_ac3_freqs[3];
+extern const uint16_t ff_ac3_bitratetab[19];
+extern const int16_t ff_ac3_window[256];
+extern const uint8_t ff_ac3_latab[260];
+extern const uint16_t ff_ac3_hth[50][3];
+extern const uint8_t ff_ac3_baptab[64];
+extern const uint8_t ff_sdecaytab[4];
+extern const uint8_t ff_fdecaytab[4];
+extern const uint16_t ff_sgaintab[4];
+extern const uint16_t ff_dbkneetab[4];
+extern const int16_t ff_floortab[8];
+extern const uint16_t ff_fgaintab[8];
+extern const uint8_t ff_ac3_bndsz[50];
+extern const uint8_t ff_qntztab[16];
+extern const uint8_t ff_nfchans_tbl[8];
+extern const uint8_t ff_eac3_blocks[4];
+
+#endif /* AC3TAB_H */
Added: eac3/eac3.h
==============================================================================
--- (empty file)
+++ eac3/eac3.h Sat Jul 7 16:04:27 2007
@@ -0,0 +1,368 @@
+/*
+ * E-AC3 parser
+ * Copyright (c) 2007 Bartlomiej Wolowiec
+ *
+ * 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
+ */
+#ifndef EAC3_H
+#define EAC3_H
+
+// TODO clean...
+
+#include "dsputil.h"
+#include "avcodec.h"
+#include "ac3.h"
+#include "random.h"
+
+#define DBA_NEW 0x01
+#define DBA_NONE 0x02
+#define DBA_RESERVED 0x03
+#define DBA_REUSE 0x00
+
+// TODO
+#define MAX_CHANNELS AC3_MAX_CHANNELS
+
+/** adjustments in dB gain */
+#define LEVEL_MINUS_3DB (0.7071067811865476f) /* sqrt(2)/2 */
+#define LEVEL_MINUS_4POINT5DB (0.5946035575013605f)
+#define LEVEL_MINUS_6DB (0.5000000000000000f)
+#define LEVEL_PLUS_3DB (1.4142135623730951f) /* sqrt(2) */
+#define LEVEL_PLUS_6DB (2.0000000000000000f)
+#define LEVEL_ZERO (0.0000000000000000f)
+
+#define AC3_BLOCK_SIZE 256
+#define MAX_BLOCKS 6
+#define MAX_SPX_CODES 18
+#define TODO_SIZE 1024
+
+
+/** output configurations. */
+#define AC3_OUTPUT_UNMODIFIED 0x01
+#define AC3_OUTPUT_MONO 0x02
+#define AC3_OUTPUT_STEREO 0x04
+#define AC3_OUTPUT_DOLBY 0x08
+#define AC3_OUTPUT_LFEON 0x10
+/** AC-3 channel mode (audio coding mode) */
+
+typedef enum {
+ AC3_CHANNEL_MODE_DUALMONO = 0,
+ AC3_CHANNEL_MODE_MONO,
+ AC3_CHANNEL_MODE_STEREO,
+ AC3_CHANNEL_MODE_3F,
+ AC3_CHANNEL_MODE_2F_1R,
+ AC3_CHANNEL_MODE_3F_1R,
+ AC3_CHANNEL_MODE_2F_2R,
+ AC3_CHANNEL_MODE_3F_2R
+} AC3ChannelMode;
+
+typedef struct EAC3Context{
+ // TODO erase unused variables
+ // TODO add documentation
+//Syncinfo
+ int syncword;
+
+//BSI
+ int strmtyp; // 2); ///< Stream type
+ int substreamid; // 3); ///< Substream identification
+ int frmsiz; // 11); ///< Frame size
+ int fscod; // 2); ///< Sample rate code
+ int fscod2; // 2); ///< Sample rate code 2
+ int numblkscod; // 2); ///< Number of audio blocks
+ int acmod; // 3); ///< Audio coding mode
+ int lfeon; // 1); ///< Low frequency effect channel on
+ int bsid; // 5); ///< Bit stream identification
+ int dialnorm; // 5); ///<Dialogue normalization
+ int compre; // 1); ///< Compression gain word exists
+ int compr; // 8); ///< Compression gain word
+ int dialnorm2; // 5); ///< Dialog normalization ch2
+ int compr2e; // 1); ///< Compression gain word ch2 exists
+ int compr2; // 8); ///< Compression gain word ch2
+ int chanmape; // 1); ///< Custom channel map exists
+ int chanmap; // 16); ///< Custom channel map
+ int mixmdate; // 1); ///< Mixing meta-data exists
+ int dmixmod; // 2); ///<
+ int ltrtcmixlev; // 3);
+ int lorocmixlev; // 3);
+ int ltrtsurmixlev; // 3);
+ int lorosurmixlev; // 3);
+ int lfemixlevcode; // 1); ///< lfe mix level code exists
+ int lfemixlevcod; // 5); ///< lfe mix level code
+ int pgmscle; // 1); ///< Program scale factor exists
+ int pgmscl; // 6); ///< Program scale factor
+ int pgmscl2e; // 1); ///< Program scale factor #2 exists
+ int pgmscl2; // 6); ///< Program scale factor #2
+ int extpgmscle; // 1); ///< External program scale factor exists
+ int extpgmscl; // 6); ///< External program scale factor
+ int mixdef; // 2); ///< Mix control type
+ int mixdata; // 12); ///< Mixing parameter data
+ int mixdeflen; // 5); ///< Length of mixing parameter data field
+// int *mixdata; // 8*(mixdeflen+2));
+ int paninfoe; // 1); ///< Pan information exists
+ int paninfo; // 14); ///< Pan information
+ int paninfo2e; // 1); ///< Pan information 2 exists
+ int paninfo2; // 14); ///< Pan information 2
+ int frmmixcfginfoe; // 1); ///< Frame mixing configuration information exists
+ int blkmixcfginfo0; // 5);
+ int blkmixcfginfoe; // 1); ///< Block mixing configuration information exists
+ int blkmixcfginfoblk; // 5); ///< Block mixing configuration information
+ int infomdate; // 1); ///< Informational meta-data exists
+ int bsmod; // 3); ///< Bit stream mode
+ int copyrightb; // 1); ///< Copyright bit
+ int origbs; // 1); ///< Original bit stream
+ int dsurmod; // 2);
+ int dheadphonmod; // 2);
+ int dsurexmod; // 2);
+ int audprodie; // 1);
+ int mixlevel; // 5); ///< Mix level
+ int roomtyp; // 2); ///< Room type
+ int adconvtyp; // 1); ///< A/D converter type
+ int audprodi2e; // 1); ///< Audio production information exists ch2
+ int mixlevel2; // 5); ///< Mixing level ch2
+ int roomtyp2; // 2); ///< room type ch2
+ int adconvtyp2; // 1); ///< A/D converter type
+ int sourcefscod; // 1); ///< Source sample rate code
+ int convsync; // 1); ///< Converter synchronization flag
+ int blkid; // 1); ///< Block identification
+ int frmsizecod; // 6); ///< Frame size code
+ int addbsie; // 1); ///< Additional bit stream information exists
+ int addbsil; // 6); ///< Additional bit stream information length
+ int addbsi[64]; // (addbsil+1)*8); ///< Additional bit stream information
+
+//Audfrm
+ int expstre; // 1); ///< Exponent strategy syntax enabled
+ int ahte; // 1); ///< Adaptive hybrid transform enabled
+ int snroffststr; // 2); ///< SNR offset strategy
+ int transproce; // 1); ///< Transient pre-noise processing enabled
+ int blkswe; // 1); ///< Block switch syntax enabled
+ int dithflage; // 1); ///< Dither flag syntax enabled
+ int bamode; // 1); ///< Bit allocation model syntax enabled
+ int frmfgaincode; // 1); ///< Fast gain codes enabled
+ int dbaflde; // 1); ///< Delta bit allocation syntax enabled
+ int skipflde; // 1); ///< Skip Filed syntax enabled
+ int spxattene; // 1); ///< Spectral extension attenuation enabled
+ int cplinu[MAX_BLOCKS]; // 1); ///< Coupling in use
+ int cplstre[MAX_BLOCKS]; // 1); ///< Coupling strategy exists
+ int cplexpstr[MAX_BLOCKS]; // 2); ///< Coupling exponents strategy
+ int chexpstr[MAX_BLOCKS][MAX_CHANNELS]; // 2); ///< Channel exponent strategy
+ int frmcplexpstr; // 5); ///< Frame based coupling exponent strategy
+ int frmchexpstr[MAX_CHANNELS]; // 5); ///< frame based channel exponent strategy
+ int lfeexpstr[MAX_BLOCKS]; // 1); ///< Lfe exponent strategy
+ int convexpstre; // 1); ///< Converter exponent strategy exists
+ int convexpstr[MAX_CHANNELS]; // 5); ///< Converter channel exponent strategy
+ int cplahtinu; // 1); ///< Coupling channel AHT in use
+ int chahtinu[MAX_CHANNELS]; // 1); ///< Channel AHT in use
+ int lfeahtinu; // 1); ///< Lfe channel AHT in use
+ int frmcsnroffst; // 6); ///< Frame coarse SNR offset
+ int frmfsnroffst; // 4); ///< Frame fine SNR offset
+ int chintransproc[MAX_CHANNELS]; // 1); ///< Channel in transient pre-noise processing
+ int transprocloc[MAX_CHANNELS]; // 10); ///< Transient location relative to start of frame
+ int transproclen[MAX_CHANNELS]; // 8); ///< Transient processing length
+ int chinspxatten[MAX_CHANNELS]; // 1); ///< Channel in spectral extension attenuation process
+ int spxattencod[MAX_CHANNELS]; // 5); ///< spectral extension attenuation code
+ int blkstrtinfoe; // 1); ///< Block start information exists
+ uint32_t blkstrtinfo; // nblkstrtbits); TODO ///< Block start information
+ int ncplblks;
+
+// EAC3Audblk
+ int blksw[MAX_CHANNELS]; // 1); ///< Block switch flag
+ int dithflag[MAX_CHANNELS]; // 1); ///< Dither flag
+ int dynrnge; // 1); ///< Dynamic range gain word exists
+ int dynrng; // 8); ///< Dynamic range gain word
+ int dynrng2e; // 1); ///< Dynamic range gain word exists, ch2
+ int dynrng2; // 8); ///< Dynamic range gain word
+ int spxstre; // 1); ///< Spectral extension strategy exists
+ int spxinu; // 1); ///< spectral extension in use
+ int chinspx[MAX_CHANNELS]; // 1); ///< Channel in spectral extension
+ int spxstrtf; // 2); ///< Spectral extension start copy frequency code
+ int spxbegf; // 3); ///< Spectral extension begin frequency code
+ int spxendf; // 3); ///< Spectral extension end frequency code
+ int spxbndstrce; // 1); ///< Spectral extension band structure exists
+ int spxbndstrc[MAX_SPX_CODES]; // 1); // [spxbegf...spxendf] ///< Spectral extension band structure
+ int spxcoe[MAX_CHANNELS]; // 1); ///< Spectral extension coordinates exists
+ int spxblnd[MAX_CHANNELS]; // 5); ///< Spectral extension blend
+ int mstrspxco[MAX_CHANNELS]; // 2); ///< Master spectral extension coordinates
+ int spxcoexp[MAX_CHANNELS][MAX_SPX_CODES]; // 4); ///< Spectral extension coordinate exponent
+ int spxcomant[MAX_CHANNELS][MAX_SPX_CODES]; // 2); ///< Spectral extension coordinate mantissa
+ int ecplinu; // 1); ///< Enhanced coupling in use
+ int chincpl[MAX_CHANNELS]; // 1); ///< Channel in coupling
+ int phsflginu; // 1); ///< Phase flag in use
+ int cplbegf; // 4); ///< Coupling begin frequency code
+ int cplendf; // 4); ///< Coupling end frequency code
+ int cplbndstrce; // 1); ///< Coupling band structure exists
+ int cplbndstrc[19]; // 1); ///< Coupling band structure
+ int ecplbegf; // 4); ///< Enhanced coupling begin frequency code
+ int ecplendf; // 4); ///< Enhanced coupling end frequency code
+ int ecplbndstrce; // 1); ///< Enhanced coupling band structure exists
+ int ecplbndstrc[TODO_SIZE]; // 1); ///< Enhanced coupling band structure
+ int cplcoe[MAX_CHANNELS]; // 1); ///< Coupling coordinates exists
+ int mstrcplco[MAX_CHANNELS]; // 2); ///< Master coupling coordinates
+ int cplcoexp[MAX_CHANNELS][TODO_SIZE]; // 4); ///< Coupling coordinate exponent
+ int cplcomant[MAX_CHANNELS][TODO_SIZE]; // 4); ///< Coupling coordinate mantissa
+ int phsflg[TODO_SIZE]; // 1); ///< Phase flag
+ int ecplangleintrp; // 1); ///< Enhanced coupling angle interpolation flag
+ int ecplparam1e[MAX_CHANNELS]; // 1); ///< Enhanced coupling parameters 1 exists
+ int ecplparam2e[MAX_CHANNELS]; // 1); ///< Enhanced coupling parameters 2 exists
+ int ecplamp[MAX_CHANNELS][TODO_SIZE]; // 5); ///< Enhanced coupling amplitude scaling
+ int ecplangle[MAX_CHANNELS][TODO_SIZE]; // 6); ///< Enhanced coupling angle
+ int ecplchaos[MAX_CHANNELS][TODO_SIZE]; // 3); ///< Enhanced coupling chaos
+ int ecpltrans[MAX_CHANNELS]; // 1); ///< Enhanced coupling transient present
+ int rematstr; // 1); ///< Rematrixing strategy
+ int rematflg[TODO_SIZE]; // 1); ///< Rematrixing flag
+ int chbwcod[MAX_CHANNELS]; // 6); ///< Rematrixing strategy
+ int cplabsexp; // 4); ///< Coupling absolute exponent
+ int cplexps[TODO_SIZE]; // 7); ///< Coupling exponent
+
+ int gainrng[MAX_CHANNELS]; // 2); ///< Channel Gain range code
+// int lfeexps[3]; // 7); // 0...nlfegrps = const 0...2
+ int baie; // 1); ///< Bit allocation information exists
+ int sdcycod; // 2); ///< Slow decay code
+ int fdcycod; // 2); ///< Fast decay code
+ int sgaincod; // 2); ///< Slow gain code
+ int dbpbcod; // 2); ///< dB per bit code
+ int floorcod; // 3); ///< Masking floor code
+ int snroffste; // 1); ///< SNR offset exists
+ int csnroffst; // 6); ///< Coarse SNR offset
+ int blkfsnroffst; // 4); ///< Block fine SNR offset
+ int cplfsnroffst; // 4); ///< Coupling fine SNR offset
+ int fsnroffst[MAX_CHANNELS]; // 4); ///< Channel fine SNR offset
+ int lfefsnroffst; // 4); ///< Lfe fine SNR offset
+ int fgaincode; // 1); ///< Channel fast gain code enabled
+ int cplfgaincod; // 3); ///< Coupling fast gain code code
+ int fgaincod[MAX_CHANNELS]; // 3); ///< Channel fast gain code
+ int lfefgaincod; // 3); ///< Lfe fast gain code
+ int convsnroffste; // 1); ///< Converter SNR offset exists
+ int convsnroffst; // 10); ///< Converter SNR offset
+ int cplleake; // 1); ///< Coupling leak initialization exists
+ int cplfleak; // 3); ///< Coupling fast leak initialization
+ int cplsleak; // 3); ///< Coupling slow leak initialization
+ int deltbaie; // 1); ///< Delta bit allocation information exists
+ int cpldeltbae; // 2); ///< Coupling delta bit allocation exists
+ uint8_t deltbae[MAX_CHANNELS]; // 2); ///< Delta bit allocation exists
+ int cpldeltnseg; // 3); ///< Coupling delta bit allocation number of segments
+ int cpldeltoffst[9]; // 5); 0..cpldeltnseg ///< Coupling bit allocation offset
+ int cpldeltlen[9]; // 4); 0..cpldeltnseg ///< Coupling delta bit allocation length
+ int cpldeltba[9]; // 3); 0..cpldeltnseg ///< Coupling delta bit allocation
+ uint8_t deltnseg[MAX_CHANNELS]; // 3); ///< Channel delta bit allocation number of segments
+ uint8_t deltoffst[MAX_CHANNELS][9]; // 5); 0..deltnseg[ch] ///< Channel delta bit allocation offset
+ uint8_t deltlen[MAX_CHANNELS][9]; // 4); 0..deltnseg[ch] ///< Channel delta bit allocation length
+ uint8_t deltba[MAX_CHANNELS][9]; // 3); 0..deltnseg[ch] ///< Channel delta bit allocation
+ int skiple; // 1); ///< Skip length exists
+ int skipl; // 9); ///< Skip length
+ int skipfld; // TODO skipl * 8); ///< Skip field
+
+ int got_cplchan;
+// int chmant[MAX_CHANNELS][TODO_SIZE];
+ int chgaqmod[MAX_CHANNELS]; ///< Channel gain adaptive quantization mode
+ int chgaqgain[MAX_CHANNELS][TODO_SIZE]; // [ch][0..chgaqsections[ch]] ///< Channel gain adaptive quantization gain
+ int pre_chmant[6][MAX_CHANNELS][TODO_SIZE]; // [][][nchmant[ch]] ///< Pre channel mantissas
+ int cplmant[TODO_SIZE]; // cplmant ///< Coupling mantisass
+ int cplgaqmod; ///< Coupling channel gain adaptive quantization mode
+ int cplgaqgain[TODO_SIZE]; // [cplgaqsections] ///< Coupling gain adaptive quantization gain
+ int pre_cplmant[6][TODO_SIZE]; // [][ncplmant] ///< Pre coupling channel_mantissas
+ int lfegaqmod; ///< Lfe channel gain adaptive quantization mode
+ int lfegaqgain[TODO_SIZE]; ///< LFE channel gain adaptive quantization mode
+ int pre_lfemant[6][TODO_SIZE]; ///< Pre lfe channel mantissas
+
+
+
+
+ int firstspxcos[MAX_CHANNELS]; // TODO type ? ///< First spectral extension coordinates states
+ int firstcplcos[MAX_CHANNELS]; // TODO type ? ///< First coupling coordinates states
+ int firstcplleak; // TODO type ? ///< First coupling leak state
+
+
+
+ // TODO
+ int lfegaqbin[TODO_SIZE];
+ int lfegaqsections;
+ int cplgaqbin[TODO_SIZE];
+ int cplgaqsections;
+ int chgaqbin[MAX_CHANNELS][TODO_SIZE]; // [][nchmant]
+ int chgaqsections[MAX_CHANNELS];
+ int nchmant[MAX_CHANNELS]; ///< Number of fbw channel mantissas
+ int ncplsubnd; ///< Number of coupling sub-bands
+ int ncplbnd; ///< Number of structured coupled bands
+ int nrematbnds;
+ int ncplgrps; ///< Number of coupled exponent groups
+ int ncplmant; ///< Number of coupled mantissas
+
+ int nlfemant; ///< Number of lfe mantissas
+ int nchgrps[MAX_CHANNELS]; ///< Number of fbw channel exponent groups
+ uint8_t dexps[MAX_CHANNELS][AC3_MAX_COEFS]; ///< Differential exponents
+
+ int cplstrtmant;
+ int cplendmant;
+ int endmant[MAX_CHANNELS];
+ int strtmant[MAX_CHANNELS];
+ int firstchincpl;
+ int ecpl_start_subbnd, ecpl_end_subbnd;
+ int nlfegrps; ///< Number of lfe channel exponent groups
+
+ int necplbnd;
+ int nspxbnds;
+ int spxbndsztab[MAX_SPX_CODES]; // max_spxendf + 1 = 18 ?
+ int nfchans; ///< Number of fbw channels
+
+ uint8_t bap[MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers
+ int16_t psd[MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents
+ int16_t bndpsd[MAX_CHANNELS][350]; ///< interpolated exponents FIXME in ac3dec [50] !?
+ int16_t mask[MAX_CHANNELS][350]; ///< masking values
+
+
+ DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][AC3_MAX_COEFS]);
+
+ /// TODO move to AC3BitAllocParameters
+ int sdecay;
+ int fdecay;
+ int sgain;
+ int dbknee;
+ int floor;
+
+ AC3BitAllocParameters bit_alloc_params;
+
+ AVRandomState dith_state; ///< for dither generation
+
+
+ int ntchans; ///< Total of all channels
+ int lfe_channel;
+
+ GetBitContext *gbc;
+
+ MDCTContext imdct_512; ///< for 512 sample imdct transform
+ MDCTContext imdct_256; ///< for 256 sample imdct transform
+ DSPContext dsp; ///< for optimization
+
+ DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][AC3_BLOCK_SIZE]); ///< delay - added to the next block
+ DECLARE_ALIGNED_16(float, window[AC3_BLOCK_SIZE]); ///< window coefficients
+ DECLARE_ALIGNED_16(float, tmp_output[AC3_BLOCK_SIZE * 24]); ///< temp storage for output before windowing
+ DECLARE_ALIGNED_16(float, tmp_imdct[AC3_BLOCK_SIZE * 24]); ///< temp storage for imdct transform
+ DECLARE_ALIGNED_16(float, output[MAX_CHANNELS][AC3_BLOCK_SIZE]); ///< output after imdct transform and windowing
+ DECLARE_ALIGNED_16(int16_t, int_output[MAX_CHANNELS][AC3_BLOCK_SIZE]);///< final 16-bit integer output
+ float add_bias; ///< offset for float_to_int16 conversion
+ float mul_bias; ///< scaling for float_to_int16 conversion
+
+ AC3ChannelMode blkoutput;
+}EAC3Context;
+
+
+int eac3_parse_syncinfo(GetBitContext *gbc, EAC3Context *s);
+int eac3_parse_bsi(GetBitContext *gbc, EAC3Context *s);
+int eac3_parse_audfrm(GetBitContext *gbc, EAC3Context *s);
+int eac3_parse_audblk(GetBitContext *gbc, EAC3Context *s, const int blk);
+int eac3_parse_auxdata(GetBitContext *gbc, EAC3Context *s);
+
+#endif
Added: eac3/eac3_parser.c
==============================================================================
--- (empty file)
+++ eac3/eac3_parser.c Sat Jul 7 16:04:27 2007
@@ -0,0 +1,1271 @@
+/*
+ * E-AC3 parser
+ * Copyright (c) 2007 Bartlomiej Wolowiec
+ *
+ * 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
+ */
+
+//#define DEBUG
+
+#include "avcodec.h"
+#include "bitstream.h"
+#include "ac3.h"
+#include "random.h"
+
+#ifdef DEBUG
+#define GET_BITS(a, gbc, n) a = get_bits(gbc, n); av_log(NULL, AV_LOG_INFO, "%s: %i\n", __STRING(a), a)
+#else
+#define GET_BITS(a, gbc, n) a = get_bits(gbc, n)
+#ifdef assert
+#undef assert
+#endif //assert
+#define assert(x) if(!(x)){av_log(NULL, AV_LOG_INFO, "Error: %s\n", #x); return 1;}
+#endif //DEBUG
+
+#include "eac3.h"
+
+int eac3_parse_syncinfo(GetBitContext *gbc, EAC3Context *s){
+ GET_BITS(s->syncword, gbc, 16);
+ return 0;
+}
+
+int eac3_parse_bsi(GetBitContext *gbc, EAC3Context *s){
+ int i, blk;
+
+ GET_BITS(s->strmtyp, gbc, 2);
+ GET_BITS(s->substreamid, gbc, 3);
+ GET_BITS(s->frmsiz, gbc, 11);
+ GET_BITS(s->fscod, gbc, 2);
+ if(s->fscod == 0x3)
+ {
+ assert(0 && "TODO");
+ GET_BITS(s->fscod2, gbc, 2);
+ s->numblkscod = 0x3; /* six blocks per frame */
+ }
+ else
+ {
+ GET_BITS(s->numblkscod, gbc, 2);
+ }
+ GET_BITS(s->acmod, gbc, 3);
+ GET_BITS(s->lfeon, gbc, 1);
+
+ //calc
+ s->nfchans = ff_ac3_channels[s->acmod];
+ s->ntchans = s->nfchans;
+ if(s->lfeon){
+ s->lfe_channel = s->ntchans+1;
+
+ s->nlfemant = 7;
+ s->endmant[s->lfe_channel] = 7;
+ s->nchgrps[s->lfe_channel] = 2;
+
+ s->ntchans ++ ;
+ }
+
+ GET_BITS(s->bsid, gbc, 5);
+ assert(s->bsid == 16);
+ GET_BITS(s->dialnorm, gbc, 5);
+ GET_BITS(s->compre, gbc, 1);
+ if(s->compre) {
+ GET_BITS(s->compr, gbc, 8);
+ }
+ if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
+ {
+ GET_BITS(s->dialnorm2, gbc, 5);
+ GET_BITS(s->compr2e, gbc, 1);
+ if(s->compr2e) {
+ GET_BITS(s->compr2, gbc, 8);
+ }
+
+ }
+ if(s->strmtyp == 0x1) /* if dependent stream */
+ {
+ GET_BITS(s->chanmape, gbc, 1);
+ if(s->chanmape) {
+ GET_BITS(s->chanmap, gbc, 16);
+ }
+ }
+ GET_BITS(s->mixmdate, gbc, 1);
+ if(s->mixmdate) /* Mixing metadata */
+ {
+ if(s->acmod > 0x2) /* if more than 2 channels */ {
+ GET_BITS(s->dmixmod, gbc, 2);
+ }
+ if((s->acmod & 0x1) && (s->acmod > 0x2)) /* if three front channels exist */
+ {
+ GET_BITS(s->ltrtcmixlev, gbc, 3);
+ GET_BITS(s->lorocmixlev, gbc, 3);
+ }
+ if(s->acmod & 0x4) /* if a surround channel exists */
+ {
+
+ GET_BITS(s->ltrtsurmixlev, gbc, 3);
+ GET_BITS(s->lorosurmixlev, gbc, 3);
+ }
+ if(s->lfeon) /* if the LFE channel exists */
+ {
+ GET_BITS(s->lfemixlevcode, gbc, 1);
+ if(s->lfemixlevcode) {
+ GET_BITS(s->lfemixlevcod, gbc, 5);
+ }
+ }
+ if(s->strmtyp == 0x0) /* if independent stream */
+ {
+ GET_BITS(s->pgmscle, gbc, 1);
+ if(s->pgmscle) {
+ GET_BITS(s->pgmscl, gbc, 6);
+ }
+ if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
+ {
+ GET_BITS(s->pgmscl2e, gbc, 1);
+ if(s->pgmscl2e) {
+ GET_BITS(s->pgmscl2, gbc, 6);
+ }
+ }
+ GET_BITS(s->extpgmscle, gbc, 1);
+ if(s->extpgmscle) {
+ GET_BITS(s->extpgmscl, gbc, 6);
+ }
+ GET_BITS(s->mixdef, gbc, 2);
+ if(s->mixdef == 0x1) /* mixing option 2 */ {
+ GET_BITS(s->mixdata, gbc, 5);
+ }
+ else if(s->mixdef == 0x2) /* mixing option 3 */ {
+ GET_BITS(s->mixdata, gbc, 12);
+ }
+ else if(s->mixdef == 0x3) /* mixing option 4 */
+ {
+ GET_BITS(s->mixdeflen, gbc, 5);
+ assert( 0 && "TODO");
+// GET_BITS(s->mixdata, gbc, 8*(mixdeflen+2));
+ }
+ if(s->acmod < 0x2) /* if mono or dual mono source */
+ {
+ GET_BITS(s->paninfoe, gbc, 1);
+ if(s->paninfoe) {
+ GET_BITS(s->paninfo, gbc, 14);
+ }
+ if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
+ {
+ GET_BITS(s->paninfo2e, gbc, 1);
+ if(s->paninfo2e) {
+ GET_BITS(s->paninfo2, gbc, 14);
+ }
+ }
+ }
+ GET_BITS(s->frmmixcfginfoe, gbc, 1);
+ if(s->frmmixcfginfoe) /* mixing configuration information */
+ {
+ if(s->numblkscod == 0x0) {
+ GET_BITS(s->blkmixcfginfo0, gbc, 5);
+ }
+ else
+ {
+ for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++)
+ {
+ GET_BITS(s->blkmixcfginfoe, gbc, 1);
+ if(s->blkmixcfginfoe){
+ GET_BITS(s->blkmixcfginfoblk, gbc, 5);
+ }
+ }
+ }
+ }
+ }
+ }
+ GET_BITS(s->infomdate, gbc, 1);
+ if(s->infomdate) /* Informational metadata */
+ {
+ GET_BITS(s->bsmod, gbc, 3);
+
+ GET_BITS(s->copyrightb, gbc, 1);
+ GET_BITS(s->origbs, gbc, 1);
+ if(s->acmod == 0x2) /* if in 2/0 mode */
+ {
+ GET_BITS(s->dsurmod, gbc, 2);
+ GET_BITS(s->dheadphonmod, gbc, 2);
+ }
+ if(s->acmod >= 0x6) /* if both surround channels exist */ {
+ GET_BITS(s->dsurexmod, gbc, 2);
+ }
+ GET_BITS(s->audprodie, gbc, 1);
+ if(s->audprodie)
+ {
+ GET_BITS(s->mixlevel, gbc, 5);
+ GET_BITS(s->roomtyp, gbc, 2);
+ GET_BITS(s->adconvtyp, gbc, 1);
+ }
+ if(s->acmod == 0x0) /* if 1+1 mode (dual mono, so some items need a second value) */
+ {
+ GET_BITS(s->audprodi2e, gbc, 1);
+ if(s->audprodi2e)
+ {
+ GET_BITS(s->mixlevel2, gbc, 5);
+ GET_BITS(s->roomtyp2, gbc, 2);
+ GET_BITS(s->adconvtyp2, gbc, 1);
+ }
+ }
+ if(s->fscod < 0x3) /* if not half sample rate */ {
+ GET_BITS(s->sourcefscod, gbc, 1); // TODO
+ }
+ }
+ if((s->strmtyp == 0x0) && (s->numblkscod != 0x3) ) {
+ GET_BITS(s->convsync, gbc, 1);
+ }
+ if(s->strmtyp == 0x2) /* if bit stream converted from AC-3 */
+ {
+ if(s->numblkscod == 0x3) /* 6 blocks per frame */ {
+ s->blkid = 1;
+ }
+ else {
+ GET_BITS(s->blkid, gbc, 1);
+ }
+ if(s->blkid) {
+ GET_BITS(s->frmsizecod, gbc, 6);
+ }
+ }
+ GET_BITS(s->addbsie, gbc, 1);
+ if(s->addbsie)
+ {
+ GET_BITS(s->addbsil, gbc, 6);
+ for(i=0; i<s->addbsil+1; i++){
+ GET_BITS(s->addbsi[i], gbc, 8);
+ }
+ }
+
+ return 0;
+} /* end of bsi */
+
+
+int eac3_parse_audfrm(GetBitContext *gbc, EAC3Context *s){
+ int blk, ch;
+
+ /* These fields for audio frame exist flags and strategy data */
+ if(s->numblkscod == 0x3) /* six blocks per frame */
+ {
+ GET_BITS(s->expstre, gbc, 1);
+ GET_BITS(s->ahte, gbc, 1);
+ }
+ else
+ {
+ s->expstre = 1;
+ s->ahte = 0;
+ }
+ GET_BITS(s->snroffststr, gbc, 2);
+ GET_BITS(s->transproce, gbc, 1);
+ GET_BITS(s->blkswe, gbc, 1);
+ GET_BITS(s->dithflage, gbc, 1);
+ GET_BITS(s->bamode, gbc, 1);
+ GET_BITS(s->frmfgaincode, gbc, 1);
+ GET_BITS(s->dbaflde, gbc, 1);
+ GET_BITS(s->skipflde, gbc, 1);
+ GET_BITS(s->spxattene, gbc, 1);
+ /* These fields for coupling data */
+ if(s->acmod > 0x1)
+ {
+ s->cplstre[0] = 1;
+ GET_BITS(s->cplinu[0], gbc, 1);
+ for(blk = 1; blk < ff_eac3_blocks[s->numblkscod]; blk++)
+ {
+ GET_BITS(s->cplstre[blk], gbc, 1);
+
+ if(s->cplstre[blk] == 1) {
+ GET_BITS(s->cplinu[blk], gbc, 1);
+ }
+ else {
+ s->cplinu[blk] = s->cplinu[blk-1];
+ }
+ }
+ }
+ else
+ {
+ for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
+ s->cplinu[blk] = 0;
+ }
+ }
+
+ // calc
+ s->ncplblks = 0;
+ for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
+ s->ncplblks += s->cplinu[blk];
+ }
+
+ /* These fields for exponent strategy data */
+ if(s->expstre)
+ {
+ for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++)
+ {
+ if(s->cplinu[blk] == 1) {
+ GET_BITS(s->cplexpstr[blk], gbc, 2);
+ }
+
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->chexpstr[blk][ch], gbc, 2); // TODO
+ }
+ }
+ }
+ else
+ {
+ if( (s->acmod > 0x1) && (s->ncplblks > 0) ) {
+ GET_BITS(s->frmcplexpstr, gbc, 5);
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->frmchexpstr[ch], gbc, 5);
+ }
+ /* cplexpstr[blk] and chexpstr[blk][ch] derived from table lookups ? see Table E2.14 */
+ assert(0 && "TODO");
+ }
+ if(s->lfeon)
+ {
+ for(blk = 0; blk < ff_eac3_blocks[s->numblkscod]; blk++) {
+ GET_BITS(s->lfeexpstr[blk], gbc, 1);
+ s->chexpstr[blk][s->lfe_channel] = s->lfeexpstr[blk];
+ }
+ }
+ /* These fields for converter exponent strategy data */
+ if(s->strmtyp == 0x0)
+ {
+ if(s->numblkscod != 0x3) {
+ GET_BITS(s->convexpstre, gbc, 1);
+ }
+ else {
+ s->convexpstre = 1;
+ }
+ if(s->convexpstre == 1)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->convexpstr[ch], gbc, 5);
+ }
+ }
+ }
+ /* These fields for AHT data */
+ if(s->ahte)
+ {
+ /* coupling can use AHT only when coupling in use for all blocks */
+ /* ncplregs derived from cplstre and cplexpstr ? see Section E3.3.2 */
+ assert( 0 && "TODO: AHT" );
+ /*
+ if( (s->ncplblks == 6) && (s->ncplregs ==1) ) {
+ GET_BITS(s->cplahtinu, gbc, 1);
+ }
+ else {
+ cplahtinu = 0
+ }
+
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ // nchregs derived from chexpstr ? see Section E3.3.2
+ if(s->nchregs[ch] == 1) {
+ GET_BITS(s->chahtinu[ch], gbc, 1);
+ }
+ else {
+ chahtinu[ch] = 0
+ }
+ }
+ if(lfeon)
+ {
+ // nlferegs derived from lfeexpstr ? see Section E3.3.2
+ if(nlferegs == 1) {
+ GET_BITS(s->lfeahtinu, gbc, 1);
+ }
+ else {
+ lfeahtinu = 0
+ }
+ }
+ */
+ }
+ /* These fields for audio frame SNR offset data */
+ if(s->snroffststr == 0x0)
+ {
+ GET_BITS(s->frmcsnroffst, gbc, 6);
+ GET_BITS(s->frmfsnroffst, gbc, 4);
+ }
+ /* These fields for audio frame transient pre-noise processing data */
+ if(s->transproce)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ GET_BITS(s->chintransproc[ch], gbc, 1);
+ if(s->chintransproc[ch])
+ {
+ GET_BITS(s->transprocloc[ch], gbc, 10);
+ GET_BITS(s->transproclen[ch], gbc, 8);
+ }
+ }
+ }
+ /* These fields for spectral extension attenuation data */
+ if(s->spxattene)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ GET_BITS(s->chinspxatten[ch], gbc, 1);
+ if(s->chinspxatten[ch])
+ {
+ GET_BITS(s->spxattencod[ch], gbc, 5);
+ }
+ }
+ }
+ /* These fields for block start information */
+ if (s->numblkscod != 0x0) {
+ GET_BITS(s->blkstrtinfoe, gbc, 1);
+ }
+ else {
+ s->blkstrtinfoe = 0;
+ }
+ if(s->blkstrtinfoe)
+ {
+ /* nblkstrtbits determined from frmsiz (see Section E2.3.2.27) */
+ // nblkstrtbits = (numblks - 1) * (4 + ceiling (log2 (words_per_frame)))
+ // where numblks is derived from the numblkscod in Table E2.15 <- TODO ???
+ // words_per_frame = frmsiz + 1
+ int nblkstrtbits = (ff_eac3_blocks[s->numblkscod]-1) * (4 + (av_log2(s->frmsiz-1)+1) );
+ av_log(NULL, AV_LOG_INFO, "nblkstrtbits = %i\n", nblkstrtbits);
+ GET_BITS(s->blkstrtinfo, gbc, nblkstrtbits);
+ }
+ /* These fields for syntax state initialization */
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ s->firstspxcos[ch] = 1;
+ s->firstcplcos[ch] = 1;
+ }
+ s->firstcplleak = 1;
+
+ return 0;
+} /* end of audfrm */
+
+int eac3_parse_audblk(GetBitContext *gbc, EAC3Context *s, const int blk){
+ int ch, grp, seg;
+ int bnd, sbnd, i, n, bin;
+ /* These fields for block switch and dither flags */
+ if(s->blkswe)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->blksw[ch], gbc, 1);
+ }
+ }
+ else
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ s->blksw[ch] = 0;
+ }
+ }
+ if(s->dithflage)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->dithflag[ch], gbc, 1);
+ }
+ }
+ else
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ s->dithflag[ch] = 1; /* dither on */
+ }
+ }
+ /* These fields for dynamic range control */
+ GET_BITS(s->dynrnge, gbc, 1);
+ if(s->dynrnge) {
+ GET_BITS(s->dynrng, gbc, 8);
+ }
+ if(s->acmod == 0x0) /* if 1+1 mode */
+ {
+ GET_BITS(s->dynrng2e, gbc, 1);
+ if(s->dynrng2e) {
+ GET_BITS(s->dynrng2, gbc, 8);
+ }
+ }
+ /* These fields for spectral extension strategy information */
+ if(blk == 0) {
+ s->spxstre = 1;
+ }
+ else {
+ GET_BITS(s->spxstre, gbc, 1);
+ }
+ assert(blk || s->spxstre);
+ if(s->spxstre)
+ {
+ GET_BITS(s->spxinu, gbc, 1);
+ if(s->spxinu)
+ {
+ if(s->acmod == 0x1)
+ {
+ s->chinspx[0] = 1;
+ }
+ else
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->chinspx[ch], gbc, 1);
+ }
+ }
+ GET_BITS(s->spxstrtf, gbc, 2);
+ GET_BITS(s->spxbegf, gbc, 3);
+ GET_BITS(s->spxendf, gbc, 3);
+ if(s->spxbegf < 6) {
+ s->spxbegf += 2;
+ }
+ else {
+ s->spxbegf = s->spxbegf * 2 - 3;
+ }
+ if(s->spxendf < 3) {
+ s->spxendf += 5;
+ }
+ else {
+ s->spxendf = s->spxendf * 2 + 3;
+ }
+ GET_BITS(s->spxbndstrce, gbc, 1);
+
+ assert(blk || s->spxbndstrce); // TODO default values..
+
+ if(s->spxbndstrce)
+ {
+ for(bnd = s->spxbegf+1; bnd < s->spxendf; bnd++) {
+ GET_BITS(s->spxbndstrc[bnd], gbc, 1);
+ }
+ }
+ //calc
+ s->nspxbnds = 1;
+ s->spxbndsztab[0] = 12;
+ for (bnd = s->spxbegf+1; bnd < s->spxendf; bnd ++)
+ {
+ if (s->spxbndstrc[bnd] == 0)
+ {
+ s->spxbndsztab[s->nspxbnds] = 12;
+ s->nspxbnds++;
+ }
+ else
+ {
+ s->spxbndsztab[s->nspxbnds - 1] += 12;
+ }
+ }
+ assert(s->nspxbnds < MAX_SPX_CODES);
+ }
+ else /* !spxinu */
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ s->chinspx[ch] = 0;
+ s->firstspxcos[ch] = 1;
+ }
+ }
+ }
+
+
+ /* These fields for spectral extension coordinates */
+ if(s->spxinu)
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ if(s->chinspx[ch])
+ {
+ if(s->firstspxcos[ch])
+ {
+ s->spxcoe[ch] = 1;
+ s->firstspxcos[ch] = 0;
+ }
+ else /* !firstspxcos[ch] */ {
+ GET_BITS(s->spxcoe[ch], gbc, 1);
+ }
+ assert(blk || s->spxcoe[ch]);
+ if(s->spxcoe[ch])
+ {
+ GET_BITS(s->spxblnd[ch], gbc, 5);
+ GET_BITS(s->mstrspxco[ch], gbc, 2);
+ /* nspxbnds determined from spxbegf, spxendf, and spxbndstrc[ ] */
+ assert(s->nspxbnds < MAX_SPX_CODES);
+ for(bnd = 0; bnd < s->nspxbnds; bnd++)
+ {
+ GET_BITS(s->spxcoexp[ch][bnd], gbc, 4);
+ GET_BITS(s->spxcomant[ch][bnd], gbc, 2);
+ }
+ }
+ }
+ else /* !chinspx[ch] */
+ {
+ s->firstspxcos[ch] = 1;
+ }
+ }
+ }
+ /* These fields for coupling strategy and enhanced coupling strategy information */
+ if(s->cplstre[blk])
+ {
+ if (s->cplinu[blk])
+ {
+ GET_BITS(s->ecplinu, gbc, 1);
+ assert(!s->ecplinu && "TODO");
+ if (s->acmod == 0x2)
+ {
+ s->chincpl[0] = 1;
+ s->chincpl[1] = 1;
+ }
+ else
+ {
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->chincpl[ch], gbc, 1);
+ }
+ }
+ if (s->ecplinu == 0) /* standard coupling in use */
+ {
+ if(s->acmod == 0x2) /* if in 2/0 mode */ {
+ GET_BITS(s->phsflginu, gbc, 1);
+ }
+ GET_BITS(s->cplbegf, gbc, 4);
+ if (s->spxinu == 0) /* if SPX not in use */
+ {
+ GET_BITS(s->cplendf, gbc, 4);
+ s->cplendf = s->cplendf + 3;
+ }
+ else /* SPX in use */
+ {
+ s->cplendf = s->spxbegf - 1;
+ }
+
+ // calc
+ s->cplstrtmant = 37 + (12 * s->cplbegf);
+ s->cplendmant = 37 + (12 * (s->cplendf + 3));
+
+ GET_BITS(s->cplbndstrce, gbc, 1);
+ if(s->cplbndstrce)
+ {
+ for(bnd = s->cplbegf+1; bnd < s->cplendf; bnd++) {
+ GET_BITS(s->cplbndstrc[bnd], gbc, 1);
+ }
+ }
+ //TODO calc ncplsubnd ?
+ s->ncplsubnd = s->cplendf - s->spxbegf + 1;
+ s->ncplbnd = s->ncplsubnd;
+ for(bnd = 1; bnd < s->cplendf; bnd++){
+ s->ncplbnd -= s->cplbndstrc[bnd];
+ }
+
+ }
+ else /* enhanced coupling in use */
+ {
+ assert(0 && "TODO enhanced coupling");
+ GET_BITS(s->ecplbegf, gbc, 4);
+ if(s->ecplbegf < 3) {
+ s->ecpl_start_subbnd = s->ecplbegf * 2;
+ }
+ else if(s->ecplbegf < 13) {
+ s->ecpl_start_subbnd = s->ecplbegf + 2;
+ }
+ else {
+ s->ecpl_start_subbnd = s->ecplbegf * 2 - 10;
+ }
+ if (s->spxinu == 0) /* if SPX not in use */
+ {
+ GET_BITS(s->ecplendf, gbc, 4);
+ s->ecpl_end_subbnd = s->ecplendf + 7;
+ }
+ else /* SPX in use */
+ {
+ if(s->spxbegf < 6) {
+ s->ecpl_end_subbnd = s->spxbegf + 5;
+ }
+ else {
+ s->ecpl_end_subbnd = s->spxbegf * 2;
+ }
+ }
+ GET_BITS(s->ecplbndstrce, gbc, 1);
+ if (s->ecplbndstrce)
+ {
+ for(sbnd = FFMAX(9, s->ecpl_start_subbnd+1);
+ sbnd < s->ecpl_end_subbnd; sbnd++)
+ {
+ GET_BITS(s->ecplbndstrc[sbnd], gbc, 1);
+ }
+ }
+ //necplbnd = ecpl_end_subbnd - ecpl_start_subbnd;
+ //necplbnd -= ecplbndstrc[ecpl_start_subbnd] + ... + ecplbndstrc[ecpl_end_subbnd -1]
+ // CALC
+ s->necplbnd = s->ecpl_end_subbnd - s->ecpl_start_subbnd;
+ for(bnd=s->ecpl_start_subbnd; bnd<s->ecpl_end_subbnd; bnd++){
+ s->necplbnd -= s->ecplbndstrc[bnd];
+ }
+
+ } /* ecplinu[blk] */
+ }
+ else /* !cplinu[blk] */
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ s->chincpl[ch] = 0;
+ s->firstcplcos[ch] = 1;
+ }
+ s->firstcplleak = 1;
+ s->phsflginu = 0;
+ s->ecplinu = 0;
+ }
+ } /* cplstre[blk] */
+ /* These fields for coupling coordinates */
+ if(s->cplinu[blk])
+ {
+ assert(0 && "NOT TESTED");
+ if(s->ecplinu == 0) /* standard coupling in use */
+ {
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ if(s->chincpl[ch])
+ {
+ if (s->firstcplcos[ch])
+ {
+ s->cplcoe[ch] = 1;
+ s->firstcplcos[ch] = 0;
+ }
+ else /* !firstcplcos[ch] */ {
+ GET_BITS(s->cplcoe[ch], gbc, 1);
+ }
+ if(s->cplcoe[ch])
+ {
+ GET_BITS(s->mstrcplco[ch], gbc, 2);
+ /* ncplbnd derived from cplbegf, cplendf, and cplbndstrc */
+ for(bnd = 0; bnd < s->ncplbnd; bnd++)
+ {
+ GET_BITS(s->cplcoexp[ch][bnd], gbc, 4);
+ GET_BITS(s->cplcomant[ch][bnd], gbc, 4);
+ }
+ } /* cplcoe[ch] */
+ }
+ else /* ! chincpl[ch] */
+ {
+ s->firstcplcos[ch] = 1;
+ }
+ } /* ch */
+ if((s->acmod == 0x2) && s->phsflginu && (s->cplcoe[0] || s->cplcoe[1]))
+ {
+ for(bnd = 0; bnd < s->ncplbnd; bnd++) {
+ GET_BITS(s->phsflg[bnd], gbc, 1);
+ }
+ }
+ }
+ else /* enhanced coupling in use */
+ {
+ s->firstchincpl = -1;
+ GET_BITS(s->ecplangleintrp, gbc, 1);
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ if(s->chincpl[ch])
+ {
+ if(s->firstchincpl == -1) {
+ s->firstchincpl = ch;
+ }
+ if(s->firstcplcos[ch])
+ {
+ s->ecplparam1e[ch] = 1;
+ if (ch > s->firstchincpl) {
+ s->ecplparam2e[ch] = 1;
+ }
+ else {
+ s->ecplparam2e[ch] = 0;
+ }
+ s->firstcplcos[ch] = 0;
+ }
+ else /* !firstcplcos[ch] */
+ {
+ GET_BITS(s->ecplparam1e[ch], gbc, 1);
+ if(ch > s->firstchincpl) {
+ GET_BITS(s->ecplparam2e[ch], gbc, 1);
+ }
+ else {
+ s->ecplparam2e[ch] = 0;
+ }
+ }
+ if(s->ecplparam1e[ch])
+ {
+ /* necplbnd derived from ecpl_start_subbnd, ecpl_end_subbnd, and ecplbndstrc */
+ for(bnd = 0; bnd < s->necplbnd; bnd++) {
+ GET_BITS(s->ecplamp[ch][bnd], gbc, 5);
+ }
+ }
+ if(s->ecplparam2e[ch])
+ {
+ /* necplbnd derived from ecpl_start_subbnd, ecpl_end_subbnd, and ecplbndstrc */
+ for(bnd = 0; bnd < s->necplbnd; bnd++)
+ {
+ GET_BITS(s->ecplangle[ch][bnd], gbc, 6);
+ GET_BITS(s->ecplchaos[ch][bnd], gbc, 3);
+ }
+ }
+ if(ch > s->firstchincpl) {
+ GET_BITS(s->ecpltrans[ch], gbc, 1);
+ }
+ }
+ else /* !chincpl[ch] */
+ {
+ s->firstcplcos[ch] = 1;
+ }
+ } /* ch */
+ } /* ecplinu[blk] */
+ } /* cplinu[blk] */
+ /* These fields for rematrixing operation in the 2/0 mode */
+ if(s->acmod == 0x2) /* if in 2/0 mode */
+ {
+ if (blk == 0) {
+ s->rematstr = 1;
+ }
+ else {
+ GET_BITS(s->rematstr, gbc, 1);
+ }
+ if(s->rematstr)
+ {
+ /* nrematbnds determined from cplinu, ecplinu, spxinu, cplbegf, ecplbegf and spxbegf
+ * TODO: how ? */
+ assert( 0 && "TODO");
+ for(bnd = 0; bnd < s->nrematbnds; bnd++) {
+ GET_BITS(s->rematflg[bnd], gbc, 1);
+ }
+ }
+ }
+ /* This field for channel bandwidth code */
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ assert(blk || s->chexpstr[blk][ch]!=EXP_REUSE);
+ if(s->chexpstr[blk][ch] != EXP_REUSE)
+ {
+ if((!s->chincpl[ch]) && (!s->chinspx[ch])) {
+ GET_BITS(s->chbwcod[ch], gbc, 6);
+ if(s->chbwcod[ch] > 60)
+ return 1;
+ }
+ }
+ }
+
+ // calc
+ for(ch = 1; ch<=s->nfchans; ch++){
+ int grpsize = 3 << (s->chexpstr[blk][ch] - 1);
+
+ if(s->chincpl[ch])
+ s->endmant[ch] = s->cplstrtmant; /* channel is coupled */
+ else
+ s->endmant[ch] = ((s->chbwcod[ch] + 12) * 3) + 37; /* (ch is not coupled) */
+
+ s->nchgrps[ch] = (s->endmant[ch] + grpsize - 4) / grpsize;
+ assert(s->nchgrps[ch]<AC3_MAX_COEFS);
+ }
+
+ /* These fields for exponents */
+ if(s->cplinu[blk]) /* exponents for the coupling channel */
+ {
+ if(s->cplexpstr[blk] != EXP_REUSE)
+ {
+ GET_BITS(s->cplabsexp, gbc, 4);
+ /* ncplgrps derived from cplbegf, ecplbegf, cplendf, ecplendf, and cplexpstr */
+ /* how... ? */
+ assert(0 && "TODO");
+ for(grp = 0; grp< s->ncplgrps; grp++) {
+ GET_BITS(s->cplexps[grp], gbc, 7);
+ }
+ }
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) /* exponents for full bandwidth channels */
+ {
+ assert(blk || s->chexpstr[blk][ch] != EXP_REUSE);
+ if(s->chexpstr[blk][ch] != EXP_REUSE)
+ {
+ GET_BITS(s->dexps[ch][0], gbc, 4);
+
+ ff_ac3_decode_exponents(gbc, s->chexpstr[blk][ch], s->nchgrps[ch], s->dexps[ch][0],
+ s->dexps[ch] + 1);
+
+
+ GET_BITS(s->gainrng[ch], gbc, 2);
+ }
+ }
+ if(s->lfeon) /* exponents for the low frequency effects channel */
+ {
+ if(s->lfeexpstr[blk] != EXP_REUSE)
+ {
+ ch = s->lfe_channel;
+ GET_BITS(s->dexps[ch][0], gbc, 4);
+ s->nlfegrps = 2;
+ ff_ac3_decode_exponents(gbc, s->lfeexpstr[blk], s->nlfegrps, s->dexps[ch][0],
+ s->dexps[ch] + 1);
+ }
+ }
+ /* These fields for bit-allocation parametric information */
+ if(s->bamode)
+ {
+ GET_BITS(s->baie, gbc, 1);
+ assert(s->baie || blk);
+ if(s->baie)
+ {
+ GET_BITS(s->sdcycod, gbc, 2);
+ GET_BITS(s->fdcycod, gbc, 2);
+ GET_BITS(s->sgaincod, gbc, 2);
+ GET_BITS(s->dbpbcod, gbc, 2);
+ GET_BITS(s->floorcod, gbc, 3);
+ }
+ }
+ else
+ {
+ s->sdcycod = 0x2;
+ s->fdcycod = 0x1;
+ s->sgaincod = 0x1;
+ s->dbpbcod = 0x2;
+ s->floorcod = 0x7;
+ }
+
+ s->sdecay = ff_sdecaytab[s->sdcycod]; /* Table 7.6 */
+ s->fdecay = ff_fdecaytab[s->fdcycod]; /* Table 7.7 */
+ s->sgain = ff_sgaintab[s->sgaincod]; /* Table 7.8 */
+ s->dbknee = ff_dbkneetab[s->dbpbcod]; /* Table 7.9 */
+ s->floor = ff_floortab[s->floorcod]; /* Table 7.10 */
+
+ if(s->snroffststr == 0x0)
+ {
+ if(s->cplinu[blk]) {
+ s->cplfsnroffst = s->frmfsnroffst;
+ }
+ s->csnroffst = s->frmcsnroffst;
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ s->fsnroffst[ch] = s->frmfsnroffst;
+ }
+ if(s->lfeon) {
+ s->lfefsnroffst = s->frmfsnroffst;
+ }
+ }
+ else
+ {
+ assert(0 && "NOT TESTED");
+ if(blk == 0) {
+ s->snroffste = 1;
+ }
+ else {
+ GET_BITS(s->snroffste, gbc, 1);
+ }
+ if(s->snroffste)
+ {
+ GET_BITS(s->csnroffst, gbc, 6);
+ if(s->snroffststr == 0x1)
+ {
+ GET_BITS(s->blkfsnroffst, gbc, 4);
+ s->cplfsnroffst = s->blkfsnroffst;
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ s->fsnroffst[ch] = s->blkfsnroffst;
+ }
+ s->lfefsnroffst = s->blkfsnroffst;
+ }
+ else if(s->snroffststr == 0x2)
+ {
+ if(s->cplinu[blk]) {
+ GET_BITS(s->cplfsnroffst, gbc, 4);
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->fsnroffst[ch], gbc, 4);
+ }
+ if(s->lfeon) {
+ GET_BITS(s->lfefsnroffst, gbc, 4);
+ }
+ }
+ }
+ }
+
+ if(s->lfeon){
+ s->fsnroffst[s->lfe_channel] = s->lfefsnroffst;
+ }
+
+ if(s->frmfgaincode) {
+ GET_BITS(s->fgaincode, gbc, 1);
+ }
+ else {
+ s->fgaincode = 0;
+ }
+ if(s->fgaincode)
+ {
+ if(s->cplinu[blk]) {
+ GET_BITS(s->cplfgaincod, gbc, 3);
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->fgaincod[ch], gbc, 3);
+ }
+ if(s->lfeon) {
+ GET_BITS(s->lfefgaincod, gbc, 3);
+ }
+ }
+ else
+ {
+ if(s->cplinu[blk]) {
+ s->cplfgaincod = 0x4;
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ s->fgaincod[ch] = 0x4;
+ }
+ if(s->lfeon) {
+ s->lfefgaincod = 0x4;
+ }
+ }
+ if(s->lfeon){
+ s->fgaincod[s->lfe_channel] = s->lfefgaincod;
+ }
+ if(s->strmtyp == 0x0)
+ {
+ GET_BITS(s->convsnroffste, gbc, 1);
+ if(s->convsnroffste) {
+ GET_BITS(s->convsnroffst, gbc, 10);
+ }
+ }
+ if(s->cplinu[blk])
+ {
+ if (s->firstcplleak)
+ {
+ s->cplleake = 1;
+ s->firstcplleak = 0;
+ }
+ else /* !firstcplleak */
+ {
+ GET_BITS(s->cplleake, gbc, 1);
+ }
+ if(s->cplleake)
+ {
+ GET_BITS(s->cplfleak, gbc, 3);
+ GET_BITS(s->cplsleak, gbc, 3);
+ }
+ }
+ /* These fields for delta bit allocation information */
+ if(s->dbaflde)
+ {
+ assert(0 && "NOT TESTED");
+ GET_BITS(s->deltbaie, gbc, 1);
+ if(s->deltbaie)
+ {
+ if(s->cplinu[blk]) {
+ GET_BITS(s->cpldeltbae, gbc, 2);
+ }
+ for(ch = 1; ch <= s->nfchans; ch++) {
+ GET_BITS(s->deltbae[ch], gbc, 2);
+ }
+ if(s->cplinu[blk])
+ {
+ //TODO
+ if(s->cpldeltbae==DBA_NEW)
+ {
+ GET_BITS(s->cpldeltnseg, gbc, 3);
+ for(seg = 0; seg <= s->cpldeltnseg; seg++)
+ {
+ GET_BITS(s->cpldeltoffst[seg], gbc, 5);
+ GET_BITS(s->cpldeltlen[seg], gbc, 4);
+ GET_BITS(s->cpldeltba[seg], gbc, 3);
+ }
+ }
+ }
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ if(s->deltbae[ch]==DBA_NEW)
+ {
+ GET_BITS(s->deltnseg[ch], gbc, 3);
+ for(seg = 0; seg <= s->deltnseg[ch]; seg++)
+ {
+ GET_BITS(s->deltoffst[ch][seg], gbc, 5);
+ GET_BITS(s->deltlen[ch][seg], gbc, 4);
+ GET_BITS(s->deltba[ch][seg], gbc, 3);
+ }
+ }
+ }
+ } /* if(s->deltbaie) */
+ }/* if(s->dbaflde) */
+
+
+ /* These fields for inclusion of unused dummy data */
+ if(s->skipflde)
+ {
+ GET_BITS(s->skiple, gbc, 1);
+ if(s->skiple)
+ {
+ GET_BITS(s->skipl, gbc, 9);
+ // TODO skip :)
+ for(i=0; i<s->skipl; i++)
+ GET_BITS(s->skipfld, gbc, 8);
+ }
+ }
+
+ /* run bit allocation */
+ if(s->cplinu[blk]) {
+ assert(0 && "TODO");
+ }
+
+ for(ch = 1; ch<=s->nfchans+s->lfeon; ch++) {
+ int start=0, end=0;
+ end = s->endmant[ch];
+
+ ff_ac3_bit_alloc_calc_psd((int8_t *)s->dexps[ch], start, end,
+ s->psd[ch], s->bndpsd[ch]);
+
+
+ // TODO hmm... :)
+ s->bit_alloc_params.fscod = s->fscod;
+ s->bit_alloc_params.halfratecod = 0; // TODO
+ s->bit_alloc_params.sdecay = s->sdecay;
+ s->bit_alloc_params.fdecay = s->fdecay;
+ s->bit_alloc_params.sgain = s->sgain;
+ s->bit_alloc_params.dbknee = s->dbknee;
+ s->bit_alloc_params.floor = s->floor;
+ s->bit_alloc_params.cplfleak = s->cplfleak;
+ s->bit_alloc_params.cplsleak = s->cplsleak;
+
+ {
+ int fgain = ff_fgaintab[s->fgaincod[ch]];
+ if(ch == s->lfe_channel){
+ s->deltbae[ch] = DBA_NONE;
+ }
+ ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params,
+ s->bndpsd[ch], start, end, fgain,
+ (ch == s->lfe_channel),
+ s->deltbae[ch], s->deltnseg[ch],
+ s->deltoffst[ch], s->deltlen[ch],
+ s->deltba[ch], s->mask[ch]);
+ }
+
+ {
+ int snroffst = (((s->csnroffst - 15) << 4) + s->fsnroffst[ch]) << 2;
+ //av_log(NULL, AV_LOG_INFO, "s->csnroffst=%i s->fsnroffst=%i snroffst = %i\n",
+ // s->csnroffst, s->fsnroffst[ch], snroffst);
+ ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch], start, end,
+ snroffst, s->bit_alloc_params.floor,
+ s->bap[ch]);
+ }
+
+
+ }
+
+
+ /* These fields for quantized mantissa values */
+
+ s->got_cplchan = 0;
+ ff_ac3_get_transform_coeffs(gbc, s->bap, s->dexps, s->nfchans+s->lfeon, s->chincpl, s->dithflag, s->transform_coeffs, s->strtmant, s->endmant, &s->dith_state);
+
+ for(ch = 1; ch <= s->nfchans; ch++)
+ {
+ if(s->chahtinu[ch] == 0)
+ {
+ // ff_ac3_get_transform
+ }
+ else if(s->chahtinu[ch] == 1)
+ {
+ assert(0 && "TODO: AHT");
+ GET_BITS(s->chgaqmod[ch], gbc, 2);
+ if((s->chgaqmod[ch] > 0x0) && (s->chgaqmod[ch] < 0x3) )
+ {
+ for(n = 0; n < s->chgaqsections[ch]; n++) { // TODO chgaqsections ?
+ GET_BITS(s->chgaqgain[ch][n], gbc, 1);
+ }
+ }
+ else if(s->chgaqmod[ch] == 0x3)
+ {
+ for(n = 0; n < s->chgaqsections[ch]; n++) { //TODO chgaqsections ?
+ GET_BITS(s->chgaqgain[ch][n], gbc, 5);
+ }
+ }
+ for(bin = 0; bin < s->nchmant[ch]; bin++) // TODO nchmant ?
+ {
+ if(s->chgaqbin[ch][bin]) // TODO chgaqbin ?
+ {
+ for(n = 0; n < 6; n++) {
+ GET_BITS(s->pre_chmant[n][ch][bin], gbc, (0-16)); // TODO 0-16 :]
+ }
+ }
+ else {
+ GET_BITS(s->pre_chmant[0][ch][bin], gbc, (0-9)); // TODO 0-9 :]
+ }
+ }
+ s->chahtinu[ch] = -1; /* AHT info for this frame has been read ? do not read again */
+ }
+ if(s->cplinu[blk] && s->chincpl[ch] && !s->got_cplchan)
+ {
+ assert(0 && "TODO: CPL");
+ if(s->cplahtinu == 0)
+ {
+ for(bin = 0; bin < s->ncplmant; bin++) { // TODO ncplmant ?
+ GET_BITS(s->cplmant[bin], gbc, (0-16)); // TODO 0-16 :]
+ }
+ s->got_cplchan = 1;
+ }
+ else if(s->cplahtinu == 1)
+ {
+ GET_BITS(s->cplgaqmod, gbc, 2);
+ if((s->cplgaqmod > 0x0) && (s->cplgaqmod < 0x3) )
+ {
+ for(n = 0; n < s->cplgaqsections; n++) { // TODO cplgaqsections?
+ GET_BITS(s->cplgaqgain[n], gbc, 1);
+ }
+ }
+ else if(s->cplgaqmod == 0x3)
+ {
+ for(n = 0; n < s->cplgaqsections; n++) {
+ GET_BITS(s->cplgaqgain[n], gbc, 5);
+ }
+ }
+ for(bin = 0; bin < s->ncplmant; bin++) // TODO ncplmant?
+ {
+ if(s->cplgaqbin[bin])
+ {
+ for(n = 0; n < 6; n++) {
+ GET_BITS(s->pre_cplmant[n][bin], gbc, (0-16)); // TODO 0-16 :]
+ }
+ }
+ else {
+ GET_BITS(s->pre_cplmant[0][bin], gbc, (0-9));
+ }
+ }
+ s->got_cplchan = 1;
+ s->cplahtinu = -1; /* AHT info for this frame has been read ? do not read again */
+ }
+ else {
+ s->got_cplchan = 1;
+ }
+ }
+ }
+ if(s->lfeon) /* mantissas of low frequency effects channel */
+ {
+ if(s->lfeahtinu == 0)
+ {
+ //ff_ac3_get_transform
+ }
+ else if(s->lfeahtinu == 1)
+ {
+ assert(0 && "TODO: AHT");
+ GET_BITS(s->lfegaqmod, gbc, 2);
+ if( (s->lfegaqmod > 0x0) && (s->lfegaqmod < 0x3) )
+ {
+ for(n = 0; n < s->lfegaqsections; n++) { // TODO lfegaqsections?
+ GET_BITS(s->lfegaqgain[n], gbc, 1);
+ }
+ }
+ else if(s->lfegaqmod == 0x3)
+ {
+ for(n = 0; n < s->lfegaqsections; n++) { // TODO
+ GET_BITS(s->lfegaqgain[n], gbc, 5);
+ }
+ }
+ for(bin = 0; bin < s->nlfemant; bin++)
+ {
+ if(s->lfegaqbin[bin])
+ {
+ for(n = 0; n < 6; n++) {
+ GET_BITS(s->pre_lfemant[n][bin], gbc, (0-16)); // TODO 0-16 :]
+ }
+ }
+ else {
+ GET_BITS(s->pre_lfemant[0][bin], gbc, (0-9)); // TODO 0-9 :]
+ }
+ }
+ s->lfeahtinu = -1; /* AHT info for this frame has been read ? do not read again */
+ }
+ }
+ return 0;
+}
+
+int eac3_parse_auxdata(GetBitContext *gbc, EAC3Context *s){
+ // TODO
+ return 0;
+}
Added: eac3/eac3dec.c
==============================================================================
--- (empty file)
+++ eac3/eac3dec.c Sat Jul 7 16:04:27 2007
@@ -0,0 +1,234 @@
+/*
+ * EAC3 decoder
+ * Copyright (c) 2007 Bartlomiej Wolowiec
+ *
+ * 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
+ */
+
+#include "avcodec.h"
+#include "eac3.h"
+
+static void do_imdct_256(EAC3Context *ctx, int ch)
+{
+ int k;
+ float x[128];
+ FFTComplex z[2][64];
+ float *o_ptr = ctx->tmp_output;
+ int i;
+
+ for(i=0; i<2; i++) {
+ /* de-interleave coefficients */
+ for(k=0; k<128; k++) {
+ x[k] = ctx->transform_coeffs[ch][2*k+i];
+ }
+
+ /* run standard IMDCT */
+ ctx->imdct_256.fft.imdct_calc(&ctx->imdct_256, o_ptr, x, ctx->tmp_imdct);
+
+ /* reverse the post-rotation & reordering from standard IMDCT */
+ for(k=0; k<32; k++) {
+ z[i][32+k].re = -o_ptr[128+2*k];
+ z[i][32+k].im = -o_ptr[2*k];
+ z[i][31-k].re = o_ptr[2*k+1];
+ z[i][31-k].im = o_ptr[128+2*k+1];
+ }
+ }
+
+ /* apply AC-3 post-rotation & reordering */
+ for(k=0; k<64; k++) {
+ o_ptr[ 2*k ] = -z[0][ k].im;
+ o_ptr[ 2*k+1] = z[0][63-k].re;
+ o_ptr[128+2*k ] = -z[0][ k].re;
+ o_ptr[128+2*k+1] = z[0][63-k].im;
+ o_ptr[256+2*k ] = -z[1][ k].re;
+ o_ptr[256+2*k+1] = z[1][63-k].im;
+ o_ptr[384+2*k ] = z[1][ k].im;
+ o_ptr[384+2*k+1] = -z[1][63-k].re;
+ }
+}
+
+/**
+ * Performs Inverse MDCT transform
+ */
+void ff_eac3_do_imdct(EAC3Context *ctx)
+{
+ int ch;
+
+ for(ch=1; ch<=ctx->nfchans+ctx->lfeon; ch++) {
+ if(ctx->blksw[ch]) {
+ /* 256-point IMDCT */
+ do_imdct_256(ctx, ch);
+ } else {
+ /* 512-point IMDCT */
+ ctx->imdct_512.fft.imdct_calc(&ctx->imdct_512, ctx->tmp_output,
+ ctx->transform_coeffs[ch],
+ ctx->tmp_imdct);
+ }
+ /* apply window function, overlap/add output, save delay */
+ ctx->dsp.vector_fmul_add_add(ctx->output[ch], ctx->tmp_output,
+ ctx->window, ctx->delay[ch], 0,
+ AC3_BLOCK_SIZE, 1);
+ ctx->dsp.vector_fmul_reverse(ctx->delay[ch], ctx->tmp_output+256,
+ ctx->window, AC3_BLOCK_SIZE);
+ }
+}
+
+static int eac3_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+ uint8_t *buf, int buf_size){
+ int16_t *out_samples = (int16_t *)data;
+ EAC3Context *c = (EAC3Context *)avctx->priv_data;
+ int k, i, blk, ch;
+ GetBitContext gbc;
+
+ c->gbc = &gbc;
+ c->syncword = 0;
+ c->csnroffst = -1;
+
+ init_get_bits(&gbc, buf, buf_size*8);
+ eac3_parse_syncinfo(&gbc, c);
+
+ if(c->syncword != 0x0B77)
+ return -1;
+
+ if(eac3_parse_bsi(&gbc, c) || eac3_parse_audfrm(&gbc, c))
+ return -1;
+
+ if(c->fscod == 3){
+ assert(c->fscod != 3);
+ avctx->sample_rate = ff_ac3_freqs[c->fscod2] / 2;
+ }else{
+ avctx->sample_rate = ff_ac3_freqs[c->fscod];
+ }
+
+
+ avctx->bit_rate = (c->frmsiz * (avctx->sample_rate) * 16 / ( ff_eac3_blocks[c->numblkscod] * 256)) / 1000;
+#ifdef DEBUG
+ av_log(NULL, AV_LOG_INFO, "bitrate = %i\n", avctx->bit_rate);
+#endif
+ avctx->channels = c->nfchans + c->lfeon; // TODO lfe
+
+ for(blk = 0; blk < ff_eac3_blocks[c->numblkscod]; blk++)
+ {
+ for(i=0; i<AC3_MAX_CHANNELS+1; i++){
+ c->deltbae[i] = DBA_NONE;
+ c->deltnseg[i] = 0;
+ }
+#ifdef DEBUG
+ av_log(NULL, AV_LOG_INFO, "-------START BLK-------\n");
+#endif
+ if(eac3_parse_audblk(&gbc, c, blk)){
+ return -1;
+ }
+#ifdef DEBUG
+ av_log(NULL, AV_LOG_INFO, "-------END BLK-------\n");
+#endif
+ //TODO rematrixing
+ //TODO downmix_scaling...
+ //TODO scale
+
+ ff_eac3_do_imdct(c);
+ //TODO downmix
+
+#ifdef DEBUG
+ av_log(avctx, AV_LOG_INFO, "channels = %i\n", avctx->channels);
+#endif
+
+ // set output mode
+ c->blkoutput = 0;
+ if (avctx->channels == 1) {
+ c->blkoutput |= AC3_OUTPUT_MONO;
+ } else if (avctx->channels == 2) {
+ c->blkoutput |= AC3_OUTPUT_STEREO;
+ } else {
+ if (avctx->channels && avctx->channels < c->nfchans + c->lfeon )
+ av_log(avctx, AV_LOG_INFO, "ac3_decoder: E-AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",avctx->channels, c->nfchans + c->lfeon);
+ c->blkoutput |= AC3_OUTPUT_UNMODIFIED;
+ if (c->lfeon)
+ c->blkoutput |= AC3_OUTPUT_LFEON;
+ avctx->channels = c->nfchans + c->lfeon;
+ }
+
+
+ // convert float to 16-bit integer
+ for(ch = 1; ch<=c->nfchans + c->lfeon; ch++) { // <- out_channels TODO
+ for(i=0; i<AC3_BLOCK_SIZE; i++) {
+ c->output[ch][i] = c->output[ch][i] * c->mul_bias
+ c->add_bias;
+ }
+ c->dsp.float_to_int16(c->int_output[ch], c->output[ch],
+ AC3_BLOCK_SIZE);
+ }
+ for (k = 0; k < AC3_BLOCK_SIZE; k++) {
+ for (i = 1; i <= avctx->channels; i++) {
+ *(out_samples++) = c->int_output[i][k];
+ }
+ }
+
+ }
+
+#ifdef DEBUG
+ av_log(NULL, AV_LOG_INFO, "--------------------------------------------------------------------------\n");
+#endif
+
+ *data_size = ff_eac3_blocks[c->numblkscod] * 256 * avctx->channels * sizeof (int16_t); // TODO is ok?
+
+ return buf_size;
+}
+
+static int eac3_decode_init(AVCodecContext *avctx){
+ int ch;
+ EAC3Context *ctx = avctx->priv_data;
+
+ ff_ac3_decoder_tables_init();
+ ac3_common_init();
+ av_init_random(0, &ctx->dith_state);
+ ff_mdct_init(&ctx->imdct_256, 8, 1);
+ ff_mdct_init(&ctx->imdct_512, 9, 1);
+ dsputil_init(&ctx->dsp, avctx);
+ if(ctx->dsp.float_to_int16 == ff_float_to_int16_c) {
+ ctx->add_bias = 385.0f;
+ ctx->mul_bias = 1.0f;
+ } else {
+ ctx->add_bias = 0.0f;
+ ctx->mul_bias = 32767.0f;
+ }
+ ff_ac3_window_init(ctx->window);
+ for(ch=0; ch<AC3_MAX_CHANNELS; ch++) {
+ memset(ctx->delay[ch], 0, sizeof(ctx->delay[ch]));
+ }
+ memset(ctx->strtmant, 0, sizeof(int)*MAX_CHANNELS);
+ return 0;
+}
+
+static int eac3_decode_end(AVCodecContext *avctx){
+ EAC3Context *ctx = avctx->priv_data;
+ ff_mdct_end(&ctx->imdct_512);
+ ff_mdct_end(&ctx->imdct_256);
+
+ return 0;
+}
+
+AVCodec eac3_decoder = {
+ .name = "E-AC3",
+ .type = CODEC_TYPE_AUDIO,
+ .id = CODEC_ID_EAC3,
+ .priv_data_size = sizeof (EAC3Context),
+ .init = eac3_decode_init,
+ .close = eac3_decode_end,
+ .decode = eac3_decode_frame,
+
+};
Added: eac3/ffmpeg.patch
==============================================================================
--- (empty file)
+++ eac3/ffmpeg.patch Sat Jul 7 16:04:27 2007
@@ -0,0 +1,167 @@
+Index: libavcodec/Makefile
+===================================================================
+--- libavcodec/Makefile (wersja 9211)
++++ libavcodec/Makefile (kopia robocza)
+@@ -66,6 +66,7 @@
+ OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o
+ OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o
+ OBJS-$(CONFIG_DXA_DECODER) += dxa.o
++OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_parser.o
+ OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o
+ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o golomb.o
+ OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o
+Index: libavcodec/aac_ac3_parser.c
+===================================================================
+--- libavcodec/aac_ac3_parser.c (wersja 9211)
++++ libavcodec/aac_ac3_parser.c (kopia robocza)
+@@ -48,7 +48,7 @@
+ s->inbuf_ptr += len;
+ buf_size -= len;
+ if ((s->inbuf_ptr - s->inbuf) == s->header_size) {
+- len = s->sync(s->inbuf, &channels, &sample_rate, &bit_rate,
++ len = s->sync(avctx, s->inbuf, &channels, &sample_rate, &bit_rate,
+ &samples);
+ if (len == 0) {
+ /* no sync found : move by one byte (inefficient, but simple!) */
+Index: libavcodec/aac_ac3_parser.h
+===================================================================
+--- libavcodec/aac_ac3_parser.h (wersja 9211)
++++ libavcodec/aac_ac3_parser.h (kopia robocza)
+@@ -27,7 +27,7 @@
+ uint8_t *inbuf_ptr;
+ int frame_size;
+ int header_size;
+- int (*sync)(const uint8_t *buf, int *channels, int *sample_rate,
++ int (*sync)(AVCodecContext *avctx, const uint8_t *buf, int *channels, int *sample_rate,
+ int *bit_rate, int *samples);
+ uint8_t inbuf[8192]; /* input buffer */
+ } AACAC3ParseContext;
+Index: libavcodec/aac_parser.c
+===================================================================
+--- libavcodec/aac_parser.c (wersja 9211)
++++ libavcodec/aac_parser.c (kopia robocza)
+@@ -38,7 +38,7 @@
+ };
+
+
+-static int aac_sync(const uint8_t *buf, int *channels, int *sample_rate,
++static int aac_sync(AVCodecContext *avctx, const uint8_t *buf, int *channels, int *sample_rate,
+ int *bit_rate, int *samples)
+ {
+ GetBitContext bits;
+Index: libavcodec/allcodecs.c
+===================================================================
+--- libavcodec/allcodecs.c (wersja 9211)
++++ libavcodec/allcodecs.c (kopia robocza)
+@@ -171,6 +171,7 @@
+ REGISTER_DECODER(COOK, cook);
+ REGISTER_DECODER(DCA, dca);
+ REGISTER_DECODER(DSICINAUDIO, dsicinaudio);
++ REGISTER_DECODER(EAC3, eac3);
+ REGISTER_ENCDEC (FLAC, flac);
+ REGISTER_DECODER(IMC, imc);
+ REGISTER_ENCDEC (LIBAMR_NB, libamr_nb);
+@@ -260,6 +261,7 @@
+ /* parsers */
+ REGISTER_PARSER (AAC, aac);
+ REGISTER_PARSER (AC3, ac3);
++ REGISTER_PARSER (EAC3, eac3);
+ REGISTER_PARSER (CAVSVIDEO, cavsvideo);
+ REGISTER_PARSER (DCA, dca);
+ REGISTER_PARSER (DVBSUB, dvbsub);
+Index: libavcodec/avcodec.h
+===================================================================
+--- libavcodec/avcodec.h (wersja 9211)
++++ libavcodec/avcodec.h (kopia robocza)
+@@ -222,6 +222,7 @@
+ CODEC_ID_MPEG4AAC,
+ #endif
+ CODEC_ID_AC3,
++ CODEC_ID_EAC3,
+ CODEC_ID_DTS,
+ CODEC_ID_VORBIS,
+ CODEC_ID_DVAUDIO,
+@@ -2261,6 +2262,7 @@
+ extern AVCodec dsicinvideo_decoder;
+ extern AVCodec dvvideo_decoder;
+ extern AVCodec dxa_decoder;
++extern AVCodec eac3_decoder;
+ extern AVCodec eightbps_decoder;
+ extern AVCodec ffv1_decoder;
+ extern AVCodec ffvhuff_decoder;
+@@ -3021,6 +3023,7 @@
+ extern AVCodecParser dca_parser;
+ extern AVCodecParser dvbsub_parser;
+ extern AVCodecParser dvdsub_parser;
++extern AVCodecParser eac3_parser;
+ extern AVCodecParser h261_parser;
+ extern AVCodecParser h263_parser;
+ extern AVCodecParser h264_parser;
+Index: libavcodec/Makefile
+===================================================================
+--- libavcodec/Makefile (wersja 9211)
++++ libavcodec/Makefile (kopia robocza)
+@@ -66,6 +66,7 @@
+ OBJS-$(CONFIG_DVVIDEO_DECODER) += dv.o
+ OBJS-$(CONFIG_DVVIDEO_ENCODER) += dv.o
+ OBJS-$(CONFIG_DXA_DECODER) += dxa.o
++OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_parser.o
+ OBJS-$(CONFIG_EIGHTBPS_DECODER) += 8bps.o
+ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o golomb.o
+ OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o
+Index: libavformat/allformats.c
+===================================================================
+--- libavformat/allformats.c (wersja 9211)
++++ libavformat/allformats.c (kopia robocza)
+@@ -72,6 +72,7 @@
+ REGISTER_DEMUXER (DV1394, dv1394);
+ REGISTER_DEMUXER (DXA, dxa);
+ REGISTER_DEMUXER (EA, ea);
++ REGISTER_DEMUXER (AC3, ac3);
+ REGISTER_MUXDEMUX(FFM, ffm);
+ REGISTER_MUXDEMUX(FLAC, flac);
+ REGISTER_DEMUXER (FLIC, flic);
+Index: libavformat/allformats.h
+===================================================================
+--- libavformat/allformats.h (wersja 9211)
++++ libavformat/allformats.h (kopia robocza)
+@@ -43,6 +43,7 @@
+ extern AVInputFormat dv_demuxer;
+ extern AVInputFormat dxa_demuxer;
+ extern AVInputFormat ea_demuxer;
++extern AVInputFormat eac3_demuxer;
+ extern AVInputFormat ffm_demuxer;
+ extern AVInputFormat flac_demuxer;
+ extern AVInputFormat flic_demuxer;
+Index: libavformat/raw.c
+===================================================================
+--- libavformat/raw.c (wersja 9211)
++++ libavformat/raw.c (kopia robocza)
+@@ -440,6 +440,7 @@
+ if(buf == p->buf)
+ first_frames = frames;
+ }
++ av_log(NULL, AV_LOG_INFO, "first_frames = %i max_frames = %i\n", first_frames, max_frames);
+ if (first_frames>=3) return AVPROBE_SCORE_MAX * 3 / 4;
+ else if(max_frames>=3) return AVPROBE_SCORE_MAX / 2;
+ else if(max_frames>=1) return 1;
+@@ -499,6 +500,19 @@
+ .extensions = "ac3",
+ };
+ #endif
++#ifdef CONFIG_EAC3_DEMUXER
++AVInputFormat eac3_demuxer = {
++ "eac3",
++ "raw ac3",
++ 0,
++ ac3_probe,
++ ac3_read_header,
++ raw_read_partial_packet,
++ raw_read_close,
++ .flags= AVFMT_GENERIC_INDEX,
++ .extensions = "ac3",
++};
++#endif
+
+ #ifdef CONFIG_MUXERS
+ AVOutputFormat ac3_muxer = {
More information about the FFmpeg-soc
mailing list