Mercurial > libavcodec.hg
changeset 9871:4433ce8ef249 libavcodec
Simplify run level decoding:
- remove unneeded vlc code < 0 check
- reorder vlc code handling so that the unlikely escape decoding
part comes last
- move overflow check out of the decode loop
- branchless sign conversion
author | faust3 |
---|---|
date | Sat, 20 Jun 2009 11:06:48 +0000 |
parents | 40638c6c2d69 |
children | 01ccb357a33c |
files | wma.c |
diffstat | 1 files changed, 21 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/wma.c Sat Jun 20 10:33:18 2009 +0000 +++ b/wma.c Sat Jun 20 11:06:48 2009 +0000 @@ -470,23 +470,24 @@ int num_coefs, int block_len, int frame_len_bits, int coef_nb_bits) { - int code, run, level, sign; - WMACoef* eptr = ptr + num_coefs; - ptr += offset; - for(;;) { + int code, level, sign; + const unsigned int coef_mask = block_len - 1; + for (; offset < num_coefs; offset++) { code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); - if (code < 0) - return -1; - if (code == 1) { + if (code > 1) { + /** normal code */ + offset += run_table[code]; + level = level_table[code]; + } else if (code == 1) { /* EOB */ break; - } else if (code == 0) { + } else { /* escape */ if (!version) { level = get_bits(gb, coef_nb_bits); /* NOTE: this is rather suboptimal. reading block_len_bits would be better */ - run = get_bits(gb, frame_len_bits); + offset += get_bits(gb, frame_len_bits); } else { level = ff_wma_get_large_val(gb); /** escape decode */ @@ -497,31 +498,21 @@ "broken escape sequence\n"); return -1; } else - run = get_bits(gb, frame_len_bits) + 4; + offset += get_bits(gb, frame_len_bits) + 4; } else - run = get_bits(gb, 2) + 1; - } else - run = 0; + offset += get_bits(gb, 2) + 1; + } } - } else { - /* normal code */ - run = run_table[code]; - level = level_table[code]; } - sign = get_bits1(gb); - if (!sign) - level = -level; - ptr += run; - if (ptr >= eptr) - { - av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); - break; - } - *ptr++ = level; - /* NOTE: EOB can be omitted */ - if (ptr >= eptr) - break; + sign = get_bits1(gb) - 1; + ptr[offset & coef_mask] = (level^sign) - sign; } + /** NOTE: EOB can be omitted */ + if (offset > num_coefs) { + av_log(avctx, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n"); + return -1; + } + return 0; }