/*
 * WavPack lossless audio encoder
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * 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
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#define BITSTREAM_WRITER_LE

#include "libavutil/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "avcodec.h"
#include "codec_internal.h"
#include "encode.h"
#include "put_bits.h"
#include "bytestream.h"
#include "wavpackenc.h"
#include "wavpack.h"

#define UPDATE_WEIGHT(weight, delta, source, result) \
    if ((source) && (result)) { \
        int32_t s = (int32_t) ((source) ^ (result)) >> 31; \
        weight = ((delta) ^ s) + ((weight) - s); \
    }

#define APPLY_WEIGHT_F(weight, sample) ((((((sample) & 0xffff) * (weight)) >> 9) + \
    ((((sample) & ~0xffff) >> 9) * (weight)) + 1) >> 1)

#define APPLY_WEIGHT_I(weight, sample) (((weight) * (sample) + 512) >> 10)

#define APPLY_WEIGHT(weight, sample) ((sample) != (short) (sample) ? \
    APPLY_WEIGHT_F(weight, sample) : APPLY_WEIGHT_I (weight, sample))

#define CLEAR(destin) memset(&destin, 0, sizeof(destin));

#define SHIFT_LSB       13
#define SHIFT_MASK      (0x1FU << SHIFT_LSB)

#define MAG_LSB         18
#define MAG_MASK        (0x1FU << MAG_LSB)

#define SRATE_LSB       23
#define SRATE_MASK      (0xFU << SRATE_LSB)

#define EXTRA_TRY_DELTAS     1
#define EXTRA_ADJUST_DELTAS  2
#define EXTRA_SORT_FIRST     4
#define EXTRA_BRANCHES       8
#define EXTRA_SORT_LAST     16

typedef struct WavPackExtraInfo {
    struct Decorr dps[MAX_TERMS];
    int nterms, log_limit, gt16bit;
    uint32_t best_bits;
} WavPackExtraInfo;

typedef struct WavPackWords {
    int pend_data, holding_one, zeros_acc;
    int holding_zero, pend_count;
    WvChannel c[2];
} WavPackWords;

typedef struct WavPackEncodeContext {
    AVClass *class;
    AVCodecContext *avctx;
    PutBitContext pb;
    int block_samples;
    int buffer_size;
    int sample_index;
    int stereo, stereo_in;
    int ch_offset;

    int32_t *samples[2];
    int samples_size[2];

    int32_t *sampleptrs[MAX_TERMS+2][2];
    int sampleptrs_size[MAX_TERMS+2][2];

    int32_t *temp_buffer[2][2];
    int temp_buffer_size[2][2];

    int32_t *best_buffer[2];
    int best_buffer_size[2];

    int32_t *js_left, *js_right;
    int js_left_size, js_right_size;

    int32_t *orig_l, *orig_r;
    int orig_l_size, orig_r_size;

    unsigned extra_flags;
    int optimize_mono;
    int decorr_filter;
    int joint;
    int num_branches;

    uint32_t flags;
    uint32_t crc_x;
    WavPackWords w;

    uint8_t int32_sent_bits, int32_zeros, int32_ones, int32_dups;
    uint8_t float_flags, float_shift, float_max_exp, max_exp;
    int32_t shifted_ones, shifted_zeros, shifted_both;
    int32_t false_zeros, neg_zeros, ordata;

    int num_terms, shift, joint_stereo, false_stereo;
    int num_decorrs, num_passes, best_decorr, mask_decorr;
    struct Decorr decorr_passes[MAX_TERMS];
    const WavPackDecorrSpec *decorr_specs;
    float delta_decay;
} WavPackEncodeContext;

static av_cold int wavpack_encode_init(AVCodecContext *avctx)
{
    WavPackEncodeContext *s = avctx->priv_data;

    s->avctx = avctx;

    if (avctx->ch_layout.nb_channels > 255) {
        av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->ch_layout.nb_channels);
        return AVERROR(EINVAL);
    }

    if (!avctx->frame_size) {
        int block_samples;
        if (!(avctx->sample_rate & 1))
            block_samples = avctx->sample_rate / 2;
        else
            block_samples = avctx->sample_rate;

        while (block_samples * avctx->ch_layout.nb_channels > WV_MAX_SAMPLES)
            block_samples /= 2;

        while (block_samples * avctx->ch_layout.nb_channels < 40000)
            block_samples *= 2;
        avctx->frame_size = block_samples;
    } else if (avctx->frame_size && (avctx->frame_size < 128 ||
                              avctx->frame_size > WV_MAX_SAMPLES)) {
        av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n", avctx->frame_size);
        return AVERROR(EINVAL);
    }

    if (avctx->compression_level != FF_COMPRESSION_DEFAULT) {
        if (avctx->compression_level >= 3) {
            s->decorr_filter = 3;
            s->num_passes = 9;
            if      (avctx->compression_level >= 8) {
                s->num_branches = 4;
                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_SORT_LAST|EXTRA_BRANCHES;
            } else if (avctx->compression_level >= 7) {
                s->num_branches = 3;
                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
            } else if (avctx->compression_level >= 6) {
                s->num_branches = 2;
                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
            } else if (avctx->compression_level >= 5) {
                s->num_branches = 1;
                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_SORT_FIRST|EXTRA_BRANCHES;
            } else if (avctx->compression_level >= 4) {
                s->num_branches = 1;
                s->extra_flags = EXTRA_TRY_DELTAS|EXTRA_ADJUST_DELTAS|EXTRA_BRANCHES;
            }
        } else if (avctx->compression_level == 2) {
            s->decorr_filter = 2;
            s->num_passes = 4;
        } else if (avctx->compression_level == 1) {
            s->decorr_filter = 1;
            s->num_passes = 2;
        } else if (avctx->compression_level < 1) {
            s->decorr_filter = 0;
            s->num_passes = 0;
        }
    }

    s->num_decorrs = decorr_filter_sizes[s->decorr_filter];
    s->decorr_specs = decorr_filters[s->decorr_filter];

    s->delta_decay = 2.0;

    return 0;
}

static void shift_mono(int32_t *samples, int nb_samples, int shift)
{
    int i;
    for (i = 0; i < nb_samples; i++)
        samples[i] >>= shift;
}

static void shift_stereo(int32_t *left, int32_t *right,
                         int nb_samples, int shift)
{
    int i;
    for (i = 0; i < nb_samples; i++) {
        left [i] >>= shift;
        right[i] >>= shift;
    }
}

#define FLOAT_SHIFT_ONES 1
#define FLOAT_SHIFT_SAME 2
#define FLOAT_SHIFT_SENT 4
#define FLOAT_ZEROS_SENT 8
#define FLOAT_NEG_ZEROS  0x10
#define FLOAT_EXCEPTIONS 0x20

#define get_mantissa(f)     ((f) & 0x7fffff)
#define get_exponent(f)     (((f) >> 23) & 0xff)
#define get_sign(f)         (((f) >> 31) & 0x1)

static void process_float(WavPackEncodeContext *s, int32_t *sample)
{
    int32_t shift_count, value, f = *sample;

    if (get_exponent(f) == 255) {
        s->float_flags |= FLOAT_EXCEPTIONS;
        value = 0x1000000;
        shift_count = 0;
    } else if (get_exponent(f)) {
        shift_count = s->max_exp - get_exponent(f);
        value = 0x800000 + get_mantissa(f);
    } else {
        shift_count = s->max_exp ? s->max_exp - 1 : 0;
        value = get_mantissa(f);
    }

    if (shift_count < 25)
        value >>= shift_count;
    else
        value = 0;

    if (!value) {
        if (get_exponent(f) || get_mantissa(f))
            s->false_zeros++;
        else if (get_sign(f))
            s->neg_zeros++;
    } else if (shift_count) {
        int32_t mask = (1 << shift_count) - 1;

        if (!(get_mantissa(f) & mask))
            s->shifted_zeros++;
        else if ((get_mantissa(f) & mask) == mask)
            s->shifted_ones++;
        else
            s->shifted_both++;
    }

    s->ordata |= value;
    *sample = get_sign(f) ? -value : value;
}

static int scan_float(WavPackEncodeContext *s,
                      int32_t *samples_l, int32_t *samples_r,
                      int nb_samples)
{
    uint32_t crc = 0xffffffffu;
    int i;

    s->shifted_ones = s->shifted_zeros = s->shifted_both = s->ordata = 0;
    s->float_shift = s->float_flags = 0;
    s->false_zeros = s->neg_zeros = 0;
    s->max_exp = 0;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++) {
            int32_t f = samples_l[i];
            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);

            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
                s->max_exp = get_exponent(f);
        }
    } else {
        for (i = 0; i < nb_samples; i++) {
            int32_t f;

            f = samples_l[i];
            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);
            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
                s->max_exp = get_exponent(f);

            f = samples_r[i];
            crc = crc * 27 + get_mantissa(f) * 9 + get_exponent(f) * 3 + get_sign(f);

            if (get_exponent(f) > s->max_exp && get_exponent(f) < 255)
                s->max_exp = get_exponent(f);
        }
    }

    s->crc_x = crc;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++)
            process_float(s, &samples_l[i]);
    } else {
        for (i = 0; i < nb_samples; i++) {
            process_float(s, &samples_l[i]);
            process_float(s, &samples_r[i]);
        }
    }

    s->float_max_exp = s->max_exp;

    if (s->shifted_both)
        s->float_flags |= FLOAT_SHIFT_SENT;
    else if (s->shifted_ones && !s->shifted_zeros)
        s->float_flags |= FLOAT_SHIFT_ONES;
    else if (s->shifted_ones && s->shifted_zeros)
        s->float_flags |= FLOAT_SHIFT_SAME;
    else if (s->ordata && !(s->ordata & 1)) {
        do {
            s->float_shift++;
            s->ordata >>= 1;
        } while (!(s->ordata & 1));

        if (s->flags & WV_MONO_DATA)
            shift_mono(samples_l, nb_samples, s->float_shift);
        else
            shift_stereo(samples_l, samples_r, nb_samples, s->float_shift);
    }

    s->flags &= ~MAG_MASK;

    while (s->ordata) {
        s->flags += 1 << MAG_LSB;
        s->ordata >>= 1;
    }

    if (s->false_zeros || s->neg_zeros)
        s->float_flags |= FLOAT_ZEROS_SENT;

    if (s->neg_zeros)
        s->float_flags |= FLOAT_NEG_ZEROS;

    return s->float_flags & (FLOAT_EXCEPTIONS | FLOAT_ZEROS_SENT |
                             FLOAT_SHIFT_SENT | FLOAT_SHIFT_SAME);
}

static void scan_int23(WavPackEncodeContext *s,
                       int32_t *samples_l, int32_t *samples_r,
                       int nb_samples)
{
    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
    int i, total_shift = 0;

    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++) {
            int32_t M = samples_l[i];

            magdata |= (M < 0) ? ~M : M;
            xordata |= M ^ -(M & 1);
            anddata &= M;
            ordata  |= M;

            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
                return;
        }
    } else {
        for (i = 0; i < nb_samples; i++) {
            int32_t L = samples_l[i];
            int32_t R = samples_r[i];

            magdata |= (L < 0) ? ~L : L;
            magdata |= (R < 0) ? ~R : R;
            xordata |= L ^ -(L & 1);
            xordata |= R ^ -(R & 1);
            anddata &= L & R;
            ordata  |= L | R;

            if ((ordata & 1) && !(anddata & 1) && (xordata & 2))
                return;
        }
    }

    s->flags &= ~MAG_MASK;

    while (magdata) {
        s->flags += 1 << MAG_LSB;
        magdata >>= 1;
    }

    if (!(s->flags & MAG_MASK))
        return;

    if (!(ordata & 1)) {
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_zeros++;
            total_shift++;
            ordata >>= 1;
        } while (!(ordata & 1));
    } else if (anddata & 1) {
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_ones++;
            total_shift++;
            anddata >>= 1;
        } while (anddata & 1);
    } else if (!(xordata & 2)) {
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_dups++;
            total_shift++;
            xordata >>= 1;
        } while (!(xordata & 2));
    }

    if (total_shift) {
        s->flags |= WV_INT32_DATA;

        if (s->flags & WV_MONO_DATA)
            shift_mono(samples_l, nb_samples, total_shift);
        else
            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
    }
}

static int scan_int32(WavPackEncodeContext *s,
                      int32_t *samples_l, int32_t *samples_r,
                      int nb_samples)
{
    uint32_t magdata = 0, ordata = 0, xordata = 0, anddata = ~0;
    uint32_t crc = 0xffffffffu;
    int i, total_shift = 0;

    s->int32_sent_bits = s->int32_zeros = s->int32_ones = s->int32_dups = 0;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++) {
            int32_t M = samples_l[i];

            crc = crc * 9 + (M & 0xffff) * 3 + ((M >> 16) & 0xffff);
            magdata |= (M < 0) ? ~M : M;
            xordata |= M ^ -(M & 1);
            anddata &= M;
            ordata  |= M;
        }
    } else {
        for (i = 0; i < nb_samples; i++) {
            int32_t L = samples_l[i];
            int32_t R = samples_r[i];

            crc = crc * 9 + (L & 0xffff) * 3 + ((L >> 16) & 0xffff);
            crc = crc * 9 + (R & 0xffff) * 3 + ((R >> 16) & 0xffff);
            magdata |= (L < 0) ? ~L : L;
            magdata |= (R < 0) ? ~R : R;
            xordata |= L ^ -(L & 1);
            xordata |= R ^ -(R & 1);
            anddata &= L & R;
            ordata  |= L | R;
        }
    }

    s->crc_x = crc;
    s->flags &= ~MAG_MASK;

    while (magdata) {
        s->flags += 1 << MAG_LSB;
        magdata >>= 1;
    }

    if (!((s->flags & MAG_MASK) >> MAG_LSB)) {
        s->flags &= ~WV_INT32_DATA;
        return 0;
    }

    if (!(ordata & 1))
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_zeros++;
            total_shift++;
            ordata >>= 1;
        } while (!(ordata & 1));
    else if (anddata & 1)
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_ones++;
            total_shift++;
            anddata >>= 1;
        } while (anddata & 1);
    else if (!(xordata & 2))
        do {
            s->flags -= 1 << MAG_LSB;
            s->int32_dups++;
            total_shift++;
            xordata >>= 1;
        } while (!(xordata & 2));

    if (((s->flags & MAG_MASK) >> MAG_LSB) > 23) {
        s->int32_sent_bits = (uint8_t)(((s->flags & MAG_MASK) >> MAG_LSB) - 23);
        total_shift += s->int32_sent_bits;
        s->flags &= ~MAG_MASK;
        s->flags += 23 << MAG_LSB;
    }

    if (total_shift) {
        s->flags |= WV_INT32_DATA;

        if (s->flags & WV_MONO_DATA)
            shift_mono(samples_l, nb_samples, total_shift);
        else
            shift_stereo(samples_l, samples_r, nb_samples, total_shift);
    }

    return s->int32_sent_bits;
}

static int8_t store_weight(int weight)
{
    weight = av_clip(weight, -1024, 1024);
    if (weight > 0)
        weight -= (weight + 64) >> 7;

    return (weight + 4) >> 3;
}

static int restore_weight(int8_t weight)
{
    int result = 8 * weight;

    if (result > 0)
        result += (result + 64) >> 7;

    return result;
}

static int log2s(int32_t value)
{
    return (value < 0) ? -wp_log2(-value) : wp_log2(value);
}

static void decorr_mono(int32_t *in_samples, int32_t *out_samples,
                        int nb_samples, struct Decorr *dpp, int dir)
{
    int m = 0, i;

    dpp->sumA = 0;

    if (dir < 0) {
        out_samples += (nb_samples - 1);
        in_samples  += (nb_samples - 1);
    }

    dpp->weightA = restore_weight(store_weight(dpp->weightA));

    for (i = 0; i < MAX_TERM; i++)
        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));

    if (dpp->value > MAX_TERM) {
        while (nb_samples--) {
            int32_t left, sam_A;

            sam_A = ((3 - (dpp->value & 1)) * dpp->samplesA[0] - dpp->samplesA[1]) >> !(dpp->value & 1);

            dpp->samplesA[1] = dpp->samplesA[0];
            dpp->samplesA[0] = left = in_samples[0];

            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
            dpp->sumA += dpp->weightA;
            out_samples[0] = left;
            in_samples += dir;
            out_samples += dir;
        }
    } else if (dpp->value > 0) {
        while (nb_samples--) {
            int k = (m + dpp->value) & (MAX_TERM - 1);
            int32_t left, sam_A;

            sam_A = dpp->samplesA[m];
            dpp->samplesA[k] = left = in_samples[0];
            m = (m + 1) & (MAX_TERM - 1);

            left -= APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam_A, left);
            dpp->sumA += dpp->weightA;
            out_samples[0] = left;
            in_samples += dir;
            out_samples += dir;
        }
    }

    if (m && dpp->value > 0 && dpp->value <= MAX_TERM) {
        int32_t temp_A[MAX_TERM];

        memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));

        for (i = 0; i < MAX_TERM; i++) {
            dpp->samplesA[i] = temp_A[m];
            m = (m + 1) & (MAX_TERM - 1);
        }
    }
}

static void reverse_mono_decorr(struct Decorr *dpp)
{
    if (dpp->value > MAX_TERM) {
        int32_t sam_A;

        if (dpp->value & 1)
            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
        else
            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;

        dpp->samplesA[1] = dpp->samplesA[0];
        dpp->samplesA[0] = sam_A;

        if (dpp->value & 1)
            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
        else
            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;

        dpp->samplesA[1] = sam_A;
    } else if (dpp->value > 1) {
        int i, j, k;

        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
            i &= (MAX_TERM - 1);
            j &= (MAX_TERM - 1);
            dpp->samplesA[i] ^= dpp->samplesA[j];
            dpp->samplesA[j] ^= dpp->samplesA[i];
            dpp->samplesA[i] ^= dpp->samplesA[j];
        }
    }
}

#define count_bits(av) ((av) ? 32 - ff_clz(av) : 0)

static uint32_t log2sample(uint32_t v, int limit, uint32_t *result)
{
    uint32_t dbits = count_bits(v);

    if ((v += v >> 9) < (1 << 8)) {
        *result += (dbits << 8) + ff_wp_log2_table[(v << (9 - dbits)) & 0xff];
    } else {
        *result += dbits = (dbits << 8) + ff_wp_log2_table[(v >> (dbits - 9)) & 0xff];

        if (limit && dbits >= limit)
            return 1;
    }

    return 0;
}

static uint32_t log2mono(int32_t *samples, int nb_samples, int limit)
{
    uint32_t result = 0;
    while (nb_samples--) {
        if (log2sample(abs(*samples++), limit, &result))
            return UINT32_MAX;
    }
    return result;
}

static uint32_t log2stereo(int32_t *samples_l, int32_t *samples_r,
                           int nb_samples, int limit)
{
    uint32_t result = 0;
    while (nb_samples--) {
        if (log2sample(abs(*samples_l++), limit, &result) ||
            log2sample(abs(*samples_r++), limit, &result))
            return UINT32_MAX;
    }
    return result;
}

static void decorr_mono_buffer(int32_t *samples, int32_t *outsamples,
                               int nb_samples, struct Decorr *dpp,
                               int tindex)
{
    struct Decorr dp, *dppi = dpp + tindex;
    int delta = dppi->delta, pre_delta, term = dppi->value;

    if (delta == 7)
        pre_delta = 7;
    else if (delta < 2)
        pre_delta = 3;
    else
        pre_delta = delta + 1;

    CLEAR(dp);
    dp.value = term;
    dp.delta = pre_delta;
    decorr_mono(samples, outsamples, FFMIN(2048, nb_samples), &dp, -1);
    dp.delta = delta;

    if (tindex == 0)
        reverse_mono_decorr(&dp);
    else
        CLEAR(dp.samplesA);

    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
    dppi->weightA = dp.weightA;

    if (delta == 0) {
        dp.delta = 1;
        decorr_mono(samples, outsamples, nb_samples, &dp, 1);
        dp.delta = 0;
        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
    }

    decorr_mono(samples, outsamples, nb_samples, &dp, 1);
}

static void recurse_mono(WavPackEncodeContext *s, WavPackExtraInfo *info,
                         int depth, int delta, uint32_t input_bits)
{
    int term, branches = s->num_branches - depth;
    int32_t *samples, *outsamples;
    uint32_t term_bits[22], bits;

    if (branches < 1 || depth + 1 == info->nterms)
        branches = 1;

    CLEAR(term_bits);
    samples = s->sampleptrs[depth][0];
    outsamples = s->sampleptrs[depth + 1][0];

    for (term = 1; term <= 18; term++) {
        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
            continue;

        if (term > 8 && term < 17)
            continue;

        if (!s->extra_flags && (term > 4 && term < 17))
            continue;

        info->dps[depth].value = term;
        info->dps[depth].delta = delta;
        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);
        bits = log2mono(outsamples, s->block_samples, info->log_limit);

        if (bits < info->best_bits) {
            info->best_bits = bits;
            CLEAR(s->decorr_passes);
            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
            memcpy(s->sampleptrs[info->nterms + 1][0],
                   s->sampleptrs[depth + 1][0], s->block_samples * 4);
        }

        term_bits[term + 3] = bits;
    }

    while (depth + 1 < info->nterms && branches--) {
        uint32_t local_best_bits = input_bits;
        int best_term = 0, i;

        for (i = 0; i < 22; i++)
            if (term_bits[i] && term_bits[i] < local_best_bits) {
                local_best_bits = term_bits[i];
                best_term = i - 3;
            }

        if (!best_term)
            break;

        term_bits[best_term + 3] = 0;

        info->dps[depth].value = best_term;
        info->dps[depth].delta = delta;
        decorr_mono_buffer(samples, outsamples, s->block_samples, info->dps, depth);

        recurse_mono(s, info, depth + 1, delta, local_best_bits);
    }
}

static void sort_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
{
    int reversed = 1;
    uint32_t bits;

    while (reversed) {
        int ri, i;

        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
        reversed = 0;

        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {

            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
                break;

            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
                                   s->block_samples, info->dps, ri);
                continue;
            }

            info->dps[ri  ] = s->decorr_passes[ri+1];
            info->dps[ri+1] = s->decorr_passes[ri  ];

            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
                decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
                                   s->block_samples, info->dps, i);

            bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
            if (bits < info->best_bits) {
                reversed = 1;
                info->best_bits = bits;
                CLEAR(s->decorr_passes);
                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
                memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
                       s->block_samples * 4);
            } else {
                info->dps[ri  ] = s->decorr_passes[ri];
                info->dps[ri+1] = s->decorr_passes[ri+1];
                decorr_mono_buffer(s->sampleptrs[ri][0], s->sampleptrs[ri+1][0],
                                   s->block_samples, info->dps, ri);
            }
        }
    }
}

static void delta_mono(WavPackEncodeContext *s, WavPackExtraInfo *info)
{
    int lower = 0, delta, d;
    uint32_t bits;

    if (!s->decorr_passes[0].value)
        return;
    delta = s->decorr_passes[0].delta;

    for (d = delta - 1; d >= 0; d--) {
        int i;

        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
            info->dps[i].value = s->decorr_passes[i].value;
            info->dps[i].delta = d;
            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
                               s->block_samples, info->dps, i);
        }

        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
        if (bits >= info->best_bits)
            break;

        lower = 1;
        info->best_bits = bits;
        CLEAR(s->decorr_passes);
        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
        memcpy(s->sampleptrs[info->nterms + 1][0],  s->sampleptrs[i][0],
               s->block_samples * 4);
    }

    for (d = delta + 1; !lower && d <= 7; d++) {
        int i;

        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
            info->dps[i].value = s->decorr_passes[i].value;
            info->dps[i].delta = d;
            decorr_mono_buffer(s->sampleptrs[i][0], s->sampleptrs[i+1][0],
                               s->block_samples, info->dps, i);
        }

        bits = log2mono(s->sampleptrs[i][0], s->block_samples, info->log_limit);
        if (bits >= info->best_bits)
            break;

        info->best_bits = bits;
        CLEAR(s->decorr_passes);
        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
               s->block_samples * 4);
    }
}

static int allocate_buffers2(WavPackEncodeContext *s, int nterms)
{
    int i;

    for (i = 0; i < nterms + 2; i++) {
        av_fast_padded_malloc(&s->sampleptrs[i][0], &s->sampleptrs_size[i][0],
                              s->block_samples * 4);
        if (!s->sampleptrs[i][0])
            return AVERROR(ENOMEM);
        if (!(s->flags & WV_MONO_DATA)) {
            av_fast_padded_malloc(&s->sampleptrs[i][1], &s->sampleptrs_size[i][1],
                                  s->block_samples * 4);
            if (!s->sampleptrs[i][1])
                return AVERROR(ENOMEM);
        }
    }

    return 0;
}

static int allocate_buffers(WavPackEncodeContext *s)
{
    int i;

    for (i = 0; i < 2; i++) {
        av_fast_padded_malloc(&s->best_buffer[0], &s->best_buffer_size[0],
                              s->block_samples * 4);
        if (!s->best_buffer[0])
            return AVERROR(ENOMEM);

        av_fast_padded_malloc(&s->temp_buffer[i][0], &s->temp_buffer_size[i][0],
                              s->block_samples * 4);
        if (!s->temp_buffer[i][0])
            return AVERROR(ENOMEM);
        if (!(s->flags & WV_MONO_DATA)) {
            av_fast_padded_malloc(&s->best_buffer[1], &s->best_buffer_size[1],
                                  s->block_samples * 4);
            if (!s->best_buffer[1])
                return AVERROR(ENOMEM);

            av_fast_padded_malloc(&s->temp_buffer[i][1], &s->temp_buffer_size[i][1],
                                  s->block_samples * 4);
            if (!s->temp_buffer[i][1])
                return AVERROR(ENOMEM);
        }
    }

    return 0;
}

static void analyze_mono(WavPackEncodeContext *s, int32_t *samples, int do_samples)
{
    WavPackExtraInfo info;
    int i;

    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
    info.log_limit = FFMIN(6912, info.log_limit);

    info.nterms = s->num_terms;

    if (allocate_buffers2(s, s->num_terms))
        return;

    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
    memcpy(s->sampleptrs[0][0], samples, s->block_samples * 4);

    for (i = 0; i < info.nterms && info.dps[i].value; i++)
        decorr_mono(s->sampleptrs[i][0], s->sampleptrs[i + 1][0],
                    s->block_samples, info.dps + i, 1);

    info.best_bits = log2mono(s->sampleptrs[info.nterms][0], s->block_samples, 0) * 1;
    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);

    if (s->extra_flags & EXTRA_BRANCHES)
        recurse_mono(s, &info, 0, (int) floor(s->delta_decay + 0.5),
                     log2mono(s->sampleptrs[0][0], s->block_samples, 0));

    if (s->extra_flags & EXTRA_SORT_FIRST)
        sort_mono(s, &info);

    if (s->extra_flags & EXTRA_TRY_DELTAS) {
        delta_mono(s, &info);

        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
        else
            s->delta_decay = 2.0;
    }

    if (s->extra_flags & EXTRA_SORT_LAST)
        sort_mono(s, &info);

    if (do_samples)
        memcpy(samples, s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);

    for (i = 0; i < info.nterms; i++)
        if (!s->decorr_passes[i].value)
            break;

    s->num_terms = i;
}

static void scan_word(WavPackEncodeContext *s, WvChannel *c,
                      int32_t *samples, int nb_samples, int dir)
{
    if (dir < 0)
        samples += nb_samples - 1;

    while (nb_samples--) {
        uint32_t low, value = labs(samples[0]);

        if (value < GET_MED(0)) {
            DEC_MED(0);
        } else {
            low = GET_MED(0);
            INC_MED(0);

            if (value - low < GET_MED(1)) {
                DEC_MED(1);
            } else {
                low += GET_MED(1);
                INC_MED(1);

                if (value - low < GET_MED(2)) {
                    DEC_MED(2);
                } else {
                    INC_MED(2);
                }
            }
        }
        samples += dir;
    }
}

static int wv_mono(WavPackEncodeContext *s, int32_t *samples,
                   int no_history, int do_samples)
{
    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
    int nb_samples = s->block_samples;
    int buf_size = sizeof(int32_t) * nb_samples;
    uint32_t best_size = UINT32_MAX, size;
    int log_limit, pi, i, ret;

    for (i = 0; i < nb_samples; i++)
        if (samples[i])
            break;

    if (i == nb_samples) {
        CLEAR(s->decorr_passes);
        CLEAR(s->w);
        s->num_terms = 0;
        return 0;
    }

    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
    log_limit = FFMIN(6912, log_limit);

    if ((ret = allocate_buffers(s)) < 0)
        return ret;

    if (no_history || s->num_passes >= 7)
        s->best_decorr = s->mask_decorr = 0;

    for (pi = 0; pi < s->num_passes;) {
        const WavPackDecorrSpec *wpds;
        int nterms, c, j;

        if (!pi) {
            c = s->best_decorr;
        } else {
            if (s->mask_decorr == 0)
                c = 0;
            else
                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;

            if (c == s->best_decorr) {
                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
                continue;
            }
        }

        wpds = &s->decorr_specs[c];
        nterms = decorr_filter_nterms[s->decorr_filter];

        while (1) {
        memcpy(s->temp_buffer[0][0], samples, buf_size);
        CLEAR(save_decorr_passes);

        for (j = 0; j < nterms; j++) {
            CLEAR(temp_decorr_pass);
            temp_decorr_pass.delta = wpds->delta;
            temp_decorr_pass.value = wpds->terms[j];

            if (temp_decorr_pass.value < 0)
                temp_decorr_pass.value = 1;

            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
                        FFMIN(nb_samples, 2048), &temp_decorr_pass, -1);

            if (j) {
                CLEAR(temp_decorr_pass.samplesA);
            } else {
                reverse_mono_decorr(&temp_decorr_pass);
            }

            memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));
            decorr_mono(s->temp_buffer[j&1][0], s->temp_buffer[~j&1][0],
                        nb_samples, &temp_decorr_pass, 1);
        }

        size = log2mono(s->temp_buffer[j&1][0], nb_samples, log_limit);
        if (size != UINT32_MAX || !nterms)
            break;
        nterms >>= 1;
        }

        if (size < best_size) {
            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
            s->num_terms = nterms;
            s->best_decorr = c;
            best_size = size;
        }

        if (pi++)
            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
    }

    if (s->extra_flags)
        analyze_mono(s, samples, do_samples);
    else if (do_samples)
        memcpy(samples, s->best_buffer[0], buf_size);

    if (no_history || s->extra_flags) {
        CLEAR(s->w);
        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
    }
    return 0;
}

static void decorr_stereo(int32_t *in_left, int32_t *in_right,
                          int32_t *out_left, int32_t *out_right,
                          int nb_samples, struct Decorr *dpp, int dir)
{
    int m = 0, i;

    dpp->sumA = dpp->sumB = 0;

    if (dir < 0) {
        out_left  += nb_samples - 1;
        out_right += nb_samples - 1;
        in_left   += nb_samples - 1;
        in_right  += nb_samples - 1;
    }

    dpp->weightA = restore_weight(store_weight(dpp->weightA));
    dpp->weightB = restore_weight(store_weight(dpp->weightB));

    for (i = 0; i < MAX_TERM; i++) {
        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
    }

    switch (dpp->value) {
    case 2:
        while (nb_samples--) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0];
            dpp->samplesA[0] = dpp->samplesA[1];
            out_left[0] = tmp = (dpp->samplesA[1] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
            dpp->sumA += dpp->weightA;

            sam = dpp->samplesB[0];
            dpp->samplesB[0] = dpp->samplesB[1];
            out_right[0] = tmp = (dpp->samplesB[1] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
            dpp->sumB += dpp->weightB;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    case 17:
        while (nb_samples--) {
            int32_t sam, tmp;

            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            dpp->samplesA[1] = dpp->samplesA[0];
            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
            dpp->sumA += dpp->weightA;

            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
            dpp->samplesB[1] = dpp->samplesB[0];
            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT (dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
            dpp->sumB += dpp->weightB;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    case 18:
        while (nb_samples--) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
            dpp->samplesA[1] = dpp->samplesA[0];
            out_left[0] = tmp = (dpp->samplesA[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
            dpp->sumA += dpp->weightA;

            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
            dpp->samplesB[1] = dpp->samplesB[0];
            out_right[0] = tmp = (dpp->samplesB[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
            dpp->sumB += dpp->weightB;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    default: {
        int k = dpp->value & (MAX_TERM - 1);

        while (nb_samples--) {
            int32_t sam, tmp;

            sam = dpp->samplesA[m];
            out_left[0] = tmp = (dpp->samplesA[k] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);
            dpp->sumA += dpp->weightA;

            sam = dpp->samplesB[m];
            out_right[0] = tmp = (dpp->samplesB[k] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
            dpp->sumB += dpp->weightB;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
            m = (m + 1) & (MAX_TERM - 1);
            k = (k + 1) & (MAX_TERM - 1);
        }

        if (m) {
            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
            int k;

            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));

            for (k = 0; k < MAX_TERM; k++) {
                dpp->samplesA[k] = temp_A[m];
                dpp->samplesB[k] = temp_B[m];
                m = (m + 1) & (MAX_TERM - 1);
            }
        }
        break;
        }
    case -1:
        while (nb_samples--) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            out_left[0] = tmp = (sam_B = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
            dpp->sumA += dpp->weightA;

            out_right[0] = tmp = (dpp->samplesA[0] = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
            dpp->sumB += dpp->weightB;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    case -2:
        while (nb_samples--) {
            int32_t sam_A, sam_B, tmp;

            sam_B = dpp->samplesB[0];
            out_right[0] = tmp = (sam_A = in_right[0]) - APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
            dpp->sumB += dpp->weightB;

            out_left[0] = tmp = (dpp->samplesB[0] = in_left[0]) - APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
            dpp->sumA += dpp->weightA;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    case -3:
        while (nb_samples--) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            sam_B = dpp->samplesB[0];

            dpp->samplesA[0] = tmp = in_right[0];
            out_right[0] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
            dpp->sumB += dpp->weightB;

            dpp->samplesB[0] = tmp = in_left[0];
            out_left[0] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
            dpp->sumA += dpp->weightA;

            in_left   += dir;
            out_left  += dir;
            in_right  += dir;
            out_right += dir;
        }
        break;
    }
}

static void reverse_decorr(struct Decorr *dpp)
{
    if (dpp->value > MAX_TERM) {
        int32_t sam_A, sam_B;

        if (dpp->value & 1) {
            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
        } else {
            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
        }

        dpp->samplesA[1] = dpp->samplesA[0];
        dpp->samplesB[1] = dpp->samplesB[0];
        dpp->samplesA[0] = sam_A;
        dpp->samplesB[0] = sam_B;

        if (dpp->value & 1) {
            sam_A = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            sam_B = 2 * dpp->samplesB[0] - dpp->samplesB[1];
        } else {
            sam_A = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;
            sam_B = (3 * dpp->samplesB[0] - dpp->samplesB[1]) >> 1;
        }

        dpp->samplesA[1] = sam_A;
        dpp->samplesB[1] = sam_B;
    } else if (dpp->value > 1) {
        int i, j, k;

        for (i = 0, j = dpp->value - 1, k = 0; k < dpp->value / 2; i++, j--, k++) {
            i &= (MAX_TERM - 1);
            j &= (MAX_TERM - 1);
            dpp->samplesA[i] ^= dpp->samplesA[j];
            dpp->samplesA[j] ^= dpp->samplesA[i];
            dpp->samplesA[i] ^= dpp->samplesA[j];
            dpp->samplesB[i] ^= dpp->samplesB[j];
            dpp->samplesB[j] ^= dpp->samplesB[i];
            dpp->samplesB[i] ^= dpp->samplesB[j];
        }
    }
}

static void decorr_stereo_quick(int32_t *in_left,  int32_t *in_right,
                                int32_t *out_left, int32_t *out_right,
                                int nb_samples, struct Decorr *dpp)
{
    int m = 0, i;

    dpp->weightA = restore_weight(store_weight(dpp->weightA));
    dpp->weightB = restore_weight(store_weight(dpp->weightB));

    for (i = 0; i < MAX_TERM; i++) {
        dpp->samplesA[i] = wp_exp2(log2s(dpp->samplesA[i]));
        dpp->samplesB[i] = wp_exp2(log2s(dpp->samplesB[i]));
    }

    switch (dpp->value) {
    case 2:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0];
            dpp->samplesA[0] = dpp->samplesA[1];
            out_left[i] = tmp = (dpp->samplesA[1] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[0];
            dpp->samplesB[0] = dpp->samplesB[1];
            out_right[i] = tmp = (dpp->samplesB[1] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    case 17:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            dpp->samplesA[1] = dpp->samplesA[0];
            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
            dpp->samplesB[1] = dpp->samplesB[0];
            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    case 18:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
            dpp->samplesA[1] = dpp->samplesA[0];
            out_left[i] = tmp = (dpp->samplesA[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
            dpp->samplesB[1] = dpp->samplesB[0];
            out_right[i] = tmp = (dpp->samplesB[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    default: {
        int k = dpp->value & (MAX_TERM - 1);

        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[m];
            out_left[i] = tmp = (dpp->samplesA[k] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[m];
            out_right[i] = tmp = (dpp->samplesB[k] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);

            m = (m + 1) & (MAX_TERM - 1);
            k = (k + 1) & (MAX_TERM - 1);
        }

        if (m) {
            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
            int k;

            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));

            for (k = 0; k < MAX_TERM; k++) {
                dpp->samplesA[k] = temp_A[m];
                dpp->samplesB[k] = temp_B[m];
                m = (m + 1) & (MAX_TERM - 1);
            }
        }
        break;
    }
    case -1:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            out_left[i] = tmp = (sam_B = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);

            out_right[i] = tmp = (dpp->samplesA[0] = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
        }
        break;
    case -2:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_B = dpp->samplesB[0];
            out_right[i] = tmp = (sam_A = in_right[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);

            out_left[i] = tmp = (dpp->samplesB[0] = in_left[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    case -3:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            sam_B = dpp->samplesB[0];

            dpp->samplesA[0] = tmp = in_right[i];
            out_right[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);

            dpp->samplesB[0] = tmp = in_left[i];
            out_left[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    }
}

static void decorr_stereo_buffer(WavPackExtraInfo *info,
                                 int32_t *in_left,  int32_t *in_right,
                                 int32_t *out_left, int32_t *out_right,
                                 int nb_samples, int tindex)
{
    struct Decorr dp = {0}, *dppi = info->dps + tindex;
    int delta = dppi->delta, pre_delta;
    int term = dppi->value;

    if (delta == 7)
        pre_delta = 7;
    else if (delta < 2)
        pre_delta = 3;
    else
        pre_delta = delta + 1;

    dp.value = term;
    dp.delta = pre_delta;
    decorr_stereo(in_left, in_right, out_left, out_right,
                  FFMIN(2048, nb_samples), &dp, -1);
    dp.delta = delta;

    if (tindex == 0) {
        reverse_decorr(&dp);
    } else {
        CLEAR(dp.samplesA);
        CLEAR(dp.samplesB);
    }

    memcpy(dppi->samplesA, dp.samplesA, sizeof(dp.samplesA));
    memcpy(dppi->samplesB, dp.samplesB, sizeof(dp.samplesB));
    dppi->weightA = dp.weightA;
    dppi->weightB = dp.weightB;

    if (delta == 0) {
        dp.delta = 1;
        decorr_stereo(in_left, in_right, out_left, out_right, nb_samples, &dp, 1);
        dp.delta = 0;
        memcpy(dp.samplesA, dppi->samplesA, sizeof(dp.samplesA));
        memcpy(dp.samplesB, dppi->samplesB, sizeof(dp.samplesB));
        dppi->weightA = dp.weightA = dp.sumA / nb_samples;
        dppi->weightB = dp.weightB = dp.sumB / nb_samples;
    }

    if (info->gt16bit)
        decorr_stereo(in_left, in_right, out_left, out_right,
                           nb_samples, &dp, 1);
    else
        decorr_stereo_quick(in_left, in_right, out_left, out_right,
                            nb_samples, &dp);
}

static void sort_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
{
    int reversed = 1;
    uint32_t bits;

    while (reversed) {
        int ri, i;

        memcpy(info->dps, s->decorr_passes, sizeof(s->decorr_passes));
        reversed = 0;

        for (ri = 0; ri < info->nterms && s->decorr_passes[ri].value; ri++) {

            if (ri + 1 >= info->nterms || !s->decorr_passes[ri+1].value)
                break;

            if (s->decorr_passes[ri].value == s->decorr_passes[ri+1].value) {
                decorr_stereo_buffer(info,
                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
                                     s->block_samples, ri);
                continue;
            }

            info->dps[ri  ] = s->decorr_passes[ri+1];
            info->dps[ri+1] = s->decorr_passes[ri  ];

            for (i = ri; i < info->nterms && s->decorr_passes[i].value; i++)
                decorr_stereo_buffer(info,
                                     s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
                                     s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
                                     s->block_samples, i);

            bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
                              s->block_samples, info->log_limit);

            if (bits < info->best_bits) {
                reversed = 1;
                info->best_bits = bits;
                CLEAR(s->decorr_passes);
                memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
                memcpy(s->sampleptrs[info->nterms + 1][0],
                       s->sampleptrs[i][0], s->block_samples * 4);
                memcpy(s->sampleptrs[info->nterms + 1][1],
                       s->sampleptrs[i][1], s->block_samples * 4);
            } else {
                info->dps[ri  ] = s->decorr_passes[ri  ];
                info->dps[ri+1] = s->decorr_passes[ri+1];
                decorr_stereo_buffer(info,
                                     s->sampleptrs[ri  ][0], s->sampleptrs[ri  ][1],
                                     s->sampleptrs[ri+1][0], s->sampleptrs[ri+1][1],
                                     s->block_samples, ri);
            }
        }
    }
}

static void delta_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info)
{
    int lower = 0, delta, d, i;
    uint32_t bits;

    if (!s->decorr_passes[0].value)
        return;
    delta = s->decorr_passes[0].delta;

    for (d = delta - 1; d >= 0; d--) {
        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
            info->dps[i].value = s->decorr_passes[i].value;
            info->dps[i].delta = d;
            decorr_stereo_buffer(info,
                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
                                 s->block_samples, i);
        }

        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
                          s->block_samples, info->log_limit);
        if (bits >= info->best_bits)
            break;
        lower = 1;
        info->best_bits = bits;
        CLEAR(s->decorr_passes);
        memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
        memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[i][0],
               s->block_samples * 4);
        memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[i][1],
               s->block_samples * 4);
    }

    for (d = delta + 1; !lower && d <= 7; d++) {
        for (i = 0; i < info->nterms && s->decorr_passes[i].value; i++) {
            info->dps[i].value = s->decorr_passes[i].value;
            info->dps[i].delta = d;
            decorr_stereo_buffer(info,
                                 s->sampleptrs[i  ][0], s->sampleptrs[i  ][1],
                                 s->sampleptrs[i+1][0], s->sampleptrs[i+1][1],
                                 s->block_samples, i);
        }

        bits = log2stereo(s->sampleptrs[i][0], s->sampleptrs[i][1],
                          s->block_samples, info->log_limit);

        if (bits < info->best_bits) {
            info->best_bits = bits;
            CLEAR(s->decorr_passes);
            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * i);
            memcpy(s->sampleptrs[info->nterms + 1][0],
                   s->sampleptrs[i][0], s->block_samples * 4);
            memcpy(s->sampleptrs[info->nterms + 1][1],
                   s->sampleptrs[i][1], s->block_samples * 4);
        }
        else
            break;
    }
}

static void recurse_stereo(WavPackEncodeContext *s, WavPackExtraInfo *info,
                           int depth, int delta, uint32_t input_bits)
{
    int term, branches = s->num_branches - depth;
    int32_t *in_left, *in_right, *out_left, *out_right;
    uint32_t term_bits[22], bits;

    if (branches < 1 || depth + 1 == info->nterms)
        branches = 1;

    CLEAR(term_bits);
    in_left   = s->sampleptrs[depth    ][0];
    in_right  = s->sampleptrs[depth    ][1];
    out_left  = s->sampleptrs[depth + 1][0];
    out_right = s->sampleptrs[depth + 1][1];

    for (term = -3; term <= 18; term++) {
        if (!term || (term > 8 && term < 17))
            continue;

        if (term == 17 && branches == 1 && depth + 1 < info->nterms)
            continue;

        if (term == -1 || term == -2)
            if (!(s->flags & WV_CROSS_DECORR))
                continue;

        if (!s->extra_flags && (term > 4 && term < 17))
            continue;

        info->dps[depth].value = term;
        info->dps[depth].delta = delta;
        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
                             s->block_samples, depth);
        bits = log2stereo(out_left, out_right, s->block_samples, info->log_limit);

        if (bits < info->best_bits) {
            info->best_bits = bits;
            CLEAR(s->decorr_passes);
            memcpy(s->decorr_passes, info->dps, sizeof(info->dps[0]) * (depth + 1));
            memcpy(s->sampleptrs[info->nterms + 1][0], s->sampleptrs[depth + 1][0],
                   s->block_samples * 4);
            memcpy(s->sampleptrs[info->nterms + 1][1], s->sampleptrs[depth + 1][1],
                   s->block_samples * 4);
        }

        term_bits[term + 3] = bits;
    }

    while (depth + 1 < info->nterms && branches--) {
        uint32_t local_best_bits = input_bits;
        int best_term = 0, i;

        for (i = 0; i < 22; i++)
            if (term_bits[i] && term_bits[i] < local_best_bits) {
                local_best_bits = term_bits[i];
                best_term = i - 3;
            }

        if (!best_term)
            break;

        term_bits[best_term + 3] = 0;

        info->dps[depth].value = best_term;
        info->dps[depth].delta = delta;
        decorr_stereo_buffer(info, in_left, in_right, out_left, out_right,
                             s->block_samples, depth);

        recurse_stereo(s, info, depth + 1, delta, local_best_bits);
    }
}

static void analyze_stereo(WavPackEncodeContext *s,
                           int32_t *in_left, int32_t *in_right,
                           int do_samples)
{
    WavPackExtraInfo info;
    int i;

    info.gt16bit = ((s->flags & MAG_MASK) >> MAG_LSB) >= 16;

    info.log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
    info.log_limit = FFMIN(6912, info.log_limit);

    info.nterms = s->num_terms;

    if (allocate_buffers2(s, s->num_terms))
        return;

    memcpy(info.dps, s->decorr_passes, sizeof(info.dps));
    memcpy(s->sampleptrs[0][0], in_left,  s->block_samples * 4);
    memcpy(s->sampleptrs[0][1], in_right, s->block_samples * 4);

    for (i = 0; i < info.nterms && info.dps[i].value; i++)
        if (info.gt16bit)
            decorr_stereo(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
                          s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
                          s->block_samples, info.dps + i, 1);
        else
            decorr_stereo_quick(s->sampleptrs[i    ][0], s->sampleptrs[i    ][1],
                                s->sampleptrs[i + 1][0], s->sampleptrs[i + 1][1],
                                s->block_samples, info.dps + i);

    info.best_bits = log2stereo(s->sampleptrs[info.nterms][0], s->sampleptrs[info.nterms][1],
                                s->block_samples, 0);

    memcpy(s->sampleptrs[info.nterms + 1][0], s->sampleptrs[i][0], s->block_samples * 4);
    memcpy(s->sampleptrs[info.nterms + 1][1], s->sampleptrs[i][1], s->block_samples * 4);

    if (s->extra_flags & EXTRA_BRANCHES)
        recurse_stereo(s, &info, 0, (int) floor(s->delta_decay + 0.5),
                       log2stereo(s->sampleptrs[0][0], s->sampleptrs[0][1],
                                  s->block_samples, 0));

    if (s->extra_flags & EXTRA_SORT_FIRST)
        sort_stereo(s, &info);

    if (s->extra_flags & EXTRA_TRY_DELTAS) {
        delta_stereo(s, &info);

        if ((s->extra_flags & EXTRA_ADJUST_DELTAS) && s->decorr_passes[0].value)
            s->delta_decay = (float)((s->delta_decay * 2.0 + s->decorr_passes[0].delta) / 3.0);
        else
            s->delta_decay = 2.0;
    }

    if (s->extra_flags & EXTRA_SORT_LAST)
        sort_stereo(s, &info);

    if (do_samples) {
        memcpy(in_left,  s->sampleptrs[info.nterms + 1][0], s->block_samples * 4);
        memcpy(in_right, s->sampleptrs[info.nterms + 1][1], s->block_samples * 4);
    }

    for (i = 0; i < info.nterms; i++)
        if (!s->decorr_passes[i].value)
            break;

    s->num_terms = i;
}

static int wv_stereo(WavPackEncodeContext *s,
                     int32_t *samples_l, int32_t *samples_r,
                     int no_history, int do_samples)
{
    struct Decorr temp_decorr_pass, save_decorr_passes[MAX_TERMS] = {{0}};
    int nb_samples = s->block_samples, ret;
    int buf_size = sizeof(int32_t) * nb_samples;
    int log_limit, force_js = 0, force_ts = 0, got_js = 0, pi, i;
    uint32_t best_size = UINT32_MAX, size;

    for (i = 0; i < nb_samples; i++)
        if (samples_l[i] || samples_r[i])
            break;

    if (i == nb_samples) {
        s->flags &= ~((uint32_t) WV_JOINT_STEREO);
        CLEAR(s->decorr_passes);
        CLEAR(s->w);
        s->num_terms = 0;
        return 0;
    }

    log_limit = (((s->flags & MAG_MASK) >> MAG_LSB) + 4) * 256;
    log_limit = FFMIN(6912, log_limit);

    if (s->joint != -1) {
        force_js =  s->joint;
        force_ts = !s->joint;
    }

    if ((ret = allocate_buffers(s)) < 0)
        return ret;

    if (no_history || s->num_passes >= 7)
        s->best_decorr = s->mask_decorr = 0;

    for (pi = 0; pi < s->num_passes;) {
        const WavPackDecorrSpec *wpds;
        int nterms, c, j;

        if (!pi)
            c = s->best_decorr;
        else {
            if (s->mask_decorr == 0)
                c = 0;
            else
                c = (s->best_decorr & (s->mask_decorr - 1)) | s->mask_decorr;

            if (c == s->best_decorr) {
                s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
                continue;
            }
        }

        wpds = &s->decorr_specs[c];
        nterms = decorr_filter_nterms[s->decorr_filter];

        while (1) {
            if (force_js || (wpds->joint_stereo && !force_ts)) {
                if (!got_js) {
                    av_fast_padded_malloc(&s->js_left,  &s->js_left_size,  buf_size);
                    av_fast_padded_malloc(&s->js_right, &s->js_right_size, buf_size);
                    memcpy(s->js_left,  samples_l, buf_size);
                    memcpy(s->js_right, samples_r, buf_size);

                    for (i = 0; i < nb_samples; i++)
                        s->js_right[i] += ((s->js_left[i] -= s->js_right[i]) >> 1);
                    got_js = 1;
                }

                memcpy(s->temp_buffer[0][0], s->js_left,  buf_size);
                memcpy(s->temp_buffer[0][1], s->js_right, buf_size);
            } else {
                memcpy(s->temp_buffer[0][0], samples_l, buf_size);
                memcpy(s->temp_buffer[0][1], samples_r, buf_size);
            }

            CLEAR(save_decorr_passes);

            for (j = 0; j < nterms; j++) {
                CLEAR(temp_decorr_pass);
                temp_decorr_pass.delta = wpds->delta;
                temp_decorr_pass.value = wpds->terms[j];

                if (temp_decorr_pass.value < 0 && !(s->flags & WV_CROSS_DECORR))
                    temp_decorr_pass.value = -3;

                decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
                              s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
                              FFMIN(2048, nb_samples), &temp_decorr_pass, -1);

                if (j) {
                    CLEAR(temp_decorr_pass.samplesA);
                    CLEAR(temp_decorr_pass.samplesB);
                } else {
                    reverse_decorr(&temp_decorr_pass);
                }

                memcpy(save_decorr_passes + j, &temp_decorr_pass, sizeof(struct Decorr));

                if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16)
                    decorr_stereo(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
                                  s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
                                  nb_samples, &temp_decorr_pass, 1);
                else
                    decorr_stereo_quick(s->temp_buffer[ j&1][0], s->temp_buffer[ j&1][1],
                                        s->temp_buffer[~j&1][0], s->temp_buffer[~j&1][1],
                                        nb_samples, &temp_decorr_pass);
            }

            size = log2stereo(s->temp_buffer[j&1][0], s->temp_buffer[j&1][1],
                              nb_samples, log_limit);
            if (size != UINT32_MAX || !nterms)
                break;
            nterms >>= 1;
        }

        if (size < best_size) {
            memcpy(s->best_buffer[0], s->temp_buffer[j&1][0], buf_size);
            memcpy(s->best_buffer[1], s->temp_buffer[j&1][1], buf_size);
            memcpy(s->decorr_passes, save_decorr_passes, sizeof(struct Decorr) * MAX_TERMS);
            s->num_terms = nterms;
            s->best_decorr = c;
            best_size = size;
        }

        if (pi++)
            s->mask_decorr = s->mask_decorr ? ((s->mask_decorr << 1) & (s->num_decorrs - 1)) : 1;
    }

    if (force_js || (s->decorr_specs[s->best_decorr].joint_stereo && !force_ts))
        s->flags |= WV_JOINT_STEREO;
    else
        s->flags &= ~((uint32_t) WV_JOINT_STEREO);

    if (s->extra_flags) {
        if (s->flags & WV_JOINT_STEREO) {
            analyze_stereo(s, s->js_left, s->js_right, do_samples);

            if (do_samples) {
                memcpy(samples_l, s->js_left,  buf_size);
                memcpy(samples_r, s->js_right, buf_size);
            }
        } else
            analyze_stereo(s, samples_l, samples_r, do_samples);
    } else if (do_samples) {
        memcpy(samples_l, s->best_buffer[0], buf_size);
        memcpy(samples_r, s->best_buffer[1], buf_size);
    }

    if (s->extra_flags || no_history ||
        s->joint_stereo != s->decorr_specs[s->best_decorr].joint_stereo) {
        s->joint_stereo = s->decorr_specs[s->best_decorr].joint_stereo;
        CLEAR(s->w);
        scan_word(s, &s->w.c[0], s->best_buffer[0], nb_samples, -1);
        scan_word(s, &s->w.c[1], s->best_buffer[1], nb_samples, -1);
    }
    return 0;
}

static void encode_flush(WavPackEncodeContext *s)
{
    WavPackWords *w = &s->w;
    PutBitContext *pb = &s->pb;

    if (w->zeros_acc) {
        int cbits = count_bits(w->zeros_acc);

        do {
            if (cbits > 31) {
                put_bits(pb, 31, 0x7FFFFFFF);
                cbits -= 31;
            } else {
                put_bits(pb, cbits, (1 << cbits) - 1);
                cbits = 0;
            }
        } while (cbits);

        put_bits(pb, 1, 0);

        while (w->zeros_acc > 1) {
            put_bits(pb, 1, w->zeros_acc & 1);
            w->zeros_acc >>= 1;
        }

        w->zeros_acc = 0;
    }

    if (w->holding_one) {
        if (w->holding_one >= 16) {
            int cbits;

            put_bits(pb, 16, (1 << 16) - 1);
            put_bits(pb, 1, 0);
            w->holding_one -= 16;
            cbits = count_bits(w->holding_one);

            do {
                if (cbits > 31) {
                    put_bits(pb, 31, 0x7FFFFFFF);
                    cbits -= 31;
                } else {
                    put_bits(pb, cbits, (1 << cbits) - 1);
                    cbits = 0;
                }
            } while (cbits);

            put_bits(pb, 1, 0);

            while (w->holding_one > 1) {
                put_bits(pb, 1, w->holding_one & 1);
                w->holding_one >>= 1;
            }

            w->holding_zero = 0;
        } else {
            put_bits(pb, w->holding_one, (1 << w->holding_one) - 1);
        }

        w->holding_one = 0;
    }

    if (w->holding_zero) {
        put_bits(pb, 1, 0);
        w->holding_zero = 0;
    }

    if (w->pend_count) {
        put_bits(pb, w->pend_count, w->pend_data);
        w->pend_data = w->pend_count = 0;
    }
}

static void wavpack_encode_sample(WavPackEncodeContext *s, WvChannel *c, int32_t sample)
{
    WavPackWords *w = &s->w;
    uint32_t ones_count, low, high;
    int sign = sample < 0;

    if (s->w.c[0].median[0] < 2 && !s->w.holding_zero && s->w.c[1].median[0] < 2) {
        if (w->zeros_acc) {
            if (sample)
                encode_flush(s);
            else {
                w->zeros_acc++;
                return;
            }
        } else if (sample) {
            put_bits(&s->pb, 1, 0);
        } else {
            CLEAR(s->w.c[0].median);
            CLEAR(s->w.c[1].median);
            w->zeros_acc = 1;
            return;
        }
    }

    if (sign)
        sample = ~sample;

    if (sample < (int32_t) GET_MED(0)) {
        ones_count = low = 0;
        high = GET_MED(0) - 1;
        DEC_MED(0);
    } else {
        low = GET_MED(0);
        INC_MED(0);

        if (sample - low < GET_MED(1)) {
            ones_count = 1;
            high = low + GET_MED(1) - 1;
            DEC_MED(1);
        } else {
            low += GET_MED(1);
            INC_MED(1);

            if (sample - low < GET_MED(2)) {
                ones_count = 2;
                high = low + GET_MED(2) - 1;
                DEC_MED(2);
            } else {
                ones_count = 2 + (sample - low) / GET_MED(2);
                low += (ones_count - 2) * GET_MED(2);
                high = low + GET_MED(2) - 1;
                INC_MED(2);
            }
        }
    }

    if (w->holding_zero) {
        if (ones_count)
            w->holding_one++;

        encode_flush(s);

        if (ones_count) {
            w->holding_zero = 1;
            ones_count--;
        } else
            w->holding_zero = 0;
    } else
        w->holding_zero = 1;

    w->holding_one = ones_count * 2;

    if (high != low) {
        uint32_t maxcode = high - low, code = sample - low;
        int bitcount = count_bits(maxcode);
        uint32_t extras = (1 << bitcount) - maxcode - 1;

        if (code < extras) {
            w->pend_data |= code << w->pend_count;
            w->pend_count += bitcount - 1;
        } else {
            w->pend_data |= ((code + extras) >> 1) << w->pend_count;
            w->pend_count += bitcount - 1;
            w->pend_data |= ((code + extras) & 1) << w->pend_count++;
        }
    }

    w->pend_data |= ((int32_t) sign << w->pend_count++);

    if (!w->holding_zero)
        encode_flush(s);
}

static void pack_int32(WavPackEncodeContext *s,
                       int32_t *samples_l, int32_t *samples_r,
                       int nb_samples)
{
    const int sent_bits = s->int32_sent_bits;
    PutBitContext *pb = &s->pb;
    int i, pre_shift;

    pre_shift = s->int32_zeros + s->int32_ones + s->int32_dups;

    if (!sent_bits)
        return;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++) {
            put_sbits(pb, sent_bits, samples_l[i] >> pre_shift);
        }
    } else {
        for (i = 0; i < nb_samples; i++) {
            put_sbits(pb, sent_bits, samples_l[i] >> pre_shift);
            put_sbits(pb, sent_bits, samples_r[i] >> pre_shift);
        }
    }
}

static void pack_float_sample(WavPackEncodeContext *s, int32_t *sample)
{
    const int max_exp = s->float_max_exp;
    PutBitContext *pb = &s->pb;
    int32_t value, shift_count;

    if (get_exponent(*sample) == 255) {
        if (get_mantissa(*sample)) {
            put_bits(pb, 1, 1);
            put_bits(pb, 23, get_mantissa(*sample));
        } else {
            put_bits(pb, 1, 0);
        }

        value = 0x1000000;
        shift_count = 0;
    } else if (get_exponent(*sample)) {
        shift_count = max_exp - get_exponent(*sample);
        value = 0x800000 + get_mantissa(*sample);
    } else {
        shift_count = max_exp ? max_exp - 1 : 0;
        value = get_mantissa(*sample);
    }

    if (shift_count < 25)
        value >>= shift_count;
    else
        value = 0;

    if (!value) {
        if (s->float_flags & FLOAT_ZEROS_SENT) {
            if (get_exponent(*sample) || get_mantissa(*sample)) {
                put_bits(pb, 1, 1);
                put_bits(pb, 23, get_mantissa(*sample));

                if (max_exp >= 25)
                    put_bits(pb, 8, get_exponent(*sample));

                put_bits(pb, 1, get_sign(*sample));
            } else {
                put_bits(pb, 1, 0);

                if (s->float_flags & FLOAT_NEG_ZEROS)
                    put_bits(pb, 1, get_sign(*sample));
            }
        }
    } else if (shift_count) {
        if (s->float_flags & FLOAT_SHIFT_SENT) {
            put_sbits(pb, shift_count, get_mantissa(*sample));
        } else if (s->float_flags & FLOAT_SHIFT_SAME) {
            put_bits(pb, 1, get_mantissa(*sample) & 1);
        }
    }
}

static void pack_float(WavPackEncodeContext *s,
                       int32_t *samples_l, int32_t *samples_r,
                       int nb_samples)
{
    int i;

    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++)
            pack_float_sample(s, &samples_l[i]);
    } else {
        for (i = 0; i < nb_samples; i++) {
            pack_float_sample(s, &samples_l[i]);
            pack_float_sample(s, &samples_r[i]);
        }
    }
}

static void decorr_stereo_pass2(struct Decorr *dpp,
                                int32_t *samples_l, int32_t *samples_r,
                                int nb_samples)
{
    int i, m, k;

    switch (dpp->value) {
    case 17:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            dpp->samplesA[1] = dpp->samplesA[0];
            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
            dpp->samplesB[1] = dpp->samplesB[0];
            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    case 18:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
            dpp->samplesA[1] = dpp->samplesA[0];
            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
            dpp->samplesB[1] = dpp->samplesB[0];
            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    default:
        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[m];
            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam);
            UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[m];
            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam);
            UPDATE_WEIGHT(dpp->weightB, dpp->delta, sam, tmp);

            m = (m + 1) & (MAX_TERM - 1);
            k = (k + 1) & (MAX_TERM - 1);
        }
        if (m) {
            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];

            memcpy(temp_A, dpp->samplesA, sizeof (dpp->samplesA));
            memcpy(temp_B, dpp->samplesB, sizeof (dpp->samplesB));

            for (k = 0; k < MAX_TERM; k++) {
                dpp->samplesA[k] = temp_A[m];
                dpp->samplesB[k] = temp_B[m];
                m = (m + 1) & (MAX_TERM - 1);
            }
        }
        break;
    case -1:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);

            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);
        }
        break;
    case -2:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_B = dpp->samplesB[0];
            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);

            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    case -3:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            sam_B = dpp->samplesB[0];

            dpp->samplesA[0] = tmp = samples_r[i];
            samples_r[i] = tmp -= APPLY_WEIGHT(dpp->weightB, sam_B);
            UPDATE_WEIGHT_CLIP(dpp->weightB, dpp->delta, sam_B, tmp);

            dpp->samplesB[0] = tmp = samples_l[i];
            samples_l[i] = tmp -= APPLY_WEIGHT(dpp->weightA, sam_A);
            UPDATE_WEIGHT_CLIP(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    }
}

#define update_weight_d2(weight, delta, source, result) \
    if (source && result) \
        weight -= (((source ^ result) >> 29) & 4) - 2;

#define update_weight_clip_d2(weight, delta, source, result) \
    if (source && result) { \
        const int32_t s = (source ^ result) >> 31; \
        if ((weight = (weight ^ s) + (2 - s)) > 1024) weight = 1024; \
        weight = (weight ^ s) - s; \
    }

static void decorr_stereo_pass_id2(struct Decorr *dpp,
                                   int32_t *samples_l, int32_t *samples_r,
                                   int nb_samples)
{
    int i, m, k;

    switch (dpp->value) {
    case 17:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
            dpp->samplesA[1] = dpp->samplesA[0];
            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);

            sam = 2 * dpp->samplesB[0] - dpp->samplesB[1];
            dpp->samplesB[1] = dpp->samplesB[0];
            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    case 18:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[0] + ((dpp->samplesA[0] - dpp->samplesA[1]) >> 1);
            dpp->samplesA[1] = dpp->samplesA[0];
            samples_l[i] = tmp = (dpp->samplesA[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[0] + ((dpp->samplesB[0] - dpp->samplesB[1]) >> 1);
            dpp->samplesB[1] = dpp->samplesB[0];
            samples_r[i] = tmp = (dpp->samplesB[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);
        }
        break;
    default:
        for (m = 0, k = dpp->value & (MAX_TERM - 1), i = 0; i < nb_samples; i++) {
            int32_t sam, tmp;

            sam = dpp->samplesA[m];
            samples_l[i] = tmp = (dpp->samplesA[k] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam);
            update_weight_d2(dpp->weightA, dpp->delta, sam, tmp);

            sam = dpp->samplesB[m];
            samples_r[i] = tmp = (dpp->samplesB[k] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam);
            update_weight_d2(dpp->weightB, dpp->delta, sam, tmp);

            m = (m + 1) & (MAX_TERM - 1);
            k = (k + 1) & (MAX_TERM - 1);
        }

        if (m) {
            int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];

            memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
            memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));

            for (k = 0; k < MAX_TERM; k++) {
                dpp->samplesA[k] = temp_A[m];
                dpp->samplesB[k] = temp_B[m];
                m = (m + 1) & (MAX_TERM - 1);
            }
        }
        break;
    case -1:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            samples_l[i] = tmp = (sam_B = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);

            samples_r[i] = tmp = (dpp->samplesA[0] = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);
        }
        break;
    case -2:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_B = dpp->samplesB[0];
            samples_r[i] = tmp = (sam_A = samples_r[i]) - APPLY_WEIGHT_I(dpp->weightB, sam_B);
            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);

            samples_l[i] = tmp = (dpp->samplesB[0] = samples_l[i]) - APPLY_WEIGHT_I(dpp->weightA, sam_A);
            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    case -3:
        for (i = 0; i < nb_samples; i++) {
            int32_t sam_A, sam_B, tmp;

            sam_A = dpp->samplesA[0];
            sam_B = dpp->samplesB[0];

            dpp->samplesA[0] = tmp = samples_r[i];
            samples_r[i] = tmp -= APPLY_WEIGHT_I(dpp->weightB, sam_B);
            update_weight_clip_d2(dpp->weightB, dpp->delta, sam_B, tmp);

            dpp->samplesB[0] = tmp = samples_l[i];
            samples_l[i] = tmp -= APPLY_WEIGHT_I(dpp->weightA, sam_A);
            update_weight_clip_d2(dpp->weightA, dpp->delta, sam_A, tmp);
        }
        break;
    }
}

static void put_metadata_block(PutByteContext *pb, int flags, int size)
{
    if (size & 1)
        flags |= WP_IDF_ODD;

    bytestream2_put_byte(pb, flags);
    bytestream2_put_byte(pb, (size + 1) >> 1);
}

static int wavpack_encode_block(WavPackEncodeContext *s,
                                int32_t *samples_l, int32_t *samples_r,
                                uint8_t *out, int out_size)
{
    int block_size, start, end, data_size, tcount, temp, m = 0;
    int i, j, ret = 0, got_extra = 0, nb_samples = s->block_samples;
    uint32_t crc = 0xffffffffu;
    struct Decorr *dpp;
    PutByteContext pb;

    if (s->flags & WV_MONO_DATA) {
        CLEAR(s->w);
    }
    if (!(s->flags & WV_MONO) && s->optimize_mono) {
        int32_t lor = 0, diff = 0;

        for (i = 0; i < nb_samples; i++) {
            lor  |= samples_l[i] | samples_r[i];
            diff |= samples_l[i] - samples_r[i];

            if (lor && diff)
                break;
        }

        if (i == nb_samples && lor && !diff) {
            s->flags &= ~(WV_JOINT_STEREO | WV_CROSS_DECORR);
            s->flags |= WV_FALSE_STEREO;

            if (!s->false_stereo) {
                s->false_stereo = 1;
                s->num_terms = 0;
                CLEAR(s->w);
            }
        } else if (s->false_stereo) {
            s->false_stereo = 0;
            s->num_terms = 0;
            CLEAR(s->w);
        }
    }

    if (s->flags & SHIFT_MASK) {
        int shift = (s->flags & SHIFT_MASK) >> SHIFT_LSB;
        int mag = (s->flags & MAG_MASK) >> MAG_LSB;

        if (s->flags & WV_MONO_DATA)
            shift_mono(samples_l, nb_samples, shift);
        else
            shift_stereo(samples_l, samples_r, nb_samples, shift);

        if ((mag -= shift) < 0)
            s->flags &= ~MAG_MASK;
        else
            s->flags -= (1 << MAG_LSB) * shift;
    }

    if ((s->flags & WV_FLOAT_DATA) || (s->flags & MAG_MASK) >> MAG_LSB >= 24) {
        av_fast_padded_malloc(&s->orig_l, &s->orig_l_size, sizeof(int32_t) * nb_samples);
        memcpy(s->orig_l, samples_l, sizeof(int32_t) * nb_samples);
        if (!(s->flags & WV_MONO_DATA)) {
            av_fast_padded_malloc(&s->orig_r, &s->orig_r_size, sizeof(int32_t) * nb_samples);
            memcpy(s->orig_r, samples_r, sizeof(int32_t) * nb_samples);
        }

        if (s->flags & WV_FLOAT_DATA)
            got_extra = scan_float(s, samples_l, samples_r, nb_samples);
        else
            got_extra = scan_int32(s, samples_l, samples_r, nb_samples);
        s->num_terms = 0;
    } else {
        scan_int23(s, samples_l, samples_r, nb_samples);
        if (s->shift != s->int32_zeros + s->int32_ones + s->int32_dups) {
            s->shift = s->int32_zeros + s->int32_ones + s->int32_dups;
            s->num_terms = 0;
        }
    }

    if (!s->num_passes && !s->num_terms) {
        s->num_passes = 1;

        if (s->flags & WV_MONO_DATA)
            ret = wv_mono(s, samples_l, 1, 0);
        else
            ret = wv_stereo(s, samples_l, samples_r, 1, 0);

        s->num_passes = 0;
    }
    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++)
            crc += (crc << 1) + samples_l[i];

        if (s->num_passes)
            ret = wv_mono(s, samples_l, !s->num_terms, 1);
    } else {
        for (i = 0; i < nb_samples; i++)
            crc += (crc << 3) + ((uint32_t)samples_l[i] << 1) + samples_l[i] + samples_r[i];

        if (s->num_passes)
            ret = wv_stereo(s, samples_l, samples_r, !s->num_terms, 1);
    }
    if (ret < 0)
        return ret;

    if (!s->ch_offset)
        s->flags |= WV_INITIAL_BLOCK;

    s->ch_offset += 1 + !(s->flags & WV_MONO);

    if (s->ch_offset == s->avctx->ch_layout.nb_channels)
        s->flags |= WV_FINAL_BLOCK;

    bytestream2_init_writer(&pb, out, out_size);
    bytestream2_put_le32(&pb, MKTAG('w', 'v', 'p', 'k'));
    bytestream2_put_le32(&pb, 0);
    bytestream2_put_le16(&pb, 0x410);
    bytestream2_put_le16(&pb, 0);
    bytestream2_put_le32(&pb, 0);
    bytestream2_put_le32(&pb, s->sample_index);
    bytestream2_put_le32(&pb, nb_samples);
    bytestream2_put_le32(&pb, s->flags);
    bytestream2_put_le32(&pb, crc);

    if (s->flags & WV_INITIAL_BLOCK &&
        s->avctx->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_MONO &&
        s->avctx->ch_layout.u.mask != AV_CH_LAYOUT_STEREO) {
        put_metadata_block(&pb, WP_ID_CHANINFO, 5);
        bytestream2_put_byte(&pb, s->avctx->ch_layout.nb_channels);
        if (s->avctx->ch_layout.u.mask >> 32)
            bytestream2_put_le32(&pb, 0);
        else
            bytestream2_put_le32(&pb, s->avctx->ch_layout.u.mask);
        bytestream2_put_byte(&pb, 0);
    } else if (s->flags & WV_INITIAL_BLOCK &&
               s->avctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC) {
        put_metadata_block(&pb, WP_ID_CHANINFO, 5);
        bytestream2_put_byte(&pb, s->avctx->ch_layout.nb_channels);
        bytestream2_put_le32(&pb, 0);
        bytestream2_put_byte(&pb, 0);
    }

    if ((s->flags & SRATE_MASK) == SRATE_MASK) {
        put_metadata_block(&pb, WP_ID_SAMPLE_RATE, 3);
        bytestream2_put_le24(&pb, s->avctx->sample_rate);
        bytestream2_put_byte(&pb, 0);
    }

    put_metadata_block(&pb, WP_ID_DECTERMS, s->num_terms);
    for (i = 0; i < s->num_terms; i++) {
        struct Decorr *dpp = &s->decorr_passes[i];
        bytestream2_put_byte(&pb, ((dpp->value + 5) & 0x1f) | ((dpp->delta << 5) & 0xe0));
    }
    if (s->num_terms & 1)
        bytestream2_put_byte(&pb, 0);

#define WRITE_DECWEIGHT(type) do {            \
        temp = store_weight(type);    \
        bytestream2_put_byte(&pb, temp);      \
        type = restore_weight(temp);  \
    } while (0)

    bytestream2_put_byte(&pb, WP_ID_DECWEIGHTS);
    bytestream2_put_byte(&pb, 0);
    start = bytestream2_tell_p(&pb);
    for (i = s->num_terms - 1; i >= 0; --i) {
        struct Decorr *dpp = &s->decorr_passes[i];

        if (store_weight(dpp->weightA) ||
            (!(s->flags & WV_MONO_DATA) && store_weight(dpp->weightB)))
                break;
    }
    tcount = i + 1;
    for (i = 0; i < s->num_terms; i++) {
        struct Decorr *dpp = &s->decorr_passes[i];
        if (i < tcount) {
            WRITE_DECWEIGHT(dpp->weightA);
            if (!(s->flags & WV_MONO_DATA))
                WRITE_DECWEIGHT(dpp->weightB);
        } else {
            dpp->weightA = dpp->weightB = 0;
        }
    }
    end = bytestream2_tell_p(&pb);
    out[start - 2] = WP_ID_DECWEIGHTS | (((end - start) & 1) ? WP_IDF_ODD: 0);
    out[start - 1] = (end - start + 1) >> 1;
    if ((end - start) & 1)
        bytestream2_put_byte(&pb, 0);

#define WRITE_DECSAMPLE(type) do {        \
        temp = log2s(type);               \
        type = wp_exp2(temp);             \
        bytestream2_put_le16(&pb, temp);  \
    } while (0)

    bytestream2_put_byte(&pb, WP_ID_DECSAMPLES);
    bytestream2_put_byte(&pb, 0);
    start = bytestream2_tell_p(&pb);
    for (i = 0; i < s->num_terms; i++) {
        struct Decorr *dpp = &s->decorr_passes[i];
        if (i == 0) {
            if (dpp->value > MAX_TERM) {
                WRITE_DECSAMPLE(dpp->samplesA[0]);
                WRITE_DECSAMPLE(dpp->samplesA[1]);
                if (!(s->flags & WV_MONO_DATA)) {
                    WRITE_DECSAMPLE(dpp->samplesB[0]);
                    WRITE_DECSAMPLE(dpp->samplesB[1]);
                }
            } else if (dpp->value < 0) {
                WRITE_DECSAMPLE(dpp->samplesA[0]);
                WRITE_DECSAMPLE(dpp->samplesB[0]);
            } else {
                for (j = 0; j < dpp->value; j++) {
                    WRITE_DECSAMPLE(dpp->samplesA[j]);
                    if (!(s->flags & WV_MONO_DATA))
                        WRITE_DECSAMPLE(dpp->samplesB[j]);
                }
            }
        } else {
            CLEAR(dpp->samplesA);
            CLEAR(dpp->samplesB);
        }
    }
    end = bytestream2_tell_p(&pb);
    out[start - 1] = (end - start) >> 1;

#define WRITE_CHAN_ENTROPY(chan) do {               \
        for (i = 0; i < 3; i++) {                   \
            temp = wp_log2(s->w.c[chan].median[i]); \
            bytestream2_put_le16(&pb, temp);        \
            s->w.c[chan].median[i] = wp_exp2(temp); \
        }                                           \
    } while (0)

    put_metadata_block(&pb, WP_ID_ENTROPY, 6 * (1 + (!(s->flags & WV_MONO_DATA))));
    WRITE_CHAN_ENTROPY(0);
    if (!(s->flags & WV_MONO_DATA))
        WRITE_CHAN_ENTROPY(1);

    if (s->flags & WV_FLOAT_DATA) {
        put_metadata_block(&pb, WP_ID_FLOATINFO, 4);
        bytestream2_put_byte(&pb, s->float_flags);
        bytestream2_put_byte(&pb, s->float_shift);
        bytestream2_put_byte(&pb, s->float_max_exp);
        bytestream2_put_byte(&pb, 127);
    }

    if (s->flags & WV_INT32_DATA) {
        put_metadata_block(&pb, WP_ID_INT32INFO, 4);
        bytestream2_put_byte(&pb, s->int32_sent_bits);
        bytestream2_put_byte(&pb, s->int32_zeros);
        bytestream2_put_byte(&pb, s->int32_ones);
        bytestream2_put_byte(&pb, s->int32_dups);
    }

    if (s->flags & WV_MONO_DATA && !s->num_passes) {
        for (i = 0; i < nb_samples; i++) {
            int32_t code = samples_l[i];

            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++) {
                int32_t sam;

                if (dpp->value > MAX_TERM) {
                    if (dpp->value & 1)
                        sam = 2 * dpp->samplesA[0] - dpp->samplesA[1];
                    else
                        sam = (3 * dpp->samplesA[0] - dpp->samplesA[1]) >> 1;

                    dpp->samplesA[1] = dpp->samplesA[0];
                    dpp->samplesA[0] = code;
                } else {
                    sam = dpp->samplesA[m];
                    dpp->samplesA[(m + dpp->value) & (MAX_TERM - 1)] = code;
                }

                code -= APPLY_WEIGHT(dpp->weightA, sam);
                UPDATE_WEIGHT(dpp->weightA, dpp->delta, sam, code);
            }

            m = (m + 1) & (MAX_TERM - 1);
            samples_l[i] = code;
        }
        if (m) {
            for (tcount = s->num_terms, dpp = s->decorr_passes; tcount--; dpp++)
                if (dpp->value > 0 && dpp->value <= MAX_TERM) {
                int32_t temp_A[MAX_TERM], temp_B[MAX_TERM];
                int k;

                memcpy(temp_A, dpp->samplesA, sizeof(dpp->samplesA));
                memcpy(temp_B, dpp->samplesB, sizeof(dpp->samplesB));

                for (k = 0; k < MAX_TERM; k++) {
                    dpp->samplesA[k] = temp_A[m];
                    dpp->samplesB[k] = temp_B[m];
                    m = (m + 1) & (MAX_TERM - 1);
                }
            }
        }
    } else if (!s->num_passes) {
        if (s->flags & WV_JOINT_STEREO) {
            for (i = 0; i < nb_samples; i++)
                samples_r[i] += ((samples_l[i] -= samples_r[i]) >> 1);
        }

        for (i = 0; i < s->num_terms; i++) {
            struct Decorr *dpp = &s->decorr_passes[i];
            if (((s->flags & MAG_MASK) >> MAG_LSB) >= 16 || dpp->delta != 2)
                decorr_stereo_pass2(dpp, samples_l, samples_r, nb_samples);
            else
                decorr_stereo_pass_id2(dpp, samples_l, samples_r, nb_samples);
        }
    }

    bytestream2_put_byte(&pb, WP_ID_DATA | WP_IDF_LONG);
    init_put_bits(&s->pb, pb.buffer + 3, bytestream2_get_bytes_left_p(&pb));
    if (s->flags & WV_MONO_DATA) {
        for (i = 0; i < nb_samples; i++)
            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
    } else {
        for (i = 0; i < nb_samples; i++) {
            wavpack_encode_sample(s, &s->w.c[0], s->samples[0][i]);
            wavpack_encode_sample(s, &s->w.c[1], s->samples[1][i]);
        }
    }
    encode_flush(s);
    flush_put_bits(&s->pb);
    data_size = put_bytes_output(&s->pb);
    bytestream2_put_le24(&pb, (data_size + 1) >> 1);
    bytestream2_skip_p(&pb, data_size);
    if (data_size & 1)
        bytestream2_put_byte(&pb, 0);

    if (got_extra) {
        bytestream2_put_byte(&pb, WP_ID_EXTRABITS | WP_IDF_LONG);
        init_put_bits(&s->pb, pb.buffer + 7, bytestream2_get_bytes_left_p(&pb));
        if (s->flags & WV_FLOAT_DATA)
            pack_float(s, s->orig_l, s->orig_r, nb_samples);
        else
            pack_int32(s, s->orig_l, s->orig_r, nb_samples);
        flush_put_bits(&s->pb);
        data_size = put_bytes_output(&s->pb);
        bytestream2_put_le24(&pb, (data_size + 5) >> 1);
        bytestream2_put_le32(&pb, s->crc_x);
        bytestream2_skip_p(&pb, data_size);
        if (data_size & 1)
            bytestream2_put_byte(&pb, 0);
    }

    block_size = bytestream2_tell_p(&pb);
    AV_WL32(out + 4, block_size - 8);

    av_assert0(!bytestream2_get_eof(&pb));

    return block_size;
}

static void fill_buffer(WavPackEncodeContext *s,
                        const int8_t *src, int32_t *dst,
                        int nb_samples)
{
    int i;

#define COPY_SAMPLES(type, offset, shift) do {            \
        const type *sptr = (const type *)src;             \
        for (i = 0; i < nb_samples; i++)                  \
            dst[i] = (sptr[i] - offset) >> shift;         \
    } while (0)

    switch (s->avctx->sample_fmt) {
    case AV_SAMPLE_FMT_U8P:
        COPY_SAMPLES(uint8_t, 0x80, 0);
        break;
    case AV_SAMPLE_FMT_S16P:
        COPY_SAMPLES(int16_t, 0, 0);
        break;
    case AV_SAMPLE_FMT_S32P:
        if (s->avctx->bits_per_raw_sample <= 24) {
            COPY_SAMPLES(int32_t, 0, 8);
            break;
        }
    case AV_SAMPLE_FMT_FLTP:
        memcpy(dst, src, nb_samples * 4);
    }
}

static void set_samplerate(WavPackEncodeContext *s)
{
    int i;

    for (i = 0; i < 15; i++) {
        if (wv_rates[i] == s->avctx->sample_rate)
            break;
    }

    s->flags = i << SRATE_LSB;
}

static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                                const AVFrame *frame, int *got_packet_ptr)
{
    WavPackEncodeContext *s = avctx->priv_data;
    int buf_size, ret;
    uint8_t *buf;

    s->block_samples = frame->nb_samples;
    av_fast_padded_malloc(&s->samples[0], &s->samples_size[0],
                          sizeof(int32_t) * s->block_samples);
    if (!s->samples[0])
        return AVERROR(ENOMEM);
    if (avctx->ch_layout.nb_channels > 1) {
        av_fast_padded_malloc(&s->samples[1], &s->samples_size[1],
                              sizeof(int32_t) * s->block_samples);
        if (!s->samples[1])
            return AVERROR(ENOMEM);
    }

    buf_size = s->block_samples * avctx->ch_layout.nb_channels * 8
             + 200 * avctx->ch_layout.nb_channels /* for headers */;
    if ((ret = ff_alloc_packet(avctx, avpkt, buf_size)) < 0)
        return ret;
    buf = avpkt->data;

    for (s->ch_offset = 0; s->ch_offset < avctx->ch_layout.nb_channels;) {
        set_samplerate(s);

        switch (s->avctx->sample_fmt) {
        case AV_SAMPLE_FMT_S16P: s->flags |= 1; break;
        case AV_SAMPLE_FMT_S32P: s->flags |= 3 - (s->avctx->bits_per_raw_sample <= 24); break;
        case AV_SAMPLE_FMT_FLTP: s->flags |= 3 | WV_FLOAT_DATA;
        }

        fill_buffer(s, frame->extended_data[s->ch_offset], s->samples[0], s->block_samples);
        if (avctx->ch_layout.nb_channels - s->ch_offset == 1) {
            s->flags |= WV_MONO;
        } else {
            s->flags |= WV_CROSS_DECORR;
            fill_buffer(s, frame->extended_data[s->ch_offset + 1], s->samples[1], s->block_samples);
        }

        s->flags += (1 << MAG_LSB) * ((s->flags & 3) * 8 + 7);

        if ((ret = wavpack_encode_block(s, s->samples[0], s->samples[1],
                                        buf, buf_size)) < 0)
            return ret;

        buf      += ret;
        buf_size -= ret;
    }
    s->sample_index += frame->nb_samples;

    avpkt->size     = buf - avpkt->data;
    *got_packet_ptr = 1;
    return 0;
}

static av_cold int wavpack_encode_close(AVCodecContext *avctx)
{
    WavPackEncodeContext *s = avctx->priv_data;
    int i;

    for (i = 0; i < MAX_TERMS + 2; i++) {
        av_freep(&s->sampleptrs[i][0]);
        av_freep(&s->sampleptrs[i][1]);
        s->sampleptrs_size[i][0] = s->sampleptrs_size[i][1] = 0;
    }

    for (i = 0; i < 2; i++) {
        av_freep(&s->samples[i]);
        s->samples_size[i] = 0;

        av_freep(&s->best_buffer[i]);
        s->best_buffer_size[i] = 0;

        av_freep(&s->temp_buffer[i][0]);
        av_freep(&s->temp_buffer[i][1]);
        s->temp_buffer_size[i][0] = s->temp_buffer_size[i][1] = 0;
    }

    av_freep(&s->js_left);
    av_freep(&s->js_right);
    s->js_left_size = s->js_right_size = 0;

    av_freep(&s->orig_l);
    av_freep(&s->orig_r);
    s->orig_l_size = s->orig_r_size = 0;

    return 0;
}

#define OFFSET(x) offsetof(WavPackEncodeContext, x)
#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption options[] = {
    { "joint_stereo",  "", OFFSET(joint), AV_OPT_TYPE_BOOL, {.i64=-1}, -1, 1, FLAGS },
    { "optimize_mono", "", OFFSET(optimize_mono), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS },
    { NULL },
};

static const AVClass wavpack_encoder_class = {
    .class_name = "WavPack encoder",
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
};

const FFCodec ff_wavpack_encoder = {
    .p.name         = "wavpack",
    CODEC_LONG_NAME("WavPack"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_WAVPACK,
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SMALL_LAST_FRAME |
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .priv_data_size = sizeof(WavPackEncodeContext),
    .p.priv_class   = &wavpack_encoder_class,
    .init           = wavpack_encode_init,
    FF_CODEC_ENCODE_CB(wavpack_encode_frame),
    .close          = wavpack_encode_close,
    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_U8P,
                                                     AV_SAMPLE_FMT_S16P,
                                                     AV_SAMPLE_FMT_S32P,
                                                     AV_SAMPLE_FMT_FLTP,
                                                     AV_SAMPLE_FMT_NONE },
};
