dither zero-bit mantissas by default. remove dithering only if it's explicitly turned off.

Originally committed as revision 9886 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Justin Ruggles 2007-08-04 01:13:08 +00:00
parent bca7db3530
commit 60f07fadd3

View File

@ -92,6 +92,7 @@ typedef struct {
int blksw[AC3_MAX_CHANNELS]; int blksw[AC3_MAX_CHANNELS];
int dithflag[AC3_MAX_CHANNELS]; int dithflag[AC3_MAX_CHANNELS];
int dither_all;
int cplinu; int cplinu;
int chincpl[AC3_MAX_CHANNELS]; int chincpl[AC3_MAX_CHANNELS];
int phsflginu; int phsflginu;
@ -460,27 +461,24 @@ typedef struct { /* grouped mantissas for 3-level 5-leve and 11-level quantizati
static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_groups *m) static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_groups *m)
{ {
GetBitContext *gb = &ctx->gb; GetBitContext *gb = &ctx->gb;
int i, gcode, tbap, dithflag, start, end; int i, gcode, tbap, start, end;
uint8_t *exps; uint8_t *exps;
uint8_t *bap; uint8_t *bap;
float *coeffs; float *coeffs;
if (ch_index >= 0) { /* fbw channels */ if (ch_index >= 0) { /* fbw channels */
dithflag = ctx->dithflag[ch_index];
exps = ctx->dexps[ch_index]; exps = ctx->dexps[ch_index];
bap = ctx->bap[ch_index]; bap = ctx->bap[ch_index];
coeffs = ctx->transform_coeffs[ch_index + 1]; coeffs = ctx->transform_coeffs[ch_index + 1];
start = 0; start = 0;
end = ctx->endmant[ch_index]; end = ctx->endmant[ch_index];
} else if (ch_index == -1) { } else if (ch_index == -1) {
dithflag = 0;
exps = ctx->dlfeexps; exps = ctx->dlfeexps;
bap = ctx->lfebap; bap = ctx->lfebap;
coeffs = ctx->transform_coeffs[0]; coeffs = ctx->transform_coeffs[0];
start = 0; start = 0;
end = 7; end = 7;
} else { } else {
dithflag = 0;
exps = ctx->dcplexps; exps = ctx->dcplexps;
bap = ctx->cplbap; bap = ctx->cplbap;
coeffs = ctx->transform_coeffs_cpl; coeffs = ctx->transform_coeffs_cpl;
@ -493,12 +491,7 @@ 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) {
coeffs[i] = 0;
}
else {
coeffs[i] = (av_random(&ctx->dith_state) & 0xFFFF) * LEVEL_MINUS_3DB; coeffs[i] = (av_random(&ctx->dith_state) & 0xFFFF) * LEVEL_MINUS_3DB;
}
break; break;
case 1: case 1:
@ -551,6 +544,39 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
return 0; return 0;
} }
/**
* Removes random dithering from coefficients with zero-bit mantissas
* reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0)
*/
static void remove_dithering(AC3DecodeContext *ctx) {
int ch, i;
int end=0;
float *coeffs;
uint8_t *bap;
for(ch=1; ch<=ctx->nfchans; ch++) {
if(!ctx->dithflag[ch-1]) {
coeffs = ctx->transform_coeffs[ch];
bap = ctx->bap[ch-1];
if(ctx->chincpl[ch-1])
end = ctx->cplstrtmant;
else
end = ctx->endmant[ch-1];
for(i=0; i<end; i++) {
if(bap[i] == 0)
coeffs[i] = 0.0f;
}
if(ctx->chincpl[ch-1]) {
bap = ctx->cplbap;
for(; i<ctx->cplendmant; i++) {
if(bap[i] == 0)
coeffs[i] = 0.0f;
}
}
}
}
}
/* Get the transform coefficients. /* Get the transform coefficients.
* This function extracts the tranform coefficients form the ac3 bitstream. * This function extracts the tranform coefficients form the ac3 bitstream.
* This function is called after bit allocation is performed. * This function is called after bit allocation is performed.
@ -592,6 +618,10 @@ static int get_transform_coeffs(AC3DecodeContext * ctx)
} }
} }
/* if any channel doesn't use dithering, zero appropriate coefficients */
if(!ctx->dither_all)
remove_dithering(ctx);
return 0; return 0;
} }
@ -708,8 +738,12 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk)
for (i = 0; i < nfchans; i++) /*block switch flag */ for (i = 0; i < nfchans; i++) /*block switch flag */
ctx->blksw[i] = get_bits1(gb); ctx->blksw[i] = get_bits1(gb);
for (i = 0; i < nfchans; i++) /* dithering flag */ ctx->dither_all = 1;
for (i = 0; i < nfchans; i++) { /* dithering flag */
ctx->dithflag[i] = get_bits1(gb); ctx->dithflag[i] = get_bits1(gb);
if(!ctx->dithflag[i])
ctx->dither_all = 0;
}
if (get_bits1(gb)) { /* dynamic range */ if (get_bits1(gb)) { /* dynamic range */
dynrng = get_sbits(gb, 8); dynrng = get_sbits(gb, 8);