libavcodec/wavpack.c
730581f3
 /*
  * WavPack lossless audio decoder
8a485dd3
  * Copyright (c) 2006,2011 Konstantin Shishkov
730581f3
  *
b78e7197
  * This file is part of FFmpeg.
  *
  * FFmpeg is free software; you can redistribute it and/or
730581f3
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
b78e7197
  * version 2.1 of the License, or (at your option) any later version.
730581f3
  *
b78e7197
  * FFmpeg is distributed in the hope that it will be useful,
730581f3
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
b78e7197
  * License along with FFmpeg; if not, write to the Free Software
730581f3
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
513c238f
 
a903f8f0
 #include "libavutil/channel_layout.h"
b6686629
 
 #define BITSTREAM_READER_LE
730581f3
 #include "avcodec.h"
b6686629
 #include "bytestream.h"
9106a698
 #include "get_bits.h"
594d4d5d
 #include "internal.h"
9684d7f1
 #include "thread.h"
28296f9c
 #include "unary.h"
93f42777
 #include "wavpack.h"
730581f3
 
 /**
ba87f080
  * @file
730581f3
  * WavPack lossless audio decoder
  */
 
965828bb
 typedef struct SavedContext {
     int offset;
     int size;
     int bits_used;
     uint32_t crc;
 } SavedContext;
 
8a485dd3
 typedef struct WavpackFrameContext {
730581f3
     AVCodecContext *avctx;
2c96535a
     int frame_flags;
a6ba65f7
     int stereo, stereo_in;
730581f3
     int joint;
     uint32_t CRC;
     GetBitContext gb;
418f77ec
     int got_extra_bits;
     uint32_t crc_extra_bits;
     GetBitContext gb_extra_bits;
730581f3
     int data_size; // in bits
     int samples;
     int terms;
     Decorr decorr[MAX_TERMS];
     int zero, one, zeroes;
418f77ec
     int extra_bits;
6b05eb31
     int and, or, shift;
760db32a
     int post_shift;
32e74395
     int hybrid, hybrid_bitrate;
     int hybrid_maxclip, hybrid_minclip;
992f7db0
     int float_flag;
     int float_shift;
     int float_max_exp;
2c96535a
     WvChannel ch[2];
965828bb
     int pos;
     SavedContext sc, extra_sc;
8a485dd3
 } WavpackFrameContext;
 
 #define WV_MAX_FRAME_DECODERS 14
 
 typedef struct WavpackContext {
     AVCodecContext *avctx;
 
     WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
     int fdec_num;
 
     int block;
     int samples;
     int ch_offset;
730581f3
 } WavpackContext;
 
28bf1115
 #define LEVEL_DECAY(a)  (((a) + 0x80) >> 8)
2c96535a
 
4fa20782
 static av_always_inline unsigned get_tail(GetBitContext *gb, int k)
730581f3
 {
     int p, e, res;
 
513c238f
     if (k < 1)
         return 0;
0f689a3d
     p   = av_log2(k);
     e   = (1 << (p + 1)) - k - 1;
43ff4aed
     res = get_bitsz(gb, p);
513c238f
     if (res >= e)
         res = (res << 1) - e + get_bits1(gb);
730581f3
     return res;
 }
 
d03d3861
 static int update_error_limit(WavpackFrameContext *ctx)
2c96535a
 {
     int i, br[2], sl[2];
 
513c238f
     for (i = 0; i <= ctx->stereo_in; i++) {
d03d3861
         if (ctx->ch[i].bitrate_acc > UINT_MAX - ctx->ch[i].bitrate_delta)
             return AVERROR_INVALIDDATA;
2c96535a
         ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;
0f689a3d
         br[i]                   = ctx->ch[i].bitrate_acc >> 16;
         sl[i]                   = LEVEL_DECAY(ctx->ch[i].slow_level);
2c96535a
     }
513c238f
     if (ctx->stereo_in && ctx->hybrid_bitrate) {
2c96535a
         int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;
513c238f
         if (balance > br[0]) {
ea71a48c
             br[1] = br[0] * 2;
2c96535a
             br[0] = 0;
513c238f
         } else if (-balance > br[0]) {
ea71a48c
             br[0]  *= 2;
0f689a3d
             br[1]   = 0;
513c238f
         } else {
2c96535a
             br[1] = br[0] + balance;
             br[0] = br[0] - balance;
         }
     }
513c238f
     for (i = 0; i <= ctx->stereo_in; i++) {
         if (ctx->hybrid_bitrate) {
             if (sl[i] - br[i] > -0x100)
2c96535a
                 ctx->ch[i].error_limit = wp_exp2(sl[i] - br[i] + 0x100);
             else
                 ctx->ch[i].error_limit = 0;
513c238f
         } else {
2c96535a
             ctx->ch[i].error_limit = wp_exp2(br[i]);
         }
     }
d03d3861
 
     return 0;
2c96535a
 }
 
513c238f
 static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
                         int channel, int *last)
730581f3
 {
     int t, t2;
     int sign, base, add, ret;
2c96535a
     WvChannel *c = &ctx->ch[channel];
730581f3
 
     *last = 0;
 
513c238f
     if ((ctx->ch[0].median[0] < 2U) && (ctx->ch[1].median[0] < 2U) &&
         !ctx->zero && !ctx->one) {
         if (ctx->zeroes) {
730581f3
             ctx->zeroes--;
513c238f
             if (ctx->zeroes) {
2c96535a
                 c->slow_level -= LEVEL_DECAY(c->slow_level);
730581f3
                 return 0;
2c96535a
             }
513c238f
         } else {
ca1daf0a
             t = get_unary_0_33(gb);
513c238f
             if (t >= 2) {
fc4f8837
                 if (t >= 32 || get_bits_left(gb) < t - 1)
55354b7d
                     goto error;
f9883a66
                 t = get_bits_long(gb, t - 1) | (1 << (t - 1));
513c238f
             } else {
                 if (get_bits_left(gb) < 0)
55354b7d
                     goto error;
             }
730581f3
             ctx->zeroes = t;
513c238f
             if (ctx->zeroes) {
2c96535a
                 memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median));
                 memset(ctx->ch[1].median, 0, sizeof(ctx->ch[1].median));
                 c->slow_level -= LEVEL_DECAY(c->slow_level);
730581f3
                 return 0;
             }
         }
     }
 
513c238f
     if (ctx->zero) {
0f689a3d
         t         = 0;
730581f3
         ctx->zero = 0;
513c238f
     } else {
ca1daf0a
         t = get_unary_0_33(gb);
513c238f
         if (get_bits_left(gb) < 0)
55354b7d
             goto error;
513c238f
         if (t == 16) {
ca1daf0a
             t2 = get_unary_0_33(gb);
513c238f
             if (t2 < 2) {
                 if (get_bits_left(gb) < 0)
55354b7d
                     goto error;
                 t += t2;
513c238f
             } else {
8b3e580b
                 if (t2 >= 32 || get_bits_left(gb) < t2 - 1)
55354b7d
                     goto error;
f9883a66
                 t += get_bits_long(gb, t2 - 1) | (1 << (t2 - 1));
55354b7d
             }
730581f3
         }
 
513c238f
         if (ctx->one) {
             ctx->one = t & 1;
0f689a3d
             t        = (t >> 1) + 1;
513c238f
         } else {
             ctx->one = t & 1;
0f689a3d
             t      >>= 1;
730581f3
         }
         ctx->zero = !ctx->one;
     }
 
d03d3861
     if (ctx->hybrid && !channel) {
         if (update_error_limit(ctx) < 0)
             goto error;
     }
2c96535a
 
513c238f
     if (!t) {
730581f3
         base = 0;
513c238f
         add  = GET_MED(0) - 1;
730581f3
         DEC_MED(0);
513c238f
     } else if (t == 1) {
730581f3
         base = GET_MED(0);
513c238f
         add  = GET_MED(1) - 1;
730581f3
         INC_MED(0);
         DEC_MED(1);
513c238f
     } else if (t == 2) {
730581f3
         base = GET_MED(0) + GET_MED(1);
513c238f
         add  = GET_MED(2) - 1;
730581f3
         INC_MED(0);
         INC_MED(1);
         DEC_MED(2);
513c238f
     } else {
24e95f9d
         base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2U);
513c238f
         add  = GET_MED(2) - 1;
730581f3
         INC_MED(0);
         INC_MED(1);
         INC_MED(2);
     }
513c238f
     if (!c->error_limit) {
c6831e2a
         if (add >= 0x2000000U) {
             av_log(ctx->avctx, AV_LOG_ERROR, "k %d is too large\n", add);
             goto error;
         }
2c96535a
         ret = base + get_tail(gb, add);
55354b7d
         if (get_bits_left(gb) <= 0)
             goto error;
513c238f
     } else {
aaeec1c6
         int mid = (base * 2U + add + 1) >> 1;
513c238f
         while (add > c->error_limit) {
             if (get_bits_left(gb) <= 0)
55354b7d
                 goto error;
513c238f
             if (get_bits1(gb)) {
a47273c8
                 add -= (mid - (unsigned)base);
2c96535a
                 base = mid;
513c238f
             } else
e2bbb95d
                 add = mid - (unsigned)base - 1;
aaeec1c6
             mid = (base * 2U + add + 1) >> 1;
2c96535a
         }
         ret = mid;
     }
730581f3
     sign = get_bits1(gb);
513c238f
     if (ctx->hybrid_bitrate)
2c96535a
         c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level);
730581f3
     return sign ? ~ret : ret;
55354b7d
 
 error:
11a39bdf
     ret = get_bits_left(gb);
     if (ret <= 0) {
         av_log(ctx->avctx, AV_LOG_ERROR, "Too few bits (%d) left\n", ret);
     }
55354b7d
     *last = 1;
     return 0;
730581f3
 }
 
513c238f
 static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc,
58e9c7f4
                                        unsigned S)
3cb08886
 {
58f3469c
     unsigned bit;
3cb08886
 
0f689a3d
     if (s->extra_bits) {
3016e919
         S *= 1 << s->extra_bits;
3cb08886
 
0f689a3d
         if (s->got_extra_bits &&
             get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
d0eff885
             S   |= get_bits_long(&s->gb_extra_bits, s->extra_bits);
513c238f
             *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16);
3cb08886
         }
     }
a548b6cb
 
3cb08886
     bit = (S & s->and) | s->or;
32e74395
     bit = ((S + bit) << s->shift) - bit;
a548b6cb
 
513c238f
     if (s->hybrid)
32e74395
         bit = av_clip(bit, s->hybrid_minclip, s->hybrid_maxclip);
a548b6cb
 
e6e7bfc1
     return bit << s->post_shift;
3cb08886
 }
 
8a485dd3
 static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
992f7db0
 {
     union {
         float    f;
         uint32_t u;
     } value;
 
83c418e6
     unsigned int sign;
992f7db0
     int exp = s->float_max_exp;
 
513c238f
     if (s->got_extra_bits) {
         const int max_bits  = 1 + 23 + 8 + 1;
6e44ba15
         const int left_bits = get_bits_left(&s->gb_extra_bits);
992f7db0
 
059a9348
         if (left_bits + 8 * AV_INPUT_BUFFER_PADDING_SIZE < max_bits)
992f7db0
             return 0.0;
     }
 
513c238f
     if (S) {
c51357d2
         S  *= 1U << s->float_shift;
992f7db0
         sign = S < 0;
513c238f
         if (sign)
5f897470
             S = -(unsigned)S;
         if (S >= 0x1000000U) {
513c238f
             if (s->got_extra_bits && get_bits1(&s->gb_extra_bits))
992f7db0
                 S = get_bits(&s->gb_extra_bits, 23);
513c238f
             else
992f7db0
                 S = 0;
             exp = 255;
513c238f
         } else if (exp) {
992f7db0
             int shift = 23 - av_log2(S);
             exp = s->float_max_exp;
513c238f
             if (exp <= shift)
992f7db0
                 shift = --exp;
             exp -= shift;
 
513c238f
             if (shift) {
992f7db0
                 S <<= shift;
513c238f
                 if ((s->float_flag & WV_FLT_SHIFT_ONES) ||
0f689a3d
                     (s->got_extra_bits &&
                      (s->float_flag & WV_FLT_SHIFT_SAME) &&
513c238f
                      get_bits1(&s->gb_extra_bits))) {
992f7db0
                     S |= (1 << shift) - 1;
513c238f
                 } else if (s->got_extra_bits &&
                            (s->float_flag & WV_FLT_SHIFT_SENT)) {
992f7db0
                     S |= get_bits(&s->gb_extra_bits, shift);
                 }
             }
513c238f
         } else {
992f7db0
             exp = s->float_max_exp;
         }
         S &= 0x7fffff;
513c238f
     } else {
992f7db0
         sign = 0;
0f689a3d
         exp  = 0;
513c238f
         if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) {
             if (get_bits1(&s->gb_extra_bits)) {
992f7db0
                 S = get_bits(&s->gb_extra_bits, 23);
513c238f
                 if (s->float_max_exp >= 25)
992f7db0
                     exp = get_bits(&s->gb_extra_bits, 8);
                 sign = get_bits1(&s->gb_extra_bits);
513c238f
             } else {
                 if (s->float_flag & WV_FLT_ZERO_SIGN)
992f7db0
                     sign = get_bits1(&s->gb_extra_bits);
             }
         }
     }
 
     *crc = *crc * 27 + S * 9 + exp * 3 + sign;
 
     value.u = (sign << 31) | (exp << 23) | S;
     return value.f;
 }
 
8a485dd3
 static void wv_reset_saved_context(WavpackFrameContext *s)
965828bb
 {
0f689a3d
     s->pos    = 0;
965828bb
     s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
 }
 
c388558d
 static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc,
                                uint32_t crc_extra_bits)
 {
     if (crc != s->CRC) {
         av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
         return AVERROR_INVALIDDATA;
     }
     if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
         av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
         return AVERROR_INVALIDDATA;
     }
 
     return 0;
 }
 
513c238f
 static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
528daa39
                                    void *dst_l, void *dst_r, const int type)
730581f3
 {
     int i, j, count = 0;
     int last, t;
3cb08886
     int A, B, L, L2, R, R2;
0f689a3d
     int pos                 = s->pos;
     uint32_t crc            = s->sc.crc;
965828bb
     uint32_t crc_extra_bits = s->extra_sc.crc;
528daa39
     int16_t *dst16_l        = dst_l;
     int16_t *dst16_r        = dst_r;
     int32_t *dst32_l        = dst_l;
     int32_t *dst32_r        = dst_r;
     float *dstfl_l          = dst_l;
     float *dstfl_r          = dst_r;
730581f3
 
0eea2129
     s->one = s->zero = s->zeroes = 0;
513c238f
     do {
2c96535a
         L = wv_get_value(s, gb, 0, &last);
513c238f
         if (last)
             break;
2c96535a
         R = wv_get_value(s, gb, 1, &last);
513c238f
         if (last)
             break;
         for (i = 0; i < s->terms; i++) {
730581f3
             t = s->decorr[i].value;
513c238f
             if (t > 0) {
                 if (t > 8) {
                     if (t & 1) {
58e9c7f4
                         A = 2U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
                         B = 2U * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1];
513c238f
                     } else {
58e9c7f4
                         A = (int)(3U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
                         B = (int)(3U * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1;
730581f3
                     }
                     s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
                     s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
0f689a3d
                     j                        = 0;
513c238f
                 } else {
730581f3
                     A = s->decorr[i].samplesA[pos];
                     B = s->decorr[i].samplesB[pos];
                     j = (pos + t) & 7;
                 }
528daa39
                 if (type != AV_SAMPLE_FMT_S16P) {
29ee6355
                     L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
                     R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
513c238f
                 } else {
83e34ae3
                     L2 = L + (unsigned)((int)(s->decorr[i].weightA * (unsigned)A + 512) >> 10);
                     R2 = R + (unsigned)((int)(s->decorr[i].weightB * (unsigned)B + 512) >> 10);
0638c2ae
                 }
0f689a3d
                 if (A && L)
                     s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
                 if (B && R)
                     s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
0638c2ae
                 s->decorr[i].samplesA[j] = L = L2;
                 s->decorr[i].samplesB[j] = R = R2;
513c238f
             } else if (t == -1) {
528daa39
                 if (type != AV_SAMPLE_FMT_S16P)
29ee6355
                     L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
                 else
83e34ae3
                     L2 = L + (unsigned)((int)(s->decorr[i].weightA * (unsigned)s->decorr[i].samplesA[0] + 512) >> 10);
0638c2ae
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
                 L = L2;
528daa39
                 if (type != AV_SAMPLE_FMT_S16P)
29ee6355
                     R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
                 else
57bb78d9
                     R2 = R + (unsigned)((int)(s->decorr[i].weightB * (unsigned)L2 + 512) >> 10);
0638c2ae
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
0f689a3d
                 R                        = R2;
0638c2ae
                 s->decorr[i].samplesA[0] = R;
513c238f
             } else {
528daa39
                 if (type != AV_SAMPLE_FMT_S16P)
29ee6355
                     R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
                 else
83e34ae3
                     R2 = R + (unsigned)((int)(s->decorr[i].weightB * (unsigned)s->decorr[i].samplesB[0] + 512) >> 10);
0638c2ae
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R);
                 R = R2;
 
513c238f
                 if (t == -3) {
0f689a3d
                     R2                       = s->decorr[i].samplesA[0];
0638c2ae
                     s->decorr[i].samplesA[0] = R;
                 }
 
528daa39
                 if (type != AV_SAMPLE_FMT_S16P)
29ee6355
                     L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
                 else
83e34ae3
                     L2 = L + (unsigned)((int)(s->decorr[i].weightA * (unsigned)R2 + 512) >> 10);
0638c2ae
                 UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
0f689a3d
                 L                        = L2;
0638c2ae
                 s->decorr[i].samplesB[0] = L;
             }
         }
042260cd
 
         if (type == AV_SAMPLE_FMT_S16P) {
8e50bd61
             if (FFABS((int64_t)L) + FFABS((int64_t)R) > (1<<19)) {
042260cd
                 av_log(s->avctx, AV_LOG_ERROR, "sample %d %d too large\n", L, R);
                 return AVERROR_INVALIDDATA;
             }
         }
 
0638c2ae
         pos = (pos + 1) & 7;
513c238f
         if (s->joint)
58e9c7f4
             L += (unsigned)(R -= (unsigned)(L >> 1));
0638c2ae
         crc = (crc * 3 + L) * 3 + R;
418f77ec
 
528daa39
         if (type == AV_SAMPLE_FMT_FLTP) {
             *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
             *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
         } else if (type == AV_SAMPLE_FMT_S32P) {
             *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
             *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
3cb08886
         } else {
528daa39
             *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
             *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
418f77ec
         }
0638c2ae
         count++;
0eea2129
     } while (!last && count < s->samples);
0638c2ae
 
513c238f
     wv_reset_saved_context(s);
866c44d4
 
     if (last && count < s->samples) {
         int size = av_get_bytes_per_sample(type);
95953c1c
         memset((uint8_t*)dst_l + count*size, 0, (s->samples-count)*size);
         memset((uint8_t*)dst_r + count*size, 0, (s->samples-count)*size);
866c44d4
     }
 
c388558d
     if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
         wv_check_crc(s, crc, crc_extra_bits))
         return AVERROR_INVALIDDATA;
0eea2129
 
474fb0c9
     return 0;
0638c2ae
 }
 
513c238f
 static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
                                  void *dst, const int type)
0638c2ae
 {
     int i, j, count = 0;
     int last, t;
3cb08886
     int A, S, T;
0f689a3d
     int pos                  = s->pos;
     uint32_t crc             = s->sc.crc;
     uint32_t crc_extra_bits  = s->extra_sc.crc;
     int16_t *dst16           = dst;
     int32_t *dst32           = dst;
     float *dstfl             = dst;
0638c2ae
 
0eea2129
     s->one = s->zero = s->zeroes = 0;
513c238f
     do {
0638c2ae
         T = wv_get_value(s, gb, 0, &last);
         S = 0;
513c238f
         if (last)
             break;
         for (i = 0; i < s->terms; i++) {
0638c2ae
             t = s->decorr[i].value;
513c238f
             if (t > 8) {
                 if (t & 1)
5f91786f
                     A =  2U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
0638c2ae
                 else
5f91786f
                     A = (int)(3U * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
0638c2ae
                 s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
0f689a3d
                 j                        = 0;
513c238f
             } else {
0638c2ae
                 A = s->decorr[i].samplesA[pos];
                 j = (pos + t) & 7;
             }
528daa39
             if (type != AV_SAMPLE_FMT_S16P)
29ee6355
                 S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
             else
83e34ae3
                 S = T + (unsigned)((int)(s->decorr[i].weightA * (unsigned)A + 512) >> 10);
513c238f
             if (A && T)
                 s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
0638c2ae
             s->decorr[i].samplesA[j] = T = S;
         }
         pos = (pos + 1) & 7;
         crc = crc * 3 + S;
418f77ec
 
528daa39
         if (type == AV_SAMPLE_FMT_FLTP) {
             *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S);
         } else if (type == AV_SAMPLE_FMT_S32P) {
             *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S);
513c238f
         } else {
528daa39
             *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S);
8a485dd3
         }
0638c2ae
         count++;
0eea2129
     } while (!last && count < s->samples);
0638c2ae
 
513c238f
     wv_reset_saved_context(s);
866c44d4
 
     if (last && count < s->samples) {
         int size = av_get_bytes_per_sample(type);
95953c1c
         memset((uint8_t*)dst + count*size, 0, (s->samples-count)*size);
866c44d4
     }
 
23a211cb
     if (s->avctx->err_recognition & AV_EF_CRCCHECK) {
         int ret = wv_check_crc(s, crc, crc_extra_bits);
         if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
             return ret;
     }
0eea2129
 
474fb0c9
     return 0;
0638c2ae
 }
 
8a485dd3
 static av_cold int wv_alloc_frame_context(WavpackContext *c)
 {
513c238f
     if (c->fdec_num == WV_MAX_FRAME_DECODERS)
8a485dd3
         return -1;
 
     c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
513c238f
     if (!c->fdec[c->fdec_num])
8a485dd3
         return -1;
     c->fdec_num++;
     c->fdec[c->fdec_num - 1]->avctx = c->avctx;
     wv_reset_saved_context(c->fdec[c->fdec_num - 1]);
 
     return 0;
 }
 
2cbaa078
 #if HAVE_THREADS
ff0bdf93
 static int init_thread_copy(AVCodecContext *avctx)
 {
     WavpackContext *s = avctx->priv_data;
     s->avctx = avctx;
     return 0;
 }
2cbaa078
 #endif
ff0bdf93
 
98a6fff9
 static av_cold int wavpack_decode_init(AVCodecContext *avctx)
730581f3
 {
     WavpackContext *s = avctx->priv_data;
 
     s->avctx = avctx;
72dee5f4
 
8a485dd3
     s->fdec_num = 0;
965828bb
 
730581f3
     return 0;
 }
 
8a485dd3
 static av_cold int wavpack_decode_end(AVCodecContext *avctx)
730581f3
 {
     WavpackContext *s = avctx->priv_data;
8a485dd3
     int i;
 
513c238f
     for (i = 0; i < s->fdec_num; i++)
8a485dd3
         av_freep(&s->fdec[i]);
     s->fdec_num = 0;
 
     return 0;
 }
 
 static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
78f75b6f
                                 AVFrame *frame, const uint8_t *buf, int buf_size)
8a485dd3
 {
     WavpackContext *wc = avctx->priv_data;
9684d7f1
     ThreadFrame tframe = { .f = frame };
8a485dd3
     WavpackFrameContext *s;
3f0b6d7a
     GetByteContext gb;
32646389
     void *samples_l = NULL, *samples_r = NULL;
474fb0c9
     int ret;
513c238f
     int got_terms   = 0, got_weights = 0, got_samples = 0,
3a1867de
         got_entropy = 0, got_bs      = 0, got_float   = 0, got_hybrid = 0;
730581f3
     int i, j, id, size, ssize, weights, t;
7d039e70
     int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;
     int multiblock;
730581f3
 
513c238f
     if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {
8a485dd3
         av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");
8c345581
         return AVERROR_INVALIDDATA;
8a485dd3
     }
 
     s = wc->fdec[block_no];
513c238f
     if (!s) {
0f689a3d
         av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",
                block_no);
8c345581
         return AVERROR_INVALIDDATA;
8a485dd3
     }
 
513c238f
     memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
     memset(s->ch, 0, sizeof(s->ch));
0f689a3d
     s->extra_bits     = 0;
     s->and            = s->or = s->shift = 0;
513c238f
     s->got_extra_bits = 0;
730581f3
 
3f0b6d7a
     bytestream2_init(&gb, buf, buf_size);
 
9b6f47c4
     s->samples = bytestream2_get_le32(&gb);
     if (s->samples != wc->samples) {
         av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "
                "a sequence: %d and %d\n", wc->samples, s->samples);
         return AVERROR_INVALIDDATA;
8a485dd3
     }
3f0b6d7a
     s->frame_flags = bytestream2_get_le32(&gb);
0f689a3d
     bpp            = av_get_bytes_per_sample(avctx->sample_fmt);
     orig_bpp       = ((s->frame_flags & 0x03) + 1) << 3;
7d039e70
     multiblock     = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;
8a485dd3
 
513c238f
     s->stereo         = !(s->frame_flags & WV_MONO);
     s->stereo_in      =  (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;
     s->joint          =   s->frame_flags & WV_JOINT_STEREO;
     s->hybrid         =   s->frame_flags & WV_HYBRID_MODE;
     s->hybrid_bitrate =   s->frame_flags & WV_HYBRID_BITRATE;
32e74395
     s->post_shift     = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
5eb04570
     if (s->post_shift < 0 || s->post_shift > 31) {
         return AVERROR_INVALIDDATA;
     }
0f689a3d
     s->hybrid_maxclip =  ((1LL << (orig_bpp - 1)) - 1);
12eebb84
     s->hybrid_minclip = ((-1UL << (orig_bpp - 1)));
3f0b6d7a
     s->CRC            = bytestream2_get_le32(&gb);
 
730581f3
     // parse metadata blocks
3f0b6d7a
     while (bytestream2_get_bytes_left(&gb)) {
         id   = bytestream2_get_byte(&gb);
         size = bytestream2_get_byte(&gb);
513c238f
         if (id & WP_IDF_LONG) {
3f0b6d7a
             size |= (bytestream2_get_byte(&gb)) << 8;
             size |= (bytestream2_get_byte(&gb)) << 16;
730581f3
         }
         size <<= 1; // size is specified in words
0f689a3d
         ssize  = size;
513c238f
         if (id & WP_IDF_ODD)
             size--;
         if (size < 0) {
0f689a3d
             av_log(avctx, AV_LOG_ERROR,
                    "Got incorrect block %02X with size %i\n", id, size);
730581f3
             break;
         }
3f0b6d7a
         if (bytestream2_get_bytes_left(&gb) < ssize) {
0f689a3d
             av_log(avctx, AV_LOG_ERROR,
                    "Block size %i is out of bounds\n", size);
730581f3
             break;
         }
513c238f
         switch (id & WP_IDF_MASK) {
730581f3
         case WP_ID_DECTERMS:
513c238f
             if (size > MAX_TERMS) {
730581f3
                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
8bfea4ab
                 s->terms = 0;
3f0b6d7a
                 bytestream2_skip(&gb, ssize);
730581f3
                 continue;
             }
8bfea4ab
             s->terms = size;
513c238f
             for (i = 0; i < s->terms; i++) {
3f0b6d7a
                 uint8_t val = bytestream2_get_byte(&gb);
                 s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5;
                 s->decorr[s->terms - i - 1].delta =  val >> 5;
730581f3
             }
             got_terms = 1;
             break;
         case WP_ID_DECWEIGHTS:
513c238f
             if (!got_terms) {
730581f3
                 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
                 continue;
             }
a6ba65f7
             weights = size >> s->stereo_in;
513c238f
             if (weights > MAX_TERMS || weights > s->terms) {
730581f3
                 av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
3f0b6d7a
                 bytestream2_skip(&gb, ssize);
730581f3
                 continue;
             }
513c238f
             for (i = 0; i < weights; i++) {
3f0b6d7a
                 t = (int8_t)bytestream2_get_byte(&gb);
ba150051
                 s->decorr[s->terms - i - 1].weightA = t * (1 << 3);
513c238f
                 if (s->decorr[s->terms - i - 1].weightA > 0)
                     s->decorr[s->terms - i - 1].weightA +=
0f689a3d
                         (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
513c238f
                 if (s->stereo_in) {
3f0b6d7a
                     t = (int8_t)bytestream2_get_byte(&gb);
ba150051
                     s->decorr[s->terms - i - 1].weightB = t * (1 << 3);
513c238f
                     if (s->decorr[s->terms - i - 1].weightB > 0)
                         s->decorr[s->terms - i - 1].weightB +=
0f689a3d
                             (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
730581f3
                 }
             }
             got_weights = 1;
             break;
         case WP_ID_DECSAMPLES:
513c238f
             if (!got_terms) {
730581f3
                 av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
                 continue;
             }
             t = 0;
3a1867de
             for (i = s->terms - 1; (i >= 0) && (t < size); i--) {
513c238f
                 if (s->decorr[i].value > 8) {
3f0b6d7a
                     s->decorr[i].samplesA[0] =
                         wp_exp2(bytestream2_get_le16(&gb));
                     s->decorr[i].samplesA[1] =
                         wp_exp2(bytestream2_get_le16(&gb));
 
513c238f
                     if (s->stereo_in) {
3f0b6d7a
                         s->decorr[i].samplesB[0] =
                             wp_exp2(bytestream2_get_le16(&gb));
                         s->decorr[i].samplesB[1] =
                             wp_exp2(bytestream2_get_le16(&gb));
0f689a3d
                         t                       += 4;
730581f3
                     }
                     t += 4;
513c238f
                 } else if (s->decorr[i].value < 0) {
3f0b6d7a
                     s->decorr[i].samplesA[0] =
                         wp_exp2(bytestream2_get_le16(&gb));
                     s->decorr[i].samplesB[0] =
                         wp_exp2(bytestream2_get_le16(&gb));
0f689a3d
                     t                       += 4;
513c238f
                 } else {
                     for (j = 0; j < s->decorr[i].value; j++) {
3f0b6d7a
                         s->decorr[i].samplesA[j] =
                             wp_exp2(bytestream2_get_le16(&gb));
9d7cee50
                         if (s->stereo_in) {
3f0b6d7a
                             s->decorr[i].samplesB[j] =
                                 wp_exp2(bytestream2_get_le16(&gb));
9d7cee50
                         }
730581f3
                     }
a6ba65f7
                     t += s->decorr[i].value * 2 * (s->stereo_in + 1);
730581f3
                 }
             }
             got_samples = 1;
             break;
         case WP_ID_ENTROPY:
513c238f
             if (size != 6 * (s->stereo_in + 1)) {
0f689a3d
                 av_log(avctx, AV_LOG_ERROR,
b94f045b
                        "Entropy vars size should be %i, got %i.\n",
0f689a3d
                        6 * (s->stereo_in + 1), size);
3f0b6d7a
                 bytestream2_skip(&gb, ssize);
730581f3
                 continue;
             }
0f689a3d
             for (j = 0; j <= s->stereo_in; j++)
513c238f
                 for (i = 0; i < 3; i++) {
3f0b6d7a
                     s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));
2c96535a
                 }
730581f3
             got_entropy = 1;
             break;
2c96535a
         case WP_ID_HYBRID:
513c238f
             if (s->hybrid_bitrate) {
                 for (i = 0; i <= s->stereo_in; i++) {
3f0b6d7a
                     s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb));
0f689a3d
                     size               -= 2;
2c96535a
                 }
             }
513c238f
             for (i = 0; i < (s->stereo_in + 1); i++) {
3f0b6d7a
                 s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16;
0f689a3d
                 size                -= 2;
2c96535a
             }
513c238f
             if (size > 0) {
                 for (i = 0; i < (s->stereo_in + 1); i++) {
3f0b6d7a
                     s->ch[i].bitrate_delta =
                         wp_exp2((int16_t)bytestream2_get_le16(&gb));
2c96535a
                 }
513c238f
             } else {
                 for (i = 0; i < (s->stereo_in + 1); i++)
2c96535a
                     s->ch[i].bitrate_delta = 0;
             }
             got_hybrid = 1;
             break;
3f0b6d7a
         case WP_ID_INT32INFO: {
             uint8_t val[4];
513c238f
             if (size != 4) {
0f689a3d
                 av_log(avctx, AV_LOG_ERROR,
3f0b6d7a
                        "Invalid INT32INFO, size = %i\n",
                        size);
                 bytestream2_skip(&gb, ssize - 4);
6b05eb31
                 continue;
             }
3f0b6d7a
             bytestream2_get_buffer(&gb, val, 4);
c07af720
             if (val[0] > 30) {
d0eff885
                 av_log(avctx, AV_LOG_ERROR,
c07af720
                        "Invalid INT32INFO, extra_bits = %d (> 30)\n", val[0]);
d0eff885
                 continue;
             } else if (val[0]) {
3f0b6d7a
                 s->extra_bits = val[0];
             } else if (val[1]) {
                 s->shift = val[1];
             } else if (val[2]) {
0f689a3d
                 s->and   = s->or = 1;
3f0b6d7a
                 s->shift = val[2];
             } else if (val[3]) {
513c238f
                 s->and   = 1;
3f0b6d7a
                 s->shift = val[3];
6b05eb31
             }
423375d4
             if (s->shift > 31) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Invalid INT32INFO, shift = %d (> 31)\n", s->shift);
                 s->and = s->or = s->shift = 0;
                 continue;
             }
32e74395
             /* original WavPack decoder forces 32-bit lossy sound to be treated
0f689a3d
              * as 24-bit one in order to have proper clipping */
32e74395
             if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {
0f689a3d
                 s->post_shift      += 8;
                 s->shift           -= 8;
32e74395
                 s->hybrid_maxclip >>= 8;
                 s->hybrid_minclip >>= 8;
             }
6b05eb31
             break;
3f0b6d7a
         }
992f7db0
         case WP_ID_FLOATINFO:
513c238f
             if (size != 4) {
0f689a3d
                 av_log(avctx, AV_LOG_ERROR,
                        "Invalid FLOATINFO, size = %i\n", size);
3f0b6d7a
                 bytestream2_skip(&gb, ssize);
992f7db0
                 continue;
             }
3f0b6d7a
             s->float_flag    = bytestream2_get_byte(&gb);
             s->float_shift   = bytestream2_get_byte(&gb);
             s->float_max_exp = bytestream2_get_byte(&gb);
4020b009
             if (s->float_shift > 31) {
                 av_log(avctx, AV_LOG_ERROR,
                        "Invalid FLOATINFO, shift = %d (> 31)\n", s->float_shift);
                 s->float_shift = 0;
                 continue;
             }
0f689a3d
             got_float        = 1;
3f0b6d7a
             bytestream2_skip(&gb, 1);
992f7db0
             break;
730581f3
         case WP_ID_DATA:
3f0b6d7a
             s->sc.offset = bytestream2_tell(&gb);
965828bb
             s->sc.size   = size * 8;
82e57604
             if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0)
                 return ret;
730581f3
             s->data_size = size * 8;
3f0b6d7a
             bytestream2_skip(&gb, size);
0f689a3d
             got_bs       = 1;
730581f3
             break;
418f77ec
         case WP_ID_EXTRABITS:
513c238f
             if (size <= 4) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n",
                        size);
3f0b6d7a
                 bytestream2_skip(&gb, size);
418f77ec
                 continue;
             }
3f0b6d7a
             s->extra_sc.offset = bytestream2_tell(&gb);
965828bb
             s->extra_sc.size   = size * 8;
82e57604
             if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0)
                 return ret;
0f689a3d
             s->crc_extra_bits  = get_bits_long(&s->gb_extra_bits, 32);
3f0b6d7a
             bytestream2_skip(&gb, size);
0f689a3d
             s->got_extra_bits  = 1;
418f77ec
             break;
8a485dd3
         case WP_ID_CHANINFO:
513c238f
             if (size <= 1) {
0f689a3d
                 av_log(avctx, AV_LOG_ERROR,
                        "Insufficient channel information\n");
8c345581
                 return AVERROR_INVALIDDATA;
8a485dd3
             }
3f0b6d7a
             chan = bytestream2_get_byte(&gb);
513c238f
             switch (size - 2) {
0f689a3d
             case 0:
3f0b6d7a
                 chmask = bytestream2_get_byte(&gb);
0f689a3d
                 break;
             case 1:
3f0b6d7a
                 chmask = bytestream2_get_le16(&gb);
0f689a3d
                 break;
             case 2:
3f0b6d7a
                 chmask = bytestream2_get_le24(&gb);
0f689a3d
                 break;
             case 3:
ac2c5217
                 chmask = bytestream2_get_le32(&gb);
0f689a3d
                 break;
8a485dd3
             case 5:
a59f85d1
                 size = bytestream2_get_byte(&gb);
                 if (avctx->channels != size)
                     av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
                            " instead of %i.\n", size, avctx->channels);
3f0b6d7a
                 chan  |= (bytestream2_get_byte(&gb) & 0xF) << 8;
                 chmask = bytestream2_get_le16(&gb);
8a485dd3
                 break;
             default:
513c238f
                 av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
                        size);
                 chan   = avctx->channels;
8a485dd3
                 chmask = avctx->channel_layout;
             }
             break;
78f75b6f
         case WP_ID_SAMPLE_RATE:
             if (size != 3) {
                 av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");
                 return AVERROR_INVALIDDATA;
             }
             sample_rate = bytestream2_get_le24(&gb);
             break;
730581f3
         default:
3f0b6d7a
             bytestream2_skip(&gb, size);
730581f3
         }
513c238f
         if (id & WP_IDF_ODD)
3f0b6d7a
             bytestream2_skip(&gb, 1);
730581f3
     }
0eea2129
 
513c238f
     if (!got_terms) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
     if (!got_weights) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
     if (!got_samples) {
         av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
     if (!got_entropy) {
         av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
     if (s->hybrid && !got_hybrid) {
         av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
     if (!got_bs) {
         av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
528daa39
     if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
513c238f
         av_log(avctx, AV_LOG_ERROR, "Float information not found\n");
8c345581
         return AVERROR_INVALIDDATA;
513c238f
     }
528daa39
     if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
513c238f
         const int size   = get_bits_left(&s->gb_extra_bits);
         const int wanted = s->samples * s->extra_bits << s->stereo_in;
         if (size < wanted) {
             av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n");
             s->got_extra_bits = 0;
aa170ed6
         }
513c238f
     }
730581f3
 
78f75b6f
     if (!wc->ch_offset) {
         int sr = (s->frame_flags >> 23) & 0xf;
         if (sr == 0xf) {
             if (!sample_rate) {
                 av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");
                 return AVERROR_INVALIDDATA;
             }
             avctx->sample_rate = sample_rate;
         } else
             avctx->sample_rate = wv_rates[sr];
 
7d039e70
         if (multiblock) {
             if (chan)
                 avctx->channels = chan;
             if (chmask)
                 avctx->channel_layout = chmask;
         } else {
             avctx->channels       = s->stereo ? 2 : 1;
             avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :
                                                 AV_CH_LAYOUT_MONO;
         }
 
78f75b6f
         /* get output buffer */
8543575c
         frame->nb_samples = s->samples + 1;
9684d7f1
         if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
78f75b6f
             return ret;
8543575c
         frame->nb_samples = s->samples;
78f75b6f
     }
 
eae1b845
     if (wc->ch_offset + s->stereo >= avctx->channels) {
         av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
c188f358
         return ((avctx->err_recognition & AV_EF_EXPLODE) || !wc->ch_offset) ? AVERROR_INVALIDDATA : 0;
eae1b845
     }
 
78f75b6f
     samples_l = frame->extended_data[wc->ch_offset];
     if (s->stereo)
         samples_r = frame->extended_data[wc->ch_offset + 1];
 
     wc->ch_offset += 1 + s->stereo;
 
513c238f
     if (s->stereo_in) {
474fb0c9
         ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);
         if (ret < 0)
             return ret;
513c238f
     } else {
474fb0c9
         ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);
         if (ret < 0)
             return ret;
dba2b63a
 
528daa39
         if (s->stereo)
             memcpy(samples_r, samples_l, bpp * s->samples);
8a485dd3
     }
 
474fb0c9
     return 0;
8a485dd3
 }
 
c2a016ad
 static void wavpack_decode_flush(AVCodecContext *avctx)
 {
     WavpackContext *s = avctx->priv_data;
     int i;
 
     for (i = 0; i < s->fdec_num; i++)
         wv_reset_saved_context(s->fdec[i]);
 }
 
0eea2129
 static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
                                 int *got_frame_ptr, AVPacket *avpkt)
8a485dd3
 {
513c238f
     WavpackContext *s  = avctx->priv_data;
8a485dd3
     const uint8_t *buf = avpkt->data;
513c238f
     int buf_size       = avpkt->size;
9873d71f
     AVFrame *frame     = data;
14165fe1
     int frame_size, ret, frame_flags;
8a485dd3
 
5074f454
     if (avpkt->size <= WV_HEADER_SIZE)
fd062912
         return AVERROR_INVALIDDATA;
 
513c238f
     s->block     = 0;
8a485dd3
     s->ch_offset = 0;
 
0eea2129
     /* determine number of samples */
9b6f47c4
     s->samples  = AV_RL32(buf + 20);
     frame_flags = AV_RL32(buf + 24);
4744f67d
     if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) {
0eea2129
         av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
                s->samples);
8c345581
         return AVERROR_INVALIDDATA;
0eea2129
     }
 
14165fe1
     if (frame_flags & 0x80) {
528daa39
         avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
14165fe1
     } else if ((frame_flags & 0x03) <= 1) {
528daa39
         avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
14165fe1
     } else {
528daa39
         avctx->sample_fmt          = AV_SAMPLE_FMT_S32P;
07d49437
         avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
14165fe1
     }
 
513c238f
     while (buf_size > 0) {
9b6f47c4
         if (buf_size <= WV_HEADER_SIZE)
             break;
         frame_size = AV_RL32(buf + 4) - 12;
         buf       += 20;
         buf_size  -= 20;
d1bec4be
         if (frame_size <= 0 || frame_size > buf_size) {
0f689a3d
             av_log(avctx, AV_LOG_ERROR,
                    "Block %d has invalid size (size %d vs. %d bytes left)\n",
                    s->block, frame_size, buf_size);
c2a016ad
             wavpack_decode_flush(avctx);
0fe8c9f4
             return AVERROR_INVALIDDATA;
8a485dd3
         }
474fb0c9
         if ((ret = wavpack_decode_block(avctx, s->block,
78f75b6f
                                         frame, buf, frame_size)) < 0) {
c2a016ad
             wavpack_decode_flush(avctx);
474fb0c9
             return ret;
c2a016ad
         }
8a485dd3
         s->block++;
0f689a3d
         buf      += frame_size;
         buf_size -= frame_size;
a6ba65f7
     }
730581f3
 
89806691
     if (s->ch_offset != avctx->channels) {
         av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
         return AVERROR_INVALIDDATA;
     }
 
35596bd4
     *got_frame_ptr = 1;
 
0eea2129
     return avpkt->size;
730581f3
 }
 
e7e2df27
 AVCodec ff_wavpack_decoder = {
ec6402b7
     .name           = "wavpack",
b2bed932
     .long_name      = NULL_IF_CONFIG_SMALL("WavPack"),
ec6402b7
     .type           = AVMEDIA_TYPE_AUDIO,
36ef5369
     .id             = AV_CODEC_ID_WAVPACK,
ec6402b7
     .priv_data_size = sizeof(WavpackContext),
     .init           = wavpack_decode_init,
     .close          = wavpack_decode_end,
     .decode         = wavpack_decode_frame,
4ba8c521
     .flush          = wavpack_decode_flush,
ff0bdf93
     .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
444e9874
     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
730581f3
 };