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 | |
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')
-rw-r--r-- | libavcodec/wma.c | 40 | ||||
-rw-r--r-- | libavcodec/wma.h | 1 |
2 files changed, 41 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]; diff --git a/libavcodec/wma.h b/libavcodec/wma.h index 5a16331363..a207dfc956 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -150,6 +150,7 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, int ff_wma_init(AVCodecContext * avctx, int flags2); int ff_wma_total_gain_to_bits(int total_gain); int ff_wma_end(AVCodecContext *avctx); +unsigned int ff_wma_get_large_val(GetBitContext* gb); int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb, VLC *vlc, const uint16_t *level_table, const uint16_t *run_table, |