1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

AC-3 decoder, soc revision 48, Aug 16 11:27:49 2006 UTC by cloud9

I realized that the bug was not in the imdct routine but in the
get_transform_coeffs.
Fixed it.
Code now uses the ffmpeg's imdct routines.
All the mplayer's ac3 samples are decoded
successfully.
Also improved downmixing.
Now all the downmixing coeffcients for channels
are normalized such that the sum of coefficients
used to construct the output for single channel
never exceeds 1.0.

Originally committed as revision 9659 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Justin Ruggles 2007-07-14 15:58:42 +00:00
parent 2fbbd087bb
commit 45b0ed13a8

View File

@ -34,6 +34,7 @@
#include "avutil.h" #include "avutil.h"
#include "common.h" #include "common.h"
#include "math.h" #include "math.h"
#include "crc.h"
#define N 512 /* constant for IMDCT Block size */ #define N 512 /* constant for IMDCT Block size */
@ -158,8 +159,8 @@ typedef struct {
DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][BLOCK_SIZE]); DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][BLOCK_SIZE]);
/* For IMDCT. */ /* For IMDCT. */
FFTContext fft_64; //N/8 point IFFT context MDCTContext imdct_512; //N/8 point IFFT context
FFTContext fft_128; //N/4 point IFFT context MDCTContext imdct_256; //N/4 point IFFT context
DECLARE_ALIGNED_16(float, output[MAX_CHANNELS][BLOCK_SIZE]); DECLARE_ALIGNED_16(float, output[MAX_CHANNELS][BLOCK_SIZE]);
DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][BLOCK_SIZE]); DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][BLOCK_SIZE]);
DECLARE_ALIGNED_16(float, tmp_imdct[BLOCK_SIZE]); DECLARE_ALIGNED_16(float, tmp_imdct[BLOCK_SIZE]);
@ -398,8 +399,8 @@ static int ac3_decode_init(AVCodecContext *avctx)
AC3DecodeContext *ctx = avctx->priv_data; AC3DecodeContext *ctx = avctx->priv_data;
ac3_tables_init(); ac3_tables_init();
ff_fft_init(&ctx->fft_64, 6, 1); ff_mdct_init(&ctx->imdct_256, 8, 1);
ff_fft_init(&ctx->fft_128, 7, 1); ff_mdct_init(&ctx->imdct_512, 9, 1);
dither_seed(&ctx->dith_state, 0); dither_seed(&ctx->dith_state, 0);
return 0; return 0;
@ -838,9 +839,9 @@ static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
case 0: case 0:
for (ch = 0; ch < ctx->nfchans; ch++) for (ch = 0; ch < ctx->nfchans; ch++)
if (((ctx->chincpl) >> ch) & 1) { if (((ctx->chincpl) >> ch) & 1) {
if (!(((ctx->dithflag) >> ch) & 1)) { if ((ctx->dithflag >> ch) & 1) {
TRANSFORM_COEFF(cplcoeff, dither_int16(&ctx->dith_state), exps[start], scale_factors); TRANSFORM_COEFF(cplcoeff, dither_int16(&ctx->dith_state), exps[start], scale_factors);
ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch]; ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch] * LEVEL_MINUS_3DB;
} else } else
ctx->transform_coeffs[ch + 1][start] = 0; ctx->transform_coeffs[ch + 1][start] = 0;
} }
@ -887,7 +888,7 @@ static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
break; break;
default: default:
TRANSFORM_COEFF(cplcoeff, get_bits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), TRANSFORM_COEFF(cplcoeff, get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]),
exps[start], scale_factors); exps[start], scale_factors);
} }
for (ch = 0; ch < ctx->nfchans; ch++) for (ch = 0; ch < ctx->nfchans; ch++)
@ -932,13 +933,13 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
tbap = bap[i]; tbap = bap[i];
switch (tbap) { switch (tbap) {
case 0: case 0:
if (dithflag) { if (!dithflag) {
coeffs[i] = 0; coeffs[i] = 0;
continue; continue;
} }
else { else {
TRANSFORM_COEFF(coeffs[i], dither_int16(&ctx->dith_state), exps[i], factors); TRANSFORM_COEFF(coeffs[i], dither_int16(&ctx->dith_state), exps[i], factors);
coeffs[i] *= LEVEL_PLUS_3DB; coeffs[i] *= LEVEL_MINUS_3DB;
continue; continue;
} }
@ -983,7 +984,7 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
continue; continue;
default: default:
TRANSFORM_COEFF(coeffs[i], get_bits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), exps[i], factors); TRANSFORM_COEFF(coeffs[i], get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), exps[i], factors);
continue; continue;
} }
} }
@ -1075,6 +1076,7 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx)
int to = ctx->blkoutput; int to = ctx->blkoutput;
float clev = clevs[ctx->cmixlev]; float clev = clevs[ctx->cmixlev];
float slev = slevs[ctx->surmixlev]; float slev = slevs[ctx->surmixlev];
float nf = 1.0; //normalization factor for downmix coeffs
if (to == AC3_OUTPUT_UNMODIFIED) if (to == AC3_OUTPUT_UNMODIFIED)
return; return;
@ -1084,107 +1086,142 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx)
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */ case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */
ctx->chcoeffs[0] *= LEVEL_MINUS_6DB; nf = 0.5;
ctx->chcoeffs[1] *= LEVEL_MINUS_6DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
break; break;
} }
break; break;
case AC3_INPUT_MONO: case AC3_INPUT_MONO:
switch (to) { switch (to) {
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB;
ctx->chcoeffs[0] *= nf;
break; break;
} }
break; break;
case AC3_INPUT_STEREO: case AC3_INPUT_STEREO:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB;
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
break; break;
} }
break; break;
case AC3_INPUT_3F: case AC3_INPUT_3F:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB / (1.0 + clev);
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[1] *= (clev * LEVEL_PLUS_3DB); ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[1] *= ((nf * clev * LEVEL_MINUS_3DB) / 2.0);
break; break;
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[1] *= clev; nf = 1.0 / (1.0 + clev);
ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[2] *= nf;
ctx->chcoeffs[1] *= (nf * clev);
break; break;
} }
break; break;
case AC3_INPUT_2F_1R: case AC3_INPUT_2F_1R:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = 2.0 * LEVEL_MINUS_3DB / (2.0 + slev);
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB; nf = 1.0 / (1.0 + (slev * LEVEL_MINUS_3DB));
ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_DOLBY: case AC3_OUTPUT_DOLBY:
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB; nf = 1.0 / (1.0 + LEVEL_MINUS_3DB);
ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
break; break;
} }
break; break;
case AC3_INPUT_3F_1R: case AC3_INPUT_3F_1R:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB / (1.0 + clev + (slev / 2.0));
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[1] *= clev * LEVEL_PLUS_3DB; ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[1] *= clev; nf = 1.0 / (1.0 + clev + (slev * LEVEL_MINUS_3DB));
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[2] *= nf;
ctx->chcoeffs[1] *= (nf * clev);
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_DOLBY: case AC3_OUTPUT_DOLBY:
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB; nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
break; break;
} }
break; break;
case AC3_INPUT_2F_2R: case AC3_INPUT_2F_2R:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB / (1.0 + slev);
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[2] *= slev; nf = 1.0 / (1.0 + slev);
ctx->chcoeffs[3] *= slev; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[2] *= (nf * slev);
ctx->chcoeffs[3] *= (nf * slev);
break; break;
case AC3_OUTPUT_DOLBY: case AC3_OUTPUT_DOLBY:
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB; nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
break; break;
} }
break; break;
case AC3_INPUT_3F_2R: case AC3_INPUT_3F_2R:
switch (to) { switch (to) {
case AC3_OUTPUT_MONO: case AC3_OUTPUT_MONO:
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB; nf = LEVEL_MINUS_3DB / (1.0 + clev + slev);
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[1] *= clev * LEVEL_PLUS_3DB; ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
ctx->chcoeffs[4] *= slev * LEVEL_MINUS_3DB; ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
ctx->chcoeffs[4] *= (nf * slev * LEVEL_MINUS_3DB);
break; break;
case AC3_OUTPUT_STEREO: case AC3_OUTPUT_STEREO:
ctx->chcoeffs[1] *= clev; nf = 1.0 / (1.0 + clev + slev);
ctx->chcoeffs[3] *= slev; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[4] *= slev; ctx->chcoeffs[2] *= nf;
ctx->chcoeffs[1] *= (nf * clev);
ctx->chcoeffs[3] *= (nf * slev);
ctx->chcoeffs[4] *= (nf * slev);
break; break;
case AC3_OUTPUT_DOLBY: case AC3_OUTPUT_DOLBY:
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB; nf = 1.0 / (1.0 + (3.0 * LEVEL_MINUS_3DB));
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB; ctx->chcoeffs[0] *= nf;
ctx->chcoeffs[4] *= LEVEL_MINUS_3DB; ctx->chcoeffs[1] *= nf;
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
ctx->chcoeffs[4] *= (nf * LEVEL_MINUS_3DB);
break; break;
} }
break; break;
@ -1529,102 +1566,39 @@ static void dump_floats(const char *name, int prec, const float *tab, int n)
(pim) = _are * _bim + _aim * _bre;\ (pim) = _are * _bim + _aim * _bre;\
} }
static void do_imdct_256(FFTContext *fft_ctx, float *coeffs, float *output, static void do_imdct_256(AC3DecodeContext *ctx, int chindex)
float *delay, float *tmp_imdct, float *tmp_output)
{ {
int k, n2, n4, n8; int k;
float x1[128], x2[128]; float x1[128], x2[128];
FFTComplex *z1 = (FFTComplex *)tmp_imdct;
FFTComplex *z2 = (FFTComplex *)(tmp_imdct + 128);
n2 = N / 2; for (k = 0; k < N / 4; k++) {
n4 = N / 4; x1[k] = ctx->transform_coeffs[chindex][2 * k];
n8 = N / 8; x2[k] = ctx->transform_coeffs[chindex][2 * k + 1];
for (k = 0; k < n4; k++) {
x1[k] = coeffs[2 * k];
x2[k] = coeffs[2 * k + 1];
} }
/* Pre IFFT Complex Multiply Step. */ ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output, x1, ctx->tmp_imdct);
for (k = 0; k < n8; k++) { ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output + 256, x2, ctx->tmp_imdct);
CMUL(z1[k].re, z1[k].im, x1[n4 - 2 * k - 1], x1[2 * k], x_cos2[k], x_sin2[k]);
CMUL(z2[k].re, z2[k].im, x2[n4 - 2 * k - 1], x2[2 * k], x_cos2[k], x_sin2[k]);
}
/* N/8 pointe complex IFFT. */ for (k = 0; k < N / 2; k++) {
ff_fft_permute(fft_ctx, z1); ctx->output[chindex][k] = ctx->tmp_output[k] * window[k] + ctx->delay[chindex][k];
ff_fft_calc(fft_ctx, z1); //dump_floats("samples", 10, ctx->output[chindex], 256);
ff_fft_permute(fft_ctx, z2); ctx->delay[chindex][k] = ctx->tmp_output[N / 2 + k] * window[255 - k];
ff_fft_calc(fft_ctx, z2);
/* Post IFFT Complex Multiply Step. */
for (k = 0; k < n8; k++) {
CMUL(z1[k].re, z1[k].im, z1[k].re, z1[k].im, x_cos2[k], x_sin2[k]);
CMUL(z2[k].re, z2[k].im, z2[k].re, z2[k].im, x_cos2[k], x_sin2[k]);
}
/* Windowing and de-interleaving step. */
for (k = 0; k < n8; k++) {
tmp_output[2 * k] = -z1[k].im * window[2 * k];
tmp_output[2 * k + 1] = z1[n8 - k - 1].re * window[2 * k + 1];
tmp_output[n4 + 2 * k] = -z1[k].re * window[n4 + 2 * k];
tmp_output[n4 + 2 * k + 1] = z1[n8 - k - 1].im * window[n4 + 2 * k + 1];
tmp_output[n2 + 2 * k] = -z2[k].re * window[n2 - 2 * k - 1];
tmp_output[n2 + 2* k + 1] = z2[n8 - k - 1].im * window[n2 - 2 * k - 2];
tmp_output[3 * n4 + 2 * k] = z2[k].im * window[n4 - 2 * k - 1] ;
tmp_output[3 * n4 + 2 * k + 1] = -z2[n8 - k - 1].re * window[n4 - 2 * k - 2] ;
}
/* Overlap and add step. */
for (k = 0; k < n2; k++) {
output[k] = 2 * (tmp_output[k] + delay[k]);
delay[k] = tmp_output[n2 + k];
} }
} }
static void do_imdct_512(FFTContext *fft_ctx, float *coeffs, float *output, static void do_imdct_512(AC3DecodeContext *ctx, int chindex)
float *delay, float *tmp_imdct, float *tmp_output)
{ {
int k, n2, n4, n8; int k;
FFTComplex *z = (FFTComplex *)tmp_imdct;
n2 = N / 2; ff_imdct_calc(&ctx->imdct_512, ctx->tmp_output,
n4 = N / 4; ctx->transform_coeffs[chindex], ctx->tmp_imdct);
n8 = N / 8; //ff_imdct_calc_ac3_512(&ctx->imdct_512, ctx->tmp_output, ctx->transform_coeffs[chindex],
// ctx->tmp_imdct, window);
for (k = 0; k < N / 2; k++) {
/* Pre IFFT Complex Multiply Step. */ ctx->output[chindex][k] = ctx->tmp_output[k] * window[k] + ctx->delay[chindex][k];
for (k = 0; k < n4; k++) //dump_floats("samples", 10, ctx->output[chindex], 256);
CMUL(z[k].re, z[k].im, coeffs[n2 - 2 * k - 1], coeffs[2 * k], x_cos1[k], x_sin1[k]); ctx->delay[chindex][k] = ctx->tmp_output[N / 2 + k] * window[255 - k];
/* Permutation needed before calling ff_fft_calc. */
ff_fft_permute(fft_ctx, z);
/* N/4 pointe complex IFFT. */
ff_fft_calc(fft_ctx, z);
/* Post IFFT Complex Multiply Step. */
for (k = 0; k < n4; k++)
CMUL(z[k].re, z[k].im, z[k].re, z[k].im, x_cos1[k], x_sin1[k]);
/* Windowing and de-interleaving step. */
for (k = 0; k < n8; k++) {
tmp_output[2 * k] = -z[n8 + k].im * window[2 * k];
tmp_output[2 * k + 1] = z[n8 - k - 1].re * window[2 * k + 1];
tmp_output[n4 + 2 * k] = -z[k].re * window[n4 + 2 * k];
tmp_output[n4 + 2 * k + 1] = z[n4 - k - 1].im * window[n4 + 2 * k + 1];
tmp_output[n2 + 2 * k] = -z[n8 + k].re * window[n2 - 2 * k - 1];
tmp_output[n2 + 2* k + 1] = z[n8 - k - 1].im * window[n2 - 2 * k - 2];
tmp_output[3 * n4 + 2 * k] = z[k].im * window[n4 - 2 * k - 1] ;
tmp_output[3 * n4 + 2 * k + 1] = -z[n4 - k - 1].re * window[n4 - 2 * k - 2] ;
}
/* Overlap and add step. */
for (k = 0; k < n2; k++) {
output[k] = 2 * (tmp_output[k] + delay[k]);
delay[k] = tmp_output[n2 + k];
} }
} }
@ -1633,18 +1607,13 @@ static inline void do_imdct(AC3DecodeContext *ctx)
int i; int i;
if (ctx->blkoutput & AC3_OUTPUT_LFEON) { if (ctx->blkoutput & AC3_OUTPUT_LFEON) {
do_imdct_512(&ctx->fft_128, ctx->transform_coeffs[0], ctx->output[0], do_imdct_512(ctx, 0);
ctx->delay[0], ctx->tmp_imdct, ctx->tmp_output);
} }
for (i = 0; i < ctx->nfchans; i++) { for (i = 0; i < ctx->nfchans; i++) {
if (!((ctx->blksw >> i) & 1)) { if ((ctx->blksw >> i) & 1)
do_imdct_512(&ctx->fft_128, ctx->transform_coeffs[i + 1], ctx->output[i + 1], do_imdct_256(ctx, i + 1);
ctx->delay[i + 1], ctx->tmp_imdct, ctx->tmp_output); else
} else { do_imdct_512(ctx, i + 1);
av_log(NULL, AV_LOG_INFO, "block switching enabled.\n");
do_imdct_256(&ctx->fft_64, ctx->transform_coeffs[i + 1], ctx->output[i + 1],
ctx->delay[i + 1], ctx->tmp_imdct, ctx->tmp_output);
}
} }
} }
@ -1661,7 +1630,7 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
int dynrng, chbwcod, ngrps, cplabsexp, skipl; int dynrng, chbwcod, ngrps, cplabsexp, skipl;
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
ctx->chcoeffs[i] = 1.0; ctx->chcoeffs[i] = 2.0;
for (i = 0; i < nfchans; i++) /*block switch flag */ for (i = 0; i < nfchans; i++) /*block switch flag */
ctx->blksw |= get_bits1(gb) << i; ctx->blksw |= get_bits1(gb) << i;
@ -1670,14 +1639,14 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
ctx->dithflag |= get_bits1(gb) << i; ctx->dithflag |= get_bits1(gb) << i;
if (get_bits1(gb)) { /* dynamic range */ if (get_bits1(gb)) { /* dynamic range */
dynrng = get_bits(gb, 8); dynrng = get_sbits(gb, 8);
drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]); drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
for (i = 0; i < nfchans; i++) for (i = 0; i < nfchans; i++)
ctx->chcoeffs[i] *= drange; ctx->chcoeffs[i] *= drange;
} }
if (acmod == 0x00 && get_bits1(gb)) { /* dynamic range 1+1 mode */ if (acmod == 0x00 && get_bits1(gb)) { /* dynamic range 1+1 mode */
dynrng = get_bits(gb, 8); dynrng = get_sbits(gb, 8);
drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]); drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
ctx->chcoeffs[1] *= drange; ctx->chcoeffs[1] *= drange;
} }
@ -1931,9 +1900,12 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
static inline int16_t convert(float f) static inline int16_t convert(float f)
{ {
int a; if (f >= 1.0)
a = lrintf(f * 32767.0); return 32767;
return ((int16_t)a); else if (f <= -1.0)
return -32768;
else
return (lrintf(f * 32767.0));
} }
static int frame_count = 0; static int frame_count = 0;
@ -1943,7 +1915,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data; AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data;
int frame_start; int frame_start;
int16_t *out_samples = (int16_t *)data; int16_t *out_samples = (int16_t *)data;
int i, j, k, value; int i, j, k, value, fs_58;
uint16_t crc1;
av_log(NULL, AV_LOG_INFO, "decoding frame %d buf_size = %d\n", frame_count++, buf_size); av_log(NULL, AV_LOG_INFO, "decoding frame %d buf_size = %d\n", frame_count++, buf_size);
@ -1966,38 +1939,34 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
return buf_size; return buf_size;
} }
//Check for the errors.
/* if (ac3_error_check(ctx)) {
*data_size = 0;
return -1;
} */
//Parse the BSI. //Parse the BSI.
//If 'bsid' is not valid decoder shall not decode the audio as per the standard. //If 'bsid' is not valid decoder shall not decode the audio as per the standard.
ac3_parse_bsi(ctx); ac3_parse_bsi(ctx);
avctx->sample_rate = ctx->sampling_rate; avctx->sample_rate = ctx->sampling_rate;
avctx->bit_rate = ctx->bit_rate; avctx->bit_rate = ctx->bit_rate;
avctx->channels = 0;
if (avctx->channels == 0) { if (avctx->channels == 0) {
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED; ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
avctx->channels = ctx->nfchans; if (ctx->lfeon)
} else if (ctx->nfchans + ctx->lfeon < avctx->channels) { ctx->blkoutput |= AC3_OUTPUT_LFEON;
av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n", avctx->channels = ctx->nfchans + ctx->lfeon;
avctx->channels, ctx->nfchans + ctx->lfeon); }
avctx->channels = ctx->nfchans; else if (avctx->channels == 1)
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
} else if (avctx->channels == 1) {
ctx->blkoutput |= AC3_OUTPUT_MONO; ctx->blkoutput |= AC3_OUTPUT_MONO;
} else if (avctx->channels == 2) { else if (avctx->channels == 2) {
if (ctx->dsurmod == 0x02) if (ctx->dsurmod == 0x02)
ctx->blkoutput |= AC3_OUTPUT_DOLBY; ctx->blkoutput |= AC3_OUTPUT_DOLBY;
else else
ctx->blkoutput |= AC3_OUTPUT_STEREO; ctx->blkoutput |= AC3_OUTPUT_STEREO;
} }
if (ctx->lfeon) { else {
avctx->channels++; if (avctx->channels < (ctx->nfchans + ctx->lfeon))
ctx->blkoutput |= AC3_OUTPUT_LFEON; av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",avctx->channels, ctx->nfchans + ctx->lfeon);
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
if (ctx->lfeon)
ctx->blkoutput |= AC3_OUTPUT_LFEON;
avctx->channels = ctx->nfchans + ctx->lfeon;
} }
av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->bit_rate * 1000, avctx->sample_rate); av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->bit_rate * 1000, avctx->sample_rate);
@ -2009,10 +1978,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
*data_size = 0; *data_size = 0;
return ctx->frame_size; return ctx->frame_size;
} }
j = ((ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1);
for (k = 0; k < BLOCK_SIZE; k++) { for (k = 0; k < BLOCK_SIZE; k++) {
j = ((ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1); j = (ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1;
for (;j < avctx->channels + 1; j++) { for (; j <= avctx->channels; j++) {
value = convert(ctx->output[j][k]); value = convert(ctx->output[j][k]);
*(out_samples++) = value; *(out_samples++) = value;
} }