Mercurial > libavcodec.hg
annotate wmadec.c @ 11557:53822d92c3f7 libavcodec
Make sure the EC code does not attempt to use inter based concealment if there
is no reference frame available. (this can happen because the EC code will attempt
to use reference frames even for I/IDR frames)
author | michael |
---|---|
date | Tue, 30 Mar 2010 20:46:46 +0000 |
parents | d5673aafc6bf |
children | 8a4984c5cacc |
rev | line source |
---|---|
783 | 1 /* |
2 * WMA compatible decoder | |
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
7712
diff
changeset
|
3 * Copyright (c) 2002 The FFmpeg Project |
783 | 4 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
783 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
783 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
783 | 13 * 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 | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3776
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
3022
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
783 | 20 */ |
1106 | 21 |
22 /** | |
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8629
diff
changeset
|
23 * @file libavcodec/wmadec.c |
1106 | 24 * WMA compatible decoder. |
1967
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
25 * This decoder handles Microsoft Windows Media Audio data, versions 1 & 2. |
2967 | 26 * WMA v1 is identified by audio format 0x160 in Microsoft media files |
1967
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
27 * (ASF/AVI/WAV). WMA v2 is identified by audio format 0x161. |
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
28 * |
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
29 * To use this decoder, a calling application must supply the extra data |
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
30 * bytes provided with the WMA data. These are the extra, codec-specific |
2967 | 31 * bytes at the end of a WAVEFORMATEX data structure. Transmit these bytes |
32 * to the decoder using the extradata[_size] fields in AVCodecContext. There | |
1967
2b0fc6b25ab8
add the minimal documentation to make this decoder useful
melanson
parents:
1750
diff
changeset
|
33 * should be 4 extra bytes for v1 data and 6 extra bytes for v2 data. |
1106 | 34 */ |
35 | |
783 | 36 #include "avcodec.h" |
4490 | 37 #include "wma.h" |
783 | 38 |
4490 | 39 #undef NDEBUG |
40 #include <assert.h> | |
3113 | 41 |
42 #define EXPVLCBITS 8 | |
43 #define EXPMAX ((19+EXPVLCBITS-1)/EXPVLCBITS) | |
44 | |
45 #define HGAINVLCBITS 9 | |
46 #define HGAINMAX ((13+HGAINVLCBITS-1)/HGAINVLCBITS) | |
3022 | 47 |
4601 | 48 static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len); |
783 | 49 |
1342
f574934c4219
uniformization (now it uses the same trace functions as h264, defined in common.h)
al3x
parents:
1303
diff
changeset
|
50 #ifdef TRACE |
5517 | 51 static void dump_shorts(WMACodecContext *s, const char *name, const short *tab, int n) |
783 | 52 { |
53 int i; | |
54 | |
4600 | 55 tprintf(s->avctx, "%s[%d]:\n", name, n); |
783 | 56 for(i=0;i<n;i++) { |
57 if ((i & 7) == 0) | |
4600 | 58 tprintf(s->avctx, "%4d: ", i); |
59 tprintf(s->avctx, " %5d.0", tab[i]); | |
783 | 60 if ((i & 7) == 7) |
4600 | 61 tprintf(s->avctx, "\n"); |
783 | 62 } |
63 } | |
64 | |
5517 | 65 static void dump_floats(WMACodecContext *s, const char *name, int prec, const float *tab, int n) |
783 | 66 { |
67 int i; | |
68 | |
4600 | 69 tprintf(s->avctx, "%s[%d]:\n", name, n); |
783 | 70 for(i=0;i<n;i++) { |
71 if ((i & 7) == 0) | |
4600 | 72 tprintf(s->avctx, "%4d: ", i); |
73 tprintf(s->avctx, " %8.*f", prec, tab[i]); | |
783 | 74 if ((i & 7) == 7) |
4600 | 75 tprintf(s->avctx, "\n"); |
783 | 76 } |
77 if ((i & 7) != 0) | |
4600 | 78 tprintf(s->avctx, "\n"); |
783 | 79 } |
80 #endif | |
81 | |
82 static int wma_decode_init(AVCodecContext * avctx) | |
83 { | |
4601 | 84 WMACodecContext *s = avctx->priv_data; |
10275 | 85 int i, flags2; |
783 | 86 uint8_t *extradata; |
2967 | 87 |
4600 | 88 s->avctx = avctx; |
89 | |
783 | 90 /* extract flag infos */ |
91 flags2 = 0; | |
92 extradata = avctx->extradata; | |
4490 | 93 if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { |
5089 | 94 flags2 = AV_RL16(extradata+2); |
4490 | 95 } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { |
5089 | 96 flags2 = AV_RL16(extradata+4); |
783 | 97 } |
4491 | 98 // for(i=0; i<avctx->extradata_size; i++) |
99 // av_log(NULL, AV_LOG_ERROR, "%02X ", extradata[i]); | |
4490 | 100 |
783 | 101 s->use_exp_vlc = flags2 & 0x0001; |
102 s->use_bit_reservoir = flags2 & 0x0002; | |
103 s->use_variable_block_len = flags2 & 0x0004; | |
104 | |
5086
a10ebd496bd9
sanity checks (should prevent hypothetical div by zero issue)
michael
parents:
4785
diff
changeset
|
105 if(ff_wma_init(avctx, flags2)<0) |
a10ebd496bd9
sanity checks (should prevent hypothetical div by zero issue)
michael
parents:
4785
diff
changeset
|
106 return -1; |
783 | 107 |
108 /* init MDCT */ | |
109 for(i = 0; i < s->nb_block_sizes; i++) | |
9658
67a20f0eb42c
Support for getting (i)MDCT output multiplied by a constant scaling factor.
serge
parents:
9472
diff
changeset
|
110 ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 1, 1.0); |
2967 | 111 |
783 | 112 if (s->use_noise_coding) { |
4490 | 113 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); | |
783 | 116 } |
117 | |
118 if (s->use_exp_vlc) { | |
11215
964d01b50f17
remove a Huffman table from WMA which also exists in AAC
stefang
parents:
11062
diff
changeset
|
119 init_vlc(&s->exp_vlc, EXPVLCBITS, sizeof(ff_aac_scalefactor_bits), //FIXME move out of context |
964d01b50f17
remove a Huffman table from WMA which also exists in AAC
stefang
parents:
11062
diff
changeset
|
120 ff_aac_scalefactor_bits, 1, 1, |
964d01b50f17
remove a Huffman table from WMA which also exists in AAC
stefang
parents:
11062
diff
changeset
|
121 ff_aac_scalefactor_code, 4, 4, 0); |
783 | 122 } else { |
123 wma_lsp_to_curve_init(s, s->frame_len); | |
124 } | |
125 | |
7451
85ab7655ad4d
Modify all codecs to report their supported input and output sample format(s).
pross
parents:
7244
diff
changeset
|
126 avctx->sample_fmt = SAMPLE_FMT_S16; |
783 | 127 return 0; |
128 } | |
129 | |
4497 | 130 /** |
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 */ | |
4601 | 136 static inline float pow_m1_4(WMACodecContext *s, float x) |
783 | 137 { |
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 | |
4601 | 155 static void wma_lsp_to_curve_init(WMACodecContext *s, int frame_len) |
2967 | 156 { |
783 | 157 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 | |
4497 | 192 /** |
193 * NOTE: We use the same code as Vorbis here | |
194 * @todo optimize it further with SSE/3Dnow | |
195 */ | |
4601 | 196 static void wma_lsp_to_curve(WMACodecContext *s, |
2967 | 197 float *out, float *val_max_ptr, |
783 | 198 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 | |
4497 | 223 /** |
224 * decode exponents coded with LSP coefficients (same idea as Vorbis) | |
225 */ | |
4601 | 226 static void decode_exp_lsp(WMACodecContext *s, int ch) |
783 | 227 { |
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); | |
4490 | 236 lsp_coefs[i] = ff_wma_lsp_codebook[i][val]; |
783 | 237 } |
238 | |
239 wma_lsp_to_curve(s, s->exponents[ch], &s->max_exponent[ch], | |
240 s->block_len, lsp_coefs); | |
241 } | |
242 | |
10564 | 243 /** pow(10, i / 16.0) for i in -60..95 */ |
10561 | 244 static const float pow_tab[] = { |
10312 | 245 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, | |
10561 | 309 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, | |
10564 | 313 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, | |
10312 | 323 }; |
324 | |
4497 | 325 /** |
326 * decode exponents coded with VLC codes | |
327 */ | |
4601 | 328 static int decode_exp_vlc(WMACodecContext *s, int ch) |
783 | 329 { |
330 int last_exp, n, code; | |
10275 | 331 const uint16_t *ptr; |
10313
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
332 float v, max_scale; |
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
333 uint32_t *q, *q_end, iv; |
10312 | 334 const float *ptab = pow_tab + 60; |
10313
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
335 const uint32_t *iptab = (const uint32_t*)ptab; |
2967 | 336 |
10275 | 337 ptr = s->exponent_bands[s->frame_len_bits - s->block_len_bits]; |
10313
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
338 q = (uint32_t *)s->exponents[ch]; |
783 | 339 q_end = q + s->block_len; |
340 max_scale = 0; | |
341 if (s->version == 1) { | |
342 last_exp = get_bits(&s->gb, 5) + 10; | |
10312 | 343 v = ptab[last_exp]; |
10313
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
344 iv = iptab[last_exp]; |
783 | 345 max_scale = v; |
346 n = *ptr++; | |
10317 | 347 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); | |
4490 | 353 }else |
354 last_exp = 36; | |
355 | |
783 | 356 while (q < q_end) { |
3113 | 357 code = get_vlc2(&s->gb, s->exp_vlc.table, EXPVLCBITS, EXPMAX); |
10654 | 358 if (code < 0){ |
359 av_log(s->avctx, AV_LOG_ERROR, "Exponent vlc invalid\n"); | |
783 | 360 return -1; |
10654 | 361 } |
783 | 362 /* NOTE: this offset is the same as MPEG4 AAC ! */ |
363 last_exp += code - 60; | |
10561 | 364 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); | |
10312 | 367 return -1; |
10561 | 368 } |
10312 | 369 v = ptab[last_exp]; |
10313
f7376a522a7e
WMA: use type punning and unroll loops in decode_exp_vlc()
mru
parents:
10312
diff
changeset
|
370 iv = iptab[last_exp]; |
783 | 371 if (v > max_scale) |
372 max_scale = v; | |
373 n = *ptr++; | |
10317 | 374 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); | |
783 | 380 } |
381 s->max_exponent[ch] = max_scale; | |
382 return 0; | |
383 } | |
384 | |
4737
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
385 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
386 /** |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
387 * Apply MDCT window and add into output. |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
388 * |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
389 * We ensure that when the windows overlap their squared sum |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
390 * is always 1 (MDCT reconstruction rule). |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
391 */ |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
392 static void wma_window(WMACodecContext *s, float *out) |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
393 { |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
394 float *in = s->output; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
395 int block_len, bsize, n; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
396 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
397 /* left part */ |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
398 if (s->block_len_bits <= s->prev_block_len_bits) { |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
399 block_len = s->block_len; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
400 bsize = s->frame_len_bits - s->block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
401 |
10300
4d1b9ca628fc
Drop unused args from vector_fmul_add_add, simpify code, and rename
mru
parents:
10275
diff
changeset
|
402 s->dsp.vector_fmul_add(out, in, s->windows[bsize], |
4d1b9ca628fc
Drop unused args from vector_fmul_add_add, simpify code, and rename
mru
parents:
10275
diff
changeset
|
403 out, block_len); |
4737
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
404 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
405 } else { |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
406 block_len = 1 << s->prev_block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
407 n = (s->block_len - block_len) / 2; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
408 bsize = s->frame_len_bits - s->prev_block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
409 |
10300
4d1b9ca628fc
Drop unused args from vector_fmul_add_add, simpify code, and rename
mru
parents:
10275
diff
changeset
|
410 s->dsp.vector_fmul_add(out+n, in+n, s->windows[bsize], |
4d1b9ca628fc
Drop unused args from vector_fmul_add_add, simpify code, and rename
mru
parents:
10275
diff
changeset
|
411 out+n, block_len); |
4737
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
412 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
413 memcpy(out+n+block_len, in+n+block_len, n*sizeof(float)); |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
414 } |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
415 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
416 out += s->block_len; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
417 in += s->block_len; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
418 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
419 /* right part */ |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
420 if (s->block_len_bits <= s->next_block_len_bits) { |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
421 block_len = s->block_len; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
422 bsize = s->frame_len_bits - s->block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
423 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
424 s->dsp.vector_fmul_reverse(out, in, s->windows[bsize], block_len); |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
425 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
426 } else { |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
427 block_len = 1 << s->next_block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
428 n = (s->block_len - block_len) / 2; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
429 bsize = s->frame_len_bits - s->next_block_len_bits; |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
430 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
431 memcpy(out, in, n*sizeof(float)); |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
432 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
433 s->dsp.vector_fmul_reverse(out+n, in+n, s->windows[bsize], block_len); |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
434 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
435 memset(out+n+block_len, 0, n*sizeof(float)); |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
436 } |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
437 } |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
438 |
99d9dd34903b
Optimize by building the mdct window and multipying/adding at the same time.
banan
parents:
4601
diff
changeset
|
439 |
4497 | 440 /** |
441 * @return 0 if OK. 1 if last block of frame. return -1 if | |
442 * unrecorrable error. | |
443 */ | |
4601 | 444 static int wma_decode_block(WMACodecContext *s) |
783 | 445 { |
9844
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
446 int n, v, a, ch, bsize; |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
447 int coef_nb_bits, total_gain; |
783 | 448 int nb_coefs[MAX_CHANNELS]; |
449 float mdct_norm; | |
450 | |
1343 | 451 #ifdef TRACE |
4600 | 452 tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num); |
1343 | 453 #endif |
783 | 454 |
455 /* compute current block length */ | |
456 if (s->use_variable_block_len) { | |
457 n = av_log2(s->nb_block_sizes - 1) + 1; | |
2967 | 458 |
783 | 459 if (s->reset_block_lengths) { |
460 s->reset_block_lengths = 0; | |
461 v = get_bits(&s->gb, n); | |
10654 | 462 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); | |
783 | 464 return -1; |
10654 | 465 } |
783 | 466 s->prev_block_len_bits = s->frame_len_bits - v; |
467 v = get_bits(&s->gb, n); | |
10654 | 468 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); | |
783 | 470 return -1; |
10654 | 471 } |
783 | 472 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); | |
10654 | 479 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); | |
783 | 481 return -1; |
10654 | 482 } |
783 | 483 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; | |
10654 | 493 if ((s->block_pos + s->block_len) > s->frame_len){ |
494 av_log(s->avctx, AV_LOG_ERROR, "frame_len overflow\n"); | |
783 | 495 return -1; |
10654 | 496 } |
783 | 497 |
498 if (s->nb_channels == 2) { | |
5513 | 499 s->ms_stereo = get_bits1(&s->gb); |
783 | 500 } |
501 v = 0; | |
502 for(ch = 0; ch < s->nb_channels; ch++) { | |
5513 | 503 a = get_bits1(&s->gb); |
783 | 504 s->channel_coded[ch] = a; |
505 v |= a; | |
506 } | |
7243 | 507 |
508 bsize = s->frame_len_bits - s->block_len_bits; | |
509 | |
783 | 510 /* 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 } | |
2967 | 524 |
4490 | 525 coef_nb_bits= ff_wma_total_gain_to_bits(total_gain); |
783 | 526 |
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++) { | |
5513 | 540 a = get_bits1(&s->gb); |
783 | 541 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 { | |
3113 | 559 code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX); |
10654 | 560 if (code < 0){ |
561 av_log(s->avctx, AV_LOG_ERROR, "hgain vlc invalid\n"); | |
783 | 562 return -1; |
10654 | 563 } |
783 | 564 val += code - 18; |
565 } | |
566 s->high_band_values[ch][i] = val; | |
567 } | |
568 } | |
569 } | |
570 } | |
571 } | |
2967 | 572 |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
573 /* exponents can be reused in short blocks. */ |
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
574 if ((s->block_len_bits == s->frame_len_bits) || |
5513 | 575 get_bits1(&s->gb)) { |
783 | 576 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 } | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
584 s->exponents_bsize[ch] = bsize; |
783 | 585 } |
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]) { | |
9844
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
592 int tindex; |
9868 | 593 WMACoef* ptr = &s->coefs1[ch][0]; |
783 | 594 |
595 /* special VLC tables are used for ms stereo because | |
596 there is potentially less energy there */ | |
597 tindex = (ch == 1 && s->ms_stereo); | |
9868 | 598 memset(ptr, 0, s->block_len * sizeof(WMACoef)); |
9844
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
599 ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], |
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
600 s->level_table[tindex], s->run_table[tindex], |
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
601 0, ptr, 0, nb_coefs[ch], |
eb5916527064
Move run level decode functionality to ff_wma_run_level_decode
faust3
parents:
9658
diff
changeset
|
602 s->block_len, s->frame_len_bits, coef_nb_bits); |
783 | 603 } |
604 if (s->version == 1 && s->nb_channels >= 2) { | |
605 align_get_bits(&s->gb); | |
606 } | |
607 } | |
2967 | 608 |
783 | 609 /* 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]) { | |
9868 | 621 WMACoef *coefs1; |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
622 float *coefs, *exponents, mult, mult1, noise; |
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
623 int i, j, n, n1, last_high_band, esize; |
783 | 624 float exp_power[HIGH_BAND_MAX_SIZE]; |
625 | |
626 coefs1 = s->coefs1[ch]; | |
627 exponents = s->exponents[ch]; | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
628 esize = s->exponents_bsize[ch]; |
3235 | 629 mult = pow(10, total_gain * 0.05) / s->max_exponent[ch]; |
783 | 630 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++) { | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
636 *coefs++ = s->noise_table[s->noise_index] * |
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
637 exponents[i<<bsize>>esize] * mult1; |
783 | 638 s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1); |
639 } | |
2967 | 640 |
783 | 641 n1 = s->exponent_high_sizes[bsize]; |
642 | |
643 /* compute power of high bands */ | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
644 exponents = s->exponents[ch] + |
10653 | 645 (s->high_band_start[bsize]<<bsize>>esize); |
783 | 646 last_high_band = 0; /* avoid warning */ |
647 for(j=0;j<n1;j++) { | |
2967 | 648 n = s->exponent_high_bands[s->frame_len_bits - |
783 | 649 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++) { | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
654 v = exponents[i<<bsize>>esize]; |
783 | 655 e2 += v * v; |
656 } | |
657 exp_power[j] = e2 / n; | |
658 last_high_band = j; | |
4600 | 659 tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n); |
783 | 660 } |
10653 | 661 exponents += n<<bsize>>esize; |
783 | 662 } |
663 | |
664 /* main freqs and high freqs */ | |
10653 | 665 exponents = s->exponents[ch] + (s->coefs_start<<bsize>>esize); |
783 | 666 for(j=-1;j<n1;j++) { |
667 if (j < 0) { | |
2967 | 668 n = s->high_band_start[bsize] - |
783 | 669 s->coefs_start; |
670 } else { | |
2967 | 671 n = s->exponent_high_bands[s->frame_len_bits - |
783 | 672 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]); | |
3235 | 677 /* XXX: use a table */ |
678 mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05); | |
783 | 679 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); | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
684 *coefs++ = noise * |
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
685 exponents[i<<bsize>>esize] * mult1; |
783 | 686 } |
10653 | 687 exponents += n<<bsize>>esize; |
783 | 688 } 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); | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
693 *coefs++ = ((*coefs1++) + noise) * |
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
694 exponents[i<<bsize>>esize] * mult; |
783 | 695 } |
10653 | 696 exponents += n<<bsize>>esize; |
783 | 697 } |
698 } | |
699 | |
700 /* very high freqs : noise */ | |
701 n = s->block_len - s->coefs_end[bsize]; | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
702 mult1 = mult * exponents[((-1<<bsize))>>esize]; |
783 | 703 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++) { | |
4785
4ae9ab738aec
WMA decoder improvement, output closer to the dmo binary.
banan
parents:
4737
diff
changeset
|
713 *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult; |
783 | 714 } |
715 n = s->block_len - s->coefs_end[bsize]; | |
716 for(i = 0;i < n; i++) | |
717 *coefs++ = 0.0; | |
718 } | |
719 } | |
720 } | |
721 | |
1342
f574934c4219
uniformization (now it uses the same trace functions as h264, defined in common.h)
al3x
parents:
1303
diff
changeset
|
722 #ifdef TRACE |
783 | 723 for(ch = 0; ch < s->nb_channels; ch++) { |
724 if (s->channel_coded[ch]) { | |
4600 | 725 dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len); |
726 dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len); | |
783 | 727 } |
728 } | |
729 #endif | |
2967 | 730 |
783 | 731 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]) { | |
4600 | 736 tprintf(s->avctx, "rare ms-stereo case happened\n"); |
783 | 737 memset(s->coefs[0], 0, sizeof(float) * s->block_len); |
738 s->channel_coded[0] = 1; | |
739 } | |
2967 | 740 |
10236 | 741 s->dsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len); |
783 | 742 } |
743 | |
7243 | 744 next: |
783 | 745 for(ch = 0; ch < s->nb_channels; ch++) { |
9472
05663d250d5b
Remove unused variable from wma_decode_block() found by CSA.
michael
parents:
9355
diff
changeset
|
746 int n4, index; |
783 | 747 |
7244 | 748 n4 = s->block_len / 2; |
749 if(s->channel_coded[ch]){ | |
7547 | 750 ff_imdct_calc(&s->mdct_ctx[bsize], s->output, s->coefs[ch]); |
7712
7c22b99dbf5e
Fix mid/side stereo buggy output zeroing, fixes issue264 part 2.
michael
parents:
7547
diff
changeset
|
751 }else if(!(s->ms_stereo && ch==1)) |
7244 | 752 memset(s->output, 0, sizeof(s->output)); |
783 | 753 |
7244 | 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]); | |
783 | 757 } |
7243 | 758 |
783 | 759 /* 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 */ | |
4601 | 769 static int wma_decode_frame(WMACodecContext *s, int16_t *samples) |
783 | 770 { |
5525
bc4791868c52
various simplifications around recent av_clip_int16() usage
aurel
parents:
5523
diff
changeset
|
771 int ret, i, n, ch, incr; |
783 | 772 int16_t *ptr; |
773 float *iptr; | |
774 | |
1343 | 775 #ifdef TRACE |
4600 | 776 tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len); |
1343 | 777 #endif |
783 | 778 |
779 /* read each block */ | |
780 s->block_num = 0; | |
781 s->block_pos = 0; | |
782 for(;;) { | |
783 ret = wma_decode_block(s); | |
2967 | 784 if (ret < 0) |
783 | 785 return -1; |
786 if (ret) | |
787 break; | |
788 } | |
789 | |
790 /* convert frame to integer */ | |
791 n = s->frame_len; | |
792 incr = s->nb_channels; | |
11451
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
793 if (s->dsp.float_to_int16_interleave == ff_float_to_int16_interleave_c) { |
11452 | 794 for(ch = 0; ch < s->nb_channels; ch++) { |
795 ptr = samples + ch; | |
796 iptr = s->frame_out[ch]; | |
783 | 797 |
11452 | 798 for(i=0;i<n;i++) { |
799 *ptr = av_clip_int16(lrintf(*iptr++)); | |
800 ptr += incr; | |
801 } | |
802 /* prepare for next block */ | |
803 memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len], | |
804 s->frame_len * sizeof(float)); | |
783 | 805 } |
11451
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
806 } else { |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
807 float *output[MAX_CHANNELS]; |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
808 for (ch = 0; ch < MAX_CHANNELS; ch++) |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
809 output[ch] = s->frame_out[ch]; |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
810 s->dsp.float_to_int16_interleave(samples, (const float **)output, n, incr); |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
811 for(ch = 0; ch < incr; ch++) { |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
812 /* prepare for next block */ |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
813 memmove(&s->frame_out[ch][0], &s->frame_out[ch][n], n * sizeof(float)); |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
814 } |
01559518729e
SIMD optimization using float_to_int16_interleave.
cehoyos
parents:
11215
diff
changeset
|
815 } |
783 | 816 |
1342
f574934c4219
uniformization (now it uses the same trace functions as h264, defined in common.h)
al3x
parents:
1303
diff
changeset
|
817 #ifdef TRACE |
4600 | 818 dump_shorts(s, "samples", samples, n * s->nb_channels); |
783 | 819 #endif |
820 return 0; | |
821 } | |
822 | |
2967 | 823 static int wma_decode_superframe(AVCodecContext *avctx, |
783 | 824 void *data, int *data_size, |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
825 AVPacket *avpkt) |
783 | 826 { |
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
827 const uint8_t *buf = avpkt->data; |
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
8718
diff
changeset
|
828 int buf_size = avpkt->size; |
4601 | 829 WMACodecContext *s = avctx->priv_data; |
783 | 830 int nb_frames, bit_offset, i, pos, len; |
831 uint8_t *q; | |
832 int16_t *samples; | |
2967 | 833 |
4600 | 834 tprintf(avctx, "***decode_superframe:\n"); |
783 | 835 |
1750 | 836 if(buf_size==0){ |
837 s->last_superframe_len = 0; | |
838 return 0; | |
839 } | |
5957
0f2c4fa2c4f2
wma_decode_superframe always returns s->block_align, so make
reimar
parents:
5525
diff
changeset
|
840 if (buf_size < s->block_align) |
0f2c4fa2c4f2
wma_decode_superframe always returns s->block_align, so make
reimar
parents:
5525
diff
changeset
|
841 return 0; |
0f2c4fa2c4f2
wma_decode_superframe always returns s->block_align, so make
reimar
parents:
5525
diff
changeset
|
842 buf_size = s->block_align; |
2967 | 843 |
783 | 844 samples = data; |
845 | |
1025
1f9afd8b9131
GetBitContext.size is allways multiplied by 8 -> use size_in_bits to avoid useless *8 in a few inner loops
michaelni
parents:
972
diff
changeset
|
846 init_get_bits(&s->gb, buf, buf_size*8); |
2967 | 847 |
783 | 848 if (s->use_bit_reservoir) { |
849 /* read super frame header */ | |
5518 | 850 skip_bits(&s->gb, 4); /* super frame index */ |
783 | 851 nb_frames = get_bits(&s->gb, 4) - 1; |
852 | |
7242 | 853 if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ |
854 av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); | |
855 goto fail; | |
856 } | |
857 | |
783 | 858 bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); |
859 | |
860 if (s->last_superframe_len > 0) { | |
861 // printf("skip=%d\n", s->last_bitoffset); | |
862 /* add bit_offset bits to last frame */ | |
2967 | 863 if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > |
783 | 864 MAX_CODED_SUPERFRAME_SIZE) |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
865 goto fail; |
783 | 866 q = s->last_superframe + s->last_superframe_len; |
867 len = bit_offset; | |
3362
c43fcf831f7c
Do not read full byte when less than 8 bits are still to be read.
reimar
parents:
3361
diff
changeset
|
868 while (len > 7) { |
783 | 869 *q++ = (get_bits)(&s->gb, 8); |
870 len -= 8; | |
871 } | |
872 if (len > 0) { | |
873 *q++ = (get_bits)(&s->gb, len) << (8 - len); | |
874 } | |
2967 | 875 |
783 | 876 /* XXX: bit_offset bits into last frame */ |
1025
1f9afd8b9131
GetBitContext.size is allways multiplied by 8 -> use size_in_bits to avoid useless *8 in a few inner loops
michaelni
parents:
972
diff
changeset
|
877 init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); |
783 | 878 /* skip unused bits */ |
879 if (s->last_bitoffset > 0) | |
880 skip_bits(&s->gb, s->last_bitoffset); | |
881 /* this frame is stored in the last superframe and in the | |
882 current one */ | |
883 if (wma_decode_frame(s, samples) < 0) | |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
884 goto fail; |
783 | 885 samples += s->nb_channels * s->frame_len; |
886 } | |
887 | |
888 /* read each frame starting from bit_offset */ | |
889 pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; | |
1025
1f9afd8b9131
GetBitContext.size is allways multiplied by 8 -> use size_in_bits to avoid useless *8 in a few inner loops
michaelni
parents:
972
diff
changeset
|
890 init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); |
783 | 891 len = pos & 7; |
892 if (len > 0) | |
893 skip_bits(&s->gb, len); | |
2967 | 894 |
783 | 895 s->reset_block_lengths = 1; |
896 for(i=0;i<nb_frames;i++) { | |
897 if (wma_decode_frame(s, samples) < 0) | |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
898 goto fail; |
783 | 899 samples += s->nb_channels * s->frame_len; |
900 } | |
901 | |
902 /* we copy the end of the frame in the last frame buffer */ | |
903 pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); | |
904 s->last_bitoffset = pos & 7; | |
905 pos >>= 3; | |
906 len = buf_size - pos; | |
819 | 907 if (len > MAX_CODED_SUPERFRAME_SIZE || len < 0) { |
10654 | 908 av_log(s->avctx, AV_LOG_ERROR, "len %d invalid\n", len); |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
909 goto fail; |
783 | 910 } |
911 s->last_superframe_len = len; | |
912 memcpy(s->last_superframe, buf + pos, len); | |
913 } else { | |
7242 | 914 if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ |
915 av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); | |
916 goto fail; | |
917 } | |
783 | 918 /* single frame decode */ |
919 if (wma_decode_frame(s, samples) < 0) | |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
920 goto fail; |
783 | 921 samples += s->nb_channels * s->frame_len; |
922 } | |
4490 | 923 |
924 //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); | |
925 | |
783 | 926 *data_size = (int8_t *)samples - (int8_t *)data; |
927 return s->block_align; | |
964
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
928 fail: |
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
929 /* when error, we reset the bit reservoir */ |
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
930 s->last_superframe_len = 0; |
6e6773512288
oops : better error resilience - should fix most wma decoding problems
bellard
parents:
819
diff
changeset
|
931 return -1; |
783 | 932 } |
933 | |
11062 | 934 static av_cold void flush(AVCodecContext *avctx) |
935 { | |
936 WMACodecContext *s = avctx->priv_data; | |
937 | |
938 s->last_bitoffset= | |
939 s->last_superframe_len= 0; | |
940 } | |
941 | |
783 | 942 AVCodec wmav1_decoder = |
943 { | |
944 "wmav1", | |
945 CODEC_TYPE_AUDIO, | |
946 CODEC_ID_WMAV1, | |
4601 | 947 sizeof(WMACodecContext), |
783 | 948 wma_decode_init, |
949 NULL, | |
4490 | 950 ff_wma_end, |
783 | 951 wma_decode_superframe, |
11062 | 952 .flush=flush, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
953 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 1"), |
783 | 954 }; |
955 | |
956 AVCodec wmav2_decoder = | |
957 { | |
958 "wmav2", | |
959 CODEC_TYPE_AUDIO, | |
960 CODEC_ID_WMAV2, | |
4601 | 961 sizeof(WMACodecContext), |
783 | 962 wma_decode_init, |
963 NULL, | |
4490 | 964 ff_wma_end, |
783 | 965 wma_decode_superframe, |
11062 | 966 .flush=flush, |
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6710
diff
changeset
|
967 .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio 2"), |
783 | 968 }; |