Merge branch 'mirror' into vdpau
[FFMpeg-mirror/ffmpeg-vdpau.git] / libavcodec / wavpack.c
blobb89723e2f23dc32403a49d8ef2b9536c81893471
1 /*
2 * WavPack lossless audio decoder
3 * Copyright (c) 2006 Konstantin Shishkov
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
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.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #define ALT_BITSTREAM_READER_LE
22 #include "avcodec.h"
23 #include "bitstream.h"
24 #include "unary.h"
26 /**
27 * @file wavpack.c
28 * WavPack lossless audio decoder
31 #define WV_JOINT_STEREO 0x00000010
32 #define WV_FALSE_STEREO 0x40000000
34 enum WP_ID_Flags{
35 WP_IDF_MASK = 0x1F,
36 WP_IDF_IGNORE = 0x20,
37 WP_IDF_ODD = 0x40,
38 WP_IDF_LONG = 0x80
41 enum WP_ID{
42 WP_ID_DUMMY = 0,
43 WP_ID_ENCINFO,
44 WP_ID_DECTERMS,
45 WP_ID_DECWEIGHTS,
46 WP_ID_DECSAMPLES,
47 WP_ID_ENTROPY,
48 WP_ID_HYBRID,
49 WP_ID_SHAPING,
50 WP_ID_FLOATINFO,
51 WP_ID_INT32INFO,
52 WP_ID_DATA,
53 WP_ID_CORR,
54 WP_ID_FLT,
55 WP_ID_CHANINFO
58 #define MAX_TERMS 16
60 typedef struct Decorr {
61 int delta;
62 int value;
63 int weightA;
64 int weightB;
65 int samplesA[8];
66 int samplesB[8];
67 } Decorr;
69 typedef struct WavpackContext {
70 AVCodecContext *avctx;
71 int stereo, stereo_in;
72 int joint;
73 uint32_t CRC;
74 GetBitContext gb;
75 int data_size; // in bits
76 int samples;
77 int median[6];
78 int terms;
79 Decorr decorr[MAX_TERMS];
80 int zero, one, zeroes;
81 int and, or, shift;
82 } WavpackContext;
84 // exponent table copied from WavPack source
85 static const uint8_t wp_exp2_table [256] = {
86 0x00, 0x01, 0x01, 0x02, 0x03, 0x03, 0x04, 0x05, 0x06, 0x06, 0x07, 0x08, 0x08, 0x09, 0x0a, 0x0b,
87 0x0b, 0x0c, 0x0d, 0x0e, 0x0e, 0x0f, 0x10, 0x10, 0x11, 0x12, 0x13, 0x13, 0x14, 0x15, 0x16, 0x16,
88 0x17, 0x18, 0x19, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1d, 0x1e, 0x1f, 0x20, 0x20, 0x21, 0x22, 0x23,
89 0x24, 0x24, 0x25, 0x26, 0x27, 0x28, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
90 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3a, 0x3b, 0x3c, 0x3d,
91 0x3e, 0x3f, 0x40, 0x41, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x48, 0x49, 0x4a, 0x4b,
92 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a,
93 0x5b, 0x5c, 0x5d, 0x5e, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
94 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
95 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a,
96 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
97 0x9c, 0x9d, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad,
98 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0,
99 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, 0xc9, 0xca, 0xcb, 0xcd, 0xce, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4,
100 0xd6, 0xd7, 0xd8, 0xd9, 0xdb, 0xdc, 0xdd, 0xde, 0xe0, 0xe1, 0xe2, 0xe4, 0xe5, 0xe6, 0xe8, 0xe9,
101 0xea, 0xec, 0xed, 0xee, 0xf0, 0xf1, 0xf2, 0xf4, 0xf5, 0xf6, 0xf8, 0xf9, 0xfa, 0xfc, 0xfd, 0xff
104 static av_always_inline int wp_exp2(int16_t val)
106 int res, neg = 0;
108 if(val < 0){
109 val = -val;
110 neg = 1;
113 res = wp_exp2_table[val & 0xFF] | 0x100;
114 val >>= 8;
115 res = (val > 9) ? (res << (val - 9)) : (res >> (9 - val));
116 return neg ? -res : res;
119 // macros for manipulating median values
120 #define GET_MED(n) ((median[n] >> 4) + 1)
121 #define DEC_MED(n) median[n] -= ((median[n] + (128>>n) - 2) / (128>>n)) * 2
122 #define INC_MED(n) median[n] += ((median[n] + (128>>n)) / (128>>n)) * 5
124 // macros for applying weight
125 #define UPDATE_WEIGHT_CLIP(weight, delta, samples, in) \
126 if(samples && in){ \
127 if((samples ^ in) < 0){ \
128 weight -= delta; \
129 if(weight < -1024) weight = -1024; \
130 }else{ \
131 weight += delta; \
132 if(weight > 1024) weight = 1024; \
137 static av_always_inline int get_tail(GetBitContext *gb, int k)
139 int p, e, res;
141 if(k<1)return 0;
142 p = av_log2(k);
143 e = (1 << (p + 1)) - k - 1;
144 res = p ? get_bits(gb, p) : 0;
145 if(res >= e){
146 res = (res<<1) - e + get_bits1(gb);
148 return res;
151 static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int *last)
153 int t, t2;
154 int sign, base, add, ret;
156 *last = 0;
158 if((ctx->median[0] < 2U) && (ctx->median[3] < 2U) && !ctx->zero && !ctx->one){
159 if(ctx->zeroes){
160 ctx->zeroes--;
161 if(ctx->zeroes)
162 return 0;
163 }else{
164 t = get_unary_0_33(gb);
165 if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1));
166 ctx->zeroes = t;
167 if(ctx->zeroes){
168 memset(ctx->median, 0, sizeof(ctx->median));
169 return 0;
174 if(get_bits_count(gb) >= ctx->data_size){
175 *last = 1;
176 return 0;
179 if(ctx->zero){
180 t = 0;
181 ctx->zero = 0;
182 }else{
183 t = get_unary_0_33(gb);
184 if(get_bits_count(gb) >= ctx->data_size){
185 *last = 1;
186 return 0;
188 if(t == 16) {
189 t2 = get_unary_0_33(gb);
190 if(t2 < 2) t += t2;
191 else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1));
194 if(ctx->one){
195 ctx->one = t&1;
196 t = (t>>1) + 1;
197 }else{
198 ctx->one = t&1;
199 t >>= 1;
201 ctx->zero = !ctx->one;
204 if(!t){
205 base = 0;
206 add = GET_MED(0) - 1;
207 DEC_MED(0);
208 }else if(t == 1){
209 base = GET_MED(0);
210 add = GET_MED(1) - 1;
211 INC_MED(0);
212 DEC_MED(1);
213 }else if(t == 2){
214 base = GET_MED(0) + GET_MED(1);
215 add = GET_MED(2) - 1;
216 INC_MED(0);
217 INC_MED(1);
218 DEC_MED(2);
219 }else{
220 base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2);
221 add = GET_MED(2) - 1;
222 INC_MED(0);
223 INC_MED(1);
224 INC_MED(2);
226 ret = base + get_tail(gb, add);
227 sign = get_bits1(gb);
228 return sign ? ~ret : ret;
231 static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst)
233 int i, j, count = 0;
234 int last, t;
235 int A, B, L, L2, R, R2, bit;
236 int pos = 0;
237 uint32_t crc = 0xFFFFFFFF;
239 s->one = s->zero = s->zeroes = 0;
241 L = wv_get_value(s, gb, s->median, &last);
242 if(last) break;
243 R = wv_get_value(s, gb, s->median + 3, &last);
244 if(last) break;
245 for(i = 0; i < s->terms; i++){
246 t = s->decorr[i].value;
247 j = 0;
248 if(t > 0){
249 if(t > 8){
250 if(t & 1){
251 A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
252 B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1];
253 }else{
254 A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
255 B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1;
257 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
258 s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
259 j = 0;
260 }else{
261 A = s->decorr[i].samplesA[pos];
262 B = s->decorr[i].samplesB[pos];
263 j = (pos + t) & 7;
265 L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
266 R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
267 if(A && L) s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
268 if(B && R) s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
269 s->decorr[i].samplesA[j] = L = L2;
270 s->decorr[i].samplesB[j] = R = R2;
271 }else if(t == -1){
272 L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
273 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
274 L = L2;
275 R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
276 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
277 R = R2;
278 s->decorr[i].samplesA[0] = R;
279 }else{
280 R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
281 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R);
282 R = R2;
284 if(t == -3){
285 R2 = s->decorr[i].samplesA[0];
286 s->decorr[i].samplesA[0] = R;
289 L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
290 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
291 L = L2;
292 s->decorr[i].samplesB[0] = L;
295 pos = (pos + 1) & 7;
296 if(s->joint)
297 L += (R -= (L >> 1));
298 crc = (crc * 3 + L) * 3 + R;
299 bit = (L & s->and) | s->or;
300 *dst++ = ((L + bit) << s->shift) - bit;
301 bit = (R & s->and) | s->or;
302 *dst++ = ((R + bit) << s->shift) - bit;
303 count++;
304 }while(!last && count < s->samples);
306 if(crc != s->CRC){
307 av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
308 return -1;
310 return count * 2;
313 static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst)
315 int i, j, count = 0;
316 int last, t;
317 int A, S, T, bit;
318 int pos = 0;
319 uint32_t crc = 0xFFFFFFFF;
321 s->one = s->zero = s->zeroes = 0;
323 T = wv_get_value(s, gb, s->median, &last);
324 S = 0;
325 if(last) break;
326 for(i = 0; i < s->terms; i++){
327 t = s->decorr[i].value;
328 if(t > 8){
329 if(t & 1)
330 A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
331 else
332 A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
333 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
334 j = 0;
335 }else{
336 A = s->decorr[i].samplesA[pos];
337 j = (pos + t) & 7;
339 S = T + ((s->decorr[i].weightA * A + 512) >> 10);
340 if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
341 s->decorr[i].samplesA[j] = T = S;
343 pos = (pos + 1) & 7;
344 crc = crc * 3 + S;
345 bit = (S & s->and) | s->or;
346 *dst++ = ((S + bit) << s->shift) - bit;
347 count++;
348 }while(!last && count < s->samples);
350 if(crc != s->CRC){
351 av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
352 return -1;
354 return count;
357 static av_cold int wavpack_decode_init(AVCodecContext *avctx)
359 WavpackContext *s = avctx->priv_data;
361 s->avctx = avctx;
362 s->stereo = (avctx->channels == 2);
363 avctx->sample_fmt = SAMPLE_FMT_S16;
364 avctx->channel_layout = (avctx->channels==2) ? CH_LAYOUT_STEREO : CH_LAYOUT_MONO;
366 return 0;
369 static int wavpack_decode_frame(AVCodecContext *avctx,
370 void *data, int *data_size,
371 const uint8_t *buf, int buf_size)
373 WavpackContext *s = avctx->priv_data;
374 int16_t *samples = data;
375 int samplecount;
376 int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0;
377 const uint8_t* buf_end = buf + buf_size;
378 int i, j, id, size, ssize, weights, t;
380 if (buf_size == 0){
381 *data_size = 0;
382 return 0;
385 memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
386 memset(s->median, 0, sizeof(s->median));
387 s->and = s->or = s->shift = 0;
389 s->samples = AV_RL32(buf); buf += 4;
390 if(!s->samples){
391 *data_size = 0;
392 return buf_size;
394 /* should not happen but who knows */
395 if(s->samples * 2 * avctx->channels > *data_size){
396 av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n");
397 return -1;
399 s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo;
400 s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4;
401 s->CRC = AV_RL32(buf); buf += 4;
402 // parse metadata blocks
403 while(buf < buf_end){
404 id = *buf++;
405 size = *buf++;
406 if(id & WP_IDF_LONG) {
407 size |= (*buf++) << 8;
408 size |= (*buf++) << 16;
410 size <<= 1; // size is specified in words
411 ssize = size;
412 if(id & WP_IDF_ODD) size--;
413 if(size < 0){
414 av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size);
415 break;
417 if(buf + ssize > buf_end){
418 av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size);
419 break;
421 if(id & WP_IDF_IGNORE){
422 buf += ssize;
423 continue;
425 switch(id & WP_IDF_MASK){
426 case WP_ID_DECTERMS:
427 s->terms = size;
428 if(s->terms > MAX_TERMS){
429 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
430 buf += ssize;
431 continue;
433 for(i = 0; i < s->terms; i++) {
434 s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5;
435 s->decorr[s->terms - i - 1].delta = *buf >> 5;
436 buf++;
438 got_terms = 1;
439 break;
440 case WP_ID_DECWEIGHTS:
441 if(!got_terms){
442 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
443 continue;
445 weights = size >> s->stereo_in;
446 if(weights > MAX_TERMS || weights > s->terms){
447 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
448 buf += ssize;
449 continue;
451 for(i = 0; i < weights; i++) {
452 t = (int8_t)(*buf++);
453 s->decorr[s->terms - i - 1].weightA = t << 3;
454 if(s->decorr[s->terms - i - 1].weightA > 0)
455 s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
456 if(s->stereo_in){
457 t = (int8_t)(*buf++);
458 s->decorr[s->terms - i - 1].weightB = t << 3;
459 if(s->decorr[s->terms - i - 1].weightB > 0)
460 s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
463 got_weights = 1;
464 break;
465 case WP_ID_DECSAMPLES:
466 if(!got_terms){
467 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
468 continue;
470 t = 0;
471 for(i = s->terms - 1; (i >= 0) && (t < size); i--) {
472 if(s->decorr[i].value > 8){
473 s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
474 s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2;
475 if(s->stereo_in){
476 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
477 s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2;
478 t += 4;
480 t += 4;
481 }else if(s->decorr[i].value < 0){
482 s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
483 s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
484 t += 4;
485 }else{
486 for(j = 0; j < s->decorr[i].value; j++){
487 s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;
488 if(s->stereo_in){
489 s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
492 t += s->decorr[i].value * 2 * (s->stereo_in + 1);
495 got_samples = 1;
496 break;
497 case WP_ID_ENTROPY:
498 if(size != 6 * (s->stereo_in + 1)){
499 av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size);
500 buf += ssize;
501 continue;
503 for(i = 0; i < 3 * (s->stereo_in + 1); i++){
504 s->median[i] = wp_exp2(AV_RL16(buf));
505 buf += 2;
507 got_entropy = 1;
508 break;
509 case WP_ID_INT32INFO:
510 if(size != 4 || *buf){
511 av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf);
512 buf += ssize;
513 continue;
515 if(buf[1])
516 s->shift = buf[1];
517 else if(buf[2]){
518 s->and = s->or = 1;
519 s->shift = buf[2];
520 }else if(buf[3]){
521 s->and = 1;
522 s->shift = buf[3];
524 buf += 4;
525 break;
526 case WP_ID_DATA:
527 init_get_bits(&s->gb, buf, size * 8);
528 s->data_size = size * 8;
529 buf += size;
530 got_bs = 1;
531 break;
532 default:
533 buf += size;
535 if(id & WP_IDF_ODD) buf++;
537 if(!got_terms){
538 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
539 return -1;
541 if(!got_weights){
542 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
543 return -1;
545 if(!got_samples){
546 av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
547 return -1;
549 if(!got_entropy){
550 av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
551 return -1;
553 if(!got_bs){
554 av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
555 return -1;
558 if(s->stereo_in)
559 samplecount = wv_unpack_stereo(s, &s->gb, samples);
560 else{
561 samplecount = wv_unpack_mono(s, &s->gb, samples);
562 if(s->stereo){
563 int16_t *dst = samples + samplecount * 2;
564 int16_t *src = samples + samplecount;
565 int cnt = samplecount;
566 while(cnt--){
567 *--dst = *--src;
568 *--dst = *src;
570 samplecount *= 2;
573 *data_size = samplecount * 2;
575 return buf_size;
578 AVCodec wavpack_decoder = {
579 "wavpack",
580 CODEC_TYPE_AUDIO,
581 CODEC_ID_WAVPACK,
582 sizeof(WavpackContext),
583 wavpack_decode_init,
584 NULL,
585 NULL,
586 wavpack_decode_frame,
587 .long_name = NULL_IF_CONFIG_SMALL("WavPack"),