[packman] MPlayer

Carl Eugen Hoyos ce at hoyos.ws
Sun Mar 22 16:31:02 CET 2009


Hi!

Current packman MPlayer version is quite ugly...
Since I don't know when we finally release, I'd recommend to use latest 
svn (as a kind of "prerelease"), it should contain quite a few 
improvements compared to 27637, including vdpau.
Attached is a patch especially useful for x86-64, it contains the future 
wmapro implementation from ffmpeg-soc repository. With this patch, binary 
codecs should not be necessary anymore (in case you have bandwidth 
problems).

Carl Eugen
-------------- next part --------------
Index: etc/codecs.conf
===================================================================
--- etc/codecs.conf	(revision 29032)
+++ etc/codecs.conf	(working copy)
@@ -3596,6 +3596,14 @@
   driver ffmpeg
   dll "wmav2"
 
+audiocodec ffwmapro
+  info "FFmpeg WMA Pro audio"
+  status untested
+  format 0x162
+  fourcc "WMA3"
+  driver ffmpeg
+  dll "wmapro"
+
 audiocodec ffmac3
   info "Macintosh Audio Compression and Expansion 3:1"
   status untested
Index: libavcodec/wma3data.h
===================================================================
--- libavcodec/wma3data.h	(revision 0)
+++ libavcodec/wma3data.h	(revision 0)
@@ -0,0 +1,588 @@
+/*
+ * WMA 9/3/PRO compatible decoder
+ * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
+ * Copyright (c) 2008 - 2009 Sascha Sommer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file  libavcodec/wma3data.h
+ * @brief tables for wmapro decoding
+ */
+
+#ifndef AVCODEC_WMA3DATA_H
+#define AVCODEC_WMA3DATA_H
+
+/**
+ * @brief frequencies to divide the frequency spectrum into scale factor bands
+ */
+static const uint16_t ff_wma3_critical_freq[] = {
+     100,   200,    300,    400,    510,    630,    770,
+     920,  1080,   1270,   1480,   1720,   2000,   2320,
+    2700,  3150,   3700,   4400,   5300,   6400,   7700,
+    9500, 12000,  15500,  20675,  28575,  41375,  63875,
+};
+
+
+/**
+ * @name huffman tables for DPCM-coded scale factors
+ * @{
+ */
+#define FF_WMA3_HUFF_SCALE_SIZE 121
+#define FF_WMA3_HUFF_SCALE_MAXBITS 19
+static const uint32_t ff_wma3_scale_huffcodes[FF_WMA3_HUFF_SCALE_SIZE] = {
+    0x0E639, 0x0E6C2, 0x0E6C1, 0x0E6C0, 0x0E63F, 0x0E63E, 0x0E63D, 0x0E63C,
+    0x0E63B, 0x0E63A, 0x0E638, 0x0E637, 0x0E636, 0x0E635, 0x0E634, 0x0E632,
+    0x0E633, 0x0E620, 0x0737B, 0x0E610, 0x0E611, 0x0E612, 0x0E613, 0x0E614,
+    0x0E615, 0x0E616, 0x0E617, 0x0E618, 0x0E619, 0x0E61A, 0x0E61B, 0x0E61C,
+    0x0E61D, 0x0E61E, 0x0E61F, 0x0E6C3, 0x0E621, 0x0E622, 0x0E623, 0x0E624,
+    0x0E625, 0x0E626, 0x0E627, 0x0E628, 0x0E629, 0x0E62A, 0x0E62B, 0x0E62C,
+    0x0E62D, 0x0E62E, 0x0E62F, 0x0E630, 0x0E631, 0x01CDF, 0x00E60, 0x00399,
+    0x000E7, 0x0001D, 0x00000, 0x00001, 0x00001, 0x00001, 0x00002, 0x00006,
+    0x00002, 0x00007, 0x00006, 0x0000F, 0x00038, 0x00072, 0x0039A, 0x0E6C4,
+    0x0E6C5, 0x0E6C6, 0x0E6C7, 0x0E6C8, 0x0E6C9, 0x0E6CA, 0x0E6CB, 0x0E6CC,
+    0x0E6CD, 0x0E6CE, 0x0E6CF, 0x0E6D0, 0x0E6D1, 0x0E6D2, 0x0E6D3, 0x0E6D4,
+    0x0E6D5, 0x0E6D6, 0x0E6D7, 0x0E6D8, 0x0E6D9, 0x0E6DA, 0x0E6DB, 0x0E6DC,
+    0x0E6DD, 0x0E6DE, 0x0E6DF, 0x0E6E0, 0x0E6E1, 0x0E6E2, 0x0E6E3, 0x0E6E4,
+    0x0E6E5, 0x0E6E6, 0x0E6E7, 0x0E6E8, 0x0E6E9, 0x0E6EA, 0x0E6EB, 0x0E6EC,
+    0x0E6ED, 0x0E6EE, 0x0E6EF, 0x0E6F0, 0x0E6F1, 0x0E6F2, 0x0E6F3, 0x0E6F4,
+    0x0E6F5,
+};
+
+static const uint8_t ff_wma3_scale_huffbits[FF_WMA3_HUFF_SCALE_SIZE] = {
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 18, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 16, 15, 13,
+    11,  8,  5,  2,  1,  3,  5,  6,
+     6,  7,  7,  7,  9, 10, 13, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19, 19, 19, 19, 19, 19, 19, 19,
+    19,
+};
+/** @} */
+
+
+/**
+ * @name huffman, run and level tables for run length coded scale factors
+ * @{
+ */
+#define FF_WMA3_HUFF_SCALE_RL_SIZE 120
+#define FF_WMA3_HUFF_SCALE_RL_MAXBITS 21
+static const uint32_t ff_wma3_scale_rl_huffcodes[FF_WMA3_HUFF_SCALE_RL_SIZE] = {
+    0x00010C, 0x000001, 0x10FE2A, 0x000003, 0x000003, 0x000001, 0x000013,
+    0x000020, 0x000029, 0x000014, 0x000016, 0x000045, 0x000049, 0x00002F,
+    0x000042, 0x00008E, 0x00008F, 0x000129, 0x000009, 0x00000D, 0x0004AC,
+    0x00002C, 0x000561, 0x0002E6, 0x00087C, 0x0002E2, 0x00095C, 0x000018,
+    0x000001, 0x000016, 0x000044, 0x00002A, 0x000007, 0x000159, 0x000143,
+    0x000128, 0x00015A, 0x00012D, 0x00002B, 0x0000A0, 0x000142, 0x00012A,
+    0x0002EF, 0x0004AF, 0x00087D, 0x004AE9, 0x0043F9, 0x000067, 0x000199,
+    0x002B05, 0x001583, 0x0021FE, 0x10FE2C, 0x000004, 0x00002E, 0x00010D,
+    0x00000A, 0x000244, 0x000017, 0x000245, 0x000011, 0x00010E, 0x00012C,
+    0x00002A, 0x00002F, 0x000121, 0x000046, 0x00087E, 0x0000BA, 0x000032,
+    0x0087F0, 0x0056DC, 0x0002EC, 0x0043FA, 0x002B6F, 0x004AE8, 0x0002B7,
+    0x10FE2B, 0x000001, 0x000051, 0x000010, 0x0002EE, 0x000B9C, 0x002576,
+    0x000198, 0x0056DD, 0x0000CD, 0x000AC0, 0x000170, 0x004AEF, 0x00002D,
+    0x0004AD, 0x0021FF, 0x0005CF, 0x002B04, 0x10FE29, 0x10FE28, 0x0002ED,
+    0x002E74, 0x021FC4, 0x004AEE, 0x010FE3, 0x087F17, 0x000000, 0x000097,
+    0x0002E3, 0x000ADA, 0x002575, 0x00173B, 0x0043FB, 0x002E75, 0x10FE2D,
+    0x0015B6, 0x00056C, 0x000057, 0x000123, 0x000120, 0x00021E, 0x000172,
+    0x0002B1,
+};
+
+static const uint8_t ff_wma3_scale_rl_huffbits[FF_WMA3_HUFF_SCALE_RL_SIZE] = {
+     9,  2, 21,  2,  4,  5,  5,
+     6,  6,  7,  7,  7,  7,  6,
+     7,  8,  8,  9, 10, 10, 11,
+    12, 11, 12, 12, 12, 12, 11,
+     4,  5,  7,  8,  9,  9,  9,
+     9,  9,  9,  8,  8,  9,  9,
+    12, 11, 12, 15, 15, 13, 15,
+    14, 13, 14, 21,  5,  6,  9,
+    10, 10, 11, 10, 11,  9,  9,
+     6,  8,  9,  7, 12, 10, 12,
+    16, 15, 12, 15, 14, 15, 10,
+    21,  6,  7, 11, 12, 14, 14,
+    15, 15, 14, 12, 11, 15, 12,
+    11, 14, 13, 14, 21, 21, 12,
+    16, 18, 15, 17, 20,  7,  8,
+    12, 12, 14, 15, 15, 16, 21,
+    13, 11,  7,  9,  9, 10, 11,
+    10,
+};
+
+
+static const uint8_t ff_wma3_scale_rl_run[FF_WMA3_HUFF_SCALE_RL_SIZE] = {
+     0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 23, 24,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
+    10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  0,  1,  2,  3,
+     4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+    23, 24,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
+    17, 18, 19, 20, 21, 22, 23, 24,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
+     0,  1,  0,  1,  0,  1,
+};
+
+static const uint8_t ff_wma3_scale_rl_level[FF_WMA3_HUFF_SCALE_RL_SIZE] = {
+     0,  0,  1,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+     2,  2,  2,  2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,  4,  4,
+     4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+     4,  4,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,
+     5,  5,  5,  5,  5,  5,  5,  5,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
+     7,  7,  8,  8,  9,  9,
+};
+/** @} */
+
+
+/**
+ * @name huffman, run and level codes for run length coded coefficients
+ * @{
+ */
+#define FF_WMA3_HUFF_COEF0_SIZE 272
+#define FF_WMA3_HUFF_COEF0_MAXBITS 21
+static const uint32_t ff_wma3_coef0_huffcodes[FF_WMA3_HUFF_COEF0_SIZE] = {
+    0x00004A, 0x00002B, 0x000000, 0x000003, 0x000006, 0x000009, 0x00000F,
+    0x000010, 0x000016, 0x000011, 0x000016, 0x000028, 0x00002F, 0x000026,
+    0x000029, 0x000045, 0x000055, 0x00005D, 0x000042, 0x00004E, 0x000051,
+    0x00005E, 0x00008D, 0x0000A8, 0x0000AD, 0x000080, 0x000096, 0x00009F,
+    0x0000AA, 0x0000BE, 0x00011C, 0x000153, 0x000158, 0x000170, 0x000104,
+    0x00010D, 0x000105, 0x000103, 0x00012F, 0x000177, 0x000175, 0x000157,
+    0x000174, 0x000225, 0x00023B, 0x00020D, 0x00021F, 0x000281, 0x00027B,
+    0x000282, 0x0002AC, 0x0002FD, 0x00044F, 0x000478, 0x00044D, 0x0002EC,
+    0x00044E, 0x000564, 0x000409, 0x00040B, 0x000501, 0x000545, 0x0004F3,
+    0x000541, 0x00043B, 0x0004F1, 0x0004F4, 0x0008FD, 0x000A94, 0x000811,
+    0x000B88, 0x000B91, 0x000B93, 0x0008EA, 0x000899, 0x000B8A, 0x000972,
+    0x0009E5, 0x000A8F, 0x000A84, 0x000A8E, 0x000A00, 0x000830, 0x0008E8,
+    0x000B95, 0x000871, 0x00083A, 0x000814, 0x000873, 0x000BFE, 0x001728,
+    0x001595, 0x001712, 0x00102A, 0x001021, 0x001729, 0x00152E, 0x0013C3,
+    0x001721, 0x001597, 0x00151B, 0x0010F2, 0x001403, 0x001703, 0x001503,
+    0x001708, 0x0013C1, 0x00170E, 0x00170C, 0x0010E1, 0x0011EA, 0x001020,
+    0x001500, 0x0017FA, 0x001704, 0x001705, 0x0017F0, 0x0017FB, 0x0021E6,
+    0x002B2D, 0x0020C6, 0x002B29, 0x002E4A, 0x0023AC, 0x001519, 0x0023F3,
+    0x002B2C, 0x0021C0, 0x0017FE, 0x0023D7, 0x0017F9, 0x0012E7, 0x0013C0,
+    0x002261, 0x0023D3, 0x002057, 0x002056, 0x0021D2, 0x0020C7, 0x0023D2,
+    0x0020EC, 0x0044C0, 0x002FE2, 0x00475B, 0x002A03, 0x002FE3, 0x0021E2,
+    0x0021D0, 0x002A31, 0x002E13, 0x002E05, 0x0047E5, 0x00000E, 0x000024,
+    0x000088, 0x0000B9, 0x00010C, 0x000224, 0x0002B3, 0x000283, 0x0002ED,
+    0x00047B, 0x00041E, 0x00043D, 0x0004F5, 0x0005FD, 0x000A92, 0x000B96,
+    0x000838, 0x000971, 0x000B83, 0x000B80, 0x000BF9, 0x0011D3, 0x0011E8,
+    0x0011D7, 0x001527, 0x0011F8, 0x001073, 0x0010F0, 0x0010E4, 0x0017F8,
+    0x001062, 0x001402, 0x0017E3, 0x00151A, 0x001077, 0x00152B, 0x00170D,
+    0x0021D3, 0x002E41, 0x0013C2, 0x000029, 0x0000A9, 0x00025D, 0x000419,
+    0x000544, 0x000B8B, 0x0009E4, 0x0011D2, 0x001526, 0x001724, 0x0012E6,
+    0x00150B, 0x0017FF, 0x002E26, 0x002E4B, 0x002B28, 0x0021E3, 0x002A14,
+    0x00475A, 0x002E12, 0x000057, 0x00023E, 0x000A90, 0x000BF0, 0x001072,
+    0x001502, 0x0023D6, 0x0020ED, 0x002A30, 0x0044C7, 0x00008C, 0x00047F,
+    0x00152A, 0x002262, 0x002E04, 0x0000A1, 0x0005F9, 0x000173, 0x000875,
+    0x000171, 0x00152D, 0x0002E3, 0x0017E2, 0x0002AD, 0x0021C1, 0x000479,
+    0x0021E7, 0x00041F, 0x005C4E, 0x000543, 0x005C4F, 0x000A91, 0x00898D,
+    0x000B97, 0x008746, 0x000970, 0x008745, 0x000B85, 0x00A856, 0x00152F,
+    0x010E8E, 0x0010E5, 0x00A857, 0x00170F, 0x021D11, 0x002A58, 0x010E8F,
+    0x002E40, 0x021D13, 0x002A59, 0x043A25, 0x002A02, 0x043A21, 0x0044C1,
+    0x087448, 0x0047E4, 0x043A20, 0x00542A, 0x087449, 0x00898C,
+};
+
+static const uint8_t ff_wma3_coef0_huffbits[FF_WMA3_HUFF_COEF0_SIZE] = {
+     8,  7,  2,  3,  3,  4,  4,
+     5,  5,  6,  6,  6,  6,  7,
+     7,  7,  7,  7,  8,  8,  8,
+     8,  8,  8,  8,  9,  9,  9,
+     9,  9,  9,  9,  9,  9, 10,
+    10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11,
+    11, 11, 12, 12, 12, 12, 12,
+    12, 12, 12, 12, 12, 12, 13,
+    12, 12, 12, 12, 12, 12, 13,
+    13, 13, 13, 13, 13, 13, 12,
+    12, 13, 13, 13, 13, 13, 13,
+    13, 13, 14, 14, 13, 13, 14,
+    13, 13, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 14,
+    14, 14, 14, 14, 14, 14, 15,
+    14, 15, 14, 14, 14, 14, 14,
+    14, 15, 14, 14, 14, 14, 14,
+    14, 14, 15, 15, 15, 15, 14,
+    15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15,  4,  7,
+     8,  9, 10, 10, 10, 11, 11,
+    11, 12, 12, 12, 12, 12, 12,
+    13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 13, 14,
+    15, 14, 14,  6,  9, 11, 12,
+    12, 12, 13, 13, 13, 13, 14,
+    14, 14, 14, 14, 14, 15, 15,
+    15, 15,  7, 10, 12, 13, 14,
+    14, 14, 15, 15, 15,  8, 11,
+    13, 14, 15,  9, 12,  9, 13,
+    10, 13, 10, 14, 11, 15, 11,
+    15, 12, 15, 12, 15, 12, 16,
+    12, 17, 13, 17, 13, 17, 13,
+    18, 14, 17, 14, 19, 14, 18,
+    14, 19, 14, 20, 15, 20, 15,
+    21, 15, 20, 16, 21, 16,
+};
+
+
+#define FF_WMA3_HUFF_COEF1_SIZE 244
+#define FF_WMA3_HUFF_COEF1_MAXBITS 22
+static const uint32_t ff_wma3_coef1_huffcodes[FF_WMA3_HUFF_COEF1_SIZE] = {
+    0x0001E2, 0x00007F, 0x000000, 0x000002, 0x000008, 0x00000E, 0x000019,
+    0x00002F, 0x000037, 0x000060, 0x00006C, 0x000095, 0x0000C6, 0x0000F0,
+    0x00012E, 0x000189, 0x0001A5, 0x0001F8, 0x000253, 0x00030A, 0x000344,
+    0x00034D, 0x0003F2, 0x0004BD, 0x0005D7, 0x00062A, 0x00068B, 0x000693,
+    0x000797, 0x00097D, 0x000BAB, 0x000C52, 0x000C5E, 0x000D21, 0x000D20,
+    0x000F1A, 0x000FCE, 0x000FD1, 0x0012F1, 0x001759, 0x0018AC, 0x0018A7,
+    0x0018BF, 0x001A2B, 0x001E52, 0x001E50, 0x001E31, 0x001FB8, 0x0025E6,
+    0x0025E7, 0x002EB4, 0x002EB7, 0x003169, 0x00315B, 0x00317C, 0x00316C,
+    0x0034CA, 0x00348D, 0x003F40, 0x003CA2, 0x003F76, 0x004BC3, 0x004BE5,
+    0x003F73, 0x004BF8, 0x004BF9, 0x006131, 0x00628B, 0x006289, 0x0062DA,
+    0x00628A, 0x0062D4, 0x006997, 0x0062B4, 0x006918, 0x00794D, 0x007E7B,
+    0x007E87, 0x007EEA, 0x00794E, 0x00699D, 0x007967, 0x00699F, 0x0062DB,
+    0x007E7A, 0x007EEB, 0x00BAC0, 0x0097C9, 0x00C537, 0x00C5AB, 0x00D233,
+    0x00D338, 0x00BAC1, 0x00D23D, 0x012F91, 0x00D339, 0x00FDC8, 0x00D23C,
+    0x00FDDC, 0x00FDC9, 0x00FDDD, 0x00D33C, 0x000003, 0x000016, 0x00003E,
+    0x0000C3, 0x0001A1, 0x000347, 0x00062E, 0x000BAA, 0x000F2D, 0x001A2A,
+    0x001E58, 0x00309B, 0x003CA3, 0x005D6A, 0x00629A, 0x006996, 0x00794F,
+    0x007EE5, 0x00BAD7, 0x00C5AA, 0x00C5F4, 0x00FDDF, 0x00FDDE, 0x018A20,
+    0x018A6D, 0x01A67B, 0x01A464, 0x025F21, 0x01F9E2, 0x01F9E3, 0x00000A,
+    0x00003D, 0x000128, 0x0003C7, 0x000C24, 0x0018A3, 0x002EB1, 0x003CB2,
+    0x00691F, 0x007E79, 0x000013, 0x0000BB, 0x00034E, 0x000D14, 0x0025FD,
+    0x004BE7, 0x000024, 0x000188, 0x0007EF, 0x000035, 0x000308, 0x0012F2,
+    0x00005C, 0x0003F6, 0x0025E0, 0x00006D, 0x000698, 0x000096, 0x000C25,
+    0x0000C7, 0x000F1B, 0x0000F3, 0x0012FF, 0x000174, 0x001A66, 0x0001A0,
+    0x003099, 0x0001E4, 0x00316B, 0x000252, 0x003F31, 0x00030B, 0x004BE6,
+    0x000346, 0x0062FB, 0x00034F, 0x007966, 0x0003F5, 0x007E86, 0x0005D4,
+    0x00C511, 0x00062C, 0x00C5F5, 0x000692, 0x00F299, 0x000795, 0x00F298,
+    0x0007E9, 0x018A21, 0x00097E, 0x0175AD, 0x000C27, 0x01A67A, 0x000C57,
+    0x02EB59, 0x000D22, 0x0314D9, 0x000F19, 0x03F3C2, 0x000FCD, 0x0348CB,
+    0x0012F8, 0x04BE41, 0x0018A0, 0x03F3C1, 0x0018A1, 0x04BE40, 0x0018B7,
+    0x0629B0, 0x001A64, 0x0D2329, 0x001E30, 0x03F3C3, 0x001F9F, 0x0BAD62,
+    0x001F99, 0x0FCF00, 0x00309A, 0x0629B1, 0x002EB6, 0x175AC3, 0x00314C,
+    0x069195, 0x003168, 0x0BAD63, 0x00348E, 0x175AC1, 0x003F30, 0x07E781,
+    0x003F41, 0x0D2328, 0x003F42, 0x1F9E03, 0x004BC2, 0x175AC2, 0x003F74,
+    0x175AC0, 0x005D61, 0x3F3C05, 0x006130, 0x3F3C04, 0x0062B5,
+};
+
+static const uint8_t ff_wma3_coef1_huffbits[FF_WMA3_HUFF_COEF1_SIZE] = {
+     9,  7,  2,  3,  4,  4,  5,
+     6,  6,  7,  7,  8,  8,  8,
+     9,  9,  9,  9, 10, 10, 10,
+    10, 10, 11, 11, 11, 11, 11,
+    11, 12, 12, 12, 12, 12, 12,
+    12, 12, 12, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 14,
+    14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 15, 15,
+    14, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15,
+    15, 15, 16, 16, 16, 16, 16,
+    16, 16, 16, 17, 16, 16, 16,
+    16, 16, 16, 16,  3,  5,  6,
+     8,  9, 10, 11, 12, 12, 13,
+    13, 14, 14, 15, 15, 15, 15,
+    15, 16, 16, 16, 16, 16, 17,
+    17, 17, 17, 18, 17, 17,  4,
+     6,  9, 10, 12, 13, 14, 14,
+    15, 15,  5,  8, 10, 12, 14,
+    15,  6,  9, 11,  6, 10, 13,
+     7, 10, 14,  7, 11,  8, 12,
+     8, 12,  8, 13,  9, 13,  9,
+    14,  9, 14, 10, 14, 10, 15,
+    10, 15, 10, 15, 10, 15, 11,
+    16, 11, 16, 11, 16, 11, 16,
+    11, 17, 12, 17, 12, 17, 12,
+    18, 12, 18, 12, 18, 12, 18,
+    13, 19, 13, 18, 13, 19, 13,
+    19, 13, 20, 13, 18, 13, 20,
+    13, 20, 14, 19, 14, 21, 14,
+    19, 14, 20, 14, 21, 14, 19,
+    14, 20, 14, 21, 15, 21, 14,
+    21, 15, 22, 15, 22, 15,
+};
+
+
+static const uint8_t ff_wma3_coef0_run[FF_WMA3_HUFF_COEF0_SIZE] = {
+      0,   0,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,
+     12,  13,  14,  15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,
+     26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,
+     40,  41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51,  52,  53,
+     54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,  67,
+     68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,
+     82,  83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,
+     96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109,
+    110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
+    124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137,
+    138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,   0,   1,
+      2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
+     16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
+     30,  31,  32,  33,  34,  35,  36,  37,  38,  39,   0,   1,   2,   3,
+      4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,
+     18,  19,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,   0,   1,
+      2,   3,   4,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,
+      1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,
+      1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,
+      1,   0,   1,   0,   1,   0,
+};
+
+static const uint8_t ff_wma3_coef0_level[FF_WMA3_HUFF_COEF0_SIZE] = {
+      0,   0,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,
+      1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   1,   2,   2,
+      2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+      2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+      2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   3,   3,   3,   3,
+      3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,   3,
+      3,   3,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   5,   5,
+      5,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,
+     11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  16,  17,  17,  18,
+     18,  19,  19,  20,  20,  21,  21,  22,  22,  23,  23,  24,  24,  25,
+     25,  26,  26,  27,  27,  28,
+};
+
+
+static const uint8_t ff_wma3_coef1_run[FF_WMA3_HUFF_COEF1_SIZE] = {
+     0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+    16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+    34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+    70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,
+    88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,  0,  1,  2,  3,  4,  5,
+     6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+    24, 25, 26, 27, 28, 29,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  1,
+     2,  3,  4,  5,  0,  1,  2,  0,  1,  2,  0,  1,  2,  0,  1,  0,  1,  0,
+     1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,
+     1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,
+     1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,
+     1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,  1,  0,
+     1,  0,  1,  0,  1,  0,  1,  0,  0,  0,
+};
+
+static const uint8_t ff_wma3_coef1_level[FF_WMA3_HUFF_COEF1_SIZE] = {
+     0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
+     1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  2,  2,  2,  2,  2,  2,
+     2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,
+     2,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  4,  4,
+     4,  4,  4,  4,  5,  5,  5,  6,  6,  6,  7,  7,  7,  8,  8,  9,  9, 10,
+    10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19,
+    19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28,
+    28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37,
+    37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46,
+    46, 47, 47, 48, 48, 49, 49, 50, 51, 52,
+};
+/** @} */
+
+
+/**
+ * @name huffman and vector lookup tables for vector-coded coefficients
+ * @{
+ */
+#define FF_WMA3_HUFF_VEC4_SIZE 127
+#define FF_WMA3_HUFF_VEC4_MAXBITS 14
+static const uint32_t ff_wma3_vec4_huffcodes[FF_WMA3_HUFF_VEC4_SIZE] = {
+    0x0019, 0x0027, 0x00F2, 0x03BA, 0x0930, 0x1267, 0x0031, 0x0030,
+    0x0097, 0x0221, 0x058B, 0x0124, 0x00EB, 0x01D4, 0x03D8, 0x0584,
+    0x0364, 0x045F, 0x0F66, 0x0931, 0x24CD, 0x002F, 0x0039, 0x00E8,
+    0x02C3, 0x078A, 0x0037, 0x0029, 0x0084, 0x01B1, 0x00ED, 0x0086,
+    0x00F9, 0x03AB, 0x01EB, 0x08BC, 0x011E, 0x00F3, 0x0220, 0x058A,
+    0x00EC, 0x008E, 0x012B, 0x01EA, 0x0119, 0x04B0, 0x04B1, 0x03B8,
+    0x0691, 0x0365, 0x01ED, 0x049A, 0x0EA9, 0x0EA8, 0x08BD, 0x24CC,
+    0x0026, 0x0035, 0x00DB, 0x02C4, 0x07B2, 0x0038, 0x002B, 0x007F,
+    0x01B3, 0x00F4, 0x0091, 0x0116, 0x03BB, 0x0215, 0x0932, 0x002D,
+    0x002A, 0x008A, 0x01DE, 0x0028, 0x0020, 0x005C, 0x0090, 0x0068,
+    0x01EE, 0x00E9, 0x008D, 0x012A, 0x0087, 0x005D, 0x0118, 0x0349,
+    0x01EF, 0x01E3, 0x08B9, 0x00F0, 0x00D3, 0x0214, 0x049B, 0x00DA,
+    0x0089, 0x0125, 0x0217, 0x012D, 0x0690, 0x0094, 0x007D, 0x011F,
+    0x007E, 0x0059, 0x0127, 0x01A5, 0x0111, 0x00F8, 0x045D, 0x03B9,
+    0x0259, 0x0580, 0x02C1, 0x01DF, 0x0585, 0x0216, 0x0163, 0x01B0,
+    0x03C4, 0x08B8, 0x078B, 0x0755, 0x0581, 0x0F67, 0x0000,
+};
+
+static const uint8_t ff_wma3_vec4_huffbits[FF_WMA3_HUFF_VEC4_SIZE] = {
+     5,  6,  8, 10, 12, 13,  6,  6,
+     8, 10, 11,  9,  8,  9, 10, 11,
+    10, 11, 12, 12, 14,  6,  6,  8,
+    10, 11,  6,  6,  8,  9,  8,  8,
+     8, 10,  9, 12,  9,  8, 10, 11,
+     8,  8,  9,  9,  9, 11, 11, 10,
+    11, 10,  9, 11, 12, 12, 12, 14,
+     6,  6,  8, 10, 11,  6,  6,  7,
+     9,  8,  8,  9, 10, 10, 12,  6,
+     6,  8,  9,  6,  6,  7,  8,  7,
+     9,  8,  8,  9,  8,  7,  9, 10,
+     9,  9, 12,  8,  8, 10, 11,  8,
+     8,  9, 10,  9, 11,  8,  7,  9,
+     7,  7,  9,  9,  9,  8, 11, 10,
+    10, 11, 10,  9, 11, 10,  9,  9,
+    10, 12, 11, 11, 11, 12,  1,
+};
+
+
+#define FF_WMA3_HUFF_VEC2_SIZE 137
+#define FF_WMA3_HUFF_VEC2_MAXBITS 12
+static const uint32_t ff_wma3_vec2_huffcodes[FF_WMA3_HUFF_VEC2_SIZE] = {
+    0x055, 0x01C, 0x01A, 0x02B, 0x028, 0x067, 0x08B, 0x039,
+    0x170, 0x10D, 0x2A5, 0x047, 0x464, 0x697, 0x523, 0x8CB,
+    0x01B, 0x00E, 0x000, 0x010, 0x012, 0x036, 0x048, 0x04C,
+    0x0C2, 0x09B, 0x171, 0x03B, 0x224, 0x34A, 0x2D6, 0x019,
+    0x00F, 0x002, 0x014, 0x017, 0x006, 0x05D, 0x054, 0x0C7,
+    0x0B4, 0x192, 0x10E, 0x233, 0x043, 0x02C, 0x00F, 0x013,
+    0x006, 0x02F, 0x02C, 0x068, 0x077, 0x0DF, 0x111, 0x1A4,
+    0x16A, 0x2A4, 0x027, 0x011, 0x018, 0x02D, 0x00F, 0x04A,
+    0x040, 0x097, 0x01F, 0x11B, 0x022, 0x16D, 0x066, 0x035,
+    0x005, 0x02B, 0x049, 0x009, 0x075, 0x0CB, 0x0AA, 0x187,
+    0x106, 0x08A, 0x047, 0x060, 0x06E, 0x01D, 0x074, 0x0C4,
+    0x01E, 0x118, 0x1A7, 0x038, 0x042, 0x053, 0x076, 0x0A8,
+    0x0CA, 0x082, 0x110, 0x18D, 0x12D, 0x0B9, 0x0C8, 0x0DE,
+    0x01C, 0x0AB, 0x113, 0x18C, 0x10F, 0x09A, 0x0A5, 0x0B7,
+    0x11A, 0x186, 0x1A6, 0x259, 0x153, 0x18A, 0x193, 0x020,
+    0x10C, 0x046, 0x03A, 0x107, 0x149, 0x16C, 0x2D7, 0x225,
+    0x258, 0x316, 0x696, 0x317, 0x042, 0x522, 0x290, 0x8CA,
+    0x001,
+};
+
+static const uint8_t ff_wma3_vec2_huffbits[FF_WMA3_HUFF_VEC2_SIZE] = {
+     7,  6,  6,  6,  7,  7,  8,  9,
+     9, 10, 10, 11, 11, 11, 12, 12,
+     6,  4,  5,  5,  6,  6,  7,  8,
+     8,  9,  9, 10, 10, 10, 11,  6,
+     4,  5,  5,  6,  7,  7,  8,  8,
+     9,  9, 10, 10, 11,  6,  5,  5,
+     6,  6,  7,  7,  8,  8,  9,  9,
+    10, 10,  7,  6,  6,  6,  7,  7,
+     8,  8,  9,  9, 10, 10,  7,  6,
+     7,  7,  7,  8,  8,  8,  9,  9,
+    10,  8,  7,  7,  7,  8,  8,  8,
+     9,  9,  9,  9,  8,  8,  8,  8,
+     8,  9,  9,  9,  9,  8,  8,  8,
+     9,  9,  9,  9, 10,  9,  9,  9,
+     9,  9,  9, 10,  9,  9,  9, 10,
+    10, 11, 10, 10, 10, 10, 11, 10,
+    10, 10, 11, 10, 11, 12, 11, 12,
+     3,
+};
+
+
+#define FF_WMA3_HUFF_VEC1_SIZE 101
+#define FF_WMA3_HUFF_VEC1_MAXBITS 11
+static const uint32_t ff_wma3_vec1_huffcodes[FF_WMA3_HUFF_VEC1_SIZE] = {
+    0x01A, 0x003, 0x017, 0x010, 0x00C, 0x009, 0x005, 0x000,
+    0x00D, 0x00A, 0x009, 0x00C, 0x00F, 0x002, 0x004, 0x007,
+    0x00B, 0x00F, 0x01C, 0x006, 0x010, 0x015, 0x01C, 0x022,
+    0x03B, 0x00E, 0x019, 0x023, 0x034, 0x036, 0x03A, 0x047,
+    0x008, 0x00A, 0x01E, 0x031, 0x037, 0x050, 0x053, 0x06B,
+    0x06F, 0x08C, 0x0E8, 0x0EA, 0x0EB, 0x016, 0x03E, 0x03F,
+    0x06C, 0x089, 0x08A, 0x0A3, 0x0A4, 0x0D4, 0x0DD, 0x0EC,
+    0x0EE, 0x11A, 0x1D2, 0x024, 0x025, 0x02E, 0x027, 0x0C2,
+    0x0C0, 0x0DA, 0x0DB, 0x111, 0x144, 0x116, 0x14A, 0x145,
+    0x1B8, 0x1AB, 0x1DA, 0x1DE, 0x1DB, 0x1DF, 0x236, 0x237,
+    0x3A6, 0x3A7, 0x04D, 0x04C, 0x05E, 0x05F, 0x183, 0x182,
+    0x186, 0x221, 0x187, 0x220, 0x22E, 0x22F, 0x296, 0x354,
+    0x297, 0x355, 0x372, 0x373, 0x016,
+};
+
+static const uint8_t ff_wma3_vec1_huffbits[FF_WMA3_HUFF_VEC1_SIZE] = {
+     7,  6,  5,  5,  5,  5,  5,  5,
+     4,  4,  4,  4,  4,  5,  5,  5,
+     5,  5,  5,  6,  6,  6,  6,  6,
+     6,  7,  7,  7,  7,  7,  7,  7,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  9,  9,  9,
+     9,  9,  9,  9,  9,  9,  9,  9,
+     9,  9,  9, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11,  5,
+};
+
+
+static const uint16_t ff_wma3_symbol_to_vec4[FF_WMA3_HUFF_VEC4_SIZE] = {
+        0,    1,      2,     3,     4,     5,    16,    17,    18,    19,
+       20,   32,     33,    34,    35,    48,    49,    50,    64,    65,
+       80,   256,   257,   258,   259,   260,   272,   273,   274,   275,
+      288,   289,   290,   304,   305,   320,   512,   513,   514,   515,
+      528,   529,   530,   544,   545,   560,   768,   769,   770,   784,
+      785,   800,  1024,  1025,  1040,  1280,  4096,  4097,  4098,  4099,
+     4100,  4112,  4113,  4114,  4115,  4128,  4129,  4130,  4144,  4145,
+     4160,  4352,  4353,  4354,  4355,  4368,  4369,  4370,  4384,  4385,
+     4400,  4608,  4609,  4610,  4624,  4625,  4640,  4864,  4865,  4880,
+     5120,  8192,  8193,  8194,  8195,  8208,  8209,  8210,  8224,  8225,
+     8240,  8448,  8449,  8450,  8464,  8465,  8480,  8704,  8705,  8720,
+     8960, 12288, 12289, 12290, 12304, 12305, 12320, 12544, 12545, 12560,
+    12800, 16384, 16385, 16400, 16640, 20480,     0,
+};
+
+
+static const uint8_t ff_wma3_symbol_to_vec2[FF_WMA3_HUFF_VEC2_SIZE] = {
+      0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,
+     15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,
+     30,  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,
+     48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  64,  65,
+     66,  67,  68,  69,  70,  71,  72,  73,  74,  75,  80,  81,  82,  83,  84,
+     85,  86,  87,  88,  89,  90,  96,  97,  98,  99, 100, 101, 102, 103, 104,
+    105, 112, 113, 114, 115, 116, 117, 118, 119, 120, 128, 129, 130, 131, 132,
+    133, 134, 135, 144, 145, 146, 147, 148, 149, 150, 160, 161, 162, 163, 164,
+    165, 176, 177, 178, 179, 180, 192, 193, 194, 195, 208, 209, 210, 224, 225,
+    240,   0,
+};
+/** @} */
+
+
+/**
+ * @brief decorrelation matrix for multichannel streams
+ **/
+static const float ff_wma3_default_decorrelation_matrices[] = {
+    1.000000,  0.707031, -0.707031,  0.707031,  0.707031,  0.578125,  0.707031,
+    0.410156,  0.578125, -0.707031,  0.410156,  0.578125,  0.000000, -0.816406,
+    0.500000,  0.652344,  0.500000,  0.269531,  0.500000,  0.269531, -0.500000,
+   -0.652344,  0.500000, -0.269531, -0.500000,  0.652344,  0.500000, -0.652344,
+    0.500000, -0.269531,  0.445312,  0.601562,  0.511719,  0.371094,  0.195312,
+    0.445312,  0.371094, -0.195312, -0.601562, -0.511719,  0.445312,  0.000000,
+   -0.632812,  0.000000,  0.632812,  0.445312, -0.371094, -0.195312,  0.601562,
+   -0.511719,  0.445312, -0.601562,  0.511719, -0.371094,  0.195312,  0.410156,
+    0.558594,  0.500000,  0.410156,  0.289062,  0.148438,  0.410156,  0.410156,
+    0.000000, -0.410156, -0.578125, -0.410156,  0.410156,  0.148438, -0.500000,
+   -0.410156,  0.289062,  0.558594,  0.410156, -0.148438, -0.500000,  0.410156,
+    0.289062, -0.558594,  0.410156, -0.410156,  0.000000,  0.410156, -0.578125,
+    0.410156,  0.410156, -0.558594,  0.500000, -0.410156,  0.289062, -0.148438,
+};
+
+#endif /* AVCODEC_WMA3DATA_H */
Index: libavcodec/wma3dec.c
===================================================================
--- libavcodec/wma3dec.c	(revision 0)
+++ libavcodec/wma3dec.c	(revision 0)
@@ -0,0 +1,1630 @@
+/*
+ * WMA 9/3/PRO compatible decoder
+ * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
+ * Copyright (c) 2008 - 2009 Sascha Sommer, Benjamin Larsson
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file  libavcodec/wma3dec.c
+ * @brief wmapro decoder implementation
+ */
+
+#include "avcodec.h"
+#include "bitstream.h"
+#include "wma3.h"
+#undef NDEBUG
+#include <assert.h>
+
+#define VLCBITS            9
+#define SCALEVLCBITS       8
+
+
+unsigned int bitstreamcounter;
+
+/**
+ *@brief helper function to print the most important members of the context
+ *@param s context
+ */
+static void dump_context(WMA3DecodeContext *s)
+{
+#define PRINT(a,b) av_log(s->avctx,AV_LOG_ERROR," %s = %d\n", a, b);
+#define PRINT_HEX(a,b) av_log(s->avctx,AV_LOG_ERROR," %s = %x\n", a, b);
+
+    PRINT("ed sample bit depth",s->sample_bit_depth);
+    PRINT_HEX("ed decode flags",s->decode_flags);
+    PRINT("samples per frame",s->samples_per_frame);
+    PRINT("log2 frame size",s->log2_frame_size);
+    PRINT("max num subframes",s->max_num_subframes);
+    PRINT("len prefix",s->len_prefix);
+    PRINT("num channels",s->num_channels);
+    PRINT("lossless",s->lossless);
+}
+
+/**
+ *@brief Get the samples per frame for this stream.
+ *@param sample_rate output sample_rate
+ *@param decode_flags codec compression features
+ *@return number of output samples per frame
+ */
+static int get_samples_per_frame(int sample_rate, unsigned int decode_flags)
+{
+
+    int samples_per_frame;
+    int tmp;
+
+    if (sample_rate <= 16000)
+        samples_per_frame = 512;
+    else if (sample_rate <= 22050)
+        samples_per_frame = 1024;
+    else if (sample_rate <= 48000)
+        samples_per_frame = 2048;
+    else if (sample_rate <= 96000)
+        samples_per_frame = 4096;
+    else
+        samples_per_frame = 8192;
+
+    /* WMA voice code  if (decode_flags & 0x800) {
+        tmp = ((decode_flags & 6) >> 1) | ((decode_flags & 0x600) >> 7);
+        samples_per_frame = (tmp+1)*160;
+    } else { */
+
+    tmp = decode_flags & 0x6;
+    if (tmp == 0x2)
+        samples_per_frame <<= 1;
+    else if (tmp == 0x4)
+        samples_per_frame >>= 1;
+    else if (tmp == 0x6)
+        samples_per_frame >>= 2;
+
+    return samples_per_frame;
+}
+
+/**
+ *@brief Uninitialize the decoder and free all resources.
+ *@param avctx codec context
+ *@return 0 on success, < 0 otherwise
+ */
+static av_cold int wma3_decode_end(AVCodecContext *avctx)
+{
+    WMA3DecodeContext *s = avctx->priv_data;
+    int i;
+
+    av_free(s->num_sfb);
+    av_free(s->sfb_offsets);
+    av_free(s->subwoofer_cutoffs);
+    av_free(s->sf_offsets);
+
+    if(s->def_decorrelation_mat){
+        for(i=1;i<=s->num_channels;i++)
+            av_free(s->def_decorrelation_mat[i]);
+        av_free(s->def_decorrelation_mat);
+    }
+
+    free_vlc(&s->sf_vlc);
+    free_vlc(&s->sf_rl_vlc);
+    free_vlc(&s->coef_vlc[0]);
+    free_vlc(&s->coef_vlc[1]);
+    free_vlc(&s->vec4_vlc);
+    free_vlc(&s->vec2_vlc);
+    free_vlc(&s->vec1_vlc);
+
+    for(i=0 ; i<BLOCK_NB_SIZES ; i++)
+        ff_mdct_end(&s->mdct_ctx[i]);
+
+    return 0;
+}
+
+/**
+ *@brief Initialize the decoder.
+ *@param avctx codec context
+ *@return 0 on success, -1 otherwise
+ */
+static av_cold int wma3_decode_init(AVCodecContext *avctx)
+{
+    WMA3DecodeContext *s = avctx->priv_data;
+    uint8_t *edata_ptr = avctx->extradata;
+    int* sfb_offsets;
+    unsigned int channel_mask;
+    int i;
+
+    s->avctx = avctx;
+    dsputil_init(&s->dsp, avctx);
+
+    /* FIXME: is this really the right thing to do for 24 bits? */
+    s->sample_bit_depth = 16; // avctx->bits_per_sample;
+    if (avctx->extradata_size >= 18) {
+        s->decode_flags     = AV_RL16(edata_ptr+14);
+        channel_mask    = AV_RL32(edata_ptr+2);
+//        s->sample_bit_depth = AV_RL16(edata_ptr);
+
+        /** dump the extradata */
+        for (i=0 ; i<avctx->extradata_size ; i++)
+            av_log(avctx, AV_LOG_ERROR, "[%x] ",avctx->extradata[i]);
+        av_log(avctx, AV_LOG_ERROR, "\n");
+
+    } else {
+        av_log(avctx, AV_LOG_ERROR, "Unknown extradata size %d.\n",
+                      avctx->extradata_size);
+        return -1;
+    }
+
+    /** generic init */
+    s->packet_loss = 0; // FIXME: unneeded
+    s->log2_frame_size = av_log2(avctx->block_align*8)+1;
+
+    /** frame info */
+    s->skip_frame = 1; /** skip first frame */
+    s->packet_loss = 1;
+    s->len_prefix = (s->decode_flags & 0x40) >> 6;
+
+    if(!s->len_prefix){
+         av_log(avctx, AV_LOG_ERROR, "file has no length prefix, please report\n");
+         return -1;
+    }
+
+    /** get frame len */
+    s->samples_per_frame = get_samples_per_frame(avctx->sample_rate,
+                                                 s->decode_flags);
+
+    /** init previous block len */
+    for(i=0;i<avctx->channels;i++)
+        s->channel[i].prev_block_len = s->samples_per_frame;
+
+    /** subframe info */
+    s->max_num_subframes = 1 << ((s->decode_flags & 0x38) >> 3);
+    s->num_possible_block_sizes = av_log2(s->max_num_subframes) + 1;
+    s->allow_subframes = s->max_num_subframes > 1;
+    s->min_samples_per_subframe = s->samples_per_frame / s->max_num_subframes;
+    s->dynamic_range_compression = (s->decode_flags & 0x80) >> 7;
+
+    if(s->max_num_subframes > MAX_SUBFRAMES){
+        av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %i\n",
+                      s->max_num_subframes);
+        return -1;
+    }
+
+    s->num_channels = avctx->channels;
+
+    /** extract lfe channel position */
+    s->lfe_channel = -1;
+
+    if(channel_mask & 8){
+        unsigned int mask = 1;
+        for(i=0;i<32;i++){
+            if(channel_mask & mask)
+                ++s->lfe_channel;
+            if(mask & 8)
+                break;
+            mask <<= 1;
+        }
+    }
+
+    if(s->num_channels < 0 || s->num_channels > MAX_CHANNELS){
+        av_log(avctx, AV_LOG_ERROR, "invalid number of channels %i\n",
+                      s->num_channels);
+        return -1;
+    }
+
+    init_vlc(&s->sf_vlc, SCALEVLCBITS, FF_WMA3_HUFF_SCALE_SIZE,
+                 ff_wma3_scale_huffbits, 1, 1,
+                 ff_wma3_scale_huffcodes, 4, 4, 0);
+
+    init_vlc(&s->sf_rl_vlc, VLCBITS, FF_WMA3_HUFF_SCALE_RL_SIZE,
+                 ff_wma3_scale_rl_huffbits, 1, 1,
+                 ff_wma3_scale_rl_huffcodes, 4, 4, 0);
+
+    init_vlc(&s->coef_vlc[0], VLCBITS, FF_WMA3_HUFF_COEF0_SIZE,
+                 ff_wma3_coef0_huffbits, 1, 1,
+                 ff_wma3_coef0_huffcodes, 4, 4, 0);
+
+    s->coef_max[0] = ((FF_WMA3_HUFF_COEF0_MAXBITS+VLCBITS-1)/VLCBITS);
+
+    init_vlc(&s->coef_vlc[1], VLCBITS, FF_WMA3_HUFF_COEF1_SIZE,
+                 ff_wma3_coef1_huffbits, 1, 1,
+                 ff_wma3_coef1_huffcodes, 4, 4, 0);
+
+    s->coef_max[1] = ((FF_WMA3_HUFF_COEF1_MAXBITS+VLCBITS-1)/VLCBITS);
+
+    init_vlc(&s->vec4_vlc, VLCBITS, FF_WMA3_HUFF_VEC4_SIZE,
+                 ff_wma3_vec4_huffbits, 1, 1,
+                 ff_wma3_vec4_huffcodes, 4, 4, 0);
+
+    init_vlc(&s->vec2_vlc, VLCBITS, FF_WMA3_HUFF_VEC2_SIZE,
+                 ff_wma3_vec2_huffbits, 1, 1,
+                 ff_wma3_vec2_huffcodes, 4, 4, 0);
+
+    init_vlc(&s->vec1_vlc, VLCBITS, FF_WMA3_HUFF_VEC1_SIZE,
+                 ff_wma3_vec1_huffbits, 1, 1,
+                 ff_wma3_vec1_huffcodes, 4, 4, 0);
+
+    s->num_sfb = av_mallocz(sizeof(int)*s->num_possible_block_sizes);
+    s->sfb_offsets = av_mallocz(MAX_BANDS * sizeof(int) *s->num_possible_block_sizes);
+    s->subwoofer_cutoffs = av_mallocz(sizeof(int)*s->num_possible_block_sizes);
+    s->sf_offsets = av_mallocz(s->num_possible_block_sizes *
+                               s->num_possible_block_sizes * MAX_BANDS * sizeof(int));
+
+    if(!s->num_sfb || !s->sfb_offsets || !s->subwoofer_cutoffs || !s->sf_offsets){
+        av_log(avctx, AV_LOG_ERROR, "failed to allocate scale factor offset tables\n");
+        wma3_decode_end(avctx);
+        return -1;
+    }
+
+    /** calculate number of scale factor bands and their offsets
+        for every possible block size */
+    sfb_offsets = s->sfb_offsets;
+
+    for(i=0;i<s->num_possible_block_sizes;i++){
+        int subframe_len = s->samples_per_frame / (1 << i);
+        int x;
+        int band = 1;
+
+        sfb_offsets[0] = 0;
+
+        for(x=0;x < MAX_BANDS-1 && sfb_offsets[band-1] < subframe_len;x++){
+            int offset = (subframe_len * 2 * ff_wma3_critical_freq[x]) / s->avctx->sample_rate + 2;
+            offset -= offset % 4;
+            if ( offset > sfb_offsets[band - 1] ){
+                sfb_offsets[band] = offset;
+                ++band;
+            }
+        }
+        sfb_offsets[band - 1] = subframe_len;
+        s->num_sfb[i] = band - 1;
+        sfb_offsets += MAX_BANDS;
+    }
+
+
+    /** Scale factors can be shared between blocks of different size
+        as every block has a different scale factor band layout.
+        The matrix sf_offsets is needed to find the correct scale factor.
+     */
+
+    for(i=0;i<s->num_possible_block_sizes;i++){
+        int b;
+        for(b=0;b< s->num_sfb[i];b++){
+            int x;
+            int offset = ((s->sfb_offsets[MAX_BANDS * i + b]
+                          + s->sfb_offsets[MAX_BANDS * i + b + 1] - 1)<<i)/2;
+            for(x=0;x<s->num_possible_block_sizes;x++){
+                int v = 0;
+                while(s->sfb_offsets[MAX_BANDS * x + v +1] << x < offset)
+                    ++v;
+                s->sf_offsets[  i * s->num_possible_block_sizes * MAX_BANDS
+                              + x * MAX_BANDS + b] = v;
+            }
+        }
+    }
+
+    /** init MDCT, FIXME: only init needed sizes */
+    for(i = 0; i < BLOCK_NB_SIZES; i++)
+        ff_mdct_init(&s->mdct_ctx[i], BLOCK_MIN_BITS+1+i, 1);
+
+    /** init MDCT windows: simple sinus window */
+    for(i=0 ; i<BLOCK_NB_SIZES ; i++) {
+        int n;
+        n = 1 << (BLOCK_MAX_BITS - i);
+        ff_sine_window_init(ff_sine_windows[BLOCK_MAX_BITS - i - 7], n);
+        s->windows[BLOCK_NB_SIZES-i-1] = ff_sine_windows[BLOCK_MAX_BITS - i - 7];
+    }
+
+    /** calculate subwoofer cutoff values */
+
+    for(i=0;i< s->num_possible_block_sizes;i++){
+        int block_size = s->samples_per_frame / (1 << i);
+        int cutoff = ceil(block_size * 440.0 / (double)s->avctx->sample_rate + 0.5);
+        if(cutoff < 4)
+            cutoff = 4;
+        if(cutoff > block_size)
+            cutoff = block_size;
+        s->subwoofer_cutoffs[i] = cutoff;
+    }
+
+    /** set up decorrelation matrixes */
+    s->def_decorrelation_mat = av_mallocz(sizeof(float*) * (s->num_channels + 1));
+    if(!s->def_decorrelation_mat){
+        av_log(avctx, AV_LOG_ERROR, "failed to allocate decorrelation matrix\n");
+        wma3_decode_end(avctx);
+        return -1;
+    }
+
+    s->def_decorrelation_mat[0] = 0;
+    for(i=1;i<=s->num_channels;i++){
+        const float* tab = ff_wma3_default_decorrelation_matrices;
+        s->def_decorrelation_mat[i] = av_mallocz(sizeof(float*) * i);
+        if(!s->def_decorrelation_mat[i]){
+            av_log(avctx, AV_LOG_ERROR, "failed to set up decorrelation matrix\n");
+            wma3_decode_end(avctx);
+            return -1;
+        }
+        switch(i){
+            case 1:
+                s->def_decorrelation_mat[i][0] = &tab[0];
+                break;
+            case 2:
+                s->def_decorrelation_mat[i][0] = &tab[1];
+                s->def_decorrelation_mat[i][1] = &tab[3];
+                break;
+            case 3:
+                s->def_decorrelation_mat[i][0] = &tab[5];
+                s->def_decorrelation_mat[i][1] = &tab[8];
+                s->def_decorrelation_mat[i][2] = &tab[11];
+                break;
+            case 4:
+                s->def_decorrelation_mat[i][0] = &tab[14];
+                s->def_decorrelation_mat[i][1] = &tab[18];
+                s->def_decorrelation_mat[i][2] = &tab[22];
+                s->def_decorrelation_mat[i][3] = &tab[26];
+                break;
+            case 5:
+                s->def_decorrelation_mat[i][0] = &tab[30];
+                s->def_decorrelation_mat[i][1] = &tab[35];
+                s->def_decorrelation_mat[i][2] = &tab[40];
+                s->def_decorrelation_mat[i][3] = &tab[45];
+                s->def_decorrelation_mat[i][4] = &tab[50];
+                break;
+            case 6:
+                s->def_decorrelation_mat[i][0] = &tab[55];
+                s->def_decorrelation_mat[i][1] = &tab[61];
+                s->def_decorrelation_mat[i][2] = &tab[67];
+                s->def_decorrelation_mat[i][3] = &tab[73];
+                s->def_decorrelation_mat[i][4] = &tab[79];
+                s->def_decorrelation_mat[i][5] = &tab[85];
+                break;
+        }
+    }
+
+    dump_context(s);
+    return 0;
+}
+
+/**
+ *@brief Decode how the data in the frame is split into subframes.
+ *       Every WMA frame contains the encoded data for a fixed number of
+ *       samples per channel. The data for every channel might be split
+ *       into several subframes. This function will reconstruct the list of
+ *       subframes for every channel.
+ *
+ *       If the subframes are not evenly split, the algorithm estimates the
+ *       channels with the lowest number of total samples.
+ *       Afterwards, for each of these channels a bit is read from the
+ *       bitstream that indicates if the channel contains a frame with the
+ *       next subframe size that is going to be read from the bitstream or not.
+ *       If a channel contains such a subframe, the subframe size gets added to
+ *       the channel's subframe list.
+ *       The algorithm repeats these steps until the frame is properly divided
+ *       between the individual channels.
+ *
+ *@param s context
+ *@return 0 on success, < 0 in case of an error
+ */
+static int wma_decode_tilehdr(WMA3DecodeContext *s)
+{
+    int c;
+    int missing_samples = s->num_channels * s->samples_per_frame;
+
+    /** reset tiling information */
+    for(c=0;c<s->num_channels;c++){
+        s->channel[c].num_subframes = 0;
+        s->channel[c].channel_len = 0;
+    }
+
+    /** handle the easy case with one constant-sized subframe per channel */
+    if(s->max_num_subframes == 1){
+        for(c=0;c<s->num_channels;c++){
+            s->channel[c].num_subframes = 1;
+            s->channel[c].subframe_len[0] = s->samples_per_frame;
+            s->channel[c].channel_len = 0;
+        }
+    }else{ /** subframe length and number of subframes is not constant */
+        int subframe_len_bits = 0;     /** bits needed for the subframe length */
+        int subframe_len_zero_bit = 0; /** first bit indicates if length is zero */
+        int fixed_channel_layout;      /** all channels have the same subframe layout */
+
+        fixed_channel_layout = get_bits1(&s->getbit);
+
+        /** calculate subframe len bits */
+        if(s->lossless)
+            subframe_len_bits = av_log2(s->max_num_subframes - 1) + 1;
+        else if(s->max_num_subframes == 16){
+            subframe_len_zero_bit = 1;
+            subframe_len_bits = 3;
+        }else
+            subframe_len_bits = av_log2(av_log2(s->max_num_subframes)) + 1;
+
+        /** loop until the frame data is split between the subframes */
+        while(missing_samples > 0){
+            unsigned int channel_mask = 0;
+            int min_channel_len = s->samples_per_frame;
+            int read_channel_mask = 1;
+            int channels_for_cur_subframe = 0;
+            int subframe_len;
+
+            if(fixed_channel_layout){
+                read_channel_mask = 0;
+                channels_for_cur_subframe = s->num_channels;
+                min_channel_len = s->channel[0].channel_len;
+            }else{
+                /** find channels with the smallest overall length */
+                for(c=0;c<s->num_channels;c++){
+                    if(s->channel[c].channel_len <= min_channel_len){
+                        if(s->channel[c].channel_len < min_channel_len){
+                            channels_for_cur_subframe = 0;
+                            min_channel_len = s->channel[c].channel_len;
+                        }
+                        ++channels_for_cur_subframe;
+                    }
+                }
+
+                if(channels_for_cur_subframe == 1 ||
+                  s->min_samples_per_subframe * channels_for_cur_subframe == missing_samples)
+                    read_channel_mask = 0;
+            }
+
+            /** For every channel with the minimum length, 1 bit
+                might be transmitted that informs us if the channel
+                contains a subframe with the next subframe_len. */
+            if(read_channel_mask){
+                channel_mask = get_bits(&s->getbit,channels_for_cur_subframe);
+                if(!channel_mask){
+                    av_log(s->avctx, AV_LOG_ERROR,
+                        "broken frame: zero frames for subframe_len\n");
+                    return -1;
+                }
+            }
+
+            /** if we have the choice get next subframe length from the bitstream */
+            if(s->min_samples_per_subframe * channels_for_cur_subframe != missing_samples){
+                int log2_subframe_len = 0;
+                /* 1 bit indicates if the subframe length is zero */
+                if(subframe_len_zero_bit){
+                    if(get_bits1(&s->getbit)){
+                        log2_subframe_len =
+                            get_bits(&s->getbit,subframe_len_bits-1);
+                        ++log2_subframe_len;
+                    }
+                }else
+                    log2_subframe_len = get_bits(&s->getbit,subframe_len_bits);
+
+                if(s->lossless){
+                    subframe_len =
+                        s->samples_per_frame / s->max_num_subframes;
+                    subframe_len *= log2_subframe_len + 1;
+                }else
+                    subframe_len =
+                        s->samples_per_frame / (1 << log2_subframe_len);
+
+                /** sanity check the length */
+                if(subframe_len < s->min_samples_per_subframe
+                    || subframe_len > s->samples_per_frame){
+                    av_log(s->avctx, AV_LOG_ERROR,
+                        "broken frame: subframe_len %i\n", subframe_len);
+                    return -1;
+                }
+            }else
+                subframe_len = s->min_samples_per_subframe;
+
+            for(c=0; c<s->num_channels;c++){
+                WMA3ChannelCtx* chan = &s->channel[c];
+
+                /** add subframes to the individual channels */
+                if(min_channel_len == chan->channel_len){
+                    --channels_for_cur_subframe;
+                    if(!read_channel_mask || channel_mask & (1<<channels_for_cur_subframe)){
+                        if(chan->num_subframes > 31){
+                            av_log(s->avctx, AV_LOG_ERROR,
+                                    "broken frame: num subframes > 31\n");
+                            return -1;
+                        }
+                        chan->subframe_len[chan->num_subframes] = subframe_len;
+                        chan->channel_len += subframe_len;
+                        missing_samples -= subframe_len;
+                        ++chan->num_subframes;
+                        if(missing_samples < 0
+                            || chan->channel_len > s->samples_per_frame){
+                            av_log(s->avctx, AV_LOG_ERROR,"broken frame: "
+                                    "channel len > samples_per_frame\n");
+                            return -1;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    for(c=0;c<s->num_channels;c++){
+        int i;
+        int offset = 0;
+        for(i=0;i<s->channel[c].num_subframes;i++){
+            av_log(s->avctx, AV_LOG_DEBUG,"frame[%i] channel[%i] subframe[%i]"
+                   " len %i\n",s->frame_num,c,i,s->channel[c].subframe_len[i]);
+            s->channel[c].subframe_offset[i] = offset;
+            offset += s->channel[c].subframe_len[i];
+        }
+    }
+
+    return 0;
+}
+
+static int wma_decode_channel_transform(WMA3DecodeContext* s)
+{
+    int i;
+    for(i=0;i< s->num_channels;i++){
+        memset(s->chgroup[i].decorrelation_matrix,0,4*s->num_channels * s->num_channels);
+    }
+
+    if(s->num_channels == 1 ){
+        s->num_chgroups = 0;
+        s->chgroup[0].num_channels = 1;
+        s->chgroup[0].no_rotation = 1;
+        s->chgroup[0].transform = 2;
+        s->channel[0].resampled_scale_factors[0] = 0;
+        memset(s->chgroup[0].transform_band,0,MAX_BANDS);
+        memset(s->chgroup[0].decorrelation_matrix,0,4*s->num_channels * s->num_channels);
+
+        s->chgroup[0].decorrelation_matrix[0] = 1.0;
+
+    }else{
+        int remaining_channels = s->channels_for_cur_subframe;
+
+        if(get_bits(&s->getbit,1)){
+            av_log(s->avctx,AV_LOG_ERROR,"unsupported channel transform bit\n");
+            return 0;
+        }
+
+        for(s->num_chgroups = 0; remaining_channels && s->num_chgroups < s->channels_for_cur_subframe;s->num_chgroups++){
+            WMA3ChannelGroup* chgroup = &s->chgroup[s->num_chgroups];
+            chgroup->num_channels = 0;
+            chgroup->no_rotation = 0;
+            chgroup->transform = 0;
+
+            /* decode channel mask */
+            memset(chgroup->use_channel,0,sizeof(chgroup->use_channel));
+
+            if(remaining_channels > 2){
+                for(i=0;i<s->channels_for_cur_subframe;i++){
+                    int channel_idx = s->channel_indexes_for_cur_subframe[i];
+                    if(!s->channel[channel_idx].grouped
+                       && get_bits(&s->getbit,1)){
+                        ++chgroup->num_channels;
+                        s->channel[channel_idx].grouped = 1;
+                        chgroup->use_channel[channel_idx] = 1;
+                    }
+                }
+            }else{
+                chgroup->num_channels = remaining_channels;
+                for(i=0;i<s->num_channels ;i++){
+                    chgroup->use_channel[i] = s->channel[i].grouped != 1;
+                    s->channel[i].grouped = 1;
+                }
+            }
+
+            /** done decode channel mask */
+
+            /* decide x form type
+               FIXME: port this to float, all rotations should lie
+                      on the unit circle */
+            if(chgroup->num_channels == 1){
+                chgroup->no_rotation = 1;
+                chgroup->transform = 2;
+                chgroup->decorrelation_matrix[0] = 1.0;
+
+            }else if(chgroup->num_channels == 2){
+                if(get_bits(&s->getbit,1)){
+                    if(!get_bits(&s->getbit,1)){
+                        chgroup->no_rotation = 1;
+                        chgroup->transform = 2;
+                        chgroup->decorrelation_matrix[0] = 1.0;
+                        chgroup->decorrelation_matrix[1] = 0;
+                        chgroup->decorrelation_matrix[2] = 0;
+                        chgroup->decorrelation_matrix[3] = 1.0;
+                    }
+                }else{
+                    chgroup->no_rotation = 1;
+                    chgroup->transform = 1;
+                    chgroup->decorrelation_matrix[0] = 0.70703125;  // FIXME: cos(pi/4)
+                    chgroup->decorrelation_matrix[1] = -0.70703125;
+                    chgroup->decorrelation_matrix[2] = 0.70703125;
+                    chgroup->decorrelation_matrix[3] = 0.70703125;
+                }
+            }else{
+                if(get_bits(&s->getbit,1)){
+                    if(get_bits(&s->getbit,1)){
+                        chgroup->no_rotation = 0;
+                        chgroup->transform = 0;
+                    }else{
+                        int x;
+                        chgroup->no_rotation = 1;
+                        chgroup->transform = 3;
+                        for(x = 0; x < chgroup->num_channels ; x++){
+                            int y;
+                            for(y=0;y< chgroup->num_channels ;y++){
+                                chgroup->decorrelation_matrix[y + x * chgroup->num_channels] = s->def_decorrelation_mat[chgroup->num_channels][x][y];
+                        }
+                        }
+                    }
+                }else{
+                    int i;
+                    chgroup->no_rotation = 1;
+                    chgroup->transform = 2;
+                    for(i=0;i<chgroup->num_channels;i++){
+                        chgroup->decorrelation_matrix[i+i*chgroup->num_channels] = 1.0;
+                    }
+                }
+            }
+
+            /** done decide x form type */
+
+            if(!chgroup->no_rotation){ /** decode channel transform */
+                int n_offset = chgroup->num_channels  * (chgroup->num_channels - 1) / 2;
+                int i;
+                for(i=0;i<n_offset;i++){
+                    chgroup->rotation_offset[i] = get_bits(&s->getbit,6);
+                }
+                for(i=0;i<chgroup->num_channels;i++)
+                    chgroup->positive[i] = get_bits(&s->getbit,1);
+            }
+
+            /* decode transform on / off */
+            if(chgroup->num_channels <= 1 ||  ((chgroup->no_rotation != 1 || chgroup->transform == 2) && chgroup->no_rotation)){
+                // done
+                int i;
+                for(i=0;i<s->num_bands;i++)
+                    chgroup->transform_band[i] = 1;
+            }else{
+                if(get_bits(&s->getbit,1) == 0){
+                    int i;
+                    // transform works on individual scale factor bands
+                    for(i=0;i< s->num_bands;i++){
+                        chgroup->transform_band[i] = get_bits(&s->getbit,1);
+                    }
+                }else{
+                    int i;
+                    for(i=0;i<s->num_bands;i++)
+                        chgroup->transform_band[i] = 1;
+                }
+            }
+            /** done decode transform on / off */
+            remaining_channels -= chgroup->num_channels;
+        }
+    }
+    return 1;
+}
+
+static unsigned int wma_get_large_val(WMA3DecodeContext* s)
+{
+    int n_bits = 8;
+    if(get_bits(&s->getbit,1)){
+        n_bits += 8;
+        if(get_bits(&s->getbit,1)){
+            n_bits += 8;
+            if(get_bits(&s->getbit,1)){
+                n_bits += 7;
+            }
+        }
+    }
+    return get_bits_long(&s->getbit,n_bits);
+}
+
+static inline void wma_get_vec4(WMA3DecodeContext *s,int* vals,int* masks)
+{
+        unsigned int idx;
+        int i = 0;
+        // read 4 values
+        idx = get_vlc2(&s->getbit, s->vec4_vlc.table, VLCBITS, ((FF_WMA3_HUFF_VEC4_MAXBITS+VLCBITS-1)/VLCBITS));
+
+
+        if ( idx == FF_WMA3_HUFF_VEC4_SIZE - 1 )
+        {
+          while(i < 4){
+              idx = get_vlc2(&s->getbit, s->vec2_vlc.table, VLCBITS, ((FF_WMA3_HUFF_VEC2_MAXBITS+VLCBITS-1)/VLCBITS));
+              if ( idx == FF_WMA3_HUFF_VEC2_SIZE - 1 ){
+                   vals[i] = get_vlc2(&s->getbit, s->vec1_vlc.table, VLCBITS, ((FF_WMA3_HUFF_VEC1_MAXBITS+VLCBITS-1)/VLCBITS));
+                   if(vals[i] == FF_WMA3_HUFF_VEC1_SIZE - 1)
+                       vals[i] += wma_get_large_val(s);
+                   vals[i+1] = get_vlc2(&s->getbit, s->vec1_vlc.table, VLCBITS, ((FF_WMA3_HUFF_VEC1_MAXBITS+VLCBITS-1)/VLCBITS));
+                   if(vals[i+1] == FF_WMA3_HUFF_VEC1_SIZE - 1)
+                       vals[i+1] += wma_get_large_val(s);
+              }else{
+                  vals[i] = (ff_wma3_symbol_to_vec2[idx] >> 4) & 0xF;
+                  vals[i+1] = ff_wma3_symbol_to_vec2[idx] & 0xF;
+              }
+              i += 2;
+          }
+        }
+        else
+        {
+          vals[0] = (unsigned char)(ff_wma3_symbol_to_vec4[idx] >> 8) >> 4;
+          vals[1] = (ff_wma3_symbol_to_vec4[idx] >> 8) & 0xF;
+          vals[2] = (ff_wma3_symbol_to_vec4[idx] >> 4) & 0xF;
+          vals[3] = ff_wma3_symbol_to_vec4[idx] & 0xF;
+        }
+
+        if(vals[0])
+            masks[0] = get_bits(&s->getbit,1);
+        if(vals[1])
+            masks[1] = get_bits(&s->getbit,1);
+        if(vals[2])
+            masks[2] = get_bits(&s->getbit,1);
+        if(vals[3])
+            masks[3] = get_bits(&s->getbit,1);
+}
+
+static int decode_coeffs(WMA3DecodeContext *s, int c)
+{
+    int vlctable;
+    VLC* vlc;
+    int vlcmax;
+    WMA3ChannelCtx* ci = &s->channel[c];
+    int rl_mode = 0;
+    int cur_coeff = 0;
+    int last_write = 0;
+    const uint8_t* run;
+    const uint8_t* level;
+
+    av_log(s->avctx,AV_LOG_DEBUG,"decode coefficients for channel %i\n",c);
+
+    vlctable = get_bits(&s->getbit, 1);
+    vlc = &s->coef_vlc[vlctable];
+    vlcmax = s->coef_max[vlctable];
+
+    if(vlctable){
+        run = ff_wma3_coef1_run;
+        level = ff_wma3_coef1_level;
+    }else{
+        run = ff_wma3_coef0_run;
+        level = ff_wma3_coef0_level;
+    }
+
+    while(cur_coeff < s->subframe_len){
+        if(rl_mode){
+            unsigned int idx;
+            int mask;
+            int val;
+            idx = get_vlc2(&s->getbit, vlc->table, VLCBITS, vlcmax);
+
+            if( idx == 1)
+                return 0;
+            else if( !idx ){
+                val = wma_get_large_val(s);
+                /** escape decode */
+                if(get_bits(&s->getbit,1)){
+                    if(get_bits(&s->getbit,1)){
+                        if(get_bits(&s->getbit,1)){
+                            av_log(s->avctx,AV_LOG_ERROR,"broken escape sequence\n");
+                            return 0;
+                        }else
+                            cur_coeff += get_bits(&s->getbit,s->esc_len) + 4;
+                    }else
+                        cur_coeff += get_bits(&s->getbit,2) + 1;
+                }
+            }else{
+                cur_coeff += run[idx];
+                val = level[idx];
+            }
+            mask = get_bits(&s->getbit,1) - 1;
+            ci->coeffs[cur_coeff] = (val^mask) - mask;
+            ++cur_coeff;
+        }else{
+            int i = 0;
+            int vals[4];
+            int masks[4];
+
+            if( cur_coeff >= s->subframe_len )
+                return 0;
+
+            wma_get_vec4(s,vals,masks);
+
+            while(i < 4){
+                ++cur_coeff;
+                ++last_write;
+
+                if(vals[i]){
+                    ci->coeffs[cur_coeff-1] = (((int64_t)vals[i])^(masks[i] -1)) - (masks[i] -1);
+                    last_write = 0;
+                }
+                if( cur_coeff >= s->subframe_len ) // handled entire subframe -> quit
+                    return 0;
+                if ( last_write > s->subframe_len / 256 ) // switch to RL mode
+                    rl_mode = 1;
+                ++i;
+            }
+        }
+    }
+
+    return 0;
+}
+
+static int wma_decode_scale_factors(WMA3DecodeContext* s)
+{
+    int i;
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+
+        /** resample scale factors for the new block size */
+        if(s->channel[c].reuse_sf){
+            int b;
+            for(b=0;b< s->num_bands;b++){
+                int idx0 = av_log2(s->samples_per_frame/s->subframe_len);
+                int idx1 = av_log2(s->samples_per_frame/s->channel[c].scale_factor_block_len);
+                int bidx = s->sf_offsets[s->num_possible_block_sizes * MAX_BANDS  * idx0
+                                                 + MAX_BANDS * idx1 + b];
+                s->channel[c].resampled_scale_factors[b] = s->channel[c].scale_factors[bidx];
+            }
+            s->channel[c].max_scale_factor = s->channel[c].resampled_scale_factors[0];
+            for(b=1;b<s->num_bands;b++){
+                if(s->channel[c].resampled_scale_factors[b] > s->channel[c].max_scale_factor)
+                    s->channel[c].max_scale_factor = s->channel[c].resampled_scale_factors[b];
+            }
+        }
+
+        if(s->channel[c].cur_subframe > 0){
+            s->channel[c].transmit_sf = get_bits(&s->getbit,1);
+        }else
+            s->channel[c].transmit_sf = 1;
+
+        if(s->channel[c].transmit_sf){
+            int b;
+
+            if(!s->channel[c].reuse_sf){
+                int i;
+                s->channel[c].scale_factor_step = get_bits(&s->getbit,2) + 1;
+                for(i=0;i<s->num_bands;i++){
+                    int val = get_vlc2(&s->getbit, s->sf_vlc.table, SCALEVLCBITS, ((FF_WMA3_HUFF_SCALE_MAXBITS+SCALEVLCBITS-1)/SCALEVLCBITS)); // DPCM-coded
+                    if(!i)
+                        s->channel[c].scale_factors[i] = 45 / s->channel[c].scale_factor_step + val - 60;
+                    else
+                        s->channel[c].scale_factors[i]  = s->channel[c].scale_factors[i-1] + val - 60;
+                }
+            }else{     // rl-coded
+                int i;
+                memcpy(s->channel[c].scale_factors,s->channel[c].resampled_scale_factors,
+                       4 * s->num_bands);
+
+                for(i=0;i<s->num_bands;i++){
+                    int idx;
+                    short skip;
+                    short level_mask;
+                    short val;
+
+                    idx = get_vlc2(&s->getbit, s->sf_rl_vlc.table, VLCBITS, ((FF_WMA3_HUFF_SCALE_RL_MAXBITS+VLCBITS-1)/VLCBITS));
+
+                    if( !idx ){
+                        uint32_t mask = get_bits(&s->getbit,14);
+                        level_mask = mask >> 6;
+                        val = (mask & 1) - 1;
+                        skip = (0x3f & mask)>>1;
+                    }else if(idx == 1){
+                        break;
+                    }else{
+                        skip = ff_wma3_scale_rl_run[idx];
+                        level_mask = ff_wma3_scale_rl_level[idx];
+                        val = get_bits(&s->getbit,1)-1;
+                    }
+
+                    i += skip;
+                    if(i >= s->num_bands){
+                        av_log(s->avctx,AV_LOG_ERROR,"invalid scale factor coding\n");
+                        return 0;
+                    }else
+                        s->channel[c].scale_factors[i] += (val ^ level_mask) - val;
+                }
+            }
+
+            s->channel[c].reuse_sf = 1;
+            s->channel[c].max_scale_factor = s->channel[c].scale_factors[0];
+            for(b=1;b<s->num_bands;b++){
+                if(s->channel[c].max_scale_factor < s->channel[c].scale_factors[b])
+                    s->channel[c].max_scale_factor = s->channel[c].scale_factors[b];
+            }
+            s->channel[c].scale_factor_block_len = s->subframe_len;
+        }
+    }
+    return 1;
+}
+
+static void wma_calc_decorrelation_matrix(WMA3DecodeContext *s, WMA3ChannelGroup* chgroup)
+{
+    int i;
+    int offset = 0;
+    memset(chgroup->decorrelation_matrix, 0, chgroup->num_channels * 4 * chgroup->num_channels);
+    for(i=0;i<chgroup->num_channels;i++)
+        chgroup->decorrelation_matrix[chgroup->num_channels * i + i] = chgroup->positive[i]?1.0:-1.0;
+
+    for(i=0;i<chgroup->num_channels;i++){
+        if ( i > 0 )
+        {
+            int x;
+            for(x=0;x<i;x++){
+                int y;
+                float tmp1[MAX_CHANNELS];
+                float tmp2[MAX_CHANNELS];
+                memcpy(tmp1, &chgroup->decorrelation_matrix[x * chgroup->num_channels], 4 * (i + 1));
+                memcpy(tmp2, &chgroup->decorrelation_matrix[i * chgroup->num_channels], 4 * (i + 1));
+                for(y=0;y < i + 1 ; y++){
+                    float v1 = tmp1[y];
+                    float v2 = tmp2[y];
+                    int n = chgroup->rotation_offset[offset + x];
+                    float cosv = sin(n*M_PI / 64.0);                // FIXME: use one table for this
+                    float sinv = -cos(n*M_PI / 64.0);
+
+                    chgroup->decorrelation_matrix[y + x * chgroup->num_channels] = (v1 * cosv) + (v2 * sinv);
+                    chgroup->decorrelation_matrix[y + i * chgroup->num_channels] = (v1 * -sinv) + (v2 * cosv);
+                }
+            }
+        }
+        offset += i;
+    }
+
+}
+
+static void wma_inverse_channel_transform(WMA3DecodeContext *s)
+{
+    int i;
+
+    for(i=0;i<s->num_chgroups;i++){
+
+        if(s->chgroup[i].num_channels == 1)
+            continue;
+
+        if(s->chgroup[i].no_rotation == 1 && s->chgroup[i].transform == 2)
+            continue;
+
+        if((s->num_channels == 2) &&
+            (s->chgroup[i].no_rotation == 1) &&
+            (s->chgroup[i].transform == 1)){
+            int b;
+            for(b = 0; b < s->num_bands;b++){
+                int y;
+                if(s->chgroup[i].transform_band[b] == 1){ // M/S stereo
+                    for(y=s->cur_sfb_offsets[b];y<FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);y++){
+                        float v1 = s->channel[0].coeffs[y];
+                        float v2 = s->channel[1].coeffs[y];
+                        s->channel[0].coeffs[y] = v1 - v2;
+                        s->channel[1].coeffs[y] = v1 + v2;
+                    }
+                }else{
+                    for(y=s->cur_sfb_offsets[b];y<FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);y++){
+                        s->channel[0].coeffs[y] *= 362;
+                        s->channel[0].coeffs[y] /= 256;
+                        s->channel[1].coeffs[y] *= 362;
+                        s->channel[1].coeffs[y] /= 256;
+                    }
+                }
+            }
+        }else{
+            int x;
+            int b;
+            int cnt = 0;
+            float* ch_data[MAX_CHANNELS];
+            float  sums[MAX_CHANNELS * MAX_CHANNELS];
+            if(!s->chgroup[i].no_rotation)
+                wma_calc_decorrelation_matrix(s,&s->chgroup[i]);
+
+            for(x=0;x<s->channels_for_cur_subframe;x++){
+                int chan = s->channel_indexes_for_cur_subframe[x];
+                if(s->chgroup[i].use_channel[chan] == 1){    // assign ptrs
+                    ch_data[cnt] = s->channel[chan].coeffs;
+                    ++cnt;
+                }
+            }
+
+            for(b = 0; b < s->num_bands;b++){
+                int y;
+                if(s->chgroup[i].transform_band[b] == 1){
+                    // multiply values with decorrelation_matrix
+                    for(y=s->cur_sfb_offsets[b];y<FFMIN(s->cur_sfb_offsets[b+1], s->subframe_len);y++){
+                        float* matrix = s->chgroup[i].decorrelation_matrix;
+                        int m;
+
+                        for(m = 0;m<s->chgroup[i].num_channels;m++)
+                            sums[m] = 0;
+
+                        for(m = 0;m<s->chgroup[i].num_channels * s->chgroup[i].num_channels;m++)
+                            sums[m/s->chgroup[i].num_channels] += (matrix[m] * ch_data[m%s->chgroup[i].num_channels][0]);
+
+                        for(m = 0;m<s->chgroup[i].num_channels;m++){
+                            ch_data[m][0] = sums[m];
+                            ++ch_data[m];
+                        }
+                    }
+                }else{      /** skip band */
+                    for(y=0;y<s->chgroup[i].num_channels;y++)
+                        ch_data[y] += s->cur_sfb_offsets[b+1] -  s->cur_sfb_offsets[b];
+                }
+            }
+        }
+    }
+}
+
+static void wma_window(WMA3DecodeContext *s)
+{
+    int i;
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+        int j = s->channel[c].cur_subframe;
+        float* start;
+        float* window;
+        int prev_block_len = s->channel[c].prev_block_len;
+        int block_len = s->channel[c].subframe_len[j];
+        int winlen = prev_block_len;
+        start = &s->channel[c].out[s->samples_per_frame/2 + s->channel[c].subframe_offset[j] - prev_block_len /2 ];
+
+        if(block_len <= prev_block_len){
+            start += (prev_block_len - block_len)/2;
+            winlen = block_len;
+        }
+
+        window = s->windows[av_log2(winlen)-BLOCK_MIN_BITS];
+
+        s->dsp.vector_fmul_window(start, start, start + winlen/2, window, 0, winlen/2);
+
+        s->channel[c].prev_block_len = block_len;
+    }
+}
+
+static int wma_decode_subframe(WMA3DecodeContext *s)
+{
+    int offset = s->samples_per_frame;
+    int subframe_len = s->samples_per_frame;
+    int i;
+    int total_samples = s->samples_per_frame * s->num_channels;
+    int transmit_coeffs = 0;
+
+    bitstreamcounter = get_bits_count(&s->getbit);
+
+    /** reset channel context and find the next block offset and size
+        == the next block of the channel with the smallest number of decoded samples
+    */
+    for(i=0;i<s->num_channels;i++){
+        s->channel[i].grouped = 0;
+        if(offset > s->channel[i].decoded_samples){
+            offset = s->channel[i].decoded_samples;
+            subframe_len = s->channel[i].subframe_len[s->channel[i].cur_subframe];
+        }
+    }
+
+    av_log(s->avctx, AV_LOG_DEBUG,"processing subframe with offset %i len %i\n",offset,subframe_len);
+
+    /** get a list of all channels that contain the estimated block */
+    s->channels_for_cur_subframe = 0;
+    for(i=0;i<s->num_channels;i++){
+        /** substract already processed samples */
+        total_samples -= s->channel[i].decoded_samples;
+
+        /** and count if there are multiple subframes that match our profile */
+        if(offset == s->channel[i].decoded_samples && subframe_len == s->channel[i].subframe_len[s->channel[i].cur_subframe]){
+             total_samples -= s->channel[i].subframe_len[s->channel[i].cur_subframe];
+             s->channel[i].decoded_samples += s->channel[i].subframe_len[s->channel[i].cur_subframe];
+             s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i;
+             ++s->channels_for_cur_subframe;
+        }
+    }
+
+    /** check if the frame will be complete after processing the estimated block */
+    if(total_samples == 0)
+        s->parsed_all_subframes = 1;
+
+
+    av_log(s->avctx, AV_LOG_DEBUG,"subframe is part of %i channels\n",s->channels_for_cur_subframe);
+
+    /** configure the decoder for the current subframe */
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+
+        /** calculate number of scale factor bands and their offsets */
+        /** FIXME move out of the loop */
+        if(i == 0){
+            if(s->channel[c].num_subframes <= 1){
+                s->num_bands = s->num_sfb[0];
+                s->cur_sfb_offsets = s->sfb_offsets;
+                s->cur_subwoofer_cutoff = s->subwoofer_cutoffs[0];
+            }else{
+                int frame_offset = av_log2(s->samples_per_frame/s->channel[c].subframe_len[s->channel[c].cur_subframe]);
+                s->num_bands = s->num_sfb[frame_offset];
+                s->cur_sfb_offsets = &s->sfb_offsets[MAX_BANDS * frame_offset];
+                s->cur_subwoofer_cutoff = s->subwoofer_cutoffs[frame_offset];
+            }
+        }
+        s->channel[c].coeffs = &s->channel[c].out[s->samples_per_frame/2  + offset];
+        memset(s->channel[c].coeffs,0,sizeof(float) * subframe_len);
+
+        /** init some things if this is the first subframe */
+        if(!s->channel[c].cur_subframe){
+              s->channel[c].scale_factor_step = 1;
+              s->channel[c].max_scale_factor = 0;
+              memset(s->channel[c].scale_factors, 0, sizeof(s->channel[c].scale_factors));
+              memset(s->channel[c].resampled_scale_factors, 0, sizeof(s->channel[c].resampled_scale_factors));
+        }
+
+    }
+
+    s->subframe_len = subframe_len;
+    s->esc_len = av_log2(s->subframe_len - 1) + 1;
+
+    /** skip extended header if any */
+    if(get_bits(&s->getbit,1)){
+        int num_fill_bits;
+        if(!(num_fill_bits = get_bits(&s->getbit,2))){
+            num_fill_bits = get_bits(&s->getbit,4);
+            num_fill_bits = get_bits(&s->getbit,num_fill_bits) + 1;
+        }
+
+        if(num_fill_bits >= 0){
+            skip_bits(&s->getbit,num_fill_bits);
+        }
+    }
+
+    /** no idea for what the following bit is used */
+    if(get_bits(&s->getbit,1)){
+        av_log(s->avctx,AV_LOG_ERROR,"reserved bit set\n");
+        return 0;
+    }
+
+
+    if(!wma_decode_channel_transform(s))
+        return 0;
+
+
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+        if((s->channel[c].transmit_coefs = get_bits(&s->getbit,1)))
+            transmit_coeffs = 1;
+    }
+
+    s->quant_step = 90 * s->sample_bit_depth / 16;
+
+    if(transmit_coeffs){
+        int quant;
+        int sign = 1;
+        int large_quant = 0;
+        if((get_bits(&s->getbit,1))){ /** FIXME: might influence how often getvec4 may be called */
+            av_log(s->avctx,AV_LOG_ERROR,"unsupported quant step coding\n");
+            return 0;
+        }
+        /** decode quantization step */
+        quant = get_bits(&s->getbit,6);
+        if(quant & 0x20){
+            quant |= 0xFFFFFFC0u;
+            sign = -1;
+        }
+        s->quant_step += quant;
+        if(quant <= -32 || quant > 30)
+            large_quant = 1;
+        while(large_quant){
+            quant = get_bits(&s->getbit,5);
+            if(quant != 31){
+                s->quant_step += quant * sign;
+                break;
+            }
+            s->quant_step += 31 * sign;
+            if(s->quant_step < 0){
+                s->negative_quantstep = 1;
+                av_log(s->avctx,AV_LOG_ERROR,"negative quant step\n");
+                return 0;
+            }
+        }
+
+        /** decode quantization step modifiers for every channel */
+
+        if(s->channels_for_cur_subframe == 1)
+            s->channel[s->channel_indexes_for_cur_subframe[0]].quant_step_modifier = 0;
+        else{
+            int modifier_len = get_bits(&s->getbit,3);
+            for(i=0;i<s->channels_for_cur_subframe;i++){
+                int c = s->channel_indexes_for_cur_subframe[i];
+                s->channel[c].quant_step_modifier = 0;
+                if(get_bits(&s->getbit,1)){
+                    if(modifier_len)
+                        s->channel[c].quant_step_modifier = get_bits(&s->getbit,modifier_len) + 1;
+                    else
+                        s->channel[c].quant_step_modifier = 1;
+                }else
+                    s->channel[c].quant_step_modifier = 0;
+
+            }
+        }
+
+        /** decode scale factors */
+        if(!wma_decode_scale_factors(s))
+            return 0;
+    }
+
+    av_log(s->avctx,AV_LOG_DEBUG,"BITSTREAM: subframe header length was %i\n",get_bits_count(&s->getbit) - bitstreamcounter);
+
+    /** parse coefficients */
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+        if(s->channel[c].transmit_coefs)
+                decode_coeffs(s,c);
+    }
+
+    av_log(s->avctx,AV_LOG_DEBUG,"BITSTREAM: subframe length was %i\n",get_bits_count(&s->getbit) - bitstreamcounter);
+
+    if(transmit_coeffs){
+        wma_inverse_channel_transform(s);
+        for(i=0;i<s->channels_for_cur_subframe;i++){
+            int c = s->channel_indexes_for_cur_subframe[i];
+            int b;
+            float* dst;
+            if(c == s->lfe_channel)
+                memset(&s->channel[c].coeffs[s->cur_subwoofer_cutoff],0,4 * (subframe_len - s->cur_subwoofer_cutoff));
+
+            /** inverse quantization */
+            for(b=0;b<s->num_bands;b++){
+                int start = s->cur_sfb_offsets[b];
+                int end = s->cur_sfb_offsets[b+1];
+                int min;
+                float quant;
+                if(end > s->subframe_len)
+                    end = s->subframe_len;
+
+                if(s->channel[c].transmit_sf)
+                     min = s->channel[c].scale_factor_step * (s->channel[c].max_scale_factor - s->channel[c].scale_factors[b]);
+                else
+                     min = s->channel[c].scale_factor_step * (s->channel[c].max_scale_factor - s->channel[c].resampled_scale_factors[b]);
+                quant = pow(10.0,(s->quant_step + s->channel[c].quant_step_modifier - min) / 20.0);
+                while(start < end){
+                    s->channel[c].coeffs[start] *= quant;
+                    ++start;
+                }
+            }
+
+            dst = &s->channel[c].out[s->samples_per_frame/2  + s->channel[c].subframe_offset[s->channel[c].cur_subframe]];
+            ff_imdct_half(&s->mdct_ctx[av_log2(subframe_len)-BLOCK_MIN_BITS], s->tmp, s->channel[c].coeffs); // DCTIV with reverse
+            for(b=0;b<subframe_len;b++)
+                dst[b] = s->tmp[b] / (subframe_len / 2);     // FIXME: try to remove this scaling
+        }
+    }else{
+        for(i=0;i<s->channels_for_cur_subframe;i++){
+            int c = s->channel_indexes_for_cur_subframe[i];
+            float* dst;
+            dst = &s->channel[c].out[s->samples_per_frame/2  + s->channel[c].subframe_offset[s->channel[c].cur_subframe]];
+            memset(dst,0,subframe_len * sizeof(float));
+        }
+    }
+
+    wma_window(s);
+
+    /** handled one subframe */
+    for(i=0;i<s->channels_for_cur_subframe;i++){
+        int c = s->channel_indexes_for_cur_subframe[i];
+        if(s->channel[c].cur_subframe >= s->channel[c].num_subframes){
+            av_log(s->avctx,AV_LOG_ERROR,"broken subframe\n");
+            return 0;
+        }
+        ++s->channel[c].cur_subframe;
+    }
+
+    return 1;
+}
+
+/**
+ *@brief Decode one WMA frame.
+ *@param s context
+ *@param gb current get bit context
+ *@return 0 if the trailer bit indicates that this is the last frame,
+ *        1 if there are more frames
+ */
+static int wma_decode_frame(WMA3DecodeContext *s)
+{
+    GetBitContext* gb = &s->getbit;
+    int more_frames = 0;
+    int len = 0;
+    int i;
+
+    init_get_bits(&s->getbit, s->frame_data,s->prev_packet_bit_size);
+
+    /** check for potential output buffer overflow */
+    if(s->samples + s->num_channels * s->samples_per_frame > s->samples_end){
+        av_log(s->avctx,AV_LOG_ERROR,"not enough space for the output samples\n");
+        s->packet_loss = 1;
+        return 0;
+    }
+
+    s->negative_quantstep = 0;
+    bitstreamcounter = get_bits_count(gb);
+
+    /** get frame length */
+    if(s->len_prefix)
+        len = get_bits(gb,s->log2_frame_size);
+
+    av_log(s->avctx,AV_LOG_DEBUG,"decoding frame with length %x\n",len);
+
+    /** decode tile information */
+    if(wma_decode_tilehdr(s)){
+        s->packet_loss = 1;
+        return 0;
+    }
+
+    /** read postproc transform */
+    if(s->num_channels > 1 && get_bits1(gb)){
+        av_log(s->avctx,AV_LOG_ERROR,"Unsupported postproc transform found\n");
+        s->packet_loss = 1;
+        return 0;
+    }
+
+    /** read drc info */
+    if(s->dynamic_range_compression){
+        s->drc_gain = get_bits(gb,8);
+        av_log(s->avctx,AV_LOG_DEBUG,"drc_gain %i\n",s->drc_gain);
+    }
+
+    /** no idea what these are for, might be the number of samples
+        that need to be skipped at the beginning or end of a stream */
+    if(get_bits(gb,1)){
+        int skip;
+
+        /** usually true for the first frame */
+        if(get_bits1(gb)){
+            skip = get_bits(gb,av_log2(s->samples_per_frame * 2));
+            av_log(s->avctx,AV_LOG_DEBUG,"start skip: %i\n",skip);
+        }
+
+        /** sometimes true for the last frame */
+        if(get_bits(gb,1)){
+            skip = get_bits(gb,av_log2(s->samples_per_frame * 2));
+            av_log(s->avctx,AV_LOG_DEBUG,"end skip: %i\n",skip);
+        }
+
+    }
+
+    av_log(s->avctx,AV_LOG_DEBUG,"BITSTREAM: frame header length was %i\n",get_bits_count(gb) - bitstreamcounter);
+
+    /** reset subframe states */
+    s->parsed_all_subframes = 0;
+    for(i=0;i<s->num_channels;i++){
+        s->channel[i].decoded_samples = 0;
+        s->channel[i].cur_subframe = 0;
+        s->channel[i].reuse_sf = 0;
+    }
+
+    /** parse all subframes */
+    while(!s->parsed_all_subframes){
+        if(!wma_decode_subframe(s)){
+            s->packet_loss = 1;
+            return 0;
+        }
+    }
+
+    /** convert samples to short and write them to the output buffer */
+    for(i = 0; i < s->num_channels; i++) {
+        int16_t* ptr;
+        int incr = s->num_channels;
+        /* FIXME: what about other channel layouts? */
+        const char layout[] = {0,1,4,5,2,3};
+        int chpos;
+        float* iptr = s->channel[i].out;
+        int x;
+
+        if(s->num_channels == 6){
+              chpos = layout[i];
+        }else
+              chpos = i;
+
+        ptr = s->samples + chpos;
+
+        for(x=0;x<s->samples_per_frame;x++) {
+            *ptr = av_clip_int16(lrintf(*iptr++));
+            ptr += incr;
+        }
+
+        /** reuse second half of the IMDCT output for the next frame */
+        memmove(&s->channel[i].out[0], &s->channel[i].out[s->samples_per_frame],
+                s->samples_per_frame * sizeof(float));
+    }
+
+    if(s->skip_frame)
+        s->skip_frame = 0;
+    else
+        s->samples += s->num_channels * s->samples_per_frame;
+
+
+    // FIXME: remove
+    av_log(s->avctx,AV_LOG_DEBUG,"frame[%i] skipping %i bits\n",s->frame_num,len - get_bits_count(gb) - 1);
+    if(len != get_bits_count(gb) + 2)
+        assert(0);
+
+    /** skip the rest of the frame data */
+    skip_bits_long(gb,len - get_bits_count(gb) - 1);
+
+    /** decode trailer bit */
+    more_frames = get_bits1(gb);
+
+    ++s->frame_num;
+    return more_frames;
+}
+
+/**
+ *@brief Calculate remaining input buffer length.
+ *@param s codec context
+ *@param gb bitstream reader context
+ *@return remaining size in bits
+ */
+static int remaining_bits(WMA3DecodeContext *s, GetBitContext* gb)
+{
+    return s->buf_bit_size - get_bits_count(gb);
+}
+
+/**
+ *@brief Fill the bit reservoir with a partial frame.
+ *@param s codec context
+ *@param gb bitstream reader context
+ *@param len length of the partial frame
+ */
+static void save_bits(WMA3DecodeContext *s, GetBitContext* gb, int len)
+{
+    int buflen = (s->prev_packet_bit_size + len + 8) / 8;
+    int bit_offset = s->prev_packet_bit_size % 8;
+    int pos = (s->prev_packet_bit_size - bit_offset) / 8;
+    s->prev_packet_bit_size += len;
+
+    if(len <= 0 || buflen > MAX_FRAMESIZE){
+         av_log(s->avctx, AV_LOG_ERROR, "input buffer to small\n");
+         s->packet_loss = 1;
+         return;
+    }
+
+    /** byte align prev_frame buffer */
+    if(bit_offset){
+        int missing = 8 - bit_offset;
+        if(len < missing)
+            missing = len;
+        s->frame_data[pos++] |=
+            get_bits(gb, missing) << (8 - bit_offset - missing);
+        len -= missing;
+    }
+
+    /** copy full bytes */
+    while(len > 7){
+        s->frame_data[pos++] = get_bits(gb,8);
+        len -= 8;
+    }
+
+    /** copy remaining bits */
+    if(len > 0)
+        s->frame_data[pos++] = get_bits(gb,len) << (8 - len);
+}
+
+/**
+ *@brief Decode a single WMA packet.
+ *@param avctx codec context
+ *@param data the output buffer
+ *@param data_size number of bytes that were written to the output buffer
+ *@param buf input buffer
+ *@param buf_size input buffer length
+ *@return number of bytes that were read from the input buffer
+ */
+static int wma3_decode_packet(AVCodecContext *avctx,
+                             void *data, int *data_size,
+                             const uint8_t *buf, int buf_size)
+{
+    GetBitContext gb;
+    WMA3DecodeContext *s = avctx->priv_data;
+    int more_frames=1;
+    int num_bits_prev_frame;
+    int packet_sequence_number;
+
+    s->samples = data;
+    s->samples_end = (int16_t*)((int8_t*)data + *data_size);
+    s->buf_bit_size = buf_size << 3;
+
+
+    *data_size = 0;
+
+    /** sanity check for the buffer length */
+    if(buf_size < avctx->block_align)
+        return 0;
+
+    buf_size = avctx->block_align;
+
+    /** parse packet header */
+    init_get_bits(&gb, buf, s->buf_bit_size);
+    packet_sequence_number    = get_bits(&gb, 4);
+    s->bit5                   = get_bits1(&gb);
+    s->bit6                   = get_bits1(&gb);
+
+    /** get number of bits that need to be added to the previous frame */
+    num_bits_prev_frame = get_bits(&gb, s->log2_frame_size);
+    av_log(avctx, AV_LOG_DEBUG, "packet[%d]: nbpf %x\n", avctx->frame_number,
+                  num_bits_prev_frame);
+
+    /** check for packet loss */
+    if (!s->packet_loss &&
+        ((s->packet_sequence_number + 1)&0xF) != packet_sequence_number) {
+        s->packet_loss = 1;
+        av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",
+                      s->packet_sequence_number,packet_sequence_number);
+    }
+    s->packet_sequence_number = packet_sequence_number;
+
+    if (num_bits_prev_frame > 0) {
+        /** append the previous frame data to the remaining data from the
+            previous packet to create a full frame */
+        save_bits(s,&gb,num_bits_prev_frame);
+        av_log(avctx, AV_LOG_DEBUG, "accumulated %x bits of frame data\n",
+                      s->prev_packet_bit_size);
+
+        /** decode the cross packet frame if it is valid */
+        if(!s->packet_loss)
+            wma_decode_frame(s);
+    }else if(s->prev_packet_bit_size){
+        av_log(avctx, AV_LOG_DEBUG, "ignoring %x previously saved bits\n",
+                      s->prev_packet_bit_size);
+    }
+
+    /** reset previous frame buffer */
+    s->prev_packet_bit_size = 0;
+    s->packet_loss = 0;
+    /** decode the rest of the packet */
+    while(!s->packet_loss && more_frames && remaining_bits(s,&gb) > s->log2_frame_size){
+        int frame_size = show_bits(&gb, s->log2_frame_size);
+
+        /** there is enough data for a full frame */
+        if(remaining_bits(s,&gb) >= frame_size){
+            s->prev_packet_bit_size = 0;
+            save_bits(s,&gb,frame_size);
+
+            /** decode the frame */
+            more_frames = wma_decode_frame(s);
+
+            if(!more_frames){
+                av_log(avctx, AV_LOG_DEBUG, "no more frames\n");
+            }
+        }else
+            more_frames = 0;
+    }
+
+    if(!s->packet_loss){
+        s->prev_packet_bit_size = 0;
+        /** save the rest of the data so that it can be decoded
+            with the next packet */
+        save_bits(s,&gb,remaining_bits(s,&gb));
+    }
+
+    *data_size = (int8_t *)s->samples - (int8_t *)data;
+
+    return avctx->block_align;
+}
+
+static void wma3_flush(AVCodecContext *avctx)
+{
+    WMA3DecodeContext *s = avctx->priv_data;
+    int i;
+    for(i=0;i<s->num_channels;i++)
+        memset(s->channel[i].out, 0, sizeof(s->channel[0].out));
+    s->packet_loss = 1;
+}
+
+
+/**
+ *@brief WMA9 decoder
+ */
+AVCodec wmapro_decoder =
+{
+    "wmapro",
+    CODEC_TYPE_AUDIO,
+    CODEC_ID_WMAPRO,
+    sizeof(WMA3DecodeContext),
+    wma3_decode_init,
+    NULL,
+    wma3_decode_end,
+    wma3_decode_packet,
+    .flush= wma3_flush,
+    .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 9 Professional"),
+};
Index: libavcodec/Makefile
===================================================================
--- libavcodec/Makefile	(revision 18141)
+++ libavcodec/Makefile	(working copy)
@@ -241,6 +241,7 @@
 OBJS-$(CONFIG_WMAV1_ENCODER)           += wmaenc.o wma.o
 OBJS-$(CONFIG_WMAV2_DECODER)           += wmadec.o wma.o
 OBJS-$(CONFIG_WMAV2_ENCODER)           += wmaenc.o wma.o
+OBJS-$(CONFIG_WMAPRO_DECODER)          += wma3dec.o
 OBJS-$(CONFIG_WMV1_DECODER)            += h263dec.o h263.o mpeg12data.o mpegvideo.o error_resilience.o
 OBJS-$(CONFIG_WMV1_ENCODER)            += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o mpeg12data.o mpegvideo.o error_resilience.o
 OBJS-$(CONFIG_WMV2_DECODER)            += wmv2dec.o wmv2.o msmpeg4.o msmpeg4data.o h263dec.o h263.o intrax8.o intrax8dsp.o mpeg12data.o mpegvideo.o error_resilience.o
Index: libavcodec/allcodecs.c
===================================================================
--- libavcodec/allcodecs.c	(revision 18141)
+++ libavcodec/allcodecs.c	(working copy)
@@ -223,6 +223,7 @@
     REGISTER_DECODER (WAVPACK, wavpack);
     REGISTER_ENCDEC  (WMAV1, wmav1);
     REGISTER_ENCDEC  (WMAV2, wmav2);
+    REGISTER_DECODER (WMAPRO, wmapro);  
     REGISTER_DECODER (WS_SND1, ws_snd1);
 
     /* PCM codecs */
Index: libavcodec/avcodec.h
===================================================================
--- libavcodec/avcodec.h	(revision 18141)
+++ libavcodec/avcodec.h	(working copy)
@@ -390,7 +390,7 @@
 #define CH_LAYOUT_STEREO_DOWNMIX    (CH_STEREO_LEFT|CH_STEREO_RIGHT)
 
 /* in bytes */
-#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio
+#define AVCODEC_MAX_AUDIO_FRAME_SIZE 1130496
 
 /**
  * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Index: libavcodec/wma3.h
===================================================================
--- libavcodec/wma3.h	(revision 0)
+++ libavcodec/wma3.h	(revision 0)
@@ -0,0 +1,160 @@
+/*
+ * WMA 9/3/PRO compatible decoder
+ * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion
+ * Copyright (c) 2008 - 2009 Sascha Sommer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file  libavcodec/wma3.h
+ * @brief wmapro specific structs and defines
+ */
+
+#ifndef AVCODEC_WMA3_H
+#define AVCODEC_WMA3_H
+
+#include "wma3data.h"
+#include "dsputil.h"
+
+/* current decoder limitations */
+#define MAX_CHANNELS    8                                    //< max number of handled channels
+#define MAX_SUBFRAMES  32                                    //< max number of subframes per channel
+#define MAX_BANDS      29                                    //< max number of scale factor bands
+#define MAX_FRAMESIZE  16384                                 //< maximum compressed frame size
+
+/* size of block defines taken from wma.h */
+#define BLOCK_MIN_BITS  7                                    //< log2 of min block size
+#define BLOCK_MAX_BITS 12                                    //< log2 of max block size
+#define BLOCK_MAX_SIZE (1 << BLOCK_MAX_BITS)                 //< maximum block size
+#define BLOCK_NB_SIZES (BLOCK_MAX_BITS - BLOCK_MIN_BITS + 1) //< possible block sizes
+
+/**
+ * @brief decoder context for a single channel
+ */
+typedef struct {
+    int      prev_block_len;                          //< length of the previous block
+    uint8_t  transmit_coefs;                          //< transmit coefficients
+    uint8_t  num_subframes;                           //< number of subframes
+    uint16_t subframe_len[MAX_SUBFRAMES];             //< subframe length in samples
+    uint16_t subframe_offset[MAX_SUBFRAMES];          //< subframe position
+    uint8_t  cur_subframe;                            //< subframe index
+    uint16_t channel_len;                             //< channel length in samples
+    uint16_t decoded_samples;                         //< already processed samples
+    uint8_t  grouped;                                 //< channel is part of a group
+    int      quant_step_modifier;                     //< deviation from the main quantization step
+    int      transmit_sf;                             //< transmit scale factors
+    int      reuse_sf;                                //< share scale factors between subframes
+    int      scale_factor_step;                       //< scaling step
+    int      max_scale_factor;                        //< maximum scale factor
+    int      scale_factors[MAX_BANDS];                //< scale factor values
+    int      resampled_scale_factors[MAX_BANDS];      //< scale factors from a previous block
+    int      scale_factor_block_len;                  //< scale factor reference block length
+    float*   coeffs;                                  //< pointer to the decode buffer
+    DECLARE_ALIGNED_16(float, out[2*BLOCK_MAX_SIZE]); //< output buffer
+} WMA3ChannelCtx;
+
+/**
+ * @brief channel group for channel transformations
+ */
+typedef struct {
+    int   num_channels;
+    int   no_rotation;                                     //< controls the type of the transform
+    int   transform;                                       //< also controls the type of the transform
+    char  transform_band[MAX_BANDS];                       //< controls if the transform is enabled for a certain band
+    char  rotation_offset[MAX_CHANNELS * MAX_CHANNELS];
+    char  positive[MAX_CHANNELS * MAX_CHANNELS];           //< FIXME: What are these numbers used for?
+    float decorrelation_matrix[MAX_CHANNELS*MAX_CHANNELS];
+    char  use_channel[MAX_CHANNELS];
+} WMA3ChannelGroup;
+
+/**
+ * @brief main decoder context
+ */
+typedef struct WMA3DecodeContext {
+    /** generic decoder variables */
+    AVCodecContext*  avctx;                         //< codec context for av_log
+    DSPContext       dsp;                           //< accelerated dsp functions
+    uint8_t          frame_data[MAX_FRAMESIZE +
+                      FF_INPUT_BUFFER_PADDING_SIZE];//< compressed frame data
+    MDCTContext      mdct_ctx[BLOCK_NB_SIZES];      //< MDCT context per block size
+    DECLARE_ALIGNED_16(float, tmp[BLOCK_MAX_SIZE]); //< imdct output buffer
+    float*           windows[BLOCK_NB_SIZES];       //< window per block size
+    VLC              sf_vlc;                        //< scale factor dpcm vlc
+    VLC              sf_rl_vlc;                     //< scale factor run length vlc
+    VLC              vec4_vlc;                      //< 4 coefficients per symbol
+    VLC              vec2_vlc;                      //< 2 coefficients per symbol
+    VLC              vec1_vlc;                      //< 1 coefficient per symbol
+    VLC              coef_vlc[2];                   //< coefficient run length vlc codes
+    int              coef_max[2];                   //< max length of vlc codes
+
+    /** frame size dependent frame information (set during initialization) */
+    uint8_t          lossless;                      //< lossless mode
+    unsigned int     decode_flags;                  //< used compression features
+    uint8_t          len_prefix;                    //< frame is prefixed with its length
+    uint8_t          dynamic_range_compression;     //< frame contains DRC data
+    uint8_t          sample_bit_depth;              //< bits per sample
+    uint16_t         samples_per_frame;             //< number of samples to output
+    uint16_t         log2_frame_size;               //< frame size
+    int8_t           num_channels;                  //< number of channels
+    int8_t           lfe_channel;                   //< lfe channel index
+    const float***   def_decorrelation_mat;         //< default decorrelation matrix
+    uint8_t          allow_subframes;               //< frames may contain subframes
+    uint8_t          max_num_subframes;             //< maximum number of subframes
+    int8_t           num_possible_block_sizes;      //< nb of supported block sizes
+    uint16_t         min_samples_per_subframe;      //< minimum samples per subframe
+    int*             num_sfb;                       //< scale factor bands per block size
+    int*             sfb_offsets;                   //< scale factor band offsets
+    int*             sf_offsets;                    //< scale factor resample matrix
+    int*             subwoofer_cutoffs;             //< subwoofer cutoff values
+
+    /** packet decode state */
+    uint8_t          packet_sequence_number;        //< current packet number
+    int              prev_packet_bit_size;          //< saved number of bits
+    uint8_t          bit5;                          //< padding bit? (CBR files)
+    uint8_t          bit6;                          //< unknown
+    uint8_t          packet_loss;                   //< set in case of bitstream error
+    uint8_t          negative_quantstep;            //< packet loss due to negative quant step
+
+    /** frame decode state */
+    unsigned int     frame_num;                     //< current frame number
+    GetBitContext    getbit;                        //< bitstream reader context
+    int              buf_bit_size;                  //< buffer size in bits
+    int16_t*         samples;                       //< current samplebuffer pointer
+    int16_t*         samples_end;                   //< maximum samplebuffer pointer
+    uint8_t          drc_gain;                      //< gain for the DRC tool
+    int              skip_frame;                    //< skip output step
+    int              parsed_all_subframes;          //< all subframes decoded?
+
+    /** subframe/block decode state */
+    int              subframe_len;                  //< current subframe length
+    int              channels_for_cur_subframe;     //< number of channels that contain the subframe
+    int              channel_indexes_for_cur_subframe[MAX_CHANNELS];
+    int              cur_subwoofer_cutoff;          //< subwoofer cutoff value
+    int              num_bands;                     //< number of scale factor bands
+    int*             cur_sfb_offsets;               //< sfb offsets for the current block
+    int              quant_step;                    //< quantization step
+    int              esc_len;                       //< length of escaped coefficients
+
+    uint8_t          num_chgroups;                  //< number of channel groups
+    WMA3ChannelGroup chgroup[MAX_CHANNELS];         //< channel group information
+
+    WMA3ChannelCtx   channel[MAX_CHANNELS];         //< per channel data
+} WMA3DecodeContext;
+
+#endif /* AVCODEC_WMA3_H */
+


More information about the Packman mailing list