From 60f07fadd390d4d3c04e723759c32b2a97ec99ca Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 4 Aug 2007 01:13:08 +0000 Subject: [PATCH] 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 --- libavcodec/ac3dec.c | 54 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 98e2ad0793..7a3d36b0cd 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -92,6 +92,7 @@ typedef struct { int blksw[AC3_MAX_CHANNELS]; int dithflag[AC3_MAX_CHANNELS]; + int dither_all; int cplinu; int chincpl[AC3_MAX_CHANNELS]; 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) { GetBitContext *gb = &ctx->gb; - int i, gcode, tbap, dithflag, start, end; + int i, gcode, tbap, start, end; uint8_t *exps; uint8_t *bap; float *coeffs; if (ch_index >= 0) { /* fbw channels */ - dithflag = ctx->dithflag[ch_index]; exps = ctx->dexps[ch_index]; bap = ctx->bap[ch_index]; coeffs = ctx->transform_coeffs[ch_index + 1]; start = 0; end = ctx->endmant[ch_index]; } else if (ch_index == -1) { - dithflag = 0; exps = ctx->dlfeexps; bap = ctx->lfebap; coeffs = ctx->transform_coeffs[0]; start = 0; end = 7; } else { - dithflag = 0; exps = ctx->dcplexps; bap = ctx->cplbap; 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]; switch (tbap) { case 0: - if (!dithflag) { - coeffs[i] = 0; - } - else { coeffs[i] = (av_random(&ctx->dith_state) & 0xFFFF) * LEVEL_MINUS_3DB; - } break; case 1: @@ -551,6 +544,39 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro 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; ichincpl[ch-1]) { + bap = ctx->cplbap; + for(; icplendmant; i++) { + if(bap[i] == 0) + coeffs[i] = 0.0f; + } + } + } + } +} + /* Get the transform coefficients. * This function extracts the tranform coefficients form the ac3 bitstream. * 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; } @@ -708,8 +738,12 @@ static int ac3_parse_audio_block(AC3DecodeContext *ctx, int blk) for (i = 0; i < nfchans; i++) /*block switch flag */ 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); + if(!ctx->dithflag[i]) + ctx->dither_all = 0; + } if (get_bits1(gb)) { /* dynamic range */ dynrng = get_sbits(gb, 8);