[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