[FFmpeg-cvslog] r9653 - trunk/libavcodec/ac3dec.c
jbr
subversion
Sat Jul 14 17:42:15 CEST 2007
Author: jbr
Date: Sat Jul 14 17:42:15 2007
New Revision: 9653
Log:
AC-3 decoder, soc revision 31, Jul 14 23:53:28 2006 UTC by cloud9
Removed _ from names
Removed temporary storage for the exponents
Removed ctx->samples
Now each transform coefficients are stored in audio block as an array of transform coefficients for each channel
added ctx->delay (output of later half of previous block)
added audio_block->block_output(output of this block)
Modified:
trunk/libavcodec/ac3dec.c
Modified: trunk/libavcodec/ac3dec.c
==============================================================================
--- trunk/libavcodec/ac3dec.c (original)
+++ trunk/libavcodec/ac3dec.c Sat Jul 14 17:42:15 2007
@@ -34,6 +34,10 @@
#include "avutil.h"
#include "common.h"
+#define MAX_CHANNELS 6
+#define MAX_BLOCK_SIZE 256
+#define MAX_BLOCKS 6
+
/* Synchronization information. */
typedef struct {
uint16_t sync_word; //synchronization word = always 0x0b77
@@ -44,6 +48,7 @@ typedef struct {
/* Derived Attributes */
int sampling_rate; //sampling rate - 48, 44.1 or 32 kHz (value in Hz)
int bit_rate; //nominal bit rate (value in kbps)
+ int framesize; //frame size - 16 bit words
} ac3_sync_info;
/* flags for the BSI. */
@@ -146,10 +151,7 @@ typedef struct {
uint8_t lfeexpstr; //lfe exponent strategy
uint8_t chbwcod[5]; //channel bandwdith code for channels in use
uint8_t cplabsexp; //coupling absolute exponent
- uint8_t cplexps[72]; //coupling exponents
- uint8_t exps[5][88]; //channel exponents
uint8_t gainrng[5]; //gain range
- uint8_t lfeexps[3]; //LFE exponents
uint8_t sdcycod; //slow decay code
uint8_t fdcycod; //fast decay code
uint8_t sgaincod; //slow gain code
@@ -196,8 +198,10 @@ typedef struct {
uint8_t bap[5][256]; //fbw channels bit allocation parameters table
uint8_t lfebap[256]; //lfe bit allocaiton parameters table
- float cplcoeffs[256]; //temporary storage for coupling transform coefficients
- float cplco[5][18]; //coupling co-ordinates
+ DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][MAX_BLOCK_SIZE]); //transform coefficients
+ DECLARE_ALIGNED_16(float, cplcoeffs[256]); //temporary storage for coupling transform coefficients
+ DECLARE_ALIGNED_16(float, block_output[MAX_CHANNELS][MAX_BLOCK_SIZE]);
+ float cplco[5][18]; //coupling coordinates
float chcoeffs[6]; //channel coefficients for downmix
} ac3_audio_block;
@@ -281,28 +285,41 @@ typedef struct {
ac3_sync_info sync_info;
ac3_bsi bsi;
ac3_audio_block audio_block;
- float *samples;
- int output;
dither_state state;
MDCTContext imdct_ctx_256;
MDCTContext imdct_ctx_512;
GetBitContext gb;
+ int output;
+ DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][MAX_BLOCK_SIZE]);
+ DECLARE_ALIGNED_16(FFTSample, tmp_imdct[MAX_BLOCK_SIZE * 2]);
+ DECLARE_ALIGNED_16(FFTSample, tmp_output[MAX_BLOCK_SIZE * 2]);
} AC3DecodeContext;
+static void ac3_common_init1(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 = bndsz[i];
+ for(j=0;j<v;j++) masktab[k++]=i;
+ l += v;
+ }
+ masktab[253] = masktab[254] = masktab[255] = 0;
+ bndtab[50] = 0;
+}
+
static int ac3_decode_init(AVCodecContext *avctx)
{
AC3DecodeContext *ctx = avctx->priv_data;
- ac3_common_init();
+ ac3_common_init1();
ff_mdct_init(&ctx->imdct_ctx_256, 8, 1);
ff_mdct_init(&ctx->imdct_ctx_512, 9, 1);
- ctx->samples = av_mallocz(6 * 256 * sizeof (float));
- if (!ctx->samples) {
- av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory for samples\n");
- return -1;
- }
dither_seed(&ctx->state, 0);
return 0;
@@ -323,19 +340,39 @@ static int ac3_synchronize(uint8_t *buf,
static int ac3_parse_sync_info(AC3DecodeContext *ctx)
{
ac3_sync_info *sync_info = &ctx->sync_info;
+ ac3_bsi *bsi = &ctx->bsi;
GetBitContext *gb = &ctx->gb;
sync_info->sync_word = get_bits(gb, 16);
sync_info->crc1 = get_bits(gb, 16);
sync_info->fscod = get_bits(gb, 2);
if (sync_info->fscod == 0x03)
- return -1;
+ return 0;
sync_info->frmsizecod = get_bits(gb, 6);
- if (sync_info->frmsizecod >= 0x38)
- return -1;
+ if (sync_info->frmsizecod >= 38)
+ return 0;
sync_info->sampling_rate = ac3_freqs[sync_info->fscod];
sync_info->bit_rate = ac3_bitratetab[sync_info->frmsizecod >> 1];
+ /* we include it here in order to determine validity of ac3 frame */
+ bsi->bsid = get_bits(gb, 5);
+ if (bsi->bsid > 0x08)
+ return 0;
+ bsi->bsmod = get_bits(gb, 3);
+
+ switch (sync_info->fscod) {
+ case 0x00:
+ sync_info->framesize = 4 * sync_info->bit_rate;
+ return sync_info->framesize;
+ case 0x01:
+ sync_info->framesize = 2 * (320 * sync_info->bit_rate / 147 + (sync_info->frmsizecod & 1));
+ return sync_info->framesize;
+ case 0x02:
+ sync_info->framesize = 6 * sync_info->bit_rate;
+ return sync_info->framesize;
+ }
+
+ /* never reached */
return 0;
}
@@ -345,16 +382,19 @@ static int ac3_parse_bsi(AC3DecodeContex
ac3_bsi *bsi = &ctx->bsi;
uint32_t *flags = &bsi->flags;
GetBitContext *gb = &ctx->gb;
+ int i;
*flags = 0;
bsi->cmixlev = 0;
bsi->surmixlev = 0;
bsi->dsurmod = 0;
+ ctx->audio_block.cpldeltbae = AC3_DBASTR_NONE;
+ ctx->audio_block.cpldeltnseg = 0;
+ for (i = 0; i < 5; i++) {
+ ctx->audio_block.deltbae[i] = AC3_DBASTR_NONE;
+ ctx->audio_block.deltnseg[i] = 0;
+ }
- bsi->bsid = get_bits(gb, 5);
- if (bsi->bsid > 0x08)
- return -1;
- bsi->bsmod = get_bits(gb, 3);
bsi->acmod = get_bits(gb, 3);
if (bsi->acmod & 0x01 && bsi->acmod != 0x01)
bsi->cmixlev = get_bits(gb, 2);
@@ -362,56 +402,55 @@ static int ac3_parse_bsi(AC3DecodeContex
bsi->surmixlev = get_bits(gb, 2);
if (bsi->acmod == 0x02)
bsi->dsurmod = get_bits(gb, 2);
- if (get_bits(gb, 1))
+ if (get_bits1(gb))
*flags |= AC3_BSI_LFEON;
bsi->dialnorm = get_bits(gb, 5);
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_COMPRE;
- bsi->compr = get_bits(gb, 5);
+ bsi->compr = get_bits(gb, 8);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_LANGCODE;
bsi->langcod = get_bits(gb, 8);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_AUDPRODIE;
bsi->mixlevel = get_bits(gb, 5);
bsi->roomtyp = get_bits(gb, 2);
}
if (bsi->acmod == 0x00) {
bsi->dialnorm2 = get_bits(gb, 5);
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_COMPR2E;
- bsi->compr2 = get_bits(gb, 5);
+ bsi->compr2 = get_bits(gb, 8);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_LANGCOD2E;
bsi->langcod2 = get_bits(gb, 8);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_AUDPRODIE;
bsi->mixlevel2 = get_bits(gb, 5);
bsi->roomtyp2 = get_bits(gb, 2);
}
}
- if (get_bits(gb, 1))
+ if (get_bits1(gb))
*flags |= AC3_BSI_COPYRIGHTB;
- if (get_bits(gb, 1))
+ if (get_bits1(gb))
*flags |= AC3_BSI_ORIGBS;
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_TIMECOD1E;
bsi->timecod1 = get_bits(gb, 14);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_TIMECOD2E;
bsi->timecod2 = get_bits(gb, 14);
}
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_BSI_ADDBSIE;
bsi->addbsil = get_bits(gb, 6);
- do {
- get_bits(gb, 8);
- } while (bsi->addbsil--);
+ for (i = 0; i < (bsi->addbsil + 1); i++)
+ skip_bits(gb, 8);
}
bsi->nfchans = nfchans_tbl[bsi->acmod];
@@ -419,21 +458,23 @@ static int ac3_parse_bsi(AC3DecodeContex
return 0;
}
- /* Decodes the grouped exponents (gexps) and stores them
+ /* Decodes the grouped exponents and stores them
* in decoded exponents (dexps).
* The code is derived from liba52.
* Uses liba52 tables.
*/
-static int _decode_exponents(int expstr, int ngrps, uint8_t absexp, uint8_t *gexps, uint8_t *dexps)
+static int decode_exponents(GetBitContext *gb, int expstr, int ngrps, uint8_t absexp, uint8_t *dexps)
{
int exps;
- int i = 0;
while (ngrps--) {
- exps = gexps[i++];
+ exps = get_bits(gb, 7);
absexp += exp_1[exps];
- assert(absexp <= 24);
+ if (absexp > 24) {
+ av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps);
+ return -ngrps;
+ }
switch (expstr) {
case AC3_EXPSTR_D45:
*(dexps++) = absexp;
@@ -443,8 +484,12 @@ static int _decode_exponents(int expstr,
case AC3_EXPSTR_D15:
*(dexps++) = absexp;
}
+
absexp += exp_2[exps];
- assert(absexp <= 24);
+ if (absexp > 24) {
+ av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps);
+ return -ngrps;
+ }
switch (expstr) {
case AC3_EXPSTR_D45:
*(dexps++) = absexp;
@@ -456,7 +501,10 @@ static int _decode_exponents(int expstr,
}
absexp += exp_3[exps];
- assert(absexp <= 24);
+ if (absexp > 24) {
+ av_log(NULL, AV_LOG_ERROR, "Absolute Exponent > 24, ngrp = %d\n", ngrps);
+ return -ngrps;
+ }
switch (expstr) {
case AC3_EXPSTR_D45:
*(dexps++) = absexp;
@@ -471,39 +519,20 @@ static int _decode_exponents(int expstr,
return 0;
}
-static int decode_exponents(AC3DecodeContext *ctx)
+static inline int logadd(int a, int b)
{
- ac3_audio_block *ab = &ctx->audio_block;
- int i;
- uint8_t *exps;
- uint8_t *dexps;
-
- if (ab->flags & AC3_AB_CPLINU && ab->cplexpstr != AC3_EXPSTR_REUSE)
- if (_decode_exponents(ab->cplexpstr, ab->ncplgrps, ab->cplabsexp,
- ab->cplexps, ab->dcplexps + ab->cplstrtmant))
- return -1;
- for (i = 0; i < ctx->bsi.nfchans; i++)
- if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) {
- exps = ab->exps[i];
- dexps = ab->dexps[i];
- if (_decode_exponents(ab->chexpstr[i], ab->nchgrps[i], exps[0], exps + 1, dexps + 1))
- return -1;
- }
- if (ctx->bsi.flags & AC3_BSI_LFEON && ab->lfeexpstr != AC3_EXPSTR_REUSE)
- if (_decode_exponents(ab->lfeexpstr, 2, ab->lfeexps[0], ab->lfeexps + 1, ab->dlfeexps))
- return -1;
- return 0;
-}
+ int c = a - b;
+ int address;
-static inline int16_t logadd(int16_t a, int16_t b)
-{
- int16_t c = a - b;
- uint8_t address = FFMIN((ABS(c) >> 1), 255);
+ address = FFMIN(ABS(c) >> 1, 255);
- return ((c >= 0) ? (a + latab[address]) : (b + latab[address]));
+ if (c >= 0)
+ return (a + latab[address]);
+ else
+ return (b + latab[address]);
}
-static inline int16_t calc_lowcomp(int16_t a, int16_t b0, int16_t b1, uint8_t bin)
+static inline int calc_lowcomp(int a, int b0, int b1, int bin)
{
if (bin < 7) {
if ((b0 + 256) == b1)
@@ -517,9 +546,8 @@ static inline int16_t calc_lowcomp(int16
else if (b0 > b1)
a = FFMAX(0, a - 64);
}
- else {
+ else
a = FFMAX(0, a - 128);
- }
return a;
}
@@ -529,15 +557,16 @@ static inline int16_t calc_lowcomp(int16
* chnl = 5 coupling channel
* chnl = 6 lfe channel
*/
-static int _do_bit_allocation(AC3DecodeContext *ctx, int chnl)
+static void do_bit_allocation1(AC3DecodeContext *ctx, int chnl)
{
ac3_audio_block *ab = &ctx->audio_block;
- int16_t sdecay, fdecay, sgain, dbknee, floor;
- int16_t lowcomp, fgain, snroffset, fastleak, slowleak;
- int16_t psd[256], bndpsd[50], excite[50], mask[50], delta;
- uint8_t start, end, bin, i, j, k, lastbin, bndstrt, bndend, begin, deltnseg, band, seg, address;
- uint8_t fscod = ctx->sync_info.fscod;
- uint8_t *exps, *deltoffst, *deltlen, *deltba;
+ int sdecay, fdecay, sgain, dbknee, floor;
+ int lowcomp = 0, fgain = 0, snroffset = 0, fastleak = 0, slowleak = 0;
+ int psd[256], bndpsd[50], excite[50], mask[50], delta;
+ int start = 0, end = 0, bin = 0, i = 0, j = 0, k = 0, lastbin = 0, bndstrt = 0;
+ int bndend = 0, begin = 0, deltnseg = 0, band = 0, seg = 0, address = 0;
+ int fscod = ctx->sync_info.fscod;
+ uint8_t *exps, *deltoffst = 0, *deltlen = 0, *deltba = 0;
uint8_t *baps;
int do_delta = 0;
@@ -557,7 +586,7 @@ static int _do_bit_allocation(AC3DecodeC
slowleak = (ab->cplsleak << 8) + 768;
exps = ab->dcplexps;
baps = ab->cplbap;
- if (ab->cpldeltbae == 0 || ab->cpldeltbae == 1) {
+ if (ab->cpldeltbae == AC3_DBASTR_NEW || ab->cpldeltbae == AC3_DBASTR_REUSE) {
do_delta = 1;
deltnseg = ab->cpldeltnseg;
deltoffst = ab->cpldeltoffst;
@@ -569,6 +598,8 @@ static int _do_bit_allocation(AC3DecodeC
start = 0;
end = 7;
lowcomp = 0;
+ fastleak = 0;
+ slowleak = 0;
fgain = fgaintab[ab->lfefgaincod];
snroffset = (((ab->csnroffst - 15) << 4) + ab->lfefsnroffst) << 2;
exps = ab->dlfeexps;
@@ -578,11 +609,13 @@ static int _do_bit_allocation(AC3DecodeC
start = 0;
end = ab->endmant[chnl];
lowcomp = 0;
+ fastleak = 0;
+ slowleak = 0;
fgain = fgaintab[ab->fgaincod[chnl]];
snroffset = (((ab->csnroffst - 15) << 4) + ab->fsnroffst[chnl]) << 2;
exps = ab->dexps[chnl];
baps = ab->bap[chnl];
- if (ab->deltbae[chnl] == 0 || ab->deltbae[chnl] == 1) {
+ if (ab->deltbae[chnl] == AC3_DBASTR_NEW || ab->deltbae[chnl] == AC3_DBASTR_REUSE) {
do_delta = 1;
deltnseg = ab->deltnseg[chnl];
deltoffst = ab->deltoffst[chnl];
@@ -592,7 +625,7 @@ static int _do_bit_allocation(AC3DecodeC
}
for (bin = start; bin < end; bin++) /* exponent mapping into psd */
- psd[bin] = (3072 - ((int16_t) (exps[bin] << 7)));
+ psd[bin] = (3072 - ((int)(exps[bin]) << 7));
/* psd integration */
j = start;
@@ -629,7 +662,7 @@ static int _do_bit_allocation(AC3DecodeC
break;
}
}
- for (bin = begin; bin < (FFMIN(bndend, 22)); bin++) {
+ for (bin = begin; bin < FFMIN(bndend, 22); bin++) {
if (bndend != 7 || bin != 6)
lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin);
fastleak -= fdecay;
@@ -662,12 +695,12 @@ static int _do_bit_allocation(AC3DecodeC
if (do_delta) {
band = 0;
for (seg = 0; seg < deltnseg + 1; seg++) {
- band += deltoffst[seg];
- if (deltba[seg] >= 4)
- delta = (deltba[seg] - 3) << 7;
+ band += (int)(deltoffst[seg]);
+ if ((int)(deltba[seg]) >= 4)
+ delta = ((int)(deltba[seg]) - 3) << 7;
else
- delta = (deltba[seg] - 4) << 7;
- for (k = 0; k < deltlen[seg]; k++) {
+ delta = ((int)(deltba[seg]) - 4) << 7;
+ for (k = 0; k < (int)(deltlen[seg]); k++) {
mask[band] += delta;
band++;
}
@@ -687,23 +720,21 @@ static int _do_bit_allocation(AC3DecodeC
mask[j] += floor;
for (k = i; k < lastbin; k++) {
address = (psd[i] - mask[j]) >> 5;
- address = FFMIN(63, (FFMAX(0, address)));
+ address = FFMIN(63, FFMAX(0, address));
baps[i] = baptab[address];
i++;
}
j++;
} while (end > lastbin);
-
- return 0;
}
-static int do_bit_allocation(AC3DecodeContext *ctx, int flags)
+static void do_bit_allocation(AC3DecodeContext *ctx, int flags)
{
ac3_audio_block *ab = &ctx->audio_block;
int i, snroffst = 0;
if (!flags) /* bit allocation is not required */
- return 0;
+ return;
if (ab->flags & AC3_AB_SNROFFSTE) { /* check whether snroffsts are zero */
snroffst += ab->csnroffst;
@@ -719,23 +750,18 @@ static int do_bit_allocation(AC3DecodeCo
memset(ab->bap[i], 0, sizeof (ab->bap[i]));
memset(ab->lfebap, 0, sizeof (ab->lfebap));
- return 0;
+ return;
}
}
/* perform bit allocation */
if ((ab->flags & AC3_AB_CPLINU) && (flags & 64))
- if (_do_bit_allocation(ctx, 5))
- return -1;
+ do_bit_allocation1(ctx, 5);
for (i = 0; i < ctx->bsi.nfchans; i++)
if (flags & (1 << i))
- if (_do_bit_allocation(ctx, i))
- return -1;
+ do_bit_allocation1(ctx, i);
if ((ctx->bsi.flags & AC3_BSI_LFEON) && (flags & 32))
- if (_do_bit_allocation(ctx, 6))
- return -1;
-
- return 0;
+ do_bit_allocation1(ctx, 6);
}
static inline float to_float(uint8_t exp, int16_t mantissa)
@@ -749,8 +775,8 @@ typedef struct { /* grouped mantissas fo
} mant_group;
/* Get the transform coefficients for particular channel */
-static int _get_transform_coeffs(uint8_t *exps, uint8_t *bap, float chcoeff,
- float *samples, int start, int end, int dith_flag, GetBitContext *gb,
+static int get_transform_coeffs1(uint8_t *exps, uint8_t *bap, float chcoeff,
+ float *coeffs, int start, int end, int dith_flag, GetBitContext *gb,
dither_state *state)
{
int16_t mantissa;
@@ -765,21 +791,24 @@ static int _get_transform_coeffs(uint8_t
i = 0;
while (i < start)
- samples[i++] = 0;
+ coeffs[i++] = 0;
for (i = start; i < end; i++) {
switch (bap[i]) {
case 0:
- if (!dith_flag)
- mantissa = 0;
- else
+ if (!dith_flag) {
+ coeffs[i] = 0;
+ continue;
+ }
+ else {
mantissa = dither_int16(state);
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
+ }
case 1:
if (l3_grp.gcptr > 2) {
- gcode = get_bits(gb, qntztab[1]);
+ gcode = get_bits(gb, 5);
if (gcode > 26)
return -1;
l3_grp.gcodes[0] = gcode / 9;
@@ -788,12 +817,12 @@ static int _get_transform_coeffs(uint8_t
l3_grp.gcptr = 0;
}
mantissa = l3_q_tab[l3_grp.gcodes[l3_grp.gcptr++]];
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
case 2:
if (l5_grp.gcptr > 2) {
- gcode = get_bits(gb, qntztab[2]);
+ gcode = get_bits(gb, 7);
if (gcode > 124)
return -1;
l5_grp.gcodes[0] = gcode / 25;
@@ -802,116 +831,101 @@ static int _get_transform_coeffs(uint8_t
l5_grp.gcptr = 0;
}
mantissa = l5_q_tab[l5_grp.gcodes[l5_grp.gcptr++]];
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
case 3:
- mantissa = get_bits(gb, qntztab[3]);
+ mantissa = get_bits(gb, 3);
if (mantissa > 6)
return -1;
mantissa = l7_q_tab[mantissa];
- samples[i] = to_float(exps[i], mantissa);
- break;
+ coeffs[i] = to_float(exps[i], mantissa);
+ continue;
case 4:
if (l11_grp.gcptr > 1) {
- gcode = get_bits(gb, qntztab[4]);
+ gcode = get_bits(gb, 7);
if (gcode > 120)
return -1;
l11_grp.gcodes[0] = gcode / 11;
l11_grp.gcodes[1] = gcode % 11;
}
mantissa = l11_q_tab[l11_grp.gcodes[l11_grp.gcptr++]];
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
case 5:
- mantissa = get_bits(gb, qntztab[5]);
+ mantissa = get_bits(gb, 4);
if (mantissa > 14)
return -1;
mantissa = l15_q_tab[mantissa];
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
default:
mantissa = get_bits(gb, qntztab[bap[i]]) << (16 - qntztab[bap[i]]);
- samples[i] = to_float(exps[i], mantissa) * chcoeff;
- break;
+ coeffs[i] = to_float(exps[i], mantissa) * chcoeff;
+ continue;
}
}
i = end;
while (i < 256)
- samples[i++] = 0;
+ coeffs[i++] = 0;
return 0;
}
-static int uncouple_channels(AC3DecodeContext * ctx)
+static void uncouple_channels(AC3DecodeContext * ctx)
{
ac3_audio_block *ab = &ctx->audio_block;
int ch, sbnd, bin;
int index;
- float (*samples)[256];
int16_t mantissa;
- samples = (float (*)[256])((ctx->bsi.flags & AC3_BSI_LFEON) ? (ctx->samples + 256) : (ctx->samples));
-
/* uncouple channels */
for (ch = 0; ch < ctx->bsi.nfchans; ch++)
if (ab->chincpl & (1 << ch))
for (sbnd = ab->cplbegf; sbnd < 3 + ab->cplendf; sbnd++)
for (bin = 0; bin < 12; bin++) {
index = sbnd * 12 + bin + 37;
- samples[ch][index] = ab->cplcoeffs[index] * ab->cplco[ch][sbnd] * ab->chcoeffs[ch];
- }
-
- /* generate dither if required */
- for (ch = 0; ch < ctx->bsi.nfchans; ch++)
- if ((ab->chincpl & (1 << ch)) && (ab->dithflag & (1 << ch)))
- for (index = 0; index < ab->endmant[ch]; index++)
- if (!ab->bap[ch][index]) {
- mantissa = dither_int16(&ctx->state);
- samples[ch][index] = to_float(ab->dexps[ch][index], mantissa) * ab->chcoeffs[ch];
+ ab->transform_coeffs[ch + 1][index] = ab->cplcoeffs[index] * ab->cplco[ch][sbnd] * ab->chcoeffs[ch];
+ /* generate dither if required */
+ if (!ab->bap[ch][index] && (ab->chincpl & (1 << ch)) && (ab->dithflag & (1 << ch))) {
+ mantissa = dither_int16(&ctx->state);
+ ab->transform_coeffs[ch + 1][index] = to_float(ab->dexps[ch][index], mantissa) * ab->chcoeffs[ch];
+ }
}
-
- return 0;
}
static int get_transform_coeffs(AC3DecodeContext * ctx)
{
int i;
ac3_audio_block *ab = &ctx->audio_block;
- float *samples = ctx->samples;
int got_cplchan = 0;
int dithflag = 0;
- samples += (ctx->bsi.flags & AC3_BSI_LFEON) ? 256 : 0;
for (i = 0; i < ctx->bsi.nfchans; i++) {
- if ((ab->flags & AC3_AB_CPLINU) && (ab->chincpl & (1 << i)))
- dithflag = 0; /* don't generate dither until channels are decoupled */
- else
- dithflag = ab->dithflag & (1 << i);
+ dithflag = ab->dithflag & (1 << i);
/* transform coefficients for individual channel */
- if (_get_transform_coeffs(ab->dexps[i], ab->bap[i], ab->chcoeffs[i], samples + (i * 256),
+ if (get_transform_coeffs1(ab->dexps[i], ab->bap[i], ab->chcoeffs[i], ab->transform_coeffs[i + 1],
0, ab->endmant[i], dithflag, &ctx->gb, &ctx->state))
return -1;
/* tranform coefficients for coupling channels */
if ((ab->flags & AC3_AB_CPLINU) && (ab->chincpl & (1 << i)) && !got_cplchan) {
- if (_get_transform_coeffs(ab->dcplexps, ab->cplbap, 1.0f, ab->cplcoeffs,
+ if (get_transform_coeffs1(ab->dcplexps, ab->cplbap, 1.0f, ab->cplcoeffs,
ab->cplstrtmant, ab->cplendmant, 0, &ctx->gb, &ctx->state))
return -1;
got_cplchan = 1;
}
}
if (ctx->bsi.flags & AC3_BSI_LFEON)
- if (_get_transform_coeffs(ab->lfeexps, ab->lfebap, 1.0f, samples - 256, 0, 7, 0, &ctx->gb, &ctx->state))
+ if (get_transform_coeffs1(ab->dlfeexps, ab->lfebap, 1.0f, ab->transform_coeffs[0], 0, 7, 0, &ctx->gb, &ctx->state))
return -1;
/* uncouple the channels from the coupling channel */
if (ab->flags & AC3_AB_CPLINU)
- if (uncouple_channels(ctx))
- return -1;
+ uncouple_channels(ctx);
return 0;
}
@@ -920,7 +934,7 @@ static int get_transform_coeffs(AC3Decod
* from coupling co-ordinates of each band and coupling band
* structure information
*/
-static int generate_coupling_coordinates(AC3DecodeContext * ctx)
+static void generate_coupling_coordinates(AC3DecodeContext * ctx)
{
ac3_audio_block *ab = &ctx->audio_block;
uint8_t exp, mstrcplco;
@@ -952,23 +966,19 @@ static int generate_coupling_coordinates
cplbndstrc >>= 1;
}
}
-
- return 0;
}
-static int _do_rematrixing(AC3DecodeContext *ctx, int start, int end)
+static void do_rematrixing1(AC3DecodeContext *ctx, int start, int end)
{
float tmp0, tmp1;
while (start < end) {
- tmp0 = ctx->samples[start];
- tmp1 = (ctx->samples + 256)[start];
- ctx->samples[start] = tmp0 + tmp1;
- (ctx->samples + 256)[start] = tmp0 - tmp1;
+ tmp0 = ctx->audio_block.transform_coeffs[1][start];
+ tmp1 = ctx->audio_block.transform_coeffs[2][start];
+ ctx->audio_block.transform_coeffs[1][start] = tmp0 + tmp1;
+ ctx->audio_block.transform_coeffs[2][start] = tmp0 - tmp1;
start++;
}
-
- return 0;
}
static void do_rematrixing(AC3DecodeContext *ctx)
@@ -979,16 +989,16 @@ static void do_rematrixing(AC3DecodeCont
bndend = FFMIN(ab->endmant[0], ab->endmant[1]);
if (ab->rematflg & 1)
- _do_rematrixing(ctx, bnd1, bnd2);
+ do_rematrixing1(ctx, bnd1, bnd2);
if (ab->rematflg & 2)
- _do_rematrixing(ctx, bnd2, bnd3);
+ do_rematrixing1(ctx, bnd2, bnd3);
if (ab->rematflg & 4) {
if (ab->cplbegf > 0 && ab->cplbegf <= 2 && (ab->flags & AC3_AB_CPLINU))
- _do_rematrixing(ctx, bnd3, bndend);
+ do_rematrixing1(ctx, bnd3, bndend);
else {
- _do_rematrixing(ctx, bnd3, bnd4);
+ do_rematrixing1(ctx, bnd3, bnd4);
if (ab->rematflg & 8)
- _do_rematrixing(ctx, bnd4, bndend);
+ do_rematrixing1(ctx, bnd4, bndend);
}
}
}
@@ -1002,7 +1012,7 @@ static void get_downmix_coeffs(AC3Decode
ac3_audio_block *ab = &ctx->audio_block;
if (to == AC3_OUTPUT_UNMODIFIED)
- return 0;
+ return;
switch (from) {
case AC3_INPUT_DUALMONO:
@@ -1116,284 +1126,312 @@ static void get_downmix_coeffs(AC3Decode
}
}
-static inline void downmix_dualmono_to_mono(float *samples)
+static inline void mix_dualmono_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += samples[i + 256];
- samples[i + 256] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] += output[2][i];
+ memset(output[2], 0, sizeof(output[2]));
}
-static inline void downmix_dualmono_to_stereo(float *samples)
+static inline void mix_dualmono_to_stereo(AC3DecodeContext *ctx)
{
int i;
float tmp;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- tmp = samples[i] + samples[i + 256];
- samples[i] = samples[i + 256] = tmp;
+ tmp = output[1][i] + output[2][i];
+ output[1][i] = output[2][i] = tmp;
}
}
-static inline void downmix_mono_to_stereo(float *samples)
+static inline void upmix_mono_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++)
- samples[i + 256] = samples[i];
+ output[2][i] = output[1][i];
}
-static inline void downmix_stereo_to_mono(float *samples)
+static inline void mix_stereo_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += samples[i + 256];
- samples[i + 256] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] += output[2][i];
+ memset(output[2], 0, sizeof(output[2]));
}
-static inline void downmix_3f_to_mono(float *samples)
+static inline void mix_3f_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 512]);
- samples[i + 256] = samples[i + 512] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] += (output[2][i] + output[3][i]);
+ memset(output[2], 0, sizeof(output[2]));
+ memset(output[3], 0, sizeof(output[3]));
}
-static inline void downmix_3f_to_stereo(float *samples)
+static inline void mix_3f_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += samples[i + 256];
- samples[i + 256] = samples[i + 512];
- samples[i + 512] = 0;
+ output[1][i] += output[2][i];
+ output[2][i] += output[3][i];
}
+ memset(output[3], 0, sizeof(output[3]));
}
-static inline void downmix_2f_1r_to_mono(float *samples)
+static inline void mix_2f_1r_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
+
+ for (i = 0; i < 256; i++)
+ output[1][i] += (output[2][i] + output[3][i]);
+ memset(output[2], 0, sizeof(output[2]));
+ memset(output[3], 0, sizeof(output[3]));
- for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 512]);
- samples[i + 256] = samples[i + 512] = 0;
- }
}
-static inline void downmix_2f_1r_to_stereo(float *samples)
+static inline void mix_2f_1r_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += samples[i + 512];
- samples[i + 256] += samples[i + 512];
- samples[i + 512] = 0;
+ output[1][i] += output[2][i];
+ output[2][i] += output[3][i];
}
+ memset(output[3], 0, sizeof(output[3]));
}
-static inline void downmix_2f_1r_to_dolby(float *samples)
+static inline void mix_2f_1r_to_dolby(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] -= samples[i + 512];
- samples[i + 256] += samples[i + 512];
- samples[i + 512] = 0;
+ output[1][i] -= output[3][i];
+ output[2][i] += output[3][i];
}
+ memset(output[3], 0, sizeof(output[3]));
}
-static inline void downmix_3f_1r_to_mono(float *samples)
+static inline void mix_3f_1r_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768]);
- samples[i + 256] = samples[i + 512] = samples[i + 768] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] = (output[2][i] + output[3][i] + output[4][i]);
+ memset(output[2], 0, sizeof(output[2]));
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_3f_1r_to_stereo(float *samples)
+static inline void mix_3f_1r_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 768]);
- samples[i + 256] += (samples[i + 512] + samples[i + 768]);
- samples[i + 512] = samples[i + 768] = 0;
+ output[1][i] += (output[2][i] + output[4][i]);
+ output[2][i] += (output[3][i] + output[4][i]);
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_3f_1r_to_dolby(float *samples)
+static inline void mix_3f_1r_to_dolby(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] - samples[i + 768]);
- samples[i + 256] += (samples[i + 512] + samples[i + 768]);
- samples[i + 512] = samples[i + 768] = 0;
+ output[1][i] += (output[2][i] - output[4][i]);
+ output[2][i] += (output[3][i] + output[4][i]);
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_2f_2r_to_mono(float *samples)
+static inline void mix_2f_2r_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768]);
- samples[i + 256] = samples[i + 512] = samples[i + 768] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] = (output[2][i] + output[3][i] + output[4][i]);
+ memset(output[2], 0, sizeof(output[2]));
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_2f_2r_to_stereo(float *samples)
+static inline void mix_2f_2r_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += samples[i + 512];
- samples[i + 256] = samples[i + 768];
- samples[i + 512] = samples[i + 768] = 0;
+ output[1][i] += output[3][i];
+ output[2][i] += output[4][i];
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_2f_2r_to_dolby(float *samples)
+static inline void mix_2f_2r_to_dolby(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] -= samples[i + 512];
- samples[i + 256] += samples[i + 768];
- samples[i + 512] = samples[i + 768] = 0;
+ output[1][i] -= output[3][i];
+ output[2][i] += output[4][i];
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
}
-static inline void downmix_3f_2r_to_mono(float *samples)
+static inline void mix_3f_2r_to_mono(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
- for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768] + samples[i + 1024]);
- samples[i + 256] = samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0;
- }
+ for (i = 0; i < 256; i++)
+ output[1][i] += (output[2][i] + output[3][i] + output[4][i] + output[5][i]);
+ memset(output[2], 0, sizeof(output[2]));
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
+ memset(output[5], 0, sizeof(output[5]));
}
-static inline void downmix_3f_2r_to_stereo(float *samples)
+static inline void mix_3f_2r_to_stereo(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] + samples[i + 768]);
- samples[i + 256] = (samples[i + 512] + samples[i + 1024]);
- samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0;
+ output[1][i] += (output[2][i] + output[4][i]);
+ output[2][i] += (output[3][i] + output[5][i]);
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
+ memset(output[5], 0, sizeof(output[5]));
}
-static inline void downmix_3f_2r_to_dolby(float *samples)
+static inline void mix_3f_2r_to_dolby(AC3DecodeContext *ctx)
{
int i;
+ float (*output)[256] = ctx->audio_block.block_output;
for (i = 0; i < 256; i++) {
- samples[i] += (samples[i + 256] - samples[i + 768]);
- samples[i + 256] = (samples[i + 512] + samples[i + 1024]);
- samples[i + 512] = samples[i + 768] = samples[i + 1024] = 0;
+ output[1][i] += (output[2][i] - output[4][i] - output[5][i]);
+ output[2][i] += (output[3][i] + output[4][i] + output[5][i]);
}
+ memset(output[3], 0, sizeof(output[3]));
+ memset(output[4], 0, sizeof(output[4]));
+ memset(output[5], 0, sizeof(output[5]));
}
static void do_downmix(AC3DecodeContext *ctx)
{
int from = ctx->bsi.acmod;
int to = ctx->output;
- float *samples = ctx->samples + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 256 : 0);
switch (from) {
case AC3_INPUT_DUALMONO:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_dualmono_to_mono(samples);
+ mix_dualmono_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */
- downmix_dualmono_to_stereo(samples);
+ mix_dualmono_to_stereo(ctx);
break;
}
break;
case AC3_INPUT_MONO:
switch (to) {
case AC3_OUTPUT_STEREO:
- downmix_mono_to_stereo(samples);
+ upmix_mono_to_stereo(ctx);
break;
}
break;
case AC3_INPUT_STEREO:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_stereo_to_mono(samples);
+ mix_stereo_to_mono(ctx);
break;
}
break;
case AC3_INPUT_3F:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_3f_to_mono(samples);
+ mix_3f_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO:
- downmix_3f_to_stereo(samples);
+ mix_3f_to_stereo(ctx);
break;
}
break;
case AC3_INPUT_2F_1R:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_2f_1r_to_mono(samples);
+ mix_2f_1r_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO:
- downmix_2f_1r_to_stereo(samples);
+ mix_2f_1r_to_stereo(ctx);
break;
case AC3_OUTPUT_DOLBY:
- downmix_2f_1r_to_dolby(samples);
+ mix_2f_1r_to_dolby(ctx);
break;
}
break;
case AC3_INPUT_3F_1R:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_3f_1r_to_mono(samples);
+ mix_3f_1r_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO:
- downmix_3f_1r_to_stereo(samples);
+ mix_3f_1r_to_stereo(ctx);
break;
case AC3_OUTPUT_DOLBY:
- downmix_3f_1r_to_dolby(samples);
+ mix_3f_1r_to_dolby(ctx);
break;
}
break;
case AC3_INPUT_2F_2R:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_2f_2r_to_mono(samples);
+ mix_2f_2r_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO:
- downmix_2f_2r_to_stereo(samples);
+ mix_2f_2r_to_stereo(ctx);
break;
case AC3_OUTPUT_DOLBY:
- downmix_2f_2r_to_dolby(samples);
+ mix_2f_2r_to_dolby(ctx);
break;
}
break;
case AC3_INPUT_3F_2R:
switch (to) {
case AC3_OUTPUT_MONO:
- downmix_3f_2r_to_mono(samples);
+ mix_3f_2r_to_mono(ctx);
break;
case AC3_OUTPUT_STEREO:
- downmix_3f_2r_to_stereo(samples);
+ mix_3f_2r_to_stereo(ctx);
break;
case AC3_OUTPUT_DOLBY:
- downmix_3f_2r_to_dolby(samples);
+ mix_3f_2r_to_dolby(ctx);
break;
}
break;
@@ -1405,22 +1443,23 @@ static int ac3_parse_audio_block(AC3Deco
ac3_audio_block *ab = &ctx->audio_block;
int nfchans = ctx->bsi.nfchans;
int acmod = ctx->bsi.acmod;
- int i, bnd, rbnd, grp, seg;
+ int i, bnd, rbnd, seg, grpsize;
GetBitContext *gb = &ctx->gb;
uint32_t *flags = &ab->flags;
int bit_alloc_flags = 0;
float drange;
+ uint8_t *dexps;
*flags = 0;
ab->blksw = 0;
for (i = 0; i < 5; i++)
ab->chcoeffs[i] = 1.0;
for (i = 0; i < nfchans; i++) /*block switch flag */
- ab->blksw |= get_bits(gb, 1) << i;
+ ab->blksw |= get_bits1(gb) << i;
ab->dithflag = 0;
for (i = 0; i < nfchans; i++) /* dithering flag */
- ab->dithflag |= get_bits(gb, 1) << i;
- if (get_bits(gb, 1)) { /* dynamic range */
+ ab->dithflag |= get_bits1(gb) << i;
+ if (get_bits1(gb)) { /* dynamic range */
*flags |= AC3_AB_DYNRNGE;
ab->dynrng = get_bits(gb, 8);
drange = ((((ab->dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (ab->dynrng >> 5)]);
@@ -1428,7 +1467,7 @@ static int ac3_parse_audio_block(AC3Deco
ab->chcoeffs[i] *= drange;
}
if (acmod == 0x00) { /* dynamic range 1+1 mode */
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_AB_DYNRNG2E;
ab->dynrng2 = get_bits(gb, 8);
drange = ((((ab->dynrng2 & 0x1f) | 0x20) << 13) * scale_factors[3 - (ab->dynrng2 >> 5)]);
@@ -1437,22 +1476,27 @@ static int ac3_parse_audio_block(AC3Deco
}
get_downmix_coeffs(ctx);
ab->chincpl = 0;
- if (get_bits(gb, 1)) { /* coupling strategy */
+ if (get_bits1(gb)) { /* coupling strategy */
*flags |= AC3_AB_CPLSTRE;
ab->cplbndstrc = 0;
- if (get_bits(gb, 1)) { /* coupling in use */
+ if (get_bits1(gb)) { /* coupling in use */
*flags |= AC3_AB_CPLINU;
for (i = 0; i < nfchans; i++)
- ab->chincpl |= get_bits(gb, 1) << i;
+ ab->chincpl |= get_bits1(gb) << i;
+ if (acmod == 0x00 || acmod == 0x01)
+ return -1; /* coupling needs atleast two shared channels */
if (acmod == 0x02)
- if (get_bits(gb, 1)) /* phase flag in use */
+ if (get_bits1(gb)) /* phase flag in use */
*flags |= AC3_AB_PHSFLGINU;
ab->cplbegf = get_bits(gb, 4);
ab->cplendf = get_bits(gb, 4);
- assert((ab->ncplsubnd = 3 + ab->cplendf - ab->cplbegf) > 0);
- ab->ncplbnd = ab->ncplsubnd;
+ if (3 + ab->cplendf - ab->cplbegf < 0)
+ return -1;
+ ab->ncplbnd = ab->ncplsubnd = 3 + ab->cplendf - ab->cplbegf;
+ ab->cplstrtmant = ab->cplbegf * 12 + 37;
+ ab->cplendmant = ((ab->cplendf + 3) * 12) + 37;
for (i = 0; i < ab->ncplsubnd - 1; i++) /* coupling band structure */
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
ab->cplbndstrc |= 1 << i;
ab->ncplbnd--;
}
@@ -1462,7 +1506,7 @@ static int ac3_parse_audio_block(AC3Deco
ab->cplcoe = 0;
for (i = 0; i < nfchans; i++)
if (ab->chincpl & (1 << i))
- if (get_bits(gb, 1)) { /* coupling co-ordinates */
+ if (get_bits1(gb)) { /* coupling co-ordinates */
ab->cplcoe |= 1 << i;
ab->mstrcplco[i] = get_bits(gb, 2);
for (bnd = 0; bnd < ab->ncplbnd; bnd++) {
@@ -1470,77 +1514,83 @@ static int ac3_parse_audio_block(AC3Deco
ab->cplcomant[i][bnd] = get_bits(gb, 4);
}
}
- }
- ab->phsflg = 0;
- if ((acmod == 0x02) && (*flags & AC3_AB_PHSFLGINU) && (ab->cplcoe & 1 || ab->cplcoe & (1 << 1))) {
- for (bnd = 0; bnd < ab->ncplbnd; bnd++)
- if (get_bits(gb, 1))
- ab->phsflg |= 1 << bnd;
+ ab->phsflg = 0;
+ if ((acmod == 0x02) && (*flags & AC3_AB_PHSFLGINU) && (ab->cplcoe & 1 || ab->cplcoe & (1 << 1))) {
+ for (bnd = 0; bnd < ab->ncplbnd; bnd++)
+ if (get_bits1(gb))
+ ab->phsflg |= 1 << bnd;
+ }
}
generate_coupling_coordinates(ctx);
ab->rematflg = 0;
if (acmod == 0x02) /* rematrixing */
- if (get_bits(gb, 1)) {
+ if (get_bits1(gb)) {
*flags |= AC3_AB_REMATSTR;
- if (ab->cplbegf > 2 || !(*flags & AC3_AB_CPLINU))
+ if (!(*flags & AC3_AB_CPLINU) || ab->cplbegf > 2)
for (rbnd = 0; rbnd < 4; rbnd++)
- ab->rematflg |= get_bits(gb, 1) << bnd;
- else if (ab->cplbegf > 0 && ab->cplbegf <= 2 && *flags & AC3_AB_CPLINU)
+ ab->rematflg |= get_bits1(gb) << rbnd;
+ if (ab->cplbegf > 0 && ab->cplbegf <= 2 && (*flags & AC3_AB_CPLINU))
for (rbnd = 0; rbnd < 3; rbnd++)
- ab->rematflg |= get_bits(gb, 1) << bnd;
- else if (!(ab->cplbegf) && *flags & AC3_AB_CPLINU)
+ ab->rematflg |= get_bits1(gb) << rbnd;
+ if (ab->cplbegf == 0 && (*flags & AC3_AB_CPLINU))
for (rbnd = 0; rbnd < 2; rbnd++)
- ab->rematflg |= get_bits(gb, 1) << bnd;
+ ab->rematflg |= get_bits1(gb) << rbnd;
}
+ ab->cplexpstr = AC3_EXPSTR_REUSE;
+ ab->lfeexpstr = AC3_EXPSTR_REUSE;
if (*flags & AC3_AB_CPLINU) /* coupling exponent strategy */
ab->cplexpstr = get_bits(gb, 2);
for (i = 0; i < nfchans; i++) /* channel exponent strategy */
ab->chexpstr[i] = get_bits(gb, 2);
if (ctx->bsi.flags & AC3_BSI_LFEON) /* lfe exponent strategy */
- ab->lfeexpstr = get_bits(gb, 1);
+ ab->lfeexpstr = get_bits1(gb);
for (i = 0; i < nfchans; i++) /* channel bandwidth code */
- if (ab->chexpstr[i] != AC3_EXPSTR_REUSE)
- if (!(ab->chincpl & (1 << i))) {
+ if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) {
+ if ((ab->chincpl & (1 << i)))
+ ab->endmant[i] = ab->cplstrtmant;
+ else {
ab->chbwcod[i] = get_bits(gb, 6);
- assert (ab->chbwcod[i] <= 60);
+ if (ab->chbwcod[i] > 60) {
+ av_log(NULL, AV_LOG_ERROR, "chbwcod = %d > 60", ab->chbwcod[i]);
+ return -1;
+ }
+ ab->endmant[i] = ((ab->chbwcod[i] + 12) * 3) + 37;
}
+ }
if (*flags & AC3_AB_CPLINU)
if (ab->cplexpstr != AC3_EXPSTR_REUSE) {/* coupling exponents */
bit_alloc_flags |= 64;
ab->cplabsexp = get_bits(gb, 4) << 1;
- ab->cplstrtmant = (ab->cplbegf * 12) + 37;
- ab->cplendmant = ((ab->cplendmant + 3) * 12) + 37;
ab->ncplgrps = (ab->cplendmant - ab->cplstrtmant) / (3 << (ab->cplexpstr - 1));
- for (grp = 0; grp < ab->ncplgrps; grp++)
- ab->cplexps[grp] = get_bits(gb, 7);
+ if (decode_exponents(gb, ab->cplexpstr, ab->ncplgrps, ab->cplabsexp, ab->dcplexps + ab->cplstrtmant)) {
+ av_log(NULL, AV_LOG_ERROR, "error decoding coupling exponents\n");
+ return -1;
+ }
}
for (i = 0; i < nfchans; i++) /* fbw channel exponents */
if (ab->chexpstr[i] != AC3_EXPSTR_REUSE) {
bit_alloc_flags |= 1 << i;
- if (ab->chincpl & (1 << i))
- ab->endmant[i] = (ab->cplbegf * 12) + 37;
- else
- ab->endmant[i] = ((ab->chbwcod[i] + 3) * 12) + 37;
- ab->nchgrps[i] =
- (ab->endmant[i] + (3 << (ab->chexpstr[i] - 1)) - 4) / (3 << (ab->chexpstr[i] - 1));
- ab->exps[i][0] = ab->dexps[i][0] = get_bits(gb, 4);
- for (grp = 1; grp <= ab->nchgrps[i]; grp++)
- ab->exps[i][grp] = get_bits(gb, 7);
+ grpsize = 3 << (ab->chexpstr[i] - 1);
+ ab->nchgrps[i] = (ab->endmant[i] + grpsize - 4) / grpsize;
+ dexps = ab->dexps[i];
+ dexps[0] = get_bits(gb, 4);
+ if (decode_exponents(gb, ab->chexpstr[i], ab->nchgrps[i], dexps[0], dexps + 1)) {
+ av_log(NULL, AV_LOG_ERROR, "error decoding channel %d exponents\n", i);
+ return -1;
+ }
ab->gainrng[i] = get_bits(gb, 2);
}
if (ctx->bsi.flags & AC3_BSI_LFEON) /* lfe exponents */
if (ab->lfeexpstr != AC3_EXPSTR_REUSE) {
bit_alloc_flags |= 32;
- ab->lfeexps[0] = ab->dlfeexps[0] = get_bits(gb, 4);
- ab->lfeexps[1] = get_bits(gb, 7);
- ab->lfeexps[2] = get_bits(gb, 7);
+ ab->dlfeexps[0] = get_bits(gb, 4);
+ if (decode_exponents(gb, ab->lfeexpstr, 2, ab->dlfeexps[0], ab->dlfeexps + 1)) {
+ av_log(NULL, AV_LOG_ERROR, "error decoding lfe exponents\n");
+ return -1;
+ }
}
- if (decode_exponents(ctx)) {/* decode the exponents for this block */
- av_log(NULL, AV_LOG_ERROR, "Error parsing exponents\n");
- return -1;
- }
- if (get_bits(gb, 1)) { /* bit allocation information */
+ if (get_bits1(gb)) { /* bit allocation information */
*flags |= AC3_AB_BAIE;
bit_alloc_flags |= 127;
ab->sdcycod = get_bits(gb, 2);
@@ -1549,7 +1599,7 @@ static int ac3_parse_audio_block(AC3Deco
ab->dbpbcod = get_bits(gb, 2);
ab->floorcod = get_bits(gb, 3);
}
- if (get_bits(gb, 1)) { /* snroffset */
+ if (get_bits1(gb)) { /* snroffset */
*flags |= AC3_AB_SNROFFSTE;
bit_alloc_flags |= 127;
ab->csnroffst = get_bits(gb, 6);
@@ -1567,13 +1617,13 @@ static int ac3_parse_audio_block(AC3Deco
}
}
if (*flags & AC3_AB_CPLINU)
- if (get_bits(gb, 1)) { /* coupling leak information */
+ if (get_bits1(gb)) { /* coupling leak information */
bit_alloc_flags |= 64;
*flags |= AC3_AB_CPLLEAKE;
ab->cplfleak = get_bits(gb, 3);
ab->cplsleak = get_bits(gb, 3);
}
- if (get_bits(gb, 1)) { /* delta bit allocation information */
+ if (get_bits1(gb)) { /* delta bit allocation information */
*flags |= AC3_AB_DELTBAIE;
bit_alloc_flags |= 127;
if (*flags & AC3_AB_CPLINU) {
@@ -1609,17 +1659,14 @@ static int ac3_parse_audio_block(AC3Deco
}
}
}
- if (do_bit_allocation (ctx, bit_alloc_flags)) /* perform the bit allocation */ {
- av_log(NULL, AV_LOG_ERROR, "Error in bit allocation routine\n");
- return -1;
- }
- if (get_bits(gb, 1)) { /* unused dummy data */
+
+ do_bit_allocation (ctx, bit_alloc_flags); /* perform the bit allocation */
+
+ if (get_bits1(gb)) { /* unused dummy data */
*flags |= AC3_AB_SKIPLE;
ab->skipl = get_bits(gb, 9);
- while (ab->skipl) {
- get_bits(gb, 8);
- ab->skipl--;
- }
+ for (i = 0; i < ab->skipl; i++)
+ skip_bits(gb, 8);
}
/* unpack the transform coefficients
* * this also uncouples channels if coupling is in use.
@@ -1632,59 +1679,34 @@ static int ac3_parse_audio_block(AC3Deco
if (*flags & AC3_AB_REMATSTR)
do_rematrixing(ctx);
- if (ctx->output != AC3_OUTPUT_UNMODIFIED)
- do_downmix(ctx);
-
return 0;
}
-/**** the following two functions comes from ac3dec */
-static inline int blah (int32_t i)
-{
- if (i > 0x43c07fff)
- return 32767;
- else if (i < 0x43bf8000)
- return -32768;
- else
- return i - 0x43c00000;
-}
-
-static inline void float_to_int (float * _f, int16_t * s16, int samples)
-{
- int32_t * f = (int32_t *) _f; // XXX assumes IEEE float format
- int i;
-
- for (i = 0; i < samples; i++) {
- s16[i] = blah (f[i]);
- }
-}
-/**** end */
-
-
-
-static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size)
+static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t *buf, int buf_size)
{
- AC3DecodeContext *ctx = avctx->priv_data;
+ AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data;
+ ac3_audio_block *ab = &ctx->audio_block;
int frame_start;
- int i, j, k, l;
- float tmp0[128], tmp1[128], tmp[512];
- short *out_samples = (short *)data;
- float *samples = ctx->samples;
+ int i, j, k, l, value;
+ float tmp_block_first_half[128], tmp_block_second_half[128];
+ int16_t *out_samples = (int16_t *)data;
+ int nfchans;
//Synchronize the frame.
frame_start = ac3_synchronize(buf, buf_size);
if (frame_start == -1) {
av_log(avctx, AV_LOG_ERROR, "frame is not synchronized\n");
*data_size = 0;
- return -1;
+ return buf_size;
}
//Initialize the GetBitContext with the start of valid AC3 Frame.
init_get_bits(&(ctx->gb), buf + frame_start, (buf_size - frame_start) * 8);
+
//Parse the syncinfo.
- ////If 'fscod' is not valid the decoder shall mute as per the standard.
- if (ac3_parse_sync_info(ctx)) {
- av_log(avctx, AV_LOG_ERROR, "fscod is not valid\n");
+ //If 'fscod' or 'bsid' is not valid the decoder shall mute as per the standard.
+ if (!ac3_parse_sync_info(ctx)) {
+ av_log(avctx, AV_LOG_ERROR, "\n");
*data_size = 0;
return -1;
}
@@ -1703,15 +1725,18 @@ static int ac3_decode_frame(AVCodecConte
return -1;
}
+ for (i = 0; i < MAX_BLOCKS; i++)
+ memset(ctx->delay[i], 0, sizeof(ctx->delay[i]));
avctx->sample_rate = ctx->sync_info.sampling_rate;
+ avctx->bit_rate = ctx->sync_info.bit_rate;
if (avctx->channels == 0) {
- avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0);
+ //avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0);
ctx->output = AC3_OUTPUT_UNMODIFIED;
}
else if ((ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0)) < avctx->channels) {
av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",
avctx->channels, (ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0)));
- avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0);
+ //avctx->channels = ctx->bsi.nfchans + ((ctx->bsi.flags & AC3_BSI_LFEON) ? 1 : 0);
ctx->output = AC3_OUTPUT_UNMODIFIED;
}
else if (avctx->channels == 1) {
@@ -1724,53 +1749,72 @@ static int ac3_decode_frame(AVCodecConte
}
- avctx->bit_rate = ctx->sync_info.bit_rate;
av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->sample_rate, avctx->bit_rate);
//Parse the Audio Blocks.
+ *data_size = 0;
for (i = 0; i < 6; i++) {
if (ac3_parse_audio_block(ctx, i)) {
av_log(avctx, AV_LOG_ERROR, "error parsing the audio block\n");
*data_size = 0;
return -1;
}
- samples = ctx->samples;
+
+ av_log(NULL, AV_LOG_INFO, "doing imdct\n");
+
if (ctx->bsi.flags & AC3_BSI_LFEON) {
- ff_imdct_calc(&ctx->imdct_ctx_512, ctx->samples + 1536, samples, tmp);
+ ff_imdct_calc(&ctx->imdct_ctx_512, ctx->tmp_output, ab->transform_coeffs[0], ctx->tmp_imdct);
for (l = 0; l < 256; l++)
- samples[l] = (ctx->samples + 1536)[l];
- float_to_int(samples, out_samples, 256);
- samples += 256;
- out_samples += 256;
+ ab->block_output[0][l] = ctx->tmp_output[l] * window[l] + ctx->delay[0][l] * window[255 -l];
+ memcpy(ctx->delay[0], ctx->tmp_output + 256, sizeof(ctx->delay[0]));
}
+
for (j = 0; j < ctx->bsi.nfchans; j++) {
if (ctx->audio_block.blksw & (1 << j)) {
for (k = 0; k < 128; k++) {
- tmp0[k] = samples[2 * k];
- tmp1[k] = samples[2 * k + 1];
+ tmp_block_first_half[k] = ab->transform_coeffs[j + 1][2 * k];
+ tmp_block_second_half[k] = ab->transform_coeffs[j + 1][2 * k + 1];
}
- ff_imdct_calc(&ctx->imdct_ctx_256, ctx->samples + 1536, tmp0, tmp);
+ ff_imdct_calc(&ctx->imdct_ctx_256, ctx->tmp_output, tmp_block_first_half, ctx->tmp_imdct);
for (l = 0; l < 256; l++)
- samples[l] = (ctx->samples + 1536)[l] * window[l] + (ctx->samples + 2048)[l] * window[255 - l];
- ff_imdct_calc(&ctx->imdct_ctx_256, ctx->samples + 2048, tmp1, tmp);
- float_to_int(samples, out_samples, 256);
- samples += 256;
- out_samples += 256;
- }
- else {
- ff_imdct_calc(&ctx->imdct_ctx_512, ctx->samples + 1536, samples, tmp);
+ ab->block_output[j + 1][l] = ctx->tmp_output[l] * window[l] + ctx->delay[j + 1][l] * window[255 - l];
+ ff_imdct_calc(&ctx->imdct_ctx_256, ctx->delay[j + 1], tmp_block_second_half, ctx->tmp_imdct);
+ } else {
+ ff_imdct_calc(&ctx->imdct_ctx_512, ctx->tmp_output, ab->transform_coeffs[j + 1], ctx->tmp_imdct);
for (l = 0; l < 256; l++)
- samples[l] = (ctx->samples + 1536)[l] * window[l] + (ctx->samples + 2048)[l] * window[255 - l];
- float_to_int(samples, out_samples, 256);
- memcpy(ctx->samples + 2048, ctx->samples + 1792, 256 * sizeof (float));
- samples += 256;
- out_samples += 256;
+ ab->block_output[j + 1][l] = ctx->tmp_output[l] * window[l] + ctx->delay[j + 1][l] * window[255 - l];
+ memcpy(ctx->delay[j + 1], ctx->tmp_output + 256, sizeof(ctx->delay[j + 1]));
+ }
+ }
+ if (ctx->bsi.flags & AC3_BSI_LFEON) {
+ for (l = 0; l < 256; l++) {
+ value = lrint(ab->block_output[0][l]);
+ if (value < -32768)
+ value = -32768;
+ else if (value > 32767)
+ value = 32767;
+ *(out_samples++) = value;
}
+ *data_size += 256 * sizeof(int16_t);
}
+ do_downmix(ctx);
+ if (ctx->output == AC3_OUTPUT_UNMODIFIED)
+ nfchans = ctx->bsi.nfchans;
+ else
+ nfchans = avctx->channels;
+ for (k = 0; k < nfchans; k++)
+ for (l = 0; l < 256; l++) {
+ value = lrint(ab->block_output[k + 1][l]);
+ if (value < -32768)
+ value = -32768;
+ else if (value > 32767)
+ value = 32767;
+ *(out_samples++) = value;
+ }
+ *data_size += nfchans * 256 * sizeof (int16_t);
}
- *data_size = 6 * ctx->bsi.nfchans * 256 * sizeof (int16_t);
- return (buf_size - frame_start);
+ return ctx->sync_info.framesize;
}
static int ac3_decode_end(AVCodecContext *ctx)
More information about the ffmpeg-cvslog
mailing list