summaryrefslogtreecommitdiff
path: root/apps/codecs/libwmapro/wma.c
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-07-12 15:41:10 +0000
committerMohamed Tarek <mt@rockbox.org>2010-07-12 15:41:10 +0000
commitec4ee483181d01d14444e4431159282ecd92a2c5 (patch)
tree2f5c121e1fd41f518b0ee06362e3023110043e3f /apps/codecs/libwmapro/wma.c
parentddbfffb2173630b16b5ddafaa6449cad8709bf83 (diff)
downloadrockbox-ec4ee483181d01d14444e4431159282ecd92a2c5.zip
rockbox-ec4ee483181d01d14444e4431159282ecd92a2c5.tar.gz
rockbox-ec4ee483181d01d14444e4431159282ecd92a2c5.tar.bz2
rockbox-ec4ee483181d01d14444e4431159282ecd92a2c5.tar.xz
Complete the conversion of WMA Pro to fixed point. Floating point code is still there for better history and to have a returning point in svn should something go wrong.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27402 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwmapro/wma.c')
-rw-r--r--apps/codecs/libwmapro/wma.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/apps/codecs/libwmapro/wma.c b/apps/codecs/libwmapro/wma.c
index 4b36c84..b1b1268 100644
--- a/apps/codecs/libwmapro/wma.c
+++ b/apps/codecs/libwmapro/wma.c
@@ -523,3 +523,58 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
return 0;
}
+int ff_wma_fix_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
+ VLC *vlc,
+ const int32_t *level_table, const uint16_t *run_table,
+ int version, int32_t *ptr, int offset,
+ int num_coefs, int block_len, int frame_len_bits,
+ int coef_nb_bits)
+{
+ int32_t 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 > 1) {
+ /** normal code */
+ offset += run_table[code];
+ sign = !get_bits1(gb);
+ ptr[offset & coef_mask] = sign ? -level_table[code] : level_table[code];
+ ptr[offset & coef_mask] <<= 16;
+ } else if (code == 1) {
+ /** EOB */
+ break;
+ } else {
+ /** escape */
+ if (!version) {
+ level = get_bits(gb, coef_nb_bits);
+ /** NOTE: this is rather suboptimal. reading
+ block_len_bits would be better */
+ offset += 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
+ offset += get_bits(gb, frame_len_bits) + 4;
+ } else
+ offset += get_bits(gb, 2) + 1;
+ }
+ }
+ sign = !get_bits1(gb);
+ ptr[offset & coef_mask] = sign ? -level : level;
+ ptr[offset & coef_mask] <<=16;
+ }
+ }
+ /** 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;
+}