]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/wavpack.c
move get_unary() to it's own file
[frescor/ffmpeg.git] / libavcodec / wavpack.c
1 /*
2  * WavPack lossless audio decoder
3  * Copyright (c) 2006 Konstantin Shishkov
4  *
5  * This file is part of FFmpeg.
6  *
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.
11  *
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.
16  *
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
20  */
21 #define ALT_BITSTREAM_READER_LE
22 #include "avcodec.h"
23 #include "bitstream.h"
24 #include "unary.h"
25
26 /**
27  * @file wavpack.c
28  * WavPack lossless audio decoder
29  */
30
31 #define WV_JOINT_STEREO 0x00000010
32 #define WV_FALSE_STEREO 0x40000000
33
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
39 };
40
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
56 };
57
58 #define MAX_TERMS 16
59
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;
68
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;
83
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
102 };
103
104 static av_always_inline int wp_exp2(int16_t val)
105 {
106     int res, neg = 0;
107
108     if(val < 0){
109         val = -val;
110         neg = 1;
111     }
112
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;
117 }
118
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
123
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; \
133             } \
134         }
135
136
137 static av_always_inline int get_tail(GetBitContext *gb, int k)
138 {
139     int p, e, res;
140
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);
147     }
148     return res;
149 }
150
151 static int wv_get_value(WavpackContext *ctx, GetBitContext *gb, int *median, int *last)
152 {
153     int t, t2;
154     int sign, base, add, ret;
155
156     *last = 0;
157
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(gb, 0, 33);
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;
170             }
171         }
172     }
173
174     if(get_bits_count(gb) >= ctx->data_size){
175         *last = 1;
176         return 0;
177     }
178
179     if(ctx->zero){
180         t = 0;
181         ctx->zero = 0;
182     }else{
183         t = get_unary(gb, 0, 33);
184         if(get_bits_count(gb) >= ctx->data_size){
185             *last = 1;
186             return 0;
187         }
188         if(t == 16) {
189             t2 = get_unary(gb, 0, 33);
190             if(t2 < 2) t += t2;
191             else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1));
192         }
193
194         if(ctx->one){
195             ctx->one = t&1;
196             t = (t>>1) + 1;
197         }else{
198             ctx->one = t&1;
199             t >>= 1;
200         }
201         ctx->zero = !ctx->one;
202     }
203
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);
225     }
226     ret = base + get_tail(gb, add);
227     sign = get_bits1(gb);
228     return sign ? ~ret : ret;
229 }
230
231 static int wv_unpack_stereo(WavpackContext *s, GetBitContext *gb, int16_t *dst)
232 {
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;
238
239     s->one = s->zero = s->zeroes = 0;
240     do{
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;
256                     }
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;
264                 }
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;
283
284                 if(t == -3){
285                     R2 = s->decorr[i].samplesA[0];
286                     s->decorr[i].samplesA[0] = R;
287                 }
288
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;
293             }
294         }
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);
305
306     if(crc != s->CRC){
307         av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
308         return -1;
309     }
310     return count * 2;
311 }
312
313 static int wv_unpack_mono(WavpackContext *s, GetBitContext *gb, int16_t *dst)
314 {
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;
320
321     s->one = s->zero = s->zeroes = 0;
322     do{
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;
338             }
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;
342         }
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);
349
350     if(crc != s->CRC){
351         av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
352         return -1;
353     }
354     return count;
355 }
356
357 static int wavpack_decode_init(AVCodecContext *avctx)
358 {
359     WavpackContext *s = avctx->priv_data;
360
361     s->avctx = avctx;
362     s->stereo = (avctx->channels == 2);
363
364     return 0;
365 }
366
367 static int wavpack_decode_close(AVCodecContext *avctx)
368 {
369 //    WavpackContext *s = avctx->priv_data;
370
371     return 0;
372 }
373
374 static int wavpack_decode_frame(AVCodecContext *avctx,
375                             void *data, int *data_size,
376                             uint8_t *buf, int buf_size)
377 {
378     WavpackContext *s = avctx->priv_data;
379     int16_t *samples = data;
380     int samplecount;
381     int got_terms = 0, got_weights = 0, got_samples = 0, got_entropy = 0, got_bs = 0;
382     uint8_t* buf_end = buf + buf_size;
383     int i, j, id, size, ssize, weights, t;
384
385     if (buf_size == 0){
386         *data_size = 0;
387         return 0;
388     }
389
390     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
391     memset(s->median, 0, sizeof(s->median));
392     s->and = s->or = s->shift = 0;
393
394     s->samples = AV_RL32(buf); buf += 4;
395     if(!s->samples){
396         *data_size = 0;
397         return buf_size;
398     }
399     /* should not happen but who knows */
400     if(s->samples * 2 * avctx->channels > *data_size){
401         av_log(avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc!\n");
402         return -1;
403     }
404     s->stereo_in = (AV_RL32(buf) & WV_FALSE_STEREO) ? 0 : s->stereo;
405     s->joint = AV_RL32(buf) & WV_JOINT_STEREO; buf += 4;
406     s->CRC = AV_RL32(buf); buf += 4;
407     // parse metadata blocks
408     while(buf < buf_end){
409         id = *buf++;
410         size = *buf++;
411         if(id & WP_IDF_LONG) {
412             size |= (*buf++) << 8;
413             size |= (*buf++) << 16;
414         }
415         size <<= 1; // size is specified in words
416         ssize = size;
417         if(id & WP_IDF_ODD) size--;
418         if(size < 0){
419             av_log(avctx, AV_LOG_ERROR, "Got incorrect block %02X with size %i\n", id, size);
420             break;
421         }
422         if(buf + ssize > buf_end){
423             av_log(avctx, AV_LOG_ERROR, "Block size %i is out of bounds\n", size);
424             break;
425         }
426         if(id & WP_IDF_IGNORE){
427             buf += ssize;
428             continue;
429         }
430         switch(id & WP_IDF_MASK){
431         case WP_ID_DECTERMS:
432             s->terms = size;
433             if(s->terms > MAX_TERMS){
434                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
435                 buf += ssize;
436                 continue;
437             }
438             for(i = 0; i < s->terms; i++) {
439                 s->decorr[s->terms - i - 1].value = (*buf & 0x1F) - 5;
440                 s->decorr[s->terms - i - 1].delta = *buf >> 5;
441                 buf++;
442             }
443             got_terms = 1;
444             break;
445         case WP_ID_DECWEIGHTS:
446             if(!got_terms){
447                 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
448                 continue;
449             }
450             weights = size >> s->stereo_in;
451             if(weights > MAX_TERMS || weights > s->terms){
452                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
453                 buf += ssize;
454                 continue;
455             }
456             for(i = 0; i < weights; i++) {
457                 t = (int8_t)(*buf++);
458                 s->decorr[s->terms - i - 1].weightA = t << 3;
459                 if(s->decorr[s->terms - i - 1].weightA > 0)
460                     s->decorr[s->terms - i - 1].weightA += (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
461                 if(s->stereo_in){
462                     t = (int8_t)(*buf++);
463                     s->decorr[s->terms - i - 1].weightB = t << 3;
464                     if(s->decorr[s->terms - i - 1].weightB > 0)
465                         s->decorr[s->terms - i - 1].weightB += (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
466                 }
467             }
468             got_weights = 1;
469             break;
470         case WP_ID_DECSAMPLES:
471             if(!got_terms){
472                 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
473                 continue;
474             }
475             t = 0;
476             for(i = s->terms - 1; (i >= 0) && (t < size); i--) {
477                 if(s->decorr[i].value > 8){
478                     s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
479                     s->decorr[i].samplesA[1] = wp_exp2(AV_RL16(buf)); buf += 2;
480                     if(s->stereo_in){
481                         s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
482                         s->decorr[i].samplesB[1] = wp_exp2(AV_RL16(buf)); buf += 2;
483                         t += 4;
484                     }
485                     t += 4;
486                 }else if(s->decorr[i].value < 0){
487                     s->decorr[i].samplesA[0] = wp_exp2(AV_RL16(buf)); buf += 2;
488                     s->decorr[i].samplesB[0] = wp_exp2(AV_RL16(buf)); buf += 2;
489                     t += 4;
490                 }else{
491                     for(j = 0; j < s->decorr[i].value; j++){
492                         s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;
493                         if(s->stereo_in){
494                             s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
495                         }
496                     }
497                     t += s->decorr[i].value * 2 * (s->stereo_in + 1);
498                 }
499             }
500             got_samples = 1;
501             break;
502         case WP_ID_ENTROPY:
503             if(size != 6 * (s->stereo_in + 1)){
504                 av_log(avctx, AV_LOG_ERROR, "Entropy vars size should be %i, got %i", 6 * (s->stereo_in + 1), size);
505                 buf += ssize;
506                 continue;
507             }
508             for(i = 0; i < 3 * (s->stereo_in + 1); i++){
509                 s->median[i] = wp_exp2(AV_RL16(buf));
510                 buf += 2;
511             }
512             got_entropy = 1;
513             break;
514         case WP_ID_INT32INFO:
515             if(size != 4 || *buf){
516                 av_log(avctx, AV_LOG_ERROR, "Invalid INT32INFO, size = %i, sent_bits = %i\n", size, *buf);
517                 buf += ssize;
518                 continue;
519             }
520             if(buf[1])
521                 s->shift = buf[1];
522             else if(buf[2]){
523                 s->and = s->or = 1;
524                 s->shift = buf[2];
525             }else if(buf[3]){
526                 s->and = 1;
527                 s->shift = buf[3];
528             }
529             buf += 4;
530             break;
531         case WP_ID_DATA:
532             init_get_bits(&s->gb, buf, size * 8);
533             s->data_size = size * 8;
534             buf += size;
535             got_bs = 1;
536             break;
537         default:
538             buf += size;
539         }
540         if(id & WP_IDF_ODD) buf++;
541     }
542     if(!got_terms){
543         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
544         return -1;
545     }
546     if(!got_weights){
547         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
548         return -1;
549     }
550     if(!got_samples){
551         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
552         return -1;
553     }
554     if(!got_entropy){
555         av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
556         return -1;
557     }
558     if(!got_bs){
559         av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
560         return -1;
561     }
562
563     if(s->stereo_in)
564         samplecount = wv_unpack_stereo(s, &s->gb, samples);
565     else{
566         samplecount = wv_unpack_mono(s, &s->gb, samples);
567         if(s->stereo){
568             int16_t *dst = samples + samplecount * 2;
569             int16_t *src = samples + samplecount;
570             int cnt = samplecount;
571             while(cnt--){
572                 *--dst = *--src;
573                 *--dst = *src;
574             }
575             samplecount *= 2;
576         }
577     }
578     *data_size = samplecount * 2;
579
580     return buf_size;
581 }
582
583 AVCodec wavpack_decoder = {
584     "wavpack",
585     CODEC_TYPE_AUDIO,
586     CODEC_ID_WAVPACK,
587     sizeof(WavpackContext),
588     wavpack_decode_init,
589     NULL,
590     wavpack_decode_close,
591     wavpack_decode_frame,
592 };