diff options
author | Sascha Sommer <saschasommer@freenet.de> | 2009-06-20 10:28:55 +0000 |
---|---|---|
committer | Sascha Sommer <saschasommer@freenet.de> | 2009-06-20 10:28:55 +0000 |
commit | 891bd2e5aa420ed8ca386464c60cd79b3824e6fd (patch) | |
tree | a1577ab51fd28debf8dcfae44545fc99d22f2355 /libavcodec/wma.c | |
parent | 9970c61b4b85e1df8e109aef2ba003673823e722 (diff) | |
download | ffmpeg-891bd2e5aa420ed8ca386464c60cd79b3824e6fd.tar.gz |
Add support for escape coded wmapro run level coefficients
Originally committed as revision 19232 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/wma.c')
-rw-r--r-- | libavcodec/wma.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 7cebc9e009..cfa9f6b567 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -426,6 +426,28 @@ int ff_wma_end(AVCodecContext *avctx) } /** + * Decode an uncompressed coefficient. + * @param s codec context + * @return the decoded coefficient + */ +unsigned int ff_wma_get_large_val(GetBitContext* gb) +{ + /** consumes up to 34 bits */ + int n_bits = 8; + /** decode length */ + if (get_bits1(gb)) { + n_bits += 8; + if (get_bits1(gb)) { + n_bits += 8; + if (get_bits1(gb)) { + n_bits += 7; + } + } + } + return get_bits_long(gb, n_bits); +} + +/** * Decode run level compressed coefficients. * @param avctx codec context * @param gb bitstream reader context @@ -450,6 +472,7 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, { int code, run, level, sign; WMACoef* eptr = ptr + num_coefs; + ptr += offset; for(;;) { code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX); if (code < 0) @@ -459,10 +482,27 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, break; } else if (code == 0) { /* 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); + } else { + level = ff_wma_get_large_val(gb); + /** escape decode */ + if (get_bits1(gb)) { + if (get_bits1(gb)) { + if (get_bits1(gb)) { + av_log(avctx,AV_LOG_ERROR, + "broken escape sequence\n"); + return -1; + } else + run = get_bits(gb, frame_len_bits) + 4; + } else + run = get_bits(gb, 2) + 1; + } else + run = 0; + } } else { /* normal code */ run = run_table[code]; |