/*
 * FLAC audio encoder
 * Copyright (c) 2006  Justin Ruggles <justin.ruggles@gmail.com>
 *
 * 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
 */

#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/crc.h"
#include "libavutil/intmath.h"
#include "libavutil/md5.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"

#include "avcodec.h"
#include "bswapdsp.h"
#include "codec_internal.h"
#include "encode.h"
#include "put_bits.h"
#include "lpc.h"
#include "flac.h"
#include "flacdata.h"
#include "flacencdsp.h"

#define FLAC_SUBFRAME_CONSTANT  0
#define FLAC_SUBFRAME_VERBATIM  1
#define FLAC_SUBFRAME_FIXED     8
#define FLAC_SUBFRAME_LPC      32

#define MAX_FIXED_ORDER     4
#define MAX_PARTITION_ORDER 8
#define MAX_PARTITIONS     (1 << MAX_PARTITION_ORDER)
#define MAX_LPC_PRECISION  15
#define MIN_LPC_SHIFT       0
#define MAX_LPC_SHIFT      15

enum CodingMode {
    CODING_MODE_RICE  = 4,
    CODING_MODE_RICE2 = 5,
};

typedef struct CompressionOptions {
    int compression_level;
    int block_time_ms;
    enum FFLPCType lpc_type;
    int lpc_passes;
    int lpc_coeff_precision;
    int min_prediction_order;
    int max_prediction_order;
    int prediction_order_method;
    int min_partition_order;
    int max_partition_order;
    int ch_mode;
    int exact_rice_parameters;
    int multi_dim_quant;
} CompressionOptions;

typedef struct RiceContext {
    enum CodingMode coding_mode;
    int porder;
    int params[MAX_PARTITIONS];
} RiceContext;

typedef struct FlacSubframe {
    int type;
    int type_code;
    int obits;
    int wasted;
    int order;
    int32_t coefs[MAX_LPC_ORDER];
    int shift;

    RiceContext rc;
    uint32_t rc_udata[FLAC_MAX_BLOCKSIZE];
    uint64_t rc_sums[32][MAX_PARTITIONS];

    int32_t samples[FLAC_MAX_BLOCKSIZE];
    int32_t residual[FLAC_MAX_BLOCKSIZE+11];
} FlacSubframe;

typedef struct FlacFrame {
    FlacSubframe subframes[FLAC_MAX_CHANNELS];
    int64_t samples_33bps[FLAC_MAX_BLOCKSIZE];
    int blocksize;
    int bs_code[2];
    uint8_t crc8;
    int ch_mode;
    int verbatim_only;
} FlacFrame;

typedef struct FlacEncodeContext {
    AVClass *class;
    PutBitContext pb;
    int channels;
    int samplerate;
    int sr_code[2];
    int bps_code;
    int max_blocksize;
    int min_framesize;
    int max_framesize;
    int max_encoded_framesize;
    uint32_t frame_count;
    uint64_t sample_count;
    uint8_t md5sum[16];
    FlacFrame frame;
    CompressionOptions options;
    AVCodecContext *avctx;
    LPCContext lpc_ctx;
    struct AVMD5 *md5ctx;
    uint8_t *md5_buffer;
    unsigned int md5_buffer_size;
    BswapDSPContext bdsp;
    FLACEncDSPContext flac_dsp;

    int flushed;
    int64_t next_pts;
} FlacEncodeContext;


/**
 * Write streaminfo metadata block to byte array.
 */
static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
{
    PutBitContext pb;

    memset(header, 0, FLAC_STREAMINFO_SIZE);
    init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE);

    /* streaminfo metadata block */
    put_bits(&pb, 16, s->max_blocksize);
    put_bits(&pb, 16, s->max_blocksize);
    put_bits(&pb, 24, s->min_framesize);
    put_bits(&pb, 24, s->max_framesize);
    put_bits(&pb, 20, s->samplerate);
    put_bits(&pb, 3, s->channels-1);
    put_bits(&pb,  5, s->avctx->bits_per_raw_sample - 1);
    /* write 36-bit sample count in 2 put_bits() calls */
    put_bits(&pb, 24, (s->sample_count & 0xFFFFFF000LL) >> 12);
    put_bits(&pb, 12,  s->sample_count & 0x000000FFFLL);
    flush_put_bits(&pb);
    memcpy(&header[18], s->md5sum, 16);
}


/**
 * Calculate an estimate for the maximum frame size based on verbatim mode.
 * @param blocksize block size, in samples
 * @param ch number of channels
 * @param bps bits-per-sample
 */
static int flac_get_max_frame_size(int blocksize, int ch, int bps)
{
    /* Technically, there is no limit to FLAC frame size, but an encoder
       should not write a frame that is larger than if verbatim encoding mode
       were to be used. */

    int count;

    count = 16;                  /* frame header */
    count += ch * ((7+bps+7)/8); /* subframe headers */
    if (ch == 2) {
        /* for stereo, need to account for using decorrelation */
        count += (( 2*bps+1) * blocksize + 7) / 8;
    } else {
        count += ( ch*bps    * blocksize + 7) / 8;
    }
    count += 2; /* frame footer */

    return count;
}


/**
 * Set blocksize based on samplerate.
 * Choose the closest predefined blocksize >= BLOCK_TIME_MS milliseconds.
 */
static int select_blocksize(int samplerate, int block_time_ms)
{
    int i;
    int target;
    int blocksize;

    av_assert0(samplerate > 0);
    blocksize = ff_flac_blocksize_table[1];
    target    = (samplerate * block_time_ms) / 1000;
    for (i = 0; i < 16; i++) {
        if (target >= ff_flac_blocksize_table[i] &&
            ff_flac_blocksize_table[i] > blocksize) {
            blocksize = ff_flac_blocksize_table[i];
        }
    }
    return blocksize;
}


static av_cold void dprint_compression_options(FlacEncodeContext *s)
{
    AVCodecContext     *avctx = s->avctx;
    CompressionOptions *opt   = &s->options;

    av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", opt->compression_level);

    switch (opt->lpc_type) {
    case FF_LPC_TYPE_NONE:
        av_log(avctx, AV_LOG_DEBUG, " lpc type: None\n");
        break;
    case FF_LPC_TYPE_FIXED:
        av_log(avctx, AV_LOG_DEBUG, " lpc type: Fixed pre-defined coefficients\n");
        break;
    case FF_LPC_TYPE_LEVINSON:
        av_log(avctx, AV_LOG_DEBUG, " lpc type: Levinson-Durbin recursion with Welch window\n");
        break;
    case FF_LPC_TYPE_CHOLESKY:
        av_log(avctx, AV_LOG_DEBUG, " lpc type: Cholesky factorization, %d pass%s\n",
               opt->lpc_passes, opt->lpc_passes == 1 ? "" : "es");
        break;
    }

    av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n",
           opt->min_prediction_order, opt->max_prediction_order);

    switch (opt->prediction_order_method) {
    case ORDER_METHOD_EST:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "estimate");
        break;
    case ORDER_METHOD_2LEVEL:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "2-level");
        break;
    case ORDER_METHOD_4LEVEL:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "4-level");
        break;
    case ORDER_METHOD_8LEVEL:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "8-level");
        break;
    case ORDER_METHOD_SEARCH:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "full search");
        break;
    case ORDER_METHOD_LOG:
        av_log(avctx, AV_LOG_DEBUG, " order method: %s\n", "log search");
        break;
    }


    av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n",
           opt->min_partition_order, opt->max_partition_order);

    av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", avctx->frame_size);

    av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n",
           opt->lpc_coeff_precision);
}


static av_cold int flac_encode_init(AVCodecContext *avctx)
{
    int freq = avctx->sample_rate;
    int channels = avctx->ch_layout.nb_channels;
    FlacEncodeContext *s = avctx->priv_data;
    int i, level, ret;
    uint8_t *streaminfo;

    s->avctx = avctx;

    switch (avctx->sample_fmt) {
    case AV_SAMPLE_FMT_S16:
        avctx->bits_per_raw_sample = 16;
        s->bps_code                = 4;
        break;
    case AV_SAMPLE_FMT_S32:
        if (avctx->bits_per_raw_sample <= 24) {
            if (avctx->bits_per_raw_sample < 24)
                av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
            avctx->bits_per_raw_sample = 24;
            s->bps_code                = 6;
        } else if (avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
            av_log(avctx, AV_LOG_WARNING,
                   "encoding as 24 bits-per-sample, more is considered "
                   "experimental. Add -strict experimental if you want "
                   "to encode more than 24 bits-per-sample\n");
            avctx->bits_per_raw_sample = 24;
            s->bps_code                = 6;
        } else {
            avctx->bits_per_raw_sample = 32;
            s->bps_code = 7;
        }
        break;
    }

    if (channels < 1 || channels > FLAC_MAX_CHANNELS) {
        av_log(avctx, AV_LOG_ERROR, "%d channels not supported (max %d)\n",
               channels, FLAC_MAX_CHANNELS);
        return AVERROR(EINVAL);
    }
    s->channels = channels;

    /* find samplerate in table */
    if (freq < 1)
        return AVERROR(EINVAL);
    for (i = 1; i < 12; i++) {
        if (freq == ff_flac_sample_rate_table[i]) {
            s->samplerate = ff_flac_sample_rate_table[i];
            s->sr_code[0] = i;
            s->sr_code[1] = 0;
            break;
        }
    }
    /* if not in table, samplerate is non-standard */
    if (i == 12) {
        if (freq % 1000 == 0 && freq < 255000) {
            s->sr_code[0] = 12;
            s->sr_code[1] = freq / 1000;
        } else if (freq % 10 == 0 && freq < 655350) {
            s->sr_code[0] = 14;
            s->sr_code[1] = freq / 10;
        } else if (freq < 65535) {
            s->sr_code[0] = 13;
            s->sr_code[1] = freq;
        } else if (freq < 1048576) {
            s->sr_code[0] = 0;
            s->sr_code[1] = 0;
        } else {
            av_log(avctx, AV_LOG_ERROR, "%d Hz not supported\n", freq);
            return AVERROR(EINVAL);
        }
        s->samplerate = freq;
    }

    /* set compression option defaults based on avctx->compression_level */
    if (avctx->compression_level < 0)
        s->options.compression_level = 5;
    else
        s->options.compression_level = avctx->compression_level;

    level = s->options.compression_level;
    if (level > 12) {
        av_log(avctx, AV_LOG_ERROR, "invalid compression level: %d\n",
               s->options.compression_level);
        return AVERROR(EINVAL);
    }

    s->options.block_time_ms = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level];

    if (s->options.lpc_type == FF_LPC_TYPE_DEFAULT)
        s->options.lpc_type  = ((int[]){ FF_LPC_TYPE_FIXED,    FF_LPC_TYPE_FIXED,    FF_LPC_TYPE_FIXED,
                                         FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
                                         FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
                                         FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON, FF_LPC_TYPE_LEVINSON,
                                         FF_LPC_TYPE_LEVINSON})[level];

    if (s->options.min_prediction_order < 0)
        s->options.min_prediction_order = ((int[]){  2,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1})[level];
    if (s->options.max_prediction_order < 0)
        s->options.max_prediction_order = ((int[]){  3,  4,  4,  6,  8,  8,  8,  8, 12, 12, 12, 32, 32})[level];

    if (s->options.prediction_order_method < 0)
        s->options.prediction_order_method = ((int[]){ ORDER_METHOD_EST,    ORDER_METHOD_EST,    ORDER_METHOD_EST,
                                                       ORDER_METHOD_EST,    ORDER_METHOD_EST,    ORDER_METHOD_EST,
                                                       ORDER_METHOD_4LEVEL, ORDER_METHOD_LOG,    ORDER_METHOD_4LEVEL,
                                                       ORDER_METHOD_LOG,    ORDER_METHOD_SEARCH, ORDER_METHOD_LOG,
                                                       ORDER_METHOD_SEARCH})[level];

    if (s->options.min_partition_order > s->options.max_partition_order) {
        av_log(avctx, AV_LOG_ERROR, "invalid partition orders: min=%d max=%d\n",
               s->options.min_partition_order, s->options.max_partition_order);
        return AVERROR(EINVAL);
    }
    if (s->options.min_partition_order < 0)
        s->options.min_partition_order = ((int[]){  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0})[level];
    if (s->options.max_partition_order < 0)
        s->options.max_partition_order = ((int[]){  2,  2,  3,  3,  3,  8,  8,  8,  8,  8,  8,  8,  8})[level];

    if (s->options.lpc_type == FF_LPC_TYPE_NONE) {
        s->options.min_prediction_order = 0;
        s->options.max_prediction_order = 0;
    } else if (s->options.lpc_type == FF_LPC_TYPE_FIXED) {
        if (s->options.min_prediction_order > MAX_FIXED_ORDER) {
            av_log(avctx, AV_LOG_WARNING,
                   "invalid min prediction order %d, clamped to %d\n",
                   s->options.min_prediction_order, MAX_FIXED_ORDER);
            s->options.min_prediction_order = MAX_FIXED_ORDER;
        }
        if (s->options.max_prediction_order > MAX_FIXED_ORDER) {
            av_log(avctx, AV_LOG_WARNING,
                   "invalid max prediction order %d, clamped to %d\n",
                   s->options.max_prediction_order, MAX_FIXED_ORDER);
            s->options.max_prediction_order = MAX_FIXED_ORDER;
        }
    }

    if (s->options.max_prediction_order < s->options.min_prediction_order) {
        av_log(avctx, AV_LOG_ERROR, "invalid prediction orders: min=%d max=%d\n",
               s->options.min_prediction_order, s->options.max_prediction_order);
        return AVERROR(EINVAL);
    }

    if (avctx->frame_size > 0) {
        if (avctx->frame_size < FLAC_MIN_BLOCKSIZE ||
                avctx->frame_size > FLAC_MAX_BLOCKSIZE) {
            av_log(avctx, AV_LOG_ERROR, "invalid block size: %d\n",
                   avctx->frame_size);
            return AVERROR(EINVAL);
        }
    } else {
        s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms);
    }
    s->max_blocksize = s->avctx->frame_size;

    /* set maximum encoded frame size in verbatim mode */
    s->max_framesize = flac_get_max_frame_size(s->avctx->frame_size,
                                               s->channels,
                                               s->avctx->bits_per_raw_sample);

    /* initialize MD5 context */
    s->md5ctx = av_md5_alloc();
    if (!s->md5ctx)
        return AVERROR(ENOMEM);
    av_md5_init(s->md5ctx);

    streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
    if (!streaminfo)
        return AVERROR(ENOMEM);
    write_streaminfo(s, streaminfo);
    avctx->extradata = streaminfo;
    avctx->extradata_size = FLAC_STREAMINFO_SIZE;

    s->frame_count   = 0;
    s->min_framesize = s->max_framesize;

    if ((channels == 3 &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_SURROUND)) ||
        (channels == 4 &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_2_2) &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_QUAD)) ||
        (channels == 5 &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0) &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0_BACK)) ||
        (channels == 6 &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1) &&
         av_channel_layout_compare(&avctx->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT1_BACK))) {
        if (avctx->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
            av_log(avctx, AV_LOG_ERROR, "Channel layout not supported by Flac, "
                                             "output stream will have incorrect "
                                             "channel layout.\n");
        } else {
            av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The encoder "
                                               "will use Flac channel layout for "
                                               "%d channels.\n", channels);
        }
    }

    ret = ff_lpc_init(&s->lpc_ctx, avctx->frame_size,
                      s->options.max_prediction_order, FF_LPC_TYPE_LEVINSON);

    ff_bswapdsp_init(&s->bdsp);
    ff_flacencdsp_init(&s->flac_dsp);

    dprint_compression_options(s);

    return ret;
}


static void init_frame(FlacEncodeContext *s, int nb_samples)
{
    int i, ch;
    FlacFrame *frame;

    frame = &s->frame;

    for (i = 0; i < 16; i++) {
        if (nb_samples == ff_flac_blocksize_table[i]) {
            frame->blocksize  = ff_flac_blocksize_table[i];
            frame->bs_code[0] = i;
            frame->bs_code[1] = 0;
            break;
        }
    }
    if (i == 16) {
        frame->blocksize = nb_samples;
        if (frame->blocksize <= 256) {
            frame->bs_code[0] = 6;
            frame->bs_code[1] = frame->blocksize-1;
        } else {
            frame->bs_code[0] = 7;
            frame->bs_code[1] = frame->blocksize-1;
        }
    }

    for (ch = 0; ch < s->channels; ch++) {
        FlacSubframe *sub = &frame->subframes[ch];

        sub->wasted = 0;
        sub->obits  = s->avctx->bits_per_raw_sample;

        if (sub->obits > 16)
            sub->rc.coding_mode = CODING_MODE_RICE2;
        else
            sub->rc.coding_mode = CODING_MODE_RICE;
    }

    frame->verbatim_only = 0;
}


/**
 * Copy channel-interleaved input samples into separate subframes.
 */
static void copy_samples(FlacEncodeContext *s, const void *samples)
{
    int i, j, ch;
    FlacFrame *frame;

#define COPY_SAMPLES(bits, shift0) do {                             \
    const int ## bits ## _t *samples0 = samples;                    \
    const int shift = shift0;                                       \
    frame = &s->frame;                                              \
    for (i = 0, j = 0; i < frame->blocksize; i++)                   \
        for (ch = 0; ch < s->channels; ch++, j++)                   \
            frame->subframes[ch].samples[i] = samples0[j] >> shift; \
} while (0)

    if (s->avctx->sample_fmt == AV_SAMPLE_FMT_S16)
        COPY_SAMPLES(16, 0);
    else
        COPY_SAMPLES(32, 32 - s->avctx->bits_per_raw_sample);
}


static uint64_t rice_count_exact(const int32_t *res, int n, int k)
{
    int i;
    uint64_t count = 0;

    for (i = 0; i < n; i++) {
        unsigned v = ((unsigned)(res[i]) << 1) ^ (res[i] >> 31);
        count += (v >> k) + 1 + k;
    }
    return count;
}


static uint64_t subframe_count_exact(FlacEncodeContext *s, FlacSubframe *sub,
                                     int pred_order)
{
    int p, porder, psize;
    int i, part_end;
    uint64_t count = 0;

    /* subframe header */
    count += 8;

    if (sub->wasted)
        count += sub->wasted;

    /* subframe */
    if (sub->type == FLAC_SUBFRAME_CONSTANT) {
        count += sub->obits;
    } else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
        count += s->frame.blocksize * sub->obits;
    } else {
        /* warm-up samples */
        count += pred_order * sub->obits;

        /* LPC coefficients */
        if (sub->type == FLAC_SUBFRAME_LPC)
            count += 4 + 5 + pred_order * s->options.lpc_coeff_precision;

        /* rice-encoded block */
        count += 2;

        /* partition order */
        porder = sub->rc.porder;
        psize  = s->frame.blocksize >> porder;
        count += 4;

        /* residual */
        i        = pred_order;
        part_end = psize;
        for (p = 0; p < 1 << porder; p++) {
            int k = sub->rc.params[p];
            count += sub->rc.coding_mode;
            count += rice_count_exact(&sub->residual[i], part_end - i, k);
            i = part_end;
            part_end = FFMIN(s->frame.blocksize, part_end + psize);
        }
    }

    return count;
}


#define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k)))

/**
 * Solve for d/dk(rice_encode_count) = n-((sum-(n>>1))>>(k+1)) = 0.
 */
static int find_optimal_param(uint64_t sum, int n, int max_param)
{
    int k;
    uint64_t sum2;

    if (sum <= n >> 1)
        return 0;
    sum2 = sum - (n >> 1);
    k    = av_log2(av_clipl_int32(sum2 / n));
    return FFMIN(k, max_param);
}

static int find_optimal_param_exact(uint64_t sums[32][MAX_PARTITIONS], int i, int max_param)
{
    int bestk = 0;
    int64_t bestbits = INT64_MAX;
    int k;

    for (k = 0; k <= max_param; k++) {
        int64_t bits = sums[k][i];
        if (bits < bestbits) {
            bestbits = bits;
            bestk = k;
        }
    }

    return bestk;
}

static uint64_t calc_optimal_rice_params(RiceContext *rc, int porder,
                                         uint64_t sums[32][MAX_PARTITIONS],
                                         int n, int pred_order, int max_param, int exact)
{
    int i;
    int k, cnt, part;
    uint64_t all_bits;

    part     = (1 << porder);
    all_bits = 4 * part;

    cnt = (n >> porder) - pred_order;
    for (i = 0; i < part; i++) {
        if (exact) {
            k = find_optimal_param_exact(sums, i, max_param);
            all_bits += sums[k][i];
        } else {
            k = find_optimal_param(sums[0][i], cnt, max_param);
            all_bits += rice_encode_count(sums[0][i], cnt, k);
        }
        rc->params[i] = k;
        cnt = n >> porder;
    }

    rc->porder = porder;

    return all_bits;
}


static void calc_sum_top(int pmax, int kmax, const uint32_t *data, int n, int pred_order,
                         uint64_t sums[32][MAX_PARTITIONS])
{
    int i, k;
    int parts;
    const uint32_t *res, *res_end;

    /* sums for highest level */
    parts   = (1 << pmax);

    for (k = 0; k <= kmax; k++) {
        res     = &data[pred_order];
        res_end = &data[n >> pmax];
        for (i = 0; i < parts; i++) {
            if (kmax) {
                uint64_t sum = (1LL + k) * (res_end - res);
                while (res < res_end)
                    sum += *(res++) >> k;
                sums[k][i] = sum;
            } else {
                uint64_t sum = 0;
                while (res < res_end)
                    sum += *(res++);
                sums[k][i] = sum;
            }
            res_end += n >> pmax;
        }
    }
}

static void calc_sum_next(int level, uint64_t sums[32][MAX_PARTITIONS], int kmax)
{
    int i, k;
    int parts = (1 << level);
    for (i = 0; i < parts; i++) {
        for (k=0; k<=kmax; k++)
            sums[k][i] = sums[k][2*i] + sums[k][2*i+1];
    }
}

static uint64_t calc_rice_params(RiceContext *rc,
                                 uint32_t udata[FLAC_MAX_BLOCKSIZE],
                                 uint64_t sums[32][MAX_PARTITIONS],
                                 int pmin, int pmax,
                                 const int32_t *data, int n, int pred_order, int exact)
{
    int i;
    uint64_t bits[MAX_PARTITION_ORDER+1];
    int opt_porder;
    RiceContext tmp_rc;
    int kmax = (1 << rc->coding_mode) - 2;

    av_assert1(pmin >= 0 && pmin <= MAX_PARTITION_ORDER);
    av_assert1(pmax >= 0 && pmax <= MAX_PARTITION_ORDER);
    av_assert1(pmin <= pmax);

    tmp_rc.coding_mode = rc->coding_mode;

    for (i = pred_order; i < n; i++)
        udata[i] = ((unsigned)(data[i]) << 1) ^ (data[i] >> 31);

    calc_sum_top(pmax, exact ? kmax : 0, udata, n, pred_order, sums);

    opt_porder = pmin;
    bits[pmin] = UINT32_MAX;
    for (i = pmax; ; ) {
        bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums, n, pred_order, kmax, exact);
        if (bits[i] < bits[opt_porder] || pmax == pmin) {
            opt_porder = i;
            *rc = tmp_rc;
        }
        if (i == pmin)
            break;
        calc_sum_next(--i, sums, exact ? kmax : 0);
    }

    return bits[opt_porder];
}


static int get_max_p_order(int max_porder, int n, int order)
{
    int porder = FFMIN(max_porder, av_log2(n^(n-1)));
    if (order > 0)
        porder = FFMIN(porder, av_log2(n/order));
    return porder;
}


static uint64_t find_subframe_rice_params(FlacEncodeContext *s,
                                          FlacSubframe *sub, int pred_order)
{
    int pmin = get_max_p_order(s->options.min_partition_order,
                               s->frame.blocksize, pred_order);
    int pmax = get_max_p_order(s->options.max_partition_order,
                               s->frame.blocksize, pred_order);

    uint64_t bits = 8 + pred_order * sub->obits + 2 + sub->rc.coding_mode;
    if (sub->type == FLAC_SUBFRAME_LPC)
        bits += 4 + 5 + pred_order * s->options.lpc_coeff_precision;
    bits += calc_rice_params(&sub->rc, sub->rc_udata, sub->rc_sums, pmin, pmax, sub->residual,
                             s->frame.blocksize, pred_order, s->options.exact_rice_parameters);
    return bits;
}


static void encode_residual_fixed(int32_t *res, const int32_t *smp, int n,
                                  int order)
{
    int i;

    for (i = 0; i < order; i++)
        res[i] = smp[i];

    if (order == 0) {
        for (i = order; i < n; i++)
            res[i] = smp[i];
    } else if (order == 1) {
        for (i = order; i < n; i++)
            res[i] = smp[i] - smp[i-1];
    } else if (order == 2) {
        int a = smp[order-1] - smp[order-2];
        for (i = order; i < n; i += 2) {
            int b    = smp[i  ] - smp[i-1];
            res[i]   = b - a;
            a        = smp[i+1] - smp[i  ];
            res[i+1] = a - b;
        }
    } else if (order == 3) {
        int a = smp[order-1] -   smp[order-2];
        int c = smp[order-1] - 2*smp[order-2] + smp[order-3];
        for (i = order; i < n; i += 2) {
            int b    = smp[i  ] - smp[i-1];
            int d    = b - a;
            res[i]   = d - c;
            a        = smp[i+1] - smp[i  ];
            c        = a - b;
            res[i+1] = c - d;
        }
    } else {
        int a = smp[order-1] -   smp[order-2];
        int c = smp[order-1] - 2*smp[order-2] +   smp[order-3];
        int e = smp[order-1] - 3*smp[order-2] + 3*smp[order-3] - smp[order-4];
        for (i = order; i < n; i += 2) {
            int b    = smp[i  ] - smp[i-1];
            int d    = b - a;
            int f    = d - c;
            res[i  ] = f - e;
            a        = smp[i+1] - smp[i  ];
            c        = a - b;
            e        = c - d;
            res[i+1] = e - f;
        }
    }
}


/* These four functions check for every residual whether it can be
 * contained in <INT32_MIN,INT32_MAX]. In case it doesn't, the
 * function that called this function has to try something else.
 * Each function is duplicated, once for int32_t input, once for
 * int64_t input */
#define ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT()                   \
{                                                                     \
    for (int i = 0; i < order; i++)                                   \
        res[i] = smp[i];                                              \
    if (order == 0) {                                                 \
        for (int i = order; i < n; i++) {                             \
            if (smp[i] == INT32_MIN)                                  \
                return 1;                                             \
            res[i] = smp[i];                                          \
        }                                                             \
    } else if (order == 1) {                                          \
        for (int i = order; i < n; i++) {                             \
            int64_t res64 = (int64_t)smp[i] - smp[i-1];               \
            if (res64 <= INT32_MIN || res64 > INT32_MAX)              \
                return 1;                                             \
            res[i] = res64;                                           \
        }                                                             \
    } else if (order == 2) {                                          \
        for (int i = order; i < n; i++) {                             \
            int64_t res64 = (int64_t)smp[i] - 2*(int64_t)smp[i-1] + smp[i-2]; \
            if (res64 <= INT32_MIN || res64 > INT32_MAX)              \
                return 1;                                             \
            res[i] = res64;                                           \
        }                                                             \
    } else if (order == 3) {                                          \
        for (int i = order; i < n; i++) {                             \
            int64_t res64 = (int64_t)smp[i] - 3*(int64_t)smp[i-1] + 3*(int64_t)smp[i-2] - smp[i-3];  \
            if (res64 <= INT32_MIN || res64 > INT32_MAX)              \
                return 1;                                             \
            res[i] = res64;                                           \
        }                                                             \
    } else {                                                          \
        for (int i = order; i < n; i++) {                             \
            int64_t res64 = (int64_t)smp[i] - 4*(int64_t)smp[i-1] + 6*(int64_t)smp[i-2] - 4*(int64_t)smp[i-3] + smp[i-4];   \
            if (res64 <= INT32_MIN || res64 > INT32_MAX)              \
                return 1;                                             \
            res[i] = res64;                                           \
        }                                                             \
    }                                                                 \
    return 0;                                                         \
}

static int encode_residual_fixed_with_residual_limit(int32_t *res, const int32_t *smp,
                                                      int n, int order)
{
    ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT();
}


static int encode_residual_fixed_with_residual_limit_33bps(int32_t *res, const int64_t *smp,
                                                           int n, int order)
{
    ENCODE_RESIDUAL_FIXED_WITH_RESIDUAL_LIMIT();
}

#define LPC_ENCODE_WITH_RESIDUAL_LIMIT()                 \
{                                                        \
   for (int i = 0; i < order; i++)                       \
        res[i] = smp[i];                                 \
    for (int i = order; i < len; i++) {                  \
        int64_t p = 0, tmp;                              \
        for (int j = 0; j < order; j++)                  \
            p += (int64_t)coefs[j]*smp[(i-1)-j];         \
        p >>= shift;                                     \
        tmp = smp[i] - p;                                \
        if (tmp <= INT32_MIN || tmp > INT32_MAX)         \
            return 1;                                    \
        res[i] = tmp;                                    \
    }                                                    \
    return 0;                                            \
}

static int lpc_encode_with_residual_limit(int32_t *res, const int32_t *smp, int len,
                                               int order, int32_t *coefs, int shift)
{
    LPC_ENCODE_WITH_RESIDUAL_LIMIT();
}

static int lpc_encode_with_residual_limit_33bps(int32_t *res, const int64_t *smp, int len,
                                               int order, int32_t *coefs, int shift)
{
    LPC_ENCODE_WITH_RESIDUAL_LIMIT();
}

static int lpc_encode_choose_datapath(FlacEncodeContext *s, int32_t bps,
                                      int32_t *res, const int32_t *smp,
                                      const int64_t *smp_33bps, int len,
                                      int order, int32_t *coefs, int shift)
{
    uint64_t max_residual_value = 0;
    int64_t max_sample_value = ((int64_t)(1) << (bps-1));
    /* This calculates the max size of any residual with the current
     * predictor, so we know whether we need to check the residual */
    for (int i = 0; i < order; i++)
        max_residual_value += FFABS(max_sample_value * coefs[i]);
    max_residual_value >>= shift;
    max_residual_value += max_sample_value;
    if (bps > 32) {
        if (lpc_encode_with_residual_limit_33bps(res, smp_33bps, len, order, coefs, shift))
            return 1;
    } else if (max_residual_value > INT32_MAX) {
        if (lpc_encode_with_residual_limit(res, smp, len, order, coefs, shift))
            return 1;
    } else if (bps + s->options.lpc_coeff_precision + av_log2(order) <= 32) {
        s->flac_dsp.lpc16_encode(res, smp, len, order, coefs, shift);
    } else {
        s->flac_dsp.lpc32_encode(res, smp, len, order, coefs, shift);
    }
    return 0;
}

#define DEFAULT_TO_VERBATIM()                               \
{                                                           \
    sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;    \
    if (sub->obits <= 32)                                   \
        memcpy(res, smp, n * sizeof(int32_t));              \
    return subframe_count_exact(s, sub, 0);                 \
}

static int encode_residual_ch(FlacEncodeContext *s, int ch)
{
    int i, n;
    int min_order, max_order, opt_order, omethod;
    FlacFrame *frame;
    FlacSubframe *sub;
    int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
    int shift[MAX_LPC_ORDER];
    int32_t *res, *smp;
    int64_t *smp_33bps;

    frame     = &s->frame;
    sub       = &frame->subframes[ch];
    res       = sub->residual;
    smp       = sub->samples;
    smp_33bps = frame->samples_33bps;
    n         = frame->blocksize;

    /* CONSTANT */
    if (sub->obits > 32) {
        for (i = 1; i < n; i++)
            if(smp_33bps[i] != smp_33bps[0])
                break;
        if (i == n) {
            sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
            return subframe_count_exact(s, sub, 0);
        }
    } else {
        for (i = 1; i < n; i++)
            if(smp[i] != smp[0])
                break;
        if (i == n) {
            sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT;
            res[0] = smp[0];
            return subframe_count_exact(s, sub, 0);
        }
    }

    /* VERBATIM */
    if (frame->verbatim_only || n < 5) {
        DEFAULT_TO_VERBATIM();
    }

    min_order  = s->options.min_prediction_order;
    max_order  = s->options.max_prediction_order;
    omethod    = s->options.prediction_order_method;

    /* FIXED */
    sub->type = FLAC_SUBFRAME_FIXED;
    if (s->options.lpc_type == FF_LPC_TYPE_NONE  ||
        s->options.lpc_type == FF_LPC_TYPE_FIXED || n <= max_order) {
        uint64_t bits[MAX_FIXED_ORDER+1];
        if (max_order > MAX_FIXED_ORDER)
            max_order = MAX_FIXED_ORDER;
        opt_order = 0;
        bits[0]   = UINT32_MAX;
        for (i = min_order; i <= max_order; i++) {
            if (sub->obits == 33) {
                if (encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, i))
                    continue;
            } else if (sub->obits + i >= 32) {
                if (encode_residual_fixed_with_residual_limit(res, smp, n, i))
                    continue;
            } else
                encode_residual_fixed(res, smp, n, i);
            bits[i] = find_subframe_rice_params(s, sub, i);
            if (bits[i] < bits[opt_order])
                opt_order = i;
        }
        if (opt_order == 0 && bits[0] == UINT32_MAX) {
            /* No predictor found with residuals within <INT32_MIN,INT32_MAX],
             * so encode a verbatim subframe instead */
            DEFAULT_TO_VERBATIM();
        }
        sub->order     = opt_order;
        sub->type_code = sub->type | sub->order;
        if (sub->order != max_order) {
            if (sub->obits == 33)
                encode_residual_fixed_with_residual_limit_33bps(res, smp_33bps, n, sub->order);
            else if (sub->obits + i >= 32)
                encode_residual_fixed_with_residual_limit(res, smp, n, sub->order);
            else
                encode_residual_fixed(res, smp, n, sub->order);
            find_subframe_rice_params(s, sub, sub->order);
        }
        return subframe_count_exact(s, sub, sub->order);
    }

    /* LPC */
    sub->type = FLAC_SUBFRAME_LPC;
    if (sub->obits == 33)
        /* As ff_lpc_calc_coefs is shared with other codecs and the LSB
         * probably isn't predictable anyway, throw away LSB for analysis
         * so it fits 32 bit int and existing function can be used
         * unmodified */
        for (i = 0; i < n; i++)
            smp[i] = smp_33bps[i] >> 1;

    opt_order = ff_lpc_calc_coefs(&s->lpc_ctx, smp, n, min_order, max_order,
                                  s->options.lpc_coeff_precision, coefs, shift, s->options.lpc_type,
                                  s->options.lpc_passes, omethod,
                                  MIN_LPC_SHIFT, MAX_LPC_SHIFT, 0);

    if (omethod == ORDER_METHOD_2LEVEL ||
        omethod == ORDER_METHOD_4LEVEL ||
        omethod == ORDER_METHOD_8LEVEL) {
        int levels = 1 << omethod;
        uint64_t bits[1 << ORDER_METHOD_8LEVEL];
        int order       = -1;
        int opt_index   = levels-1;
        opt_order       = max_order-1;
        bits[opt_index] = UINT32_MAX;
        for (i = levels-1; i >= 0; i--) {
            int last_order = order;
            order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1;
            order = av_clip(order, min_order - 1, max_order - 1);
            if (order == last_order)
                continue;
            if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, order+1, coefs[order], shift[order]))
                continue;
            bits[i] = find_subframe_rice_params(s, sub, order+1);
            if (bits[i] < bits[opt_index]) {
                opt_index = i;
                opt_order = order;
            }
        }
        opt_order++;
    } else if (omethod == ORDER_METHOD_SEARCH) {
        // brute-force optimal order search
        uint64_t bits[MAX_LPC_ORDER];
        opt_order = 0;
        bits[0]   = UINT32_MAX;
        for (i = min_order-1; i < max_order; i++) {
            if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i]))
                continue;
            bits[i] = find_subframe_rice_params(s, sub, i+1);
            if (bits[i] < bits[opt_order])
                opt_order = i;
        }
        opt_order++;
    } else if (omethod == ORDER_METHOD_LOG) {
        uint64_t bits[MAX_LPC_ORDER];
        int step;

        opt_order = min_order - 1 + (max_order-min_order)/3;
        memset(bits, -1, sizeof(bits));

        for (step = 16; step; step >>= 1) {
            int last = opt_order;
            for (i = last-step; i <= last+step; i += step) {
                if (i < min_order-1 || i >= max_order || bits[i] < UINT32_MAX)
                    continue;
                if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, i+1, coefs[i], shift[i]))
                    continue;
                bits[i] = find_subframe_rice_params(s, sub, i+1);
                if (bits[i] < bits[opt_order])
                    opt_order = i;
            }
        }
        opt_order++;
    }

    if (s->options.multi_dim_quant) {
        int allsteps = 1;
        int i, step, improved;
        int64_t best_score = INT64_MAX;
        int32_t qmax;

        qmax = (1 << (s->options.lpc_coeff_precision - 1)) - 1;

        for (i=0; i<opt_order; i++)
            allsteps *= 3;

        do {
            improved = 0;
            for (step = 0; step < allsteps; step++) {
                int tmp = step;
                int32_t lpc_try[MAX_LPC_ORDER];
                int64_t score = 0;
                int diffsum = 0;

                for (i=0; i<opt_order; i++) {
                    int diff = ((tmp + 1) % 3) - 1;
                    lpc_try[i] = av_clip(coefs[opt_order - 1][i] + diff, -qmax, qmax);
                    tmp /= 3;
                    diffsum += !!diff;
                }
                if (diffsum >8)
                    continue;

                if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, opt_order, lpc_try, shift[opt_order-1]))
                    continue;
                score = find_subframe_rice_params(s, sub, opt_order);
                if (score < best_score) {
                    best_score = score;
                    memcpy(coefs[opt_order-1], lpc_try, sizeof(*coefs));
                    improved=1;
                }
            }
        } while(improved);
    }

    sub->order     = opt_order;
    sub->type_code = sub->type | (sub->order-1);
    sub->shift     = shift[sub->order-1];
    for (i = 0; i < sub->order; i++)
        sub->coefs[i] = coefs[sub->order-1][i];

    if(lpc_encode_choose_datapath(s, sub->obits, res, smp, smp_33bps, n, sub->order, sub->coefs, sub->shift)) {
        /* No predictor found with residuals within <INT32_MIN,INT32_MAX],
         * so encode a verbatim subframe instead */
        DEFAULT_TO_VERBATIM();
    }

    find_subframe_rice_params(s, sub, sub->order);

    return subframe_count_exact(s, sub, sub->order);
}


static int count_frame_header(FlacEncodeContext *s)
{
    uint8_t av_unused tmp;
    int count;

    /*
    <14> Sync code
    <1>  Reserved
    <1>  Blocking strategy
    <4>  Block size in inter-channel samples
    <4>  Sample rate
    <4>  Channel assignment
    <3>  Sample size in bits
    <1>  Reserved
    */
    count = 32;

    /* coded frame number */
    PUT_UTF8(s->frame_count, tmp, count += 8;)

    /* explicit block size */
    if (s->frame.bs_code[0] == 6)
        count += 8;
    else if (s->frame.bs_code[0] == 7)
        count += 16;

    /* explicit sample rate */
    count += ((s->sr_code[0] == 12) + (s->sr_code[0] > 12) * 2) * 8;

    /* frame header CRC-8 */
    count += 8;

    return count;
}


static int encode_frame(FlacEncodeContext *s)
{
    int ch;
    uint64_t count;

    count = count_frame_header(s);

    for (ch = 0; ch < s->channels; ch++)
        count += encode_residual_ch(s, ch);

    count += (8 - (count & 7)) & 7; // byte alignment
    count += 16;                    // CRC-16

    count >>= 3;
    if (count > INT_MAX)
        return AVERROR_BUG;
    return count;
}


static void remove_wasted_bits(FlacEncodeContext *s)
{
    int ch, i, wasted_bits;

    for (ch = 0; ch < s->channels; ch++) {
        FlacSubframe *sub = &s->frame.subframes[ch];

        if (sub->obits > 32) {
            int64_t v = 0;
            for (i = 0; i < s->frame.blocksize; i++) {
                v |= s->frame.samples_33bps[i];
                if (v & 1)
                    break;
            }

            if (!v || (v & 1))
                return;

            v = ff_ctzll(v);

            /* If any wasted bits are found, samples are moved
             * from frame.samples_33bps to frame.subframes[ch] */
            for (i = 0; i < s->frame.blocksize; i++)
                sub->samples[i] = s->frame.samples_33bps[i] >> v;
            wasted_bits = v;
        } else {
            int32_t v = 0;
            for (i = 0; i < s->frame.blocksize; i++) {
                v |= sub->samples[i];
                if (v & 1)
                    break;
            }

            if (!v || (v & 1))
                return;

            v = ff_ctz(v);

            for (i = 0; i < s->frame.blocksize; i++)
                sub->samples[i] >>= v;
            wasted_bits = v;
        }

        sub->wasted = wasted_bits;
        sub->obits -= wasted_bits;

        /* for 24-bit, check if removing wasted bits makes the range better
         * suited for using RICE instead of RICE2 for entropy coding */
        if (sub->obits <= 17)
            sub->rc.coding_mode = CODING_MODE_RICE;
    }
}


static int estimate_stereo_mode(const int32_t *left_ch, const int32_t *right_ch, int n,
                                int max_rice_param, int bps)
{
    int best;
    uint64_t sum[4];
    uint64_t score[4];
    int k;

    /* calculate sum of 2nd order residual for each channel */
    sum[0] = sum[1] = sum[2] = sum[3] = 0;
    if(bps < 30) {
        int32_t lt, rt;
        for (int i = 2; i < n; i++) {
            lt = left_ch[i]  - 2*left_ch[i-1]  + left_ch[i-2];
            rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2];
            sum[2] += FFABS((lt + rt) >> 1);
            sum[3] += FFABS(lt - rt);
            sum[0] += FFABS(lt);
            sum[1] += FFABS(rt);
        }
    } else {
        int64_t lt, rt;
        for (int i = 2; i < n; i++) {
            lt = (int64_t)left_ch[i]  - 2*(int64_t)left_ch[i-1]  + left_ch[i-2];
            rt = (int64_t)right_ch[i] - 2*(int64_t)right_ch[i-1] + right_ch[i-2];
            sum[2] += FFABS((lt + rt) >> 1);
            sum[3] += FFABS(lt - rt);
            sum[0] += FFABS(lt);
            sum[1] += FFABS(rt);
        }
    }
    /* estimate bit counts */
    for (int i = 0; i < 4; i++) {
        k      = find_optimal_param(2 * sum[i], n, max_rice_param);
        sum[i] = rice_encode_count( 2 * sum[i], n, k);
    }

    /* calculate score for each mode */
    score[0] = sum[0] + sum[1];
    score[1] = sum[0] + sum[3];
    score[2] = sum[1] + sum[3];
    score[3] = sum[2] + sum[3];

    /* return mode with lowest score */
    best = 0;
    for (int i = 1; i < 4; i++)
        if (score[i] < score[best])
            best = i;

    return best;
}


/**
 * Perform stereo channel decorrelation.
 */
static void channel_decorrelation(FlacEncodeContext *s)
{
    FlacFrame *frame;
    int32_t *left, *right;
    int64_t *side_33bps;
    int n;

    frame      = &s->frame;
    n          = frame->blocksize;
    left       = frame->subframes[0].samples;
    right      = frame->subframes[1].samples;
    side_33bps = frame->samples_33bps;

    if (s->channels != 2) {
        frame->ch_mode = FLAC_CHMODE_INDEPENDENT;
        return;
    }

    if (s->options.ch_mode < 0) {
        int max_rice_param = (1 << frame->subframes[0].rc.coding_mode) - 2;
        frame->ch_mode = estimate_stereo_mode(left, right, n, max_rice_param, s->avctx->bits_per_raw_sample);
    } else
        frame->ch_mode = s->options.ch_mode;

    /* perform decorrelation and adjust bits-per-sample */
    if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT)
        return;
    if(s->avctx->bits_per_raw_sample == 32) {
        if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
            int64_t tmp;
            for (int i = 0; i < n; i++) {
                tmp           = left[i];
                left[i]       = (tmp + right[i]) >> 1;
                side_33bps[i] =  tmp - right[i];
            }
            frame->subframes[1].obits++;
        } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
            for (int i = 0; i < n; i++)
                side_33bps[i] = (int64_t)left[i] - right[i];
            frame->subframes[1].obits++;
        } else {
            for (int i = 0; i < n; i++)
                side_33bps[i] = (int64_t)left[i] - right[i];
            frame->subframes[0].obits++;
        }
    } else {
        if (frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
            int32_t tmp;
            for (int i = 0; i < n; i++) {
                tmp      = left[i];
                left[i]  = (tmp + right[i]) >> 1;
                right[i] =  tmp - right[i];
            }
            frame->subframes[1].obits++;
        } else if (frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) {
            for (int i = 0; i < n; i++)
                right[i] = left[i] - right[i];
            frame->subframes[1].obits++;
        } else {
            for (int i = 0; i < n; i++)
                left[i] -= right[i];
            frame->subframes[0].obits++;
        }
    }
}


static void write_utf8(PutBitContext *pb, uint32_t val)
{
    uint8_t tmp;
    PUT_UTF8(val, tmp, put_bits(pb, 8, tmp);)
}


static void write_frame_header(FlacEncodeContext *s)
{
    FlacFrame *frame;
    int crc;

    frame = &s->frame;

    put_bits(&s->pb, 16, 0xFFF8);
    put_bits(&s->pb, 4, frame->bs_code[0]);
    put_bits(&s->pb, 4, s->sr_code[0]);

    if (frame->ch_mode == FLAC_CHMODE_INDEPENDENT)
        put_bits(&s->pb, 4, s->channels-1);
    else
        put_bits(&s->pb, 4, frame->ch_mode + FLAC_MAX_CHANNELS - 1);

    put_bits(&s->pb, 3, s->bps_code);
    put_bits(&s->pb, 1, 0);
    write_utf8(&s->pb, s->frame_count);

    if (frame->bs_code[0] == 6)
        put_bits(&s->pb, 8, frame->bs_code[1]);
    else if (frame->bs_code[0] == 7)
        put_bits(&s->pb, 16, frame->bs_code[1]);

    if (s->sr_code[0] == 12)
        put_bits(&s->pb, 8, s->sr_code[1]);
    else if (s->sr_code[0] > 12)
        put_bits(&s->pb, 16, s->sr_code[1]);

    flush_put_bits(&s->pb);
    crc = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, s->pb.buf,
                 put_bytes_output(&s->pb));
    put_bits(&s->pb, 8, crc);
}


static inline void set_sr_golomb_flac(PutBitContext *pb, int i, int k)
{
    unsigned v, e;

    v = ((unsigned)(i) << 1) ^ (i >> 31);

    e = (v >> k) + 1;
    while (e > 31) {
        put_bits(pb, 31, 0);
        e -= 31;
    }
    put_bits(pb, e, 1);
    if (k) {
        unsigned mask = UINT32_MAX >> (32-k);
        put_bits(pb, k, v & mask);
    }
}


static void write_subframes(FlacEncodeContext *s)
{
    int ch;

    for (ch = 0; ch < s->channels; ch++) {
        FlacSubframe *sub = &s->frame.subframes[ch];
        int p, porder, psize;
        int32_t *part_end;
        int32_t *res       =  sub->residual;
        int32_t *frame_end = &sub->residual[s->frame.blocksize];

        /* subframe header */
        put_bits(&s->pb, 1, 0);
        put_bits(&s->pb, 6, sub->type_code);
        put_bits(&s->pb, 1, !!sub->wasted);
        if (sub->wasted)
            put_bits(&s->pb, sub->wasted, 1);

        /* subframe */
        if (sub->type == FLAC_SUBFRAME_CONSTANT) {
            if(sub->obits == 33)
                put_sbits63(&s->pb, 33, s->frame.samples_33bps[0]);
            else if(sub->obits == 32)
                put_bits32(&s->pb, res[0]);
            else
                put_sbits(&s->pb, sub->obits, res[0]);
        } else if (sub->type == FLAC_SUBFRAME_VERBATIM) {
            if (sub->obits == 33) {
                int64_t *res64 = s->frame.samples_33bps;
                int64_t *frame_end64 = &s->frame.samples_33bps[s->frame.blocksize];
                while (res64 < frame_end64)
                    put_sbits63(&s->pb, 33, (*res64++));
            } else if (sub->obits == 32) {
                while (res < frame_end)
                    put_bits32(&s->pb, *res++);
            } else {
                while (res < frame_end)
                    put_sbits(&s->pb, sub->obits, *res++);
            }
        } else {
            /* warm-up samples */
            if (sub->obits == 33) {
                for (int i = 0; i < sub->order; i++)
                    put_sbits63(&s->pb, 33, s->frame.samples_33bps[i]);
                res += sub->order;
            } else if (sub->obits == 32) {
                for (int i = 0; i < sub->order; i++)
                    put_bits32(&s->pb, *res++);
            } else {
                for (int i = 0; i < sub->order; i++)
                    put_sbits(&s->pb, sub->obits, *res++);
            }

            /* LPC coefficients */
            if (sub->type == FLAC_SUBFRAME_LPC) {
                int cbits = s->options.lpc_coeff_precision;
                put_bits( &s->pb, 4, cbits-1);
                put_sbits(&s->pb, 5, sub->shift);
                for (int i = 0; i < sub->order; i++)
                    put_sbits(&s->pb, cbits, sub->coefs[i]);
            }

            /* rice-encoded block */
            put_bits(&s->pb, 2, sub->rc.coding_mode - 4);

            /* partition order */
            porder  = sub->rc.porder;
            psize   = s->frame.blocksize >> porder;
            put_bits(&s->pb, 4, porder);

            /* residual */
            part_end  = &sub->residual[psize];
            for (p = 0; p < 1 << porder; p++) {
                int k = sub->rc.params[p];
                put_bits(&s->pb, sub->rc.coding_mode, k);
                while (res < part_end)
                    set_sr_golomb_flac(&s->pb, *res++, k);
                part_end = FFMIN(frame_end, part_end + psize);
            }
        }
    }
}


static void write_frame_footer(FlacEncodeContext *s)
{
    int crc;
    flush_put_bits(&s->pb);
    crc = av_bswap16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, s->pb.buf,
                            put_bytes_output(&s->pb)));
    put_bits(&s->pb, 16, crc);
    flush_put_bits(&s->pb);
}


static int write_frame(FlacEncodeContext *s, AVPacket *avpkt)
{
    init_put_bits(&s->pb, avpkt->data, avpkt->size);
    write_frame_header(s);
    write_subframes(s);
    write_frame_footer(s);
    return put_bytes_output(&s->pb);
}


static int update_md5_sum(FlacEncodeContext *s, const void *samples)
{
    const uint8_t *buf;
    int buf_size = s->frame.blocksize * s->channels *
                   ((s->avctx->bits_per_raw_sample + 7) / 8);

    if (s->avctx->bits_per_raw_sample > 16 || HAVE_BIGENDIAN) {
        av_fast_malloc(&s->md5_buffer, &s->md5_buffer_size, buf_size);
        if (!s->md5_buffer)
            return AVERROR(ENOMEM);
    }

    if (s->avctx->bits_per_raw_sample <= 16) {
        buf = (const uint8_t *)samples;
#if HAVE_BIGENDIAN
        s->bdsp.bswap16_buf((uint16_t *) s->md5_buffer,
                            (const uint16_t *) samples, buf_size / 2);
        buf = s->md5_buffer;
#endif
    } else if (s->avctx->bits_per_raw_sample <= 24) {
        int i;
        const int32_t *samples0 = samples;
        uint8_t *tmp            = s->md5_buffer;

        for (i = 0; i < s->frame.blocksize * s->channels; i++) {
            int32_t v = samples0[i] >> 8;
            AV_WL24(tmp + 3*i, v);
        }
        buf = s->md5_buffer;
    } else {
        /* s->avctx->bits_per_raw_sample <= 32 */
        int i;
        const int32_t *samples0 = samples;
        uint8_t *tmp            = s->md5_buffer;

        for (i = 0; i < s->frame.blocksize * s->channels; i++)
            AV_WL32(tmp + 4*i, samples0[i]);
        buf = s->md5_buffer;
    }
    av_md5_update(s->md5ctx, buf, buf_size);

    return 0;
}


static int flac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                             const AVFrame *frame, int *got_packet_ptr)
{
    FlacEncodeContext *s;
    int frame_bytes, out_bytes, ret;

    s = avctx->priv_data;

    /* when the last block is reached, update the header in extradata */
    if (!frame) {
        s->max_framesize = s->max_encoded_framesize;
        av_md5_final(s->md5ctx, s->md5sum);
        write_streaminfo(s, avctx->extradata);

        if (!s->flushed) {
            uint8_t *side_data = av_packet_new_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA,
                                                         avctx->extradata_size);
            if (!side_data)
                return AVERROR(ENOMEM);
            memcpy(side_data, avctx->extradata, avctx->extradata_size);

            avpkt->pts = s->next_pts;

            *got_packet_ptr = 1;
            s->flushed = 1;
        }

        return 0;
    }

    /* change max_framesize for small final frame */
    if (frame->nb_samples < s->frame.blocksize) {
        s->max_framesize = flac_get_max_frame_size(frame->nb_samples,
                                                   s->channels,
                                                   avctx->bits_per_raw_sample);
    }

    init_frame(s, frame->nb_samples);

    copy_samples(s, frame->data[0]);

    channel_decorrelation(s);

    remove_wasted_bits(s);

    frame_bytes = encode_frame(s);

    /* Fall back on verbatim mode if the compressed frame is larger than it
       would be if encoded uncompressed. */
    if (frame_bytes < 0 || frame_bytes > s->max_framesize) {
        s->frame.verbatim_only = 1;
        frame_bytes = encode_frame(s);
        if (frame_bytes < 0) {
            av_log(avctx, AV_LOG_ERROR, "Bad frame count\n");
            return frame_bytes;
        }
    }

    if ((ret = ff_get_encode_buffer(avctx, avpkt, frame_bytes, 0)) < 0)
        return ret;

    out_bytes = write_frame(s, avpkt);

    s->frame_count++;
    s->sample_count += frame->nb_samples;
    if ((ret = update_md5_sum(s, frame->data[0])) < 0) {
        av_log(avctx, AV_LOG_ERROR, "Error updating MD5 checksum\n");
        return ret;
    }
    if (out_bytes > s->max_encoded_framesize)
        s->max_encoded_framesize = out_bytes;
    if (out_bytes < s->min_framesize)
        s->min_framesize = out_bytes;

    s->next_pts = frame->pts + ff_samples_to_time_base(avctx, frame->nb_samples);

    av_shrink_packet(avpkt, out_bytes);

    *got_packet_ptr = 1;
    return 0;
}


static av_cold int flac_encode_close(AVCodecContext *avctx)
{
    FlacEncodeContext *s = avctx->priv_data;

    av_freep(&s->md5ctx);
    av_freep(&s->md5_buffer);
    ff_lpc_end(&s->lpc_ctx);
    return 0;
}

#define FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption options[] = {
{ "lpc_coeff_precision", "LPC coefficient precision", offsetof(FlacEncodeContext, options.lpc_coeff_precision), AV_OPT_TYPE_INT, {.i64 = 15 }, 0, MAX_LPC_PRECISION, FLAGS },
{ "lpc_type", "LPC algorithm", offsetof(FlacEncodeContext, options.lpc_type), AV_OPT_TYPE_INT, {.i64 = FF_LPC_TYPE_DEFAULT }, FF_LPC_TYPE_DEFAULT, FF_LPC_TYPE_NB-1, FLAGS, .unit = "lpc_type" },
{ "none",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_NONE },     INT_MIN, INT_MAX, FLAGS, .unit = "lpc_type" },
{ "fixed",    NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_FIXED },    INT_MIN, INT_MAX, FLAGS, .unit = "lpc_type" },
{ "levinson", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_LEVINSON }, INT_MIN, INT_MAX, FLAGS, .unit = "lpc_type" },
{ "cholesky", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_LPC_TYPE_CHOLESKY }, INT_MIN, INT_MAX, FLAGS, .unit = "lpc_type" },
{ "lpc_passes", "Number of passes to use for Cholesky factorization during LPC analysis", offsetof(FlacEncodeContext, options.lpc_passes),  AV_OPT_TYPE_INT, {.i64 = 2 }, 1, INT_MAX, FLAGS },
{ "min_partition_order",  NULL, offsetof(FlacEncodeContext, options.min_partition_order),  AV_OPT_TYPE_INT, {.i64 = -1 },      -1, MAX_PARTITION_ORDER, FLAGS },
{ "max_partition_order",  NULL, offsetof(FlacEncodeContext, options.max_partition_order),  AV_OPT_TYPE_INT, {.i64 = -1 },      -1, MAX_PARTITION_ORDER, FLAGS },
{ "prediction_order_method", "Search method for selecting prediction order", offsetof(FlacEncodeContext, options.prediction_order_method), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, ORDER_METHOD_LOG, FLAGS, .unit = "predm" },
{ "estimation", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_EST },    INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "2level",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_2LEVEL }, INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "4level",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_4LEVEL }, INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "8level",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_8LEVEL }, INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "search",     NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_SEARCH }, INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "log",        NULL, 0, AV_OPT_TYPE_CONST, {.i64 = ORDER_METHOD_LOG },    INT_MIN, INT_MAX, FLAGS, .unit = "predm" },
{ "ch_mode", "Stereo decorrelation mode", offsetof(FlacEncodeContext, options.ch_mode), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, FLAC_CHMODE_MID_SIDE, FLAGS, .unit = "ch_mode" },
{ "auto",       NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1                      }, INT_MIN, INT_MAX, FLAGS, .unit = "ch_mode" },
{ "indep",      NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_INDEPENDENT }, INT_MIN, INT_MAX, FLAGS, .unit = "ch_mode" },
{ "left_side",  NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_LEFT_SIDE   }, INT_MIN, INT_MAX, FLAGS, .unit = "ch_mode" },
{ "right_side", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_RIGHT_SIDE  }, INT_MIN, INT_MAX, FLAGS, .unit = "ch_mode" },
{ "mid_side",   NULL, 0, AV_OPT_TYPE_CONST, { .i64 = FLAC_CHMODE_MID_SIDE    }, INT_MIN, INT_MAX, FLAGS, .unit = "ch_mode" },
{ "exact_rice_parameters", "Calculate rice parameters exactly", offsetof(FlacEncodeContext, options.exact_rice_parameters), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
{ "multi_dim_quant",       "Multi-dimensional quantization",    offsetof(FlacEncodeContext, options.multi_dim_quant),       AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, FLAGS },
{ "min_prediction_order", NULL, offsetof(FlacEncodeContext, options.min_prediction_order), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_LPC_ORDER, FLAGS },
{ "max_prediction_order", NULL, offsetof(FlacEncodeContext, options.max_prediction_order), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, MAX_LPC_ORDER, FLAGS },

{ NULL },
};

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

const FFCodec ff_flac_encoder = {
    .p.name         = "flac",
    CODEC_LONG_NAME("FLAC (Free Lossless Audio Codec)"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_FLAC,
    .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
                      AV_CODEC_CAP_SMALL_LAST_FRAME |
                      AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
    .priv_data_size = sizeof(FlacEncodeContext),
    .init           = flac_encode_init,
    FF_CODEC_ENCODE_CB(flac_encode_frame),
    .close          = flac_encode_close,
    .p.sample_fmts  = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                     AV_SAMPLE_FMT_S32,
                                                     AV_SAMPLE_FMT_NONE },
    .p.priv_class   = &flac_encoder_class,
    .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_EOF_FLUSH,
};
