[FFmpeg-devel] [PATCH] Arithmetic decoding in ALS

Michael Niedermayer michaelni
Tue Jan 12 00:33:39 CET 2010


On Mon, Jan 11, 2010 at 09:15:05PM +0100, Thilo Borgmann wrote:
> Hi,
> 
> this patch adds arithmetic decoding using block Gilbert-Moore codes
> (BGMC) to ALS.

i think this could be placed in a seperate file

[...]
> @@ -436,6 +841,59 @@
>  }
>  
>  
> +/** Reads and decodes a block Gilbert-Moore coded symbol,
> + *  refer to ISO/IEC 14496-3, section 11.6.6.2.
> + */
> +static int32_t decode_bgmc(GetBitContext *gb, unsigned int delta, unsigned int sx,
> +                           unsigned int *h, unsigned int *l, unsigned int *v)
> +{
> +#define FIRST_QTR 0x10000 // first quarter
> +#define HALF      0x20000 // first half
> +#define THIRD_QTR 0x30000 // third quarter
> +
> +    // read current state
> +    unsigned int high   = *h;
> +    unsigned int low    = *l;
> +    unsigned int value  = *v;
> +
> +    // decode
> +    unsigned int range  = high - low + 1;
> +    unsigned int target = (((value - low + 1) << 14) - 1) / range;
> +    unsigned int symbol = 0;
> +

> +    while (cf_table[sx][(symbol + 1) << delta] > target)
> +        symbol++;

this probably can be speed up by a LUT of some of the MSBs


> +
> +    high = low + ((range * cf_table[sx][(symbol    ) << delta] - (1 << 14)) >> 14);
> +    low  = low + ((range * cf_table[sx][(symbol + 1) << delta]            ) >> 14);
> +
> +    while (1) {
> +        if (high >= HALF) {
> +            if        (low >= HALF) {
> +                value -= HALF;
> +                low   -= HALF;
> +                high  -= HALF;
> +            } else if (low >= FIRST_QTR && high < THIRD_QTR) {
> +                value -= FIRST_QTR;
> +                low   -= FIRST_QTR;
> +                high  -= FIRST_QTR;
> +            } else break;
> +        }
> +
> +        low   *= 2;
> +        high   = 2 * high  + 1;
> +        value  = 2 * value + get_bits1(gb);
> +    }
> +
> +    // save current state
> +    *h = high;
> +    *l = low;
> +    *v = value;

for (; i < sb_length; i++)
can be done inside the h/v/l load/store thus avoiding doing it for every
symbol



> +
> +    return symbol;
> +}
> +
> +
>  /** Converts PARCOR coefficient k to direct filter coefficient.
>   */
>  static void parcor_to_lpc(unsigned int k, const int32_t *par, int32_t *cof)
> @@ -557,11 +1015,13 @@
>      GetBitContext *gb        = &ctx->gb;
>      unsigned int k;
>      unsigned int s[8];
> +    unsigned int sx[8];
>      unsigned int sub_blocks, log2_sub_blocks, sb_length;
>      unsigned int start      = 0;
>      unsigned int opt_order;
>      int          sb;
>      int32_t      *quant_cof = bd->quant_cof;
> +    int32_t      *current_res;
>  
>  
>      // ensure variable block decoding by reusing this field
> @@ -594,9 +1054,15 @@
>  
>      sb_length = bd->block_length >> log2_sub_blocks;
>  
> +    if (sconf->bgmc) {
> +        s[0] = get_bits(gb, 8 + (sconf->resolution > 1));
> +        for (k = 1; k < sub_blocks; k++)
> +            s[k] = s[k - 1] + decode_rice(gb, 2);
>  
> -    if (sconf->bgmc) {
> -        // TODO: BGMC mode
> +        for (k = 0; k < sub_blocks; k++) {
> +            sx[k]   = s[k] & 0x0F;
> +            s [k] >>= 4;
> +        }
>      } else {
>          s[0] = get_bits(gb, 4 + (sconf->resolution > 1));
>          for (k = 1; k < sub_blocks; k++)
> @@ -700,9 +1166,71 @@
>  
>      // read all residuals
>      if (sconf->bgmc) {
> -        // TODO: BGMC mode
> +        unsigned int delta[sub_blocks];
> +        unsigned int k    [sub_blocks];
> +        unsigned int B = av_clip((av_ceil_log2(bd->block_length) - 3) >> 1, 0, 5);
> +        unsigned int i = start;
> +
> +        // read most significant bits
> +        unsigned int high  = (1 << 18) - 1;
> +        unsigned int low   = 0;
> +        unsigned int value = get_bits_long(gb, 18);
> +
> +        current_res = bd->raw_samples + start;
> +
> +        for (sb = 0; sb < sub_blocks; sb++, i = 0) {
> +            unsigned int cur_delta;
> +            unsigned int cur_sx = sx[sb];
> +            k[sb]               = s[sb] > B ? s[sb] - B : 0;
> +            delta[sb]           = 5 - s[sb] + k[sb];
> +            cur_delta           = delta[sb];
> +
> +            for (; i < sb_length; i++)
> +                *current_res++ = decode_bgmc(gb, cur_delta, cur_sx,
> +                                             &high, &low, &value);
> +        }
> +
> +        skip_bits(gb, -16);
> +
> +        // read least significant bits and tails
> +        i = start;
> +        current_res = bd->raw_samples + start;
> +
> +        for (sb = 0; sb < sub_blocks; sb++, i = 0) {
> +            unsigned int cur_tail_code = tail_code[sx[sb]][delta[sb]];
> +            unsigned int cur_k         = k[sb];
> +            unsigned int cur_s         = s[sb];
> +
> +            for (; i < sb_length; i++) {

> +                if (*current_res == cur_tail_code) {
> +                    unsigned int max_msb =   (2 + (sx[sb] > 2) + (sx[sb] > 10))
> +                                          << (5 - delta[sb]);
> +                    *current_res = decode_rice(gb, cur_s);
> +
> +                    if (*current_res >= 0)
> +                        *current_res += (max_msb    ) << cur_k;
> +                    else
> +                        *current_res -= (max_msb - 1) << cur_k;
> +                } else {
> +                    if (*current_res > cur_tail_code)
> +                        (*current_res)--;
> +
> +                    if (*current_res & 1)
> +                        *current_res = -(*current_res) - 1;
> +
> +                    *current_res >>= 1;
> +
> +                    if (cur_k) {
> +                        *current_res <<= cur_k;
> +                        *current_res  |= get_bits_long(gb, cur_k);
> +                    }
> +                }
> +
> +            current_res++;

this would look simpler as
int v= *current_res;

...

*current_res++= v;

> +            }
> +        }
>      } else {
> -        int32_t *current_res = bd->raw_samples + start;
> +        current_res = bd->raw_samples + start;
>  
>          for (sb = 0; sb < sub_blocks; sb++, start = 0)
>              for (; start < sb_length; start++)

> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at mplayerhq.hu
> https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-devel

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

While the State exists there can be no freedom; when there is freedom there
will be no State. -- Vladimir Lenin
-------------- 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/20100112/e963a9a8/attachment.pgp>



More information about the ffmpeg-devel mailing list