ffmpeg / libavcodec / wmadec.c @ b5ec6383
History | View | Annotate | Download (30.8 KB)
1 | bc8d1857 | Fabrice Bellard | /*
|
---|---|---|---|
2 | * WMA compatible decoder
|
||
3 | 406792e7 | Diego Biurrun | * Copyright (c) 2002 The FFmpeg Project
|
4 | bc8d1857 | Fabrice Bellard | *
|
5 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
6 | *
|
||
7 | * FFmpeg is free software; you can redistribute it and/or
|
||
8 | bc8d1857 | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
9 | * License as published by the Free Software Foundation; either
|
||
10 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
11 | bc8d1857 | Fabrice Bellard | *
|
12 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
13 | bc8d1857 | Fabrice Bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
15 | * Lesser General Public License for more details.
|
||
16 | *
|
||
17 | * You should have received a copy of the GNU Lesser General Public
|
||
18 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
19 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
20 | bc8d1857 | Fabrice Bellard | */
|
21 | 983e3246 | Michael Niedermayer | |
22 | /**
|
||
23 | ba87f080 | Diego Biurrun | * @file
|
24 | 983e3246 | Michael Niedermayer | * WMA compatible decoder.
|
25 | 7e56cd92 | Mike Melanson | * This decoder handles Microsoft Windows Media Audio data, versions 1 & 2.
|
26 | 115329f1 | Diego Biurrun | * WMA v1 is identified by audio format 0x160 in Microsoft media files
|
27 | 7e56cd92 | Mike Melanson | * (ASF/AVI/WAV). WMA v2 is identified by audio format 0x161.
|
28 | *
|
||
29 | * To use this decoder, a calling application must supply the extra data
|
||
30 | * bytes provided with the WMA data. These are the extra, codec-specific
|
||
31 | 115329f1 | Diego Biurrun | * bytes at the end of a WAVEFORMATEX data structure. Transmit these bytes
|
32 | * to the decoder using the extradata[_size] fields in AVCodecContext. There
|
||
33 | 7e56cd92 | Mike Melanson | * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data.
|
34 | 983e3246 | Michael Niedermayer | */
|
35 | |||
36 | bc8d1857 | Fabrice Bellard | #include "avcodec.h" |
37 | 59686073 | Michael Niedermayer | #include "wma.h" |
38 | bc8d1857 | Fabrice Bellard | |
39 | 59686073 | Michael Niedermayer | #undef NDEBUG
|
40 | #include <assert.h> |
||
41 | 63a5b0b1 | Jindřich Makovička | |
42 | #define EXPVLCBITS 8 |
||
43 | #define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) |
||
44 | |||
45 | #define HGAINVLCBITS 9 |
||
46 | #define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) |
||
47 | 52fa37f1 | Benjamin Larsson | |
48 | 911b9faf | Michel Bardiaux | static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); |
49 | bc8d1857 | Fabrice Bellard | |
50 | f2899fb1 | Alex Beregszaszi | #ifdef TRACE
|
51 | 7f95d9f6 | Alex Beregszaszi | static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) |
52 | bc8d1857 | Fabrice Bellard | { |
53 | int i;
|
||
54 | |||
55 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "%s[%d]:\n", name, n);
|
56 | bc8d1857 | Fabrice Bellard | for(i=0;i<n;i++) { |
57 | if ((i & 7) == 0) |
||
58 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "%4d: ", i);
|
59 | tprintf(s->avctx, " %5d.0", tab[i]);
|
||
60 | bc8d1857 | Fabrice Bellard | if ((i & 7) == 7) |
61 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "\n");
|
62 | bc8d1857 | Fabrice Bellard | } |
63 | } |
||
64 | |||
65 | 7f95d9f6 | Alex Beregszaszi | static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) |
66 | bc8d1857 | Fabrice Bellard | { |
67 | int i;
|
||
68 | |||
69 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "%s[%d]:\n", name, n);
|
70 | bc8d1857 | Fabrice Bellard | for(i=0;i<n;i++) { |
71 | if ((i & 7) == 0) |
||
72 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "%4d: ", i);
|
73 | tprintf(s->avctx, " %8.*f", prec, tab[i]);
|
||
74 | bc8d1857 | Fabrice Bellard | if ((i & 7) == 7) |
75 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "\n");
|
76 | bc8d1857 | Fabrice Bellard | } |
77 | if ((i & 7) != 0) |
||
78 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "\n");
|
79 | bc8d1857 | Fabrice Bellard | } |
80 | #endif
|
||
81 | |||
82 | static int wma_decode_init(AVCodecContext * avctx) |
||
83 | { |
||
84 | 911b9faf | Michel Bardiaux | WMACodecContext *s = avctx->priv_data; |
85 | 0a07e9d0 | Måns Rullgård | int i, flags2;
|
86 | bc8d1857 | Fabrice Bellard | uint8_t *extradata; |
87 | 115329f1 | Diego Biurrun | |
88 | a9c9a240 | Michel Bardiaux | s->avctx = avctx; |
89 | |||
90 | bc8d1857 | Fabrice Bellard | /* extract flag infos */
|
91 | flags2 = 0;
|
||
92 | extradata = avctx->extradata; |
||
93 | 59686073 | Michael Niedermayer | if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { |
94 | 2c124cb6 | Ramiro Polla | flags2 = AV_RL16(extradata+2);
|
95 | 59686073 | Michael Niedermayer | } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { |
96 | 2c124cb6 | Ramiro Polla | flags2 = AV_RL16(extradata+4);
|
97 | bc8d1857 | Fabrice Bellard | } |
98 | e8ebd573 | Michael Niedermayer | // for(i=0; i<avctx->extradata_size; i++)
|
99 | // av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]);
|
||
100 | 59686073 | Michael Niedermayer | |
101 | bc8d1857 | Fabrice Bellard | s->use_exp_vlc = flags2 & 0x0001;
|
102 | s->use_bit_reservoir = flags2 & 0x0002;
|
||
103 | s->use_variable_block_len = flags2 & 0x0004;
|
||
104 | |||
105 | 47b777ce | Michael Niedermayer | if(ff_wma_init(avctx, flags2)<0) |
106 | return -1; |
||
107 | bc8d1857 | Fabrice Bellard | |
108 | /* init MDCT */
|
||
109 | for(i = 0; i < s->nb_block_sizes; i++) |
||
110 | 7d485f16 | Siarhei Siamashka | ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0); |
111 | 115329f1 | Diego Biurrun | |
112 | bc8d1857 | Fabrice Bellard | if (s->use_noise_coding) {
|
113 | 59686073 | Michael Niedermayer | init_vlc(&s->hgain_vlc, HGAINVLCBITS, sizeof(ff_wma_hgain_huffbits),
|
114 | ff_wma_hgain_huffbits, 1, 1, |
||
115 | ff_wma_hgain_huffcodes, 2, 2, 0); |
||
116 | bc8d1857 | Fabrice Bellard | } |
117 | |||
118 | if (s->use_exp_vlc) {
|
||
119 | 3a201bd0 | Stefan Gehrer | init_vlc(&s->exp_vlc, EXPVLCBITS, sizeof(ff_aac_scalefactor_bits), //FIXME move out of context |
120 | ff_aac_scalefactor_bits, 1, 1, |
||
121 | ff_aac_scalefactor_code, 4, 4, 0); |
||
122 | bc8d1857 | Fabrice Bellard | } else {
|
123 | wma_lsp_to_curve_init(s, s->frame_len); |
||
124 | } |
||
125 | |||
126 | 5d6e4c16 | Stefano Sabatini | avctx->sample_fmt = AV_SAMPLE_FMT_S16; |
127 | bc8d1857 | Fabrice Bellard | return 0; |
128 | } |
||
129 | |||
130 | 6836af52 | Michael Niedermayer | /**
|
131 | * compute x^-0.25 with an exponent and mantissa table. We use linear
|
||
132 | * interpolation to reduce the mantissa table size at a small speed
|
||
133 | * expense (linear interpolation approximately doubles the number of
|
||
134 | * bits of precision).
|
||
135 | */
|
||
136 | 911b9faf | Michel Bardiaux | static inline float pow_m1_4(WMACodecContext *s, float x) |
137 | bc8d1857 | Fabrice Bellard | { |
138 | union {
|
||
139 | float f;
|
||
140 | unsigned int v; |
||
141 | } u, t; |
||
142 | unsigned int e, m; |
||
143 | float a, b;
|
||
144 | |||
145 | u.f = x; |
||
146 | e = u.v >> 23;
|
||
147 | m = (u.v >> (23 - LSP_POW_BITS)) & ((1 << LSP_POW_BITS) - 1); |
||
148 | /* build interpolation scale: 1 <= t < 2. */
|
||
149 | t.v = ((u.v << LSP_POW_BITS) & ((1 << 23) - 1)) | (127 << 23); |
||
150 | a = s->lsp_pow_m_table1[m]; |
||
151 | b = s->lsp_pow_m_table2[m]; |
||
152 | return s->lsp_pow_e_table[e] * (a + b * t.f);
|
||
153 | } |
||
154 | |||
155 | 911b9faf | Michel Bardiaux | static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) |
156 | 115329f1 | Diego Biurrun | { |
157 | bc8d1857 | Fabrice Bellard | float wdel, a, b;
|
158 | int i, e, m;
|
||
159 | |||
160 | wdel = M_PI / frame_len; |
||
161 | for(i=0;i<frame_len;i++) |
||
162 | s->lsp_cos_table[i] = 2.0f * cos(wdel * i); |
||
163 | |||
164 | /* tables for x^-0.25 computation */
|
||
165 | for(i=0;i<256;i++) { |
||
166 | e = i - 126;
|
||
167 | s->lsp_pow_e_table[i] = pow(2.0, e * -0.25); |
||
168 | } |
||
169 | |||
170 | /* NOTE: these two tables are needed to avoid two operations in
|
||
171 | pow_m1_4 */
|
||
172 | b = 1.0; |
||
173 | for(i=(1 << LSP_POW_BITS) - 1;i>=0;i--) { |
||
174 | m = (1 << LSP_POW_BITS) + i;
|
||
175 | a = (float)m * (0.5 / (1 << LSP_POW_BITS)); |
||
176 | a = pow(a, -0.25); |
||
177 | s->lsp_pow_m_table1[i] = 2 * a - b;
|
||
178 | s->lsp_pow_m_table2[i] = b - a; |
||
179 | b = a; |
||
180 | } |
||
181 | #if 0
|
||
182 | for(i=1;i<20;i++) {
|
||
183 | float v, r1, r2;
|
||
184 | v = 5.0 / i;
|
||
185 | r1 = pow_m1_4(s, v);
|
||
186 | r2 = pow(v,-0.25);
|
||
187 | printf("%f^-0.25=%f e=%f\n", v, r1, r2 - r1);
|
||
188 | }
|
||
189 | #endif
|
||
190 | } |
||
191 | |||
192 | 6836af52 | Michael Niedermayer | /**
|
193 | * NOTE: We use the same code as Vorbis here
|
||
194 | * @todo optimize it further with SSE/3Dnow
|
||
195 | */
|
||
196 | 911b9faf | Michel Bardiaux | static void wma_lsp_to_curve(WMACodecContext *s, |
197 | 115329f1 | Diego Biurrun | float *out, float *val_max_ptr, |
198 | bc8d1857 | Fabrice Bellard | int n, float *lsp) |
199 | { |
||
200 | int i, j;
|
||
201 | float p, q, w, v, val_max;
|
||
202 | |||
203 | val_max = 0;
|
||
204 | for(i=0;i<n;i++) { |
||
205 | p = 0.5f; |
||
206 | q = 0.5f; |
||
207 | w = s->lsp_cos_table[i]; |
||
208 | for(j=1;j<NB_LSP_COEFS;j+=2){ |
||
209 | q *= w - lsp[j - 1];
|
||
210 | p *= w - lsp[j]; |
||
211 | } |
||
212 | p *= p * (2.0f - w); |
||
213 | q *= q * (2.0f + w); |
||
214 | v = p + q; |
||
215 | v = pow_m1_4(s, v); |
||
216 | if (v > val_max)
|
||
217 | val_max = v; |
||
218 | out[i] = v; |
||
219 | } |
||
220 | *val_max_ptr = val_max; |
||
221 | } |
||
222 | |||
223 | 6836af52 | Michael Niedermayer | /**
|
224 | * decode exponents coded with LSP coefficients (same idea as Vorbis)
|
||
225 | */
|
||
226 | 911b9faf | Michel Bardiaux | static void decode_exp_lsp(WMACodecContext *s, int ch) |
227 | bc8d1857 | Fabrice Bellard | { |
228 | float lsp_coefs[NB_LSP_COEFS];
|
||
229 | int val, i;
|
||
230 | |||
231 | for(i = 0; i < NB_LSP_COEFS; i++) { |
||
232 | if (i == 0 || i >= 8) |
||
233 | val = get_bits(&s->gb, 3);
|
||
234 | else
|
||
235 | val = get_bits(&s->gb, 4);
|
||
236 | 59686073 | Michael Niedermayer | lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; |
237 | bc8d1857 | Fabrice Bellard | } |
238 | |||
239 | wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch], |
||
240 | s->block_len, lsp_coefs); |
||
241 | } |
||
242 | |||
243 | 8b4a6d47 | Måns Rullgård | /** pow(10, i / 16.0) for i in -60..95 */
|
244 | 168f92ff | Måns Rullgård | static const float pow_tab[] = { |
245 | c0d1463d | Måns Rullgård | 1.7782794100389e-04, 2.0535250264571e-04, |
246 | 2.3713737056617e-04, 2.7384196342644e-04, |
||
247 | 3.1622776601684e-04, 3.6517412725484e-04, |
||
248 | 4.2169650342858e-04, 4.8696752516586e-04, |
||
249 | 5.6234132519035e-04, 6.4938163157621e-04, |
||
250 | 7.4989420933246e-04, 8.6596432336006e-04, |
||
251 | 1.0000000000000e-03, 1.1547819846895e-03, |
||
252 | 1.3335214321633e-03, 1.5399265260595e-03, |
||
253 | 1.7782794100389e-03, 2.0535250264571e-03, |
||
254 | 2.3713737056617e-03, 2.7384196342644e-03, |
||
255 | 3.1622776601684e-03, 3.6517412725484e-03, |
||
256 | 4.2169650342858e-03, 4.8696752516586e-03, |
||
257 | 5.6234132519035e-03, 6.4938163157621e-03, |
||
258 | 7.4989420933246e-03, 8.6596432336006e-03, |
||
259 | 1.0000000000000e-02, 1.1547819846895e-02, |
||
260 | 1.3335214321633e-02, 1.5399265260595e-02, |
||
261 | 1.7782794100389e-02, 2.0535250264571e-02, |
||
262 | 2.3713737056617e-02, 2.7384196342644e-02, |
||
263 | 3.1622776601684e-02, 3.6517412725484e-02, |
||
264 | 4.2169650342858e-02, 4.8696752516586e-02, |
||
265 | 5.6234132519035e-02, 6.4938163157621e-02, |
||
266 | 7.4989420933246e-02, 8.6596432336007e-02, |
||
267 | 1.0000000000000e-01, 1.1547819846895e-01, |
||
268 | 1.3335214321633e-01, 1.5399265260595e-01, |
||
269 | 1.7782794100389e-01, 2.0535250264571e-01, |
||
270 | 2.3713737056617e-01, 2.7384196342644e-01, |
||
271 | 3.1622776601684e-01, 3.6517412725484e-01, |
||
272 | 4.2169650342858e-01, 4.8696752516586e-01, |
||
273 | 5.6234132519035e-01, 6.4938163157621e-01, |
||
274 | 7.4989420933246e-01, 8.6596432336007e-01, |
||
275 | 1.0000000000000e+00, 1.1547819846895e+00, |
||
276 | 1.3335214321633e+00, 1.5399265260595e+00, |
||
277 | 1.7782794100389e+00, 2.0535250264571e+00, |
||
278 | 2.3713737056617e+00, 2.7384196342644e+00, |
||
279 | 3.1622776601684e+00, 3.6517412725484e+00, |
||
280 | 4.2169650342858e+00, 4.8696752516586e+00, |
||
281 | 5.6234132519035e+00, 6.4938163157621e+00, |
||
282 | 7.4989420933246e+00, 8.6596432336007e+00, |
||
283 | 1.0000000000000e+01, 1.1547819846895e+01, |
||
284 | 1.3335214321633e+01, 1.5399265260595e+01, |
||
285 | 1.7782794100389e+01, 2.0535250264571e+01, |
||
286 | 2.3713737056617e+01, 2.7384196342644e+01, |
||
287 | 3.1622776601684e+01, 3.6517412725484e+01, |
||
288 | 4.2169650342858e+01, 4.8696752516586e+01, |
||
289 | 5.6234132519035e+01, 6.4938163157621e+01, |
||
290 | 7.4989420933246e+01, 8.6596432336007e+01, |
||
291 | 1.0000000000000e+02, 1.1547819846895e+02, |
||
292 | 1.3335214321633e+02, 1.5399265260595e+02, |
||
293 | 1.7782794100389e+02, 2.0535250264571e+02, |
||
294 | 2.3713737056617e+02, 2.7384196342644e+02, |
||
295 | 3.1622776601684e+02, 3.6517412725484e+02, |
||
296 | 4.2169650342858e+02, 4.8696752516586e+02, |
||
297 | 5.6234132519035e+02, 6.4938163157621e+02, |
||
298 | 7.4989420933246e+02, 8.6596432336007e+02, |
||
299 | 1.0000000000000e+03, 1.1547819846895e+03, |
||
300 | 1.3335214321633e+03, 1.5399265260595e+03, |
||
301 | 1.7782794100389e+03, 2.0535250264571e+03, |
||
302 | 2.3713737056617e+03, 2.7384196342644e+03, |
||
303 | 3.1622776601684e+03, 3.6517412725484e+03, |
||
304 | 4.2169650342858e+03, 4.8696752516586e+03, |
||
305 | 5.6234132519035e+03, 6.4938163157621e+03, |
||
306 | 7.4989420933246e+03, 8.6596432336007e+03, |
||
307 | 1.0000000000000e+04, 1.1547819846895e+04, |
||
308 | 1.3335214321633e+04, 1.5399265260595e+04, |
||
309 | 168f92ff | Måns Rullgård | 1.7782794100389e+04, 2.0535250264571e+04, |
310 | 2.3713737056617e+04, 2.7384196342644e+04, |
||
311 | 3.1622776601684e+04, 3.6517412725484e+04, |
||
312 | 4.2169650342858e+04, 4.8696752516586e+04, |
||
313 | 8b4a6d47 | Måns Rullgård | 5.6234132519035e+04, 6.4938163157621e+04, |
314 | 7.4989420933246e+04, 8.6596432336007e+04, |
||
315 | 1.0000000000000e+05, 1.1547819846895e+05, |
||
316 | 1.3335214321633e+05, 1.5399265260595e+05, |
||
317 | 1.7782794100389e+05, 2.0535250264571e+05, |
||
318 | 2.3713737056617e+05, 2.7384196342644e+05, |
||
319 | 3.1622776601684e+05, 3.6517412725484e+05, |
||
320 | 4.2169650342858e+05, 4.8696752516586e+05, |
||
321 | 5.6234132519035e+05, 6.4938163157621e+05, |
||
322 | 7.4989420933246e+05, 8.6596432336007e+05, |
||
323 | c0d1463d | Måns Rullgård | }; |
324 | |||
325 | 6836af52 | Michael Niedermayer | /**
|
326 | * decode exponents coded with VLC codes
|
||
327 | */
|
||
328 | 911b9faf | Michel Bardiaux | static int decode_exp_vlc(WMACodecContext *s, int ch) |
329 | bc8d1857 | Fabrice Bellard | { |
330 | int last_exp, n, code;
|
||
331 | 0a07e9d0 | Måns Rullgård | const uint16_t *ptr;
|
332 | ff00b94e | Måns Rullgård | float v, max_scale;
|
333 | uint32_t *q, *q_end, iv; |
||
334 | c0d1463d | Måns Rullgård | const float *ptab = pow_tab + 60; |
335 | ff00b94e | Måns Rullgård | const uint32_t *iptab = (const uint32_t*)ptab; |
336 | 115329f1 | Diego Biurrun | |
337 | 0a07e9d0 | Måns Rullgård | ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; |
338 | ff00b94e | Måns Rullgård | q = (uint32_t *)s->exponents[ch]; |
339 | bc8d1857 | Fabrice Bellard | q_end = q + s->block_len; |
340 | max_scale = 0;
|
||
341 | if (s->version == 1) { |
||
342 | last_exp = get_bits(&s->gb, 5) + 10; |
||
343 | c0d1463d | Måns Rullgård | v = ptab[last_exp]; |
344 | ff00b94e | Måns Rullgård | iv = iptab[last_exp]; |
345 | bc8d1857 | Fabrice Bellard | max_scale = v; |
346 | n = *ptr++; |
||
347 | 0e71841b | Måns Rullgård | switch (n & 3) do { |
348 | case 0: *q++ = iv; |
||
349 | case 3: *q++ = iv; |
||
350 | case 2: *q++ = iv; |
||
351 | case 1: *q++ = iv; |
||
352 | } while ((n -= 4) > 0); |
||
353 | 59686073 | Michael Niedermayer | }else
|
354 | last_exp = 36;
|
||
355 | |||
356 | bc8d1857 | Fabrice Bellard | while (q < q_end) {
|
357 | 63a5b0b1 | Jindřich Makovička | code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); |
358 | 445a9dee | Michael Niedermayer | if (code < 0){ |
359 | av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n");
|
||
360 | bc8d1857 | Fabrice Bellard | return -1; |
361 | 445a9dee | Michael Niedermayer | } |
362 | bc8d1857 | Fabrice Bellard | /* NOTE: this offset is the same as MPEG4 AAC ! */
|
363 | last_exp += code - 60;
|
||
364 | 168f92ff | Måns Rullgård | if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { |
365 | av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n",
|
||
366 | last_exp); |
||
367 | c0d1463d | Måns Rullgård | return -1; |
368 | 168f92ff | Måns Rullgård | } |
369 | c0d1463d | Måns Rullgård | v = ptab[last_exp]; |
370 | ff00b94e | Måns Rullgård | iv = iptab[last_exp]; |
371 | bc8d1857 | Fabrice Bellard | if (v > max_scale)
|
372 | max_scale = v; |
||
373 | n = *ptr++; |
||
374 | 0e71841b | Måns Rullgård | switch (n & 3) do { |
375 | case 0: *q++ = iv; |
||
376 | case 3: *q++ = iv; |
||
377 | case 2: *q++ = iv; |
||
378 | case 1: *q++ = iv; |
||
379 | } while ((n -= 4) > 0); |
||
380 | bc8d1857 | Fabrice Bellard | } |
381 | s->max_exponent[ch] = max_scale; |
||
382 | return 0; |
||
383 | } |
||
384 | |||
385 | 1890c2ac | Ian Braithwaite | |
386 | /**
|
||
387 | * Apply MDCT window and add into output.
|
||
388 | *
|
||
389 | * We ensure that when the windows overlap their squared sum
|
||
390 | * is always 1 (MDCT reconstruction rule).
|
||
391 | */
|
||
392 | static void wma_window(WMACodecContext *s, float *out) |
||
393 | { |
||
394 | float *in = s->output;
|
||
395 | int block_len, bsize, n;
|
||
396 | |||
397 | /* left part */
|
||
398 | if (s->block_len_bits <= s->prev_block_len_bits) {
|
||
399 | block_len = s->block_len; |
||
400 | bsize = s->frame_len_bits - s->block_len_bits; |
||
401 | |||
402 | 952e8721 | Måns Rullgård | s->dsp.vector_fmul_add(out, in, s->windows[bsize], |
403 | out, block_len); |
||
404 | 1890c2ac | Ian Braithwaite | |
405 | } else {
|
||
406 | block_len = 1 << s->prev_block_len_bits;
|
||
407 | n = (s->block_len - block_len) / 2;
|
||
408 | bsize = s->frame_len_bits - s->prev_block_len_bits; |
||
409 | |||
410 | 952e8721 | Måns Rullgård | s->dsp.vector_fmul_add(out+n, in+n, s->windows[bsize], |
411 | out+n, block_len); |
||
412 | 1890c2ac | Ian Braithwaite | |
413 | memcpy(out+n+block_len, in+n+block_len, n*sizeof(float)); |
||
414 | } |
||
415 | |||
416 | out += s->block_len; |
||
417 | in += s->block_len; |
||
418 | |||
419 | /* right part */
|
||
420 | if (s->block_len_bits <= s->next_block_len_bits) {
|
||
421 | block_len = s->block_len; |
||
422 | bsize = s->frame_len_bits - s->block_len_bits; |
||
423 | |||
424 | s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len); |
||
425 | |||
426 | } else {
|
||
427 | block_len = 1 << s->next_block_len_bits;
|
||
428 | n = (s->block_len - block_len) / 2;
|
||
429 | bsize = s->frame_len_bits - s->next_block_len_bits; |
||
430 | |||
431 | memcpy(out, in, n*sizeof(float)); |
||
432 | |||
433 | s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); |
||
434 | |||
435 | memset(out+n+block_len, 0, n*sizeof(float)); |
||
436 | } |
||
437 | } |
||
438 | |||
439 | |||
440 | 6836af52 | Michael Niedermayer | /**
|
441 | * @return 0 if OK. 1 if last block of frame. return -1 if
|
||
442 | * unrecorrable error.
|
||
443 | */
|
||
444 | 911b9faf | Michel Bardiaux | static int wma_decode_block(WMACodecContext *s) |
445 | bc8d1857 | Fabrice Bellard | { |
446 | c0e9b2e8 | Sascha Sommer | int n, v, a, ch, bsize;
|
447 | 5bd526d9 | Ian Braithwaite | int coef_nb_bits, total_gain;
|
448 | bc8d1857 | Fabrice Bellard | int nb_coefs[MAX_CHANNELS];
|
449 | float mdct_norm;
|
||
450 | |||
451 | aef3c69d | Alex Beregszaszi | #ifdef TRACE
|
452 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); |
453 | aef3c69d | Alex Beregszaszi | #endif
|
454 | bc8d1857 | Fabrice Bellard | |
455 | /* compute current block length */
|
||
456 | if (s->use_variable_block_len) {
|
||
457 | n = av_log2(s->nb_block_sizes - 1) + 1; |
||
458 | 115329f1 | Diego Biurrun | |
459 | bc8d1857 | Fabrice Bellard | if (s->reset_block_lengths) {
|
460 | s->reset_block_lengths = 0;
|
||
461 | v = get_bits(&s->gb, n); |
||
462 | 445a9dee | Michael Niedermayer | if (v >= s->nb_block_sizes){
|
463 | av_log(s->avctx, AV_LOG_ERROR, "prev_block_len_bits %d out of range\n", s->frame_len_bits - v);
|
||
464 | bc8d1857 | Fabrice Bellard | return -1; |
465 | 445a9dee | Michael Niedermayer | } |
466 | bc8d1857 | Fabrice Bellard | s->prev_block_len_bits = s->frame_len_bits - v; |
467 | v = get_bits(&s->gb, n); |
||
468 | 445a9dee | Michael Niedermayer | if (v >= s->nb_block_sizes){
|
469 | av_log(s->avctx, AV_LOG_ERROR, "block_len_bits %d out of range\n", s->frame_len_bits - v);
|
||
470 | bc8d1857 | Fabrice Bellard | return -1; |
471 | 445a9dee | Michael Niedermayer | } |
472 | bc8d1857 | Fabrice Bellard | s->block_len_bits = s->frame_len_bits - v; |
473 | } else {
|
||
474 | /* update block lengths */
|
||
475 | s->prev_block_len_bits = s->block_len_bits; |
||
476 | s->block_len_bits = s->next_block_len_bits; |
||
477 | } |
||
478 | v = get_bits(&s->gb, n); |
||
479 | 445a9dee | Michael Niedermayer | if (v >= s->nb_block_sizes){
|
480 | av_log(s->avctx, AV_LOG_ERROR, "next_block_len_bits %d out of range\n", s->frame_len_bits - v);
|
||
481 | bc8d1857 | Fabrice Bellard | return -1; |
482 | 445a9dee | Michael Niedermayer | } |
483 | bc8d1857 | Fabrice Bellard | s->next_block_len_bits = s->frame_len_bits - v; |
484 | } else {
|
||
485 | /* fixed block len */
|
||
486 | s->next_block_len_bits = s->frame_len_bits; |
||
487 | s->prev_block_len_bits = s->frame_len_bits; |
||
488 | s->block_len_bits = s->frame_len_bits; |
||
489 | } |
||
490 | |||
491 | /* now check if the block length is coherent with the frame length */
|
||
492 | s->block_len = 1 << s->block_len_bits;
|
||
493 | 445a9dee | Michael Niedermayer | if ((s->block_pos + s->block_len) > s->frame_len){
|
494 | av_log(s->avctx, AV_LOG_ERROR, "frame_len overflow\n");
|
||
495 | bc8d1857 | Fabrice Bellard | return -1; |
496 | 445a9dee | Michael Niedermayer | } |
497 | bc8d1857 | Fabrice Bellard | |
498 | if (s->nb_channels == 2) { |
||
499 | 5fc32c27 | Alex Beregszaszi | s->ms_stereo = get_bits1(&s->gb); |
500 | bc8d1857 | Fabrice Bellard | } |
501 | v = 0;
|
||
502 | for(ch = 0; ch < s->nb_channels; ch++) { |
||
503 | 5fc32c27 | Alex Beregszaszi | a = get_bits1(&s->gb); |
504 | bc8d1857 | Fabrice Bellard | s->channel_coded[ch] = a; |
505 | v |= a; |
||
506 | } |
||
507 | 7ee18c17 | Michael Niedermayer | |
508 | bsize = s->frame_len_bits - s->block_len_bits; |
||
509 | |||
510 | bc8d1857 | Fabrice Bellard | /* if no channel coded, no need to go further */
|
511 | /* XXX: fix potential framing problems */
|
||
512 | if (!v)
|
||
513 | goto next;
|
||
514 | |||
515 | /* read total gain and extract corresponding number of bits for
|
||
516 | coef escape coding */
|
||
517 | total_gain = 1;
|
||
518 | for(;;) {
|
||
519 | a = get_bits(&s->gb, 7);
|
||
520 | total_gain += a; |
||
521 | if (a != 127) |
||
522 | break;
|
||
523 | } |
||
524 | 115329f1 | Diego Biurrun | |
525 | 59686073 | Michael Niedermayer | coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); |
526 | bc8d1857 | Fabrice Bellard | |
527 | /* compute number of coefficients */
|
||
528 | n = s->coefs_end[bsize] - s->coefs_start; |
||
529 | for(ch = 0; ch < s->nb_channels; ch++) |
||
530 | nb_coefs[ch] = n; |
||
531 | |||
532 | /* complex coding */
|
||
533 | if (s->use_noise_coding) {
|
||
534 | |||
535 | for(ch = 0; ch < s->nb_channels; ch++) { |
||
536 | if (s->channel_coded[ch]) {
|
||
537 | int i, n, a;
|
||
538 | n = s->exponent_high_sizes[bsize]; |
||
539 | for(i=0;i<n;i++) { |
||
540 | 5fc32c27 | Alex Beregszaszi | a = get_bits1(&s->gb); |
541 | bc8d1857 | Fabrice Bellard | s->high_band_coded[ch][i] = a; |
542 | /* if noise coding, the coefficients are not transmitted */
|
||
543 | if (a)
|
||
544 | nb_coefs[ch] -= s->exponent_high_bands[bsize][i]; |
||
545 | } |
||
546 | } |
||
547 | } |
||
548 | for(ch = 0; ch < s->nb_channels; ch++) { |
||
549 | if (s->channel_coded[ch]) {
|
||
550 | int i, n, val, code;
|
||
551 | |||
552 | n = s->exponent_high_sizes[bsize]; |
||
553 | val = (int)0x80000000; |
||
554 | for(i=0;i<n;i++) { |
||
555 | if (s->high_band_coded[ch][i]) {
|
||
556 | if (val == (int)0x80000000) { |
||
557 | val = get_bits(&s->gb, 7) - 19; |
||
558 | } else {
|
||
559 | 63a5b0b1 | Jindřich Makovička | code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); |
560 | 445a9dee | Michael Niedermayer | if (code < 0){ |
561 | av_log(s->avctx, AV_LOG_ERROR, "hgain vlc invalid\n");
|
||
562 | bc8d1857 | Fabrice Bellard | return -1; |
563 | 445a9dee | Michael Niedermayer | } |
564 | bc8d1857 | Fabrice Bellard | val += code - 18;
|
565 | } |
||
566 | s->high_band_values[ch][i] = val; |
||
567 | } |
||
568 | } |
||
569 | } |
||
570 | } |
||
571 | } |
||
572 | 115329f1 | Diego Biurrun | |
573 | 5bd526d9 | Ian Braithwaite | /* exponents can be reused in short blocks. */
|
574 | if ((s->block_len_bits == s->frame_len_bits) ||
|
||
575 | 5fc32c27 | Alex Beregszaszi | get_bits1(&s->gb)) { |
576 | bc8d1857 | Fabrice Bellard | for(ch = 0; ch < s->nb_channels; ch++) { |
577 | if (s->channel_coded[ch]) {
|
||
578 | if (s->use_exp_vlc) {
|
||
579 | if (decode_exp_vlc(s, ch) < 0) |
||
580 | return -1; |
||
581 | } else {
|
||
582 | decode_exp_lsp(s, ch); |
||
583 | } |
||
584 | 5bd526d9 | Ian Braithwaite | s->exponents_bsize[ch] = bsize; |
585 | bc8d1857 | Fabrice Bellard | } |
586 | } |
||
587 | } |
||
588 | |||
589 | /* parse spectral coefficients : just RLE encoding */
|
||
590 | for(ch = 0; ch < s->nb_channels; ch++) { |
||
591 | if (s->channel_coded[ch]) {
|
||
592 | c0e9b2e8 | Sascha Sommer | int tindex;
|
593 | 9970c61b | Sascha Sommer | WMACoef* ptr = &s->coefs1[ch][0];
|
594 | bc8d1857 | Fabrice Bellard | |
595 | /* special VLC tables are used for ms stereo because
|
||
596 | there is potentially less energy there */
|
||
597 | tindex = (ch == 1 && s->ms_stereo);
|
||
598 | 9970c61b | Sascha Sommer | memset(ptr, 0, s->block_len * sizeof(WMACoef)); |
599 | c0e9b2e8 | Sascha Sommer | ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], |
600 | s->level_table[tindex], s->run_table[tindex], |
||
601 | 0, ptr, 0, nb_coefs[ch], |
||
602 | s->block_len, s->frame_len_bits, coef_nb_bits); |
||
603 | bc8d1857 | Fabrice Bellard | } |
604 | if (s->version == 1 && s->nb_channels >= 2) { |
||
605 | align_get_bits(&s->gb); |
||
606 | } |
||
607 | } |
||
608 | 115329f1 | Diego Biurrun | |
609 | bc8d1857 | Fabrice Bellard | /* normalize */
|
610 | { |
||
611 | int n4 = s->block_len / 2; |
||
612 | mdct_norm = 1.0 / (float)n4; |
||
613 | if (s->version == 1) { |
||
614 | mdct_norm *= sqrt(n4); |
||
615 | } |
||
616 | } |
||
617 | |||
618 | /* finally compute the MDCT coefficients */
|
||
619 | for(ch = 0; ch < s->nb_channels; ch++) { |
||
620 | if (s->channel_coded[ch]) {
|
||
621 | 9970c61b | Sascha Sommer | WMACoef *coefs1; |
622 | 5bd526d9 | Ian Braithwaite | float *coefs, *exponents, mult, mult1, noise;
|
623 | int i, j, n, n1, last_high_band, esize;
|
||
624 | bc8d1857 | Fabrice Bellard | float exp_power[HIGH_BAND_MAX_SIZE];
|
625 | |||
626 | coefs1 = s->coefs1[ch]; |
||
627 | exponents = s->exponents[ch]; |
||
628 | 5bd526d9 | Ian Braithwaite | esize = s->exponents_bsize[ch]; |
629 | d30ba3bb | Michael Niedermayer | mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; |
630 | bc8d1857 | Fabrice Bellard | mult *= mdct_norm; |
631 | coefs = s->coefs[ch]; |
||
632 | if (s->use_noise_coding) {
|
||
633 | mult1 = mult; |
||
634 | /* very low freqs : noise */
|
||
635 | for(i = 0;i < s->coefs_start; i++) { |
||
636 | 5bd526d9 | Ian Braithwaite | *coefs++ = s->noise_table[s->noise_index] * |
637 | exponents[i<<bsize>>esize] * mult1; |
||
638 | bc8d1857 | Fabrice Bellard | s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); |
639 | } |
||
640 | 115329f1 | Diego Biurrun | |
641 | bc8d1857 | Fabrice Bellard | n1 = s->exponent_high_sizes[bsize]; |
642 | |||
643 | /* compute power of high bands */
|
||
644 | 5bd526d9 | Ian Braithwaite | exponents = s->exponents[ch] + |
645 | f78501b2 | Michael Niedermayer | (s->high_band_start[bsize]<<bsize>>esize); |
646 | bc8d1857 | Fabrice Bellard | last_high_band = 0; /* avoid warning */ |
647 | for(j=0;j<n1;j++) { |
||
648 | 115329f1 | Diego Biurrun | n = s->exponent_high_bands[s->frame_len_bits - |
649 | bc8d1857 | Fabrice Bellard | s->block_len_bits][j]; |
650 | if (s->high_band_coded[ch][j]) {
|
||
651 | float e2, v;
|
||
652 | e2 = 0;
|
||
653 | for(i = 0;i < n; i++) { |
||
654 | 5bd526d9 | Ian Braithwaite | v = exponents[i<<bsize>>esize]; |
655 | bc8d1857 | Fabrice Bellard | e2 += v * v; |
656 | } |
||
657 | exp_power[j] = e2 / n; |
||
658 | last_high_band = j; |
||
659 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n);
|
660 | bc8d1857 | Fabrice Bellard | } |
661 | f78501b2 | Michael Niedermayer | exponents += n<<bsize>>esize; |
662 | bc8d1857 | Fabrice Bellard | } |
663 | |||
664 | /* main freqs and high freqs */
|
||
665 | f78501b2 | Michael Niedermayer | exponents = s->exponents[ch] + (s->coefs_start<<bsize>>esize); |
666 | bc8d1857 | Fabrice Bellard | for(j=-1;j<n1;j++) { |
667 | if (j < 0) { |
||
668 | 115329f1 | Diego Biurrun | n = s->high_band_start[bsize] - |
669 | bc8d1857 | Fabrice Bellard | s->coefs_start; |
670 | } else {
|
||
671 | 115329f1 | Diego Biurrun | n = s->exponent_high_bands[s->frame_len_bits - |
672 | bc8d1857 | Fabrice Bellard | s->block_len_bits][j]; |
673 | } |
||
674 | if (j >= 0 && s->high_band_coded[ch][j]) { |
||
675 | /* use noise with specified power */
|
||
676 | mult1 = sqrt(exp_power[j] / exp_power[last_high_band]); |
||
677 | d30ba3bb | Michael Niedermayer | /* XXX: use a table */
|
678 | mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05); |
||
679 | bc8d1857 | Fabrice Bellard | mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult); |
680 | mult1 *= mdct_norm; |
||
681 | for(i = 0;i < n; i++) { |
||
682 | noise = s->noise_table[s->noise_index]; |
||
683 | s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); |
||
684 | 5bd526d9 | Ian Braithwaite | *coefs++ = noise * |
685 | exponents[i<<bsize>>esize] * mult1; |
||
686 | bc8d1857 | Fabrice Bellard | } |
687 | f78501b2 | Michael Niedermayer | exponents += n<<bsize>>esize; |
688 | bc8d1857 | Fabrice Bellard | } else {
|
689 | /* coded values + small noise */
|
||
690 | for(i = 0;i < n; i++) { |
||
691 | noise = s->noise_table[s->noise_index]; |
||
692 | s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); |
||
693 | 5bd526d9 | Ian Braithwaite | *coefs++ = ((*coefs1++) + noise) * |
694 | exponents[i<<bsize>>esize] * mult; |
||
695 | bc8d1857 | Fabrice Bellard | } |
696 | f78501b2 | Michael Niedermayer | exponents += n<<bsize>>esize; |
697 | bc8d1857 | Fabrice Bellard | } |
698 | } |
||
699 | |||
700 | /* very high freqs : noise */
|
||
701 | n = s->block_len - s->coefs_end[bsize]; |
||
702 | 5bd526d9 | Ian Braithwaite | mult1 = mult * exponents[((-1<<bsize))>>esize];
|
703 | bc8d1857 | Fabrice Bellard | for(i = 0; i < n; i++) { |
704 | *coefs++ = s->noise_table[s->noise_index] * mult1; |
||
705 | s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); |
||
706 | } |
||
707 | } else {
|
||
708 | /* XXX: optimize more */
|
||
709 | for(i = 0;i < s->coefs_start; i++) |
||
710 | *coefs++ = 0.0; |
||
711 | n = nb_coefs[ch]; |
||
712 | for(i = 0;i < n; i++) { |
||
713 | 5bd526d9 | Ian Braithwaite | *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult; |
714 | bc8d1857 | Fabrice Bellard | } |
715 | n = s->block_len - s->coefs_end[bsize]; |
||
716 | for(i = 0;i < n; i++) |
||
717 | *coefs++ = 0.0; |
||
718 | } |
||
719 | } |
||
720 | } |
||
721 | |||
722 | f2899fb1 | Alex Beregszaszi | #ifdef TRACE
|
723 | bc8d1857 | Fabrice Bellard | for(ch = 0; ch < s->nb_channels; ch++) { |
724 | if (s->channel_coded[ch]) {
|
||
725 | a9c9a240 | Michel Bardiaux | dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len); |
726 | dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len); |
||
727 | bc8d1857 | Fabrice Bellard | } |
728 | } |
||
729 | #endif
|
||
730 | 115329f1 | Diego Biurrun | |
731 | bc8d1857 | Fabrice Bellard | if (s->ms_stereo && s->channel_coded[1]) { |
732 | /* nominal case for ms stereo: we do it before mdct */
|
||
733 | /* no need to optimize this case because it should almost
|
||
734 | never happen */
|
||
735 | if (!s->channel_coded[0]) { |
||
736 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "rare ms-stereo case happened\n");
|
737 | bc8d1857 | Fabrice Bellard | memset(s->coefs[0], 0, sizeof(float) * s->block_len); |
738 | s->channel_coded[0] = 1; |
||
739 | } |
||
740 | 115329f1 | Diego Biurrun | |
741 | 6044538b | Måns Rullgård | s->dsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len); |
742 | bc8d1857 | Fabrice Bellard | } |
743 | |||
744 | 7ee18c17 | Michael Niedermayer | next:
|
745 | bc8d1857 | Fabrice Bellard | for(ch = 0; ch < s->nb_channels; ch++) { |
746 | 110baa2e | Michael Niedermayer | int n4, index;
|
747 | bc8d1857 | Fabrice Bellard | |
748 | 4972a246 | Michael Niedermayer | n4 = s->block_len / 2;
|
749 | if(s->channel_coded[ch]){
|
||
750 | d46ac5bf | Loren Merritt | ff_imdct_calc(&s->mdct_ctx[bsize], s->output, s->coefs[ch]); |
751 | 29ca668f | Michael Niedermayer | }else if(!(s->ms_stereo && ch==1)) |
752 | 4972a246 | Michael Niedermayer | memset(s->output, 0, sizeof(s->output)); |
753 | |||
754 | /* multiply by the window and add in the frame */
|
||
755 | index = (s->frame_len / 2) + s->block_pos - n4;
|
||
756 | wma_window(s, &s->frame_out[ch][index]); |
||
757 | bc8d1857 | Fabrice Bellard | } |
758 | 7ee18c17 | Michael Niedermayer | |
759 | bc8d1857 | Fabrice Bellard | /* update block number */
|
760 | s->block_num++; |
||
761 | s->block_pos += s->block_len; |
||
762 | if (s->block_pos >= s->frame_len)
|
||
763 | return 1; |
||
764 | else
|
||
765 | return 0; |
||
766 | } |
||
767 | |||
768 | /* decode a frame of frame_len samples */
|
||
769 | 911b9faf | Michel Bardiaux | static int wma_decode_frame(WMACodecContext *s, int16_t *samples) |
770 | bc8d1857 | Fabrice Bellard | { |
771 | 9d06d7bc | Justin Ruggles | int ret, n, ch, incr;
|
772 | const float *output[MAX_CHANNELS]; |
||
773 | bc8d1857 | Fabrice Bellard | |
774 | aef3c69d | Alex Beregszaszi | #ifdef TRACE
|
775 | a9c9a240 | Michel Bardiaux | tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len);
|
776 | aef3c69d | Alex Beregszaszi | #endif
|
777 | bc8d1857 | Fabrice Bellard | |
778 | /* read each block */
|
||
779 | s->block_num = 0;
|
||
780 | s->block_pos = 0;
|
||
781 | for(;;) {
|
||
782 | ret = wma_decode_block(s); |
||
783 | 115329f1 | Diego Biurrun | if (ret < 0) |
784 | bc8d1857 | Fabrice Bellard | return -1; |
785 | if (ret)
|
||
786 | break;
|
||
787 | } |
||
788 | |||
789 | /* convert frame to integer */
|
||
790 | n = s->frame_len; |
||
791 | incr = s->nb_channels; |
||
792 | b5ec6383 | Justin Ruggles | for (ch = 0; ch < MAX_CHANNELS; ch++) |
793 | output[ch] = s->frame_out[ch]; |
||
794 | s->dsp.float_to_int16_interleave(samples, output, n, incr); |
||
795 | for (ch = 0; ch < incr; ch++) { |
||
796 | /* prepare for next block */
|
||
797 | memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float)); |
||
798 | } |
||
799 | bc8d1857 | Fabrice Bellard | |
800 | f2899fb1 | Alex Beregszaszi | #ifdef TRACE
|
801 | a9c9a240 | Michel Bardiaux | dump_shorts(s, "samples", samples, n * s->nb_channels);
|
802 | bc8d1857 | Fabrice Bellard | #endif
|
803 | return 0; |
||
804 | } |
||
805 | |||
806 | 115329f1 | Diego Biurrun | static int wma_decode_superframe(AVCodecContext *avctx, |
807 | bc8d1857 | Fabrice Bellard | void *data, int *data_size, |
808 | 7a00bbad | Thilo Borgmann | AVPacket *avpkt) |
809 | bc8d1857 | Fabrice Bellard | { |
810 | 7a00bbad | Thilo Borgmann | const uint8_t *buf = avpkt->data;
|
811 | int buf_size = avpkt->size;
|
||
812 | 911b9faf | Michel Bardiaux | WMACodecContext *s = avctx->priv_data; |
813 | bc8d1857 | Fabrice Bellard | int nb_frames, bit_offset, i, pos, len;
|
814 | uint8_t *q; |
||
815 | int16_t *samples; |
||
816 | 115329f1 | Diego Biurrun | |
817 | a9c9a240 | Michel Bardiaux | tprintf(avctx, "***decode_superframe:\n");
|
818 | bc8d1857 | Fabrice Bellard | |
819 | 40a3105d | Michael Niedermayer | if(buf_size==0){ |
820 | s->last_superframe_len = 0;
|
||
821 | return 0; |
||
822 | } |
||
823 | 4c1e509c | Reimar Döffinger | if (buf_size < s->block_align)
|
824 | return 0; |
||
825 | buf_size = s->block_align; |
||
826 | 115329f1 | Diego Biurrun | |
827 | bc8d1857 | Fabrice Bellard | samples = data; |
828 | |||
829 | 68f593b4 | Michael Niedermayer | init_get_bits(&s->gb, buf, buf_size*8);
|
830 | 115329f1 | Diego Biurrun | |
831 | bc8d1857 | Fabrice Bellard | if (s->use_bit_reservoir) {
|
832 | /* read super frame header */
|
||
833 | 7ae7300e | Alex Beregszaszi | skip_bits(&s->gb, 4); /* super frame index */ |
834 | bc8d1857 | Fabrice Bellard | nb_frames = get_bits(&s->gb, 4) - 1; |
835 | |||
836 | 362aba4b | Michael Niedermayer | if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ |
837 | av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n");
|
||
838 | goto fail;
|
||
839 | } |
||
840 | |||
841 | bc8d1857 | Fabrice Bellard | bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
|
842 | |||
843 | if (s->last_superframe_len > 0) { |
||
844 | // printf("skip=%d\n", s->last_bitoffset);
|
||
845 | /* add bit_offset bits to last frame */
|
||
846 | 115329f1 | Diego Biurrun | if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > |
847 | bc8d1857 | Fabrice Bellard | MAX_CODED_SUPERFRAME_SIZE) |
848 | 2f62e147 | Fabrice Bellard | goto fail;
|
849 | bc8d1857 | Fabrice Bellard | q = s->last_superframe + s->last_superframe_len; |
850 | len = bit_offset; |
||
851 | 0b52626e | Reimar Döffinger | while (len > 7) { |
852 | bc8d1857 | Fabrice Bellard | *q++ = (get_bits)(&s->gb, 8);
|
853 | len -= 8;
|
||
854 | } |
||
855 | if (len > 0) { |
||
856 | *q++ = (get_bits)(&s->gb, len) << (8 - len);
|
||
857 | } |
||
858 | 115329f1 | Diego Biurrun | |
859 | bc8d1857 | Fabrice Bellard | /* XXX: bit_offset bits into last frame */
|
860 | 68f593b4 | Michael Niedermayer | init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8);
|
861 | bc8d1857 | Fabrice Bellard | /* skip unused bits */
|
862 | if (s->last_bitoffset > 0) |
||
863 | skip_bits(&s->gb, s->last_bitoffset); |
||
864 | /* this frame is stored in the last superframe and in the
|
||
865 | current one */
|
||
866 | if (wma_decode_frame(s, samples) < 0) |
||
867 | 2f62e147 | Fabrice Bellard | goto fail;
|
868 | bc8d1857 | Fabrice Bellard | samples += s->nb_channels * s->frame_len; |
869 | } |
||
870 | |||
871 | /* read each frame starting from bit_offset */
|
||
872 | pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; |
||
873 | 68f593b4 | Michael Niedermayer | init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); |
874 | bc8d1857 | Fabrice Bellard | len = pos & 7;
|
875 | if (len > 0) |
||
876 | skip_bits(&s->gb, len); |
||
877 | 115329f1 | Diego Biurrun | |
878 | bc8d1857 | Fabrice Bellard | s->reset_block_lengths = 1;
|
879 | for(i=0;i<nb_frames;i++) { |
||
880 | if (wma_decode_frame(s, samples) < 0) |
||
881 | 2f62e147 | Fabrice Bellard | goto fail;
|
882 | bc8d1857 | Fabrice Bellard | samples += s->nb_channels * s->frame_len; |
883 | } |
||
884 | |||
885 | /* we copy the end of the frame in the last frame buffer */
|
||
886 | pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); |
||
887 | s->last_bitoffset = pos & 7;
|
||
888 | pos >>= 3;
|
||
889 | len = buf_size - pos; |
||
890 | f408fc67 | Zdenek Kabelac | if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) { |
891 | 445a9dee | Michael Niedermayer | av_log(s->avctx, AV_LOG_ERROR, "len %d invalid\n", len);
|
892 | 2f62e147 | Fabrice Bellard | goto fail;
|
893 | bc8d1857 | Fabrice Bellard | } |
894 | s->last_superframe_len = len; |
||
895 | memcpy(s->last_superframe, buf + pos, len); |
||
896 | } else {
|
||
897 | 362aba4b | Michael Niedermayer | if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ |
898 | av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n");
|
||
899 | goto fail;
|
||
900 | } |
||
901 | bc8d1857 | Fabrice Bellard | /* single frame decode */
|
902 | if (wma_decode_frame(s, samples) < 0) |
||
903 | 2f62e147 | Fabrice Bellard | goto fail;
|
904 | bc8d1857 | Fabrice Bellard | samples += s->nb_channels * s->frame_len; |
905 | } |
||
906 | 59686073 | Michael Niedermayer | |
907 | //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, s->block_align);
|
||
908 | |||
909 | bc8d1857 | Fabrice Bellard | *data_size = (int8_t *)samples - (int8_t *)data; |
910 | return s->block_align;
|
||
911 | 2f62e147 | Fabrice Bellard | fail:
|
912 | /* when error, we reset the bit reservoir */
|
||
913 | s->last_superframe_len = 0;
|
||
914 | return -1; |
||
915 | bc8d1857 | Fabrice Bellard | } |
916 | |||
917 | f28f1464 | Michael Niedermayer | static av_cold void flush(AVCodecContext *avctx) |
918 | { |
||
919 | WMACodecContext *s = avctx->priv_data; |
||
920 | |||
921 | s->last_bitoffset= |
||
922 | s->last_superframe_len= 0;
|
||
923 | } |
||
924 | |||
925 | d36beb3f | Diego Elio Pettenò | AVCodec ff_wmav1_decoder = |
926 | bc8d1857 | Fabrice Bellard | { |
927 | "wmav1",
|
||
928 | 72415b2a | Stefano Sabatini | AVMEDIA_TYPE_AUDIO, |
929 | bc8d1857 | Fabrice Bellard | CODEC_ID_WMAV1, |
930 | 911b9faf | Michel Bardiaux | sizeof(WMACodecContext),
|
931 | bc8d1857 | Fabrice Bellard | wma_decode_init, |
932 | NULL,
|
||
933 | 59686073 | Michael Niedermayer | ff_wma_end, |
934 | bc8d1857 | Fabrice Bellard | wma_decode_superframe, |
935 | f28f1464 | Michael Niedermayer | .flush=flush, |
936 | fe4bf374 | Stefano Sabatini | .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"),
|
937 | bc8d1857 | Fabrice Bellard | }; |
938 | |||
939 | d36beb3f | Diego Elio Pettenò | AVCodec ff_wmav2_decoder = |
940 | bc8d1857 | Fabrice Bellard | { |
941 | "wmav2",
|
||
942 | 72415b2a | Stefano Sabatini | AVMEDIA_TYPE_AUDIO, |
943 | bc8d1857 | Fabrice Bellard | CODEC_ID_WMAV2, |
944 | 911b9faf | Michel Bardiaux | sizeof(WMACodecContext),
|
945 | bc8d1857 | Fabrice Bellard | wma_decode_init, |
946 | NULL,
|
||
947 | 59686073 | Michael Niedermayer | ff_wma_end, |
948 | bc8d1857 | Fabrice Bellard | wma_decode_superframe, |
949 | f28f1464 | Michael Niedermayer | .flush=flush, |
950 | fe4bf374 | Stefano Sabatini | .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"),
|
951 | bc8d1857 | Fabrice Bellard | }; |