Mercurial > libavcodec.hg
annotate wavpack.c @ 3990:746a60ba3177 libavcodec
enable CMOV_IS_FAST as its faster or equal speed on every cpu (duron, athlon, PM, P3) from which ive seen benchmarks, it might be slower on P4 but noone has posted benchmarks ...
author | michael |
---|---|
date | Wed, 11 Oct 2006 12:23:40 +0000 |
parents | c8c591fe26f8 |
children | b1a1fb651bf5 |
rev | line source |
---|---|
3764 | 1 /* |
2 * WavPack lossless audio decoder | |
3 * Copyright (c) 2006 Konstantin Shishkov | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3782
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3782
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3782
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
3764 | 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:
3782
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
3764 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3782
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
3764 | 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:
3782
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3764 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 */ | |
21 #define ALT_BITSTREAM_READER_LE | |
22 #include "avcodec.h" | |
23 #include "bitstream.h" | |
24 | |
25 /** | |
26 * @file wavpack.c | |
27 * WavPack lossless audio decoder | |
28 */ | |
29 | |
30 #define WV_JOINT 0x0010 | |
31 | |
32 enum WP_ID_Flags{ | |
33 WP_IDF_MASK = 0x1F, | |
34 WP_IDF_IGNORE = 0x20, | |
35 WP_IDF_ODD = 0x40, | |
36 WP_IDF_LONG = 0x80 | |
37 }; | |
38 | |
39 enum WP_ID{ | |
40 WP_ID_DUMMY = 0, | |
41 WP_ID_ENCINFO, | |
42 WP_ID_DECTERMS, | |
43 WP_ID_DECWEIGHTS, | |
44 WP_ID_DECSAMPLES, | |
45 WP_ID_ENTROPY, | |
46 WP_ID_HYBRID, | |
47 WP_ID_SHAPING, | |
48 WP_ID_FLOATINFO, | |
49 WP_ID_INT32INFO, | |
50 WP_ID_DATA, | |
51 WP_ID_CORR, | |
52 WP_ID_FLT, | |
53 WP_ID_CHANINFO | |
54 }; | |
55 | |
56 #define MAX_TERMS 16 | |
57 | |
58 typedef struct Decorr { | |
59 int delta; | |
60 int value; | |
61 int weightA; | |
62 int weightB; | |
63 int samplesA[8]; | |
64 int samplesB[8]; | |
65 } Decorr; | |
66 | |
67 typedef struct WavpackContext { | |
68 AVCodecContext *avctx; | |
69 int stereo; | |
70 int joint; | |
71 uint32_t CRC; | |
72 GetBitContext gb; | |
73 int data_size; // in bits | |
74 int samples; | |
75 int median[6]; | |
76 int terms; | |
77 Decorr decorr[MAX_TERMS]; | |
78 int zero, one, zeroes; | |
79 } WavpackContext; | |
80 | |
81 // exponent table copied from WavPack source | |
82 static const uint8_t wp_exp2_table [256] = { | |
83 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b, | |
84 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16, | |
85 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23, | |
86 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, | |
87 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d, | |
88 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b, | |
89 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, | |
90 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, | |
91 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, | |
92 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, | |
93 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, | |
94 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, | |
95 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, | |
96 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, | |
97 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9, | |
98 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff | |
99 }; | |
100 | |
101 static always_inline int wp_exp2(int16_t val) | |
102 { | |
103 int res, neg = 0; | |
104 | |
105 if(val < 0){ | |
106 val = -val; | |
107 neg = 1; | |
108 } | |
109 | |
110 res = wp_exp2_table[val & 0xFF] | 0x100; | |
111 val >>= 8; | |
112 res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val)); | |
113 return neg ? -res : res; | |
114 } | |
115 | |
116 static inline int get_unary(GetBitContext *gb){ | |
117 int r=0; | |
118 while(get_bits1(gb) && r<33)r++; | |
119 return r; | |
120 } | |
121 | |
122 // macros for manipulating median values | |
123 #define GET_MED(n) ((median[n] >> 4) + 1) | |
124 #define DEC_MED(n) median[n] -= ((median[n] + (128>>n) - 2) / (128>>n)) * 2 | |
125 #define INC_MED(n) median[n] += ((median[n] + (128>>n)) / (128>>n)) * 5 | |
126 | |
127 // macros for applying weight | |
128 #define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \ | |
129 if(samples && in){ \ | |
130 if((samples ^ in) < 0){ \ | |
131 weight -= delta; \ | |
132 if(weight < -1024) weight = -1024; \ | |
133 }else{ \ | |
134 weight += delta; \ | |
135 if(weight > 1024) weight = 1024; \ | |
136 } \ | |
137 } | |
138 | |
139 | |
140 static always_inline int get_tail(GetBitContext *gb, int k) | |
141 { | |
142 int p, e, res; | |
143 | |
144 if(k<1 || k>65535)return 0; | |
145 p = av_log2_16bit(k); | |
146 e = (1 << (p + 1)) - k - 1; | |
3782 | 147 res = p ? get_bits(gb, p) : 0; |
3764 | 148 if(res >= e){ |
149 res = (res<<1) - e + get_bits1(gb); | |
150 } | |
151 return res; | |
152 } | |
153 | |
154 static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int *last) | |
155 { | |
156 int t, t2; | |
157 int sign, base, add, ret; | |
158 | |
159 *last = 0; | |
160 | |
161 if((ctx->median[0] < 2U) && (ctx->median[3] < 2U) && !ctx->zero && !ctx->one){ | |
162 if(ctx->zeroes){ | |
163 ctx->zeroes--; | |
164 if(ctx->zeroes) | |
165 return 0; | |
166 }else{ | |
167 t = get_unary(gb); | |
168 if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); | |
169 ctx->zeroes = t; | |
170 if(ctx->zeroes){ | |
171 memset(ctx->median, 0, sizeof(ctx->median)); | |
172 return 0; | |
173 } | |
174 } | |
175 } | |
176 | |
177 if(get_bits_count(gb) >= ctx->data_size){ | |
178 *last = 1; | |
179 return 0; | |
180 } | |
181 | |
182 if(ctx->zero){ | |
183 t = 0; | |
184 ctx->zero = 0; | |
185 }else{ | |
186 t = get_unary(gb); | |
187 if(get_bits_count(gb) >= ctx->data_size){ | |
188 *last = 1; | |
189 return 0; | |
190 } | |
191 if(t == 16) { | |
192 t2 = get_unary(gb); | |
193 if(t2 < 2) t += t2; | |
194 else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); | |
195 } | |
196 | |
197 if(ctx->one){ | |
198 ctx->one = t&1; | |
199 t = (t>>1) + 1; | |
200 }else{ | |
201 ctx->one = t&1; | |
202 t >>= 1; | |
203 } | |
204 ctx->zero = !ctx->one; | |
205 } | |
206 | |
207 if(!t){ | |
208 base = 0; | |
209 add = GET_MED(0) - 1; | |
210 DEC_MED(0); | |
211 }else if(t == 1){ | |
212 base = GET_MED(0); | |
213 add = GET_MED(1) - 1; | |
214 INC_MED(0); | |
215 DEC_MED(1); | |
216 }else if(t == 2){ | |
217 base = GET_MED(0) + GET_MED(1); | |
218 add = GET_MED(2) - 1; | |
219 INC_MED(0); | |
220 INC_MED(1); | |
221 DEC_MED(2); | |
222 }else{ | |
223 base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2); | |
224 add = GET_MED(2) - 1; | |
225 INC_MED(0); | |
226 INC_MED(1); | |
227 INC_MED(2); | |
228 } | |
229 ret = base + get_tail(gb, add); | |
230 sign = get_bits1(gb); | |
231 return sign ? ~ret : ret; | |
232 } | |
233 | |
234 static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst) | |
235 { | |
236 int i, j, count = 0; | |
237 int last, t; | |
238 int A, B, L, L2, R, R2; | |
239 int pos = 0; | |
240 uint32_t crc = 0xFFFFFFFF; | |
241 | |
242 s->one = s->zero = s->zeroes = 0; | |
243 do{ | |
244 L = wv_get_value(s, gb, s->median, &last); | |
245 if(last) break; | |
246 R = wv_get_value(s, gb, s->median + 3, &last); | |
247 if(last) break; | |
248 for(i = 0; i < s->terms; i++){ | |
249 t = s->decorr[i].value; | |
250 j = 0; | |
251 if(t > 0){ | |
252 if(t > 8){ | |
253 if(t & 1){ | |
254 A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; | |
255 B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]; | |
256 }else{ | |
257 A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; | |
258 B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1; | |
259 } | |
260 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; | |
261 s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0]; | |
262 j = 0; | |
263 }else{ | |
264 A = s->decorr[i].samplesA[pos]; | |
265 B = s->decorr[i].samplesB[pos]; | |
266 j = (pos + t) & 7; | |
267 } | |
268 L2 = L + ((s->decorr[i].weightA * A + 512) >> 10); | |
269 R2 = R + ((s->decorr[i].weightB * B + 512) >> 10); | |
270 if(A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; | |
271 if(B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta; | |
272 s->decorr[i].samplesA[j] = L = L2; | |
273 s->decorr[i].samplesB[j] = R = R2; | |
274 }else if(t == -1){ | |
275 L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10); | |
276 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L); | |
277 L = L2; | |
278 R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10); | |
279 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R); | |
280 R = R2; | |
281 s->decorr[i].samplesA[0] = R; | |
282 }else{ | |
283 R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10); | |
284 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R); | |
285 R = R2; | |
286 | |
287 if(t == -3){ | |
288 R2 = s->decorr[i].samplesA[0]; | |
289 s->decorr[i].samplesA[0] = R; | |
290 } | |
291 | |
292 L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10); | |
293 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L); | |
294 L = L2; | |
295 s->decorr[i].samplesB[0] = L; | |
296 } | |
297 } | |
298 pos = (pos + 1) & 7; | |
299 if(s->joint) | |
300 L += (R -= (L >> 1)); | |
301 crc = (crc * 3 + L) * 3 + R; | |
302 *dst++ = L; | |
303 *dst++ = R; | |
304 | |
305 count++; | |
306 }while(!last && count < s->samples); | |
307 | |
308 if(crc != s->CRC){ | |
309 av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); | |
310 return -1; | |
311 } | |
312 return count * 2; | |
313 } | |
314 | |
315 static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst) | |
316 { | |
317 int i, j, count = 0; | |
318 int last, t; | |
319 int A, S, T; | |
320 int pos = 0; | |
321 uint32_t crc = 0xFFFFFFFF; | |
322 | |
323 s->one = s->zero = s->zeroes = 0; | |
324 do{ | |
325 T = wv_get_value(s, gb, s->median, &last); | |
326 S = 0; | |
327 if(last) break; | |
328 for(i = 0; i < s->terms; i++){ | |
329 t = s->decorr[i].value; | |
330 if(t > 8){ | |
331 if(t & 1) | |
332 A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; | |
333 else | |
334 A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; | |
335 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; | |
336 j = 0; | |
337 }else{ | |
338 A = s->decorr[i].samplesA[pos]; | |
339 j = (pos + t) & 7; | |
340 } | |
341 S = T + ((s->decorr[i].weightA * A + 512) >> 10); | |
342 if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; | |
343 s->decorr[i].samplesA[j] = T = S; | |
344 } | |
345 pos = (pos + 1) & 7; | |
346 crc = crc * 3 + S; | |
347 *dst++ = S; | |
348 count++; | |
349 }while(!last && count < s->samples); | |
350 | |
351 if(crc != s->CRC){ | |
352 av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); | |
353 return -1; | |
354 } | |
355 return count; | |
356 } | |
357 | |
358 static int wavpack_decode_init(AVCodecContext *avctx) | |
359 { | |
360 WavpackContext *s = avctx->priv_data; | |
361 | |
362 s->avctx = avctx; | |
363 s->stereo = (avctx->channels == 2); | |
364 | |
365 return 0; | |
366 } | |
367 | |
368 static int wavpack_decode_close(AVCodecContext *avctx) | |
369 { | |
370 // WavpackContext *s = avctx->priv_data; | |
371 | |
372 return 0; | |
373 } | |
374 | |
375 static int wavpack_decode_frame(AVCodecContext *avctx, | |
376 void *data, int *data_size, | |
377 uint8_t *buf, int buf_size) | |
378 { | |
379 WavpackContext *s = avctx->priv_data; | |
380 int16_t *samples = data; | |
381 int samplecount; | |
382 int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0; | |
383 uint8_t* buf_end = buf + buf_size; | |
384 int i, j, id, size, ssize, weights, t; | |
385 | |
386 if (buf_size == 0) return 0; | |
387 | |
388 memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); | |
389 | |
390 s->samples = LE_32(buf); buf += 4; | |
391 s->joint = LE_32(buf) & WV_JOINT; buf += 4; | |
392 s->CRC = LE_32(buf); buf += 4; | |
393 // parse metadata blocks | |
394 while(buf < buf_end){ | |
395 id = *buf++; | |
396 size = *buf++; | |
397 if(id & WP_IDF_LONG) { | |
398 size |= (*buf++) << 8; | |
399 size |= (*buf++) << 16; | |
400 } | |
401 size <<= 1; // size is specified in words | |
402 ssize = size; | |
403 if(id & WP_IDF_ODD) size--; | |
404 if(size < 0){ | |
405 av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size); | |
406 break; | |
407 } | |
408 if(buf + ssize > buf_end){ | |
409 av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size); | |
410 break; | |
411 } | |
412 if(id & WP_IDF_IGNORE){ | |
413 buf += ssize; | |
414 continue; | |
415 } | |
416 switch(id & WP_IDF_MASK){ | |
417 case WP_ID_DECTERMS: | |
418 s->terms = size; | |
419 if(s->terms > MAX_TERMS){ | |
420 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n"); | |
421 buf += ssize; | |
422 continue; | |
423 } | |
424 for(i = 0; i < s->terms; i++) { | |
425 s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5; | |
426 s->decorr[s->terms - i - 1].delta = *buf >> 5; | |
427 buf++; | |
428 } | |
429 got_terms = 1; | |
430 break; | |
431 case WP_ID_DECWEIGHTS: | |
432 if(!got_terms){ | |
433 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); | |
434 continue; | |
435 } | |
436 weights = size >> s->stereo; | |
437 if(weights > MAX_TERMS || weights > s->terms){ | |
438 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n"); | |
439 buf += ssize; | |
440 continue; | |
441 } | |
442 for(i = 0; i < weights; i++) { | |
443 t = (int8_t)(*buf++); | |
444 s->decorr[s->terms - i - 1].weightA = t << 3; | |
445 if(s->decorr[s->terms - i - 1].weightA > 0) | |
446 s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7; | |
447 if(s->stereo){ | |
448 t = (int8_t)(*buf++); | |
449 s->decorr[s->terms - i - 1].weightB = t << 3; | |
450 if(s->decorr[s->terms - i - 1].weightB > 0) | |
451 s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7; | |
452 } | |
453 } | |
454 got_weights = 1; | |
455 break; | |
456 case WP_ID_DECSAMPLES: | |
457 if(!got_terms){ | |
458 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n"); | |
459 continue; | |
460 } | |
461 t = 0; | |
462 for(i = s->terms - 1; (i >= 0) && (t < size); i--) { | |
463 if(s->decorr[i].value > 8){ | |
464 s->decorr[i].samplesA[0] = wp_exp2(LE_16(buf)); buf += 2; | |
465 s->decorr[i].samplesA[1] = wp_exp2(LE_16(buf)); buf += 2; | |
466 if(s->stereo){ | |
467 s->decorr[i].samplesB[0] = wp_exp2(LE_16(buf)); buf += 2; | |
468 s->decorr[i].samplesB[1] = wp_exp2(LE_16(buf)); buf += 2; | |
469 t += 4; | |
470 } | |
471 t += 4; | |
472 }else if(s->decorr[i].value < 0){ | |
473 s->decorr[i].samplesA[0] = wp_exp2(LE_16(buf)); buf += 2; | |
474 s->decorr[i].samplesB[0] = wp_exp2(LE_16(buf)); buf += 2; | |
475 t += 4; | |
476 }else{ | |
477 for(j = 0; j < s->decorr[i].value; j++){ | |
478 s->decorr[i].samplesA[j] = wp_exp2(LE_16(buf)); buf += 2; | |
479 if(s->stereo){ | |
480 s->decorr[i].samplesB[j] = wp_exp2(LE_16(buf)); buf += 2; | |
481 } | |
482 } | |
483 t += s->decorr[i].value * 2 * avctx->channels; | |
484 } | |
485 } | |
486 got_samples = 1; | |
487 break; | |
488 case WP_ID_ENTROPY: | |
489 if(size != 6 * avctx->channels){ | |
490 av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * avctx->channels, size); | |
491 buf += ssize; | |
492 continue; | |
493 } | |
494 for(i = 0; i < 3 * avctx->channels; i++){ | |
495 s->median[i] = wp_exp2(LE_16(buf)); | |
496 buf += 2; | |
497 } | |
498 got_entropy = 1; | |
499 break; | |
500 case WP_ID_DATA: | |
501 init_get_bits(&s->gb, buf, size * 8); | |
502 s->data_size = size * 8; | |
503 buf += size; | |
504 got_bs = 1; | |
505 break; | |
506 default: | |
507 buf += size; | |
508 } | |
509 if(id & WP_IDF_ODD) buf++; | |
510 } | |
511 if(!got_terms){ | |
512 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); | |
513 return -1; | |
514 } | |
515 if(!got_weights){ | |
516 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); | |
517 return -1; | |
518 } | |
519 if(!got_samples){ | |
520 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); | |
521 return -1; | |
522 } | |
523 if(!got_entropy){ | |
524 av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); | |
525 return -1; | |
526 } | |
527 if(!got_bs){ | |
528 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); | |
529 return -1; | |
530 } | |
531 | |
532 if(s->stereo) | |
533 samplecount = wv_unpack_stereo(s, &s->gb, samples); | |
534 else | |
535 samplecount = wv_unpack_mono(s, &s->gb, samples); | |
536 *data_size = samplecount * 2; | |
537 | |
538 return buf_size; | |
539 } | |
540 | |
541 AVCodec wavpack_decoder = { | |
542 "wavpack", | |
543 CODEC_TYPE_AUDIO, | |
544 CODEC_ID_WAVPACK, | |
545 sizeof(WavpackContext), | |
546 wavpack_decode_init, | |
547 NULL, | |
548 wavpack_decode_close, | |
549 wavpack_decode_frame, | |
550 }; |