[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