Mercurial > libavcodec.hg
diff alsdec.c @ 11148:2d2780630361 libavcodec
Support arithmetic decoding in ALS.
author | thilo.borgmann |
---|---|
date | Sat, 13 Feb 2010 18:24:13 +0000 |
parents | 327019a2d156 |
children | 625a076b8038 |
line wrap: on
line diff
--- a/alsdec.c Sat Feb 13 18:23:46 2010 +0000 +++ b/alsdec.c Sat Feb 13 18:24:13 2010 +0000 @@ -34,6 +34,7 @@ #include "unary.h" #include "mpeg4audio.h" #include "bytestream.h" +#include "bgmc.h" #include <stdint.h> @@ -120,6 +121,28 @@ }; +/** Tail codes used in arithmetic coding using block Gilbert-Moore codes. + */ +static const uint8_t tail_code[16][6] = { + { 74, 44, 25, 13, 7, 3}, + { 68, 42, 24, 13, 7, 3}, + { 58, 39, 23, 13, 7, 3}, + {126, 70, 37, 19, 10, 5}, + {132, 70, 37, 20, 10, 5}, + {124, 70, 38, 20, 10, 5}, + {120, 69, 37, 20, 11, 5}, + {116, 67, 37, 20, 11, 5}, + {108, 66, 36, 20, 10, 5}, + {102, 62, 36, 20, 10, 5}, + { 88, 58, 34, 19, 10, 5}, + {162, 89, 49, 25, 13, 7}, + {156, 87, 49, 26, 14, 7}, + {150, 86, 47, 26, 14, 7}, + {142, 84, 47, 26, 14, 7}, + {131, 79, 46, 26, 14, 7} +}; + + enum RA_Flag { RA_FLAG_NONE, RA_FLAG_FRAMES, @@ -169,6 +192,8 @@ unsigned int frame_id; ///< the frame ID / number of the current frame unsigned int js_switch; ///< if true, joint-stereo decoding is enforced unsigned int num_blocks; ///< number of blocks used in the current frame + uint8_t *bgmc_lut; ///< pointer at lookup tables used for BGMC + unsigned int *bgmc_lut_status; ///< pointer at lookup table status flags used for BGMC int ltp_lag_length; ///< number of bits used for ltp lag value int *use_ltp; ///< contains use_ltp flags for all channels int *ltp_lag; ///< contains ltp lag values for all channels @@ -383,7 +408,6 @@ } MISSING_ERR(sconf->floating, "Floating point decoding", -1); - MISSING_ERR(sconf->bgmc, "BGMC entropy decoding", -1); MISSING_ERR(sconf->rlslms, "Adaptive RLS-LMS prediction", -1); MISSING_ERR(sconf->chan_sort, "Channel sorting", 0); @@ -554,11 +578,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 @@ -591,9 +617,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++) @@ -697,9 +729,76 @@ // 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; + unsigned int low; + unsigned int value; + + ff_bgmc_decode_init(gb, &high, &low, &value); + + current_res = bd->raw_samples + start; + + for (sb = 0; sb < sub_blocks; sb++, i = 0) { + k [sb] = s[sb] > b ? s[sb] - b : 0; + delta[sb] = 5 - s[sb] + k[sb]; + + ff_bgmc_decode(gb, sb_length, current_res, + delta[sb], sx[sb], &high, &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); + + current_res += sb_length; + } + + ff_bgmc_decode_end(gb); + + + // 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++) { + int32_t res = *current_res; + + if (res == cur_tail_code) { + unsigned int max_msb = (2 + (sx[sb] > 2) + (sx[sb] > 10)) + << (5 - delta[sb]); + + res = decode_rice(gb, cur_s); + + if (res >= 0) { + res += (max_msb ) << cur_k; + } else { + res -= (max_msb - 1) << cur_k; + } + } else { + if (res > cur_tail_code) + res--; + + if (res & 1) + res = -res; + + res >>= 1; + + if (cur_k) { + res <<= cur_k; + res |= get_bits_long(gb, cur_k); + } + } + + *current_res++ = res; + } + } } 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++) @@ -1348,6 +1447,8 @@ av_freep(&ctx->sconf.chan_pos); + ff_bgmc_end(&ctx->bgmc_lut, &ctx->bgmc_lut_status); + av_freep(&ctx->use_ltp); av_freep(&ctx->ltp_lag); av_freep(&ctx->ltp_gain); @@ -1395,6 +1496,9 @@ return -1; } + if (sconf->bgmc) + ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); + if (sconf->floating) { avctx->sample_fmt = SAMPLE_FMT_FLT; avctx->bits_per_raw_sample = 32;