[FFmpeg-devel] [PATCH] E-AC-3 decoder, round 3

Michael Niedermayer michaelni
Sat Aug 23 00:23:30 CEST 2008


On Fri, Aug 22, 2008 at 06:01:22PM -0400, Justin Ruggles wrote:
[...]
> > 
> >> +
> >> +void ff_eac3_get_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch)
> >> +{
> >> +    int bin, blk, gs;
> >> +    int end_bap, gaq_mode;
> >> +    GetBitContext *gbc = &s->gbc;
> >> +    int gaq_gain[AC3_MAX_COEFS];
> >> +
> >> +    gaq_mode = get_bits(gbc, 2);
> >> +    end_bap = (gaq_mode < 2) ? 12 : 17;
> >> +
> >> +    /* if GAQ gain is used, decode gain codes for bins with hebap between
> >> +       8 and end_bap */
> >> +    gs = 0;
> >> +    if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) {
> >> +        /* read 1-bit GAQ gain codes */
> >> +        for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
> >> +            if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap)
> >> +                gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1);
> >> +        }
> >> +    } else if (gaq_mode == EAC3_GAQ_124) {
> >> +        /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */
> >> +        int gc = 2;
> >> +        for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
> >> +            if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap) {
> >> +                if (gc++ == 2) {
> >> +                    int group_gain = get_bits(gbc, 5);
> >> +                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_gain][0];
> >> +                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_gain][1];
> >> +                    gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_gain][2];
> >> +                    gc = 0;
> >> +                }
> >> +            }
> >> +        }
> >> +    }
> >> +
> >> +    gs=0;
> >> +    for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
> >> +        int hebap = s->bap[ch][bin];
> >> +        int bits = ff_eac3_bits_vs_hebap[hebap];
> >> +        if (!hebap) {
> >> +            /* zero-mantissa dithering */
> >> +            for (blk = 0; blk < 6; blk++) {
> >> +                s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
> >> +            }
> >> +        } else if (hebap < 8) {
> >> +            /* Vector Quantization */
> >> +            int v = get_bits(gbc, bits);
> >> +            for (blk = 0; blk < 6; blk++) {
> >> +                s->pre_mantissa[ch][bin][blk] = ff_eac3_vq_hebap[hebap][v][blk] << 8;
> >> +            }
> >> +        } else {
> >> +            /* Gain Adaptive Quantization */
> >> +            int gbits, log_gain;
> >> +            if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) {
> >> +                log_gain = gaq_gain[gs++];
> >> +            } else {
> >> +                log_gain = 0;
> >> +            }
> > 
> >> +            gbits = bits - log_gain;
> > 
> > this is maybe missing a check for gbits<=0, iam not certain it can happen
> > but i think it can
> 
> going strictly by the spec, it will not happen, but to ensure this i
> will need to add a check for the 3-in-5-bit group code to be less than
> 27 to keep the gaq_gain values within their valid range of 0 to 2.

yes, i think such check should be added


> 
> > 
> >> +
> >> +            for (blk = 0; blk < 6; blk++) {
> >> +                int mant = get_sbits(gbc, gbits);
> >> +                if (mant == -(1 << (gbits-1))) {
> >> +                    /* large mantissa */
> >> +                    int64_t b;
> >> +                    mant = get_sbits(gbc, bits-2+log_gain) << (26-log_gain-bits);
> >> +                    /* remap mantissa value to correct for asymmetric quantization */
> >> +                    if (mant >= 0)
> >> +                        b = 32768 >> log_gain;
> >> +                    else
> >> +                        b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1];
> >> +                    mant += ((int64_t)ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * mant + b) >> 15;
> > 
> > this can be done without a 64 bit multiple i think
> 
> I can see how it works for the other one, but not for this one.  In the
> other case it works out well because mant will always have zeros for at
> least the low 8 bits.  For this case, I don't see where avoiding the
> 64-bit multiply is possible without loss of precision.

mant can have bits-2+log_gain bits
bits has a max of 16, log_gain 2 or 3
that makes it need of 16 + sign
ff_eac3_gaq_remap_2_4_a has 14+ sign
thus a product of them would need 30 + sign if no left shift is applied
b has to be shifted right of course but no precission is lost that way as
it would be shifted away anyway, its stil bitexact ...

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

There will always be a question for which you do not know the correct awnser.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20080823/ed32672d/attachment.pgp>



More information about the ffmpeg-devel mailing list