/**
 * 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/crc.h"
#include "libavutil/lls.h"
#include "libavutil/md5.h"
#include "avcodec.h"
#include "bitstream.h"
#include "dsputil.h"
#include "golomb.h"
#include "lpc.h"

#define FLAC_MAX_CH  8
#define FLAC_MIN_BLOCKSIZE  16
#define FLAC_MAX_BLOCKSIZE  65535

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

#define FLAC_CHMODE_NOT_STEREO      0
#define FLAC_CHMODE_LEFT_RIGHT      1
#define FLAC_CHMODE_LEFT_SIDE       8
#define FLAC_CHMODE_RIGHT_SIDE      9
#define FLAC_CHMODE_MID_SIDE       10

#define FLAC_STREAMINFO_SIZE  34

#define MAX_FIXED_ORDER     4
#define MAX_PARTITION_ORDER 8
#define MAX_PARTITIONS     (1 << MAX_PARTITION_ORDER)
#define MAX_LPC_PRECISION  15
#define MAX_LPC_SHIFT      15
#define MAX_RICE_PARAM     14

typedef struct CompressionOptions {
    int compression_level;
    int block_time_ms;
    int use_lpc;
    int lpc_coeff_precision;
    int min_prediction_order;
    int max_prediction_order;
    int prediction_order_method;
    int min_partition_order;
    int max_partition_order;
} CompressionOptions;

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

typedef struct FlacSubframe {
    int type;
    int type_code;
    int obits;
    int order;
    int32_t coefs[MAX_LPC_ORDER];
    int shift;
    RiceContext rc;
    int32_t samples[FLAC_MAX_BLOCKSIZE];
    int32_t residual[FLAC_MAX_BLOCKSIZE+1];
} FlacSubframe;

typedef struct FlacFrame {
    FlacSubframe subframes[FLAC_MAX_CH];
    int blocksize;
    int bs_code[2];
    uint8_t crc8;
    int ch_mode;
} FlacFrame;

typedef struct FlacEncodeContext {
    PutBitContext pb;
    int channels;
    int ch_code;
    int samplerate;
    int sr_code[2];
    int min_framesize;
    int min_encoded_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;
    DSPContext dsp;
    struct AVMD5 *md5ctx;
} FlacEncodeContext;

static const int flac_samplerates[16] = {
    0, 0, 0, 0,
    8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000,
    0, 0, 0, 0
};

static const int flac_blocksizes[16] = {
    0,
    192,
    576, 1152, 2304, 4608,
    0, 0,
    256, 512, 1024, 2048, 4096, 8192, 16384, 32768
};

/**
 * Writes 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->avctx->frame_size);
    put_bits(&pb, 16, s->avctx->frame_size);
    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, 15);       /* bits per 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);
}

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

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

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

    s->avctx = avctx;

    dsputil_init(&s->dsp, avctx);

    if(avctx->sample_fmt != SAMPLE_FMT_S16) {
        return -1;
    }

    if(channels < 1 || channels > FLAC_MAX_CH) {
        return -1;
    }
    s->channels = channels;
    s->ch_code = s->channels-1;

    /* find samplerate in table */
    if(freq < 1)
        return -1;
    for(i=4; i<12; i++) {
        if(freq == flac_samplerates[i]) {
            s->samplerate = flac_samplerates[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 {
            return -1;
        }
        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;
    }
    av_log(avctx, AV_LOG_DEBUG, " compression: %d\n", s->options.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 -1;
    }

    s->options.block_time_ms       = ((int[]){ 27, 27, 27,105,105,105,105,105,105,105,105,105,105})[level];
    s->options.use_lpc             = ((int[]){  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1})[level];
    s->options.min_prediction_order= ((int[]){  2,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1})[level];
    s->options.max_prediction_order= ((int[]){  3,  4,  4,  6,  8,  8,  8,  8, 12, 12, 12, 32, 32})[level];
    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];
    s->options.min_partition_order = ((int[]){  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0})[level];
    s->options.max_partition_order = ((int[]){  2,  2,  3,  3,  3,  8,  8,  8,  8,  8,  8,  8,  8})[level];

    /* set compression option overrides from AVCodecContext */
    if(avctx->use_lpc >= 0) {
        s->options.use_lpc = av_clip(avctx->use_lpc, 0, 11);
    }
    if(s->options.use_lpc == 1)
        av_log(avctx, AV_LOG_DEBUG, " use lpc: Levinson-Durbin recursion with Welch window\n");
    else if(s->options.use_lpc > 1)
        av_log(avctx, AV_LOG_DEBUG, " use lpc: Cholesky factorization\n");

    if(avctx->min_prediction_order >= 0) {
        if(s->options.use_lpc) {
            if(avctx->min_prediction_order < MIN_LPC_ORDER ||
                    avctx->min_prediction_order > MAX_LPC_ORDER) {
                av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
                       avctx->min_prediction_order);
                return -1;
            }
        } else {
            if(avctx->min_prediction_order > MAX_FIXED_ORDER) {
                av_log(avctx, AV_LOG_ERROR, "invalid min prediction order: %d\n",
                       avctx->min_prediction_order);
                return -1;
            }
        }
        s->options.min_prediction_order = avctx->min_prediction_order;
    }
    if(avctx->max_prediction_order >= 0) {
        if(s->options.use_lpc) {
            if(avctx->max_prediction_order < MIN_LPC_ORDER ||
                    avctx->max_prediction_order > MAX_LPC_ORDER) {
                av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
                       avctx->max_prediction_order);
                return -1;
            }
        } else {
            if(avctx->max_prediction_order > MAX_FIXED_ORDER) {
                av_log(avctx, AV_LOG_ERROR, "invalid max prediction order: %d\n",
                       avctx->max_prediction_order);
                return -1;
            }
        }
        s->options.max_prediction_order = avctx->max_prediction_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 -1;
    }
    av_log(avctx, AV_LOG_DEBUG, " prediction order: %d, %d\n",
           s->options.min_prediction_order, s->options.max_prediction_order);

    if(avctx->prediction_order_method >= 0) {
        if(avctx->prediction_order_method > ORDER_METHOD_LOG) {
            av_log(avctx, AV_LOG_ERROR, "invalid prediction order method: %d\n",
                   avctx->prediction_order_method);
            return -1;
        }
        s->options.prediction_order_method = avctx->prediction_order_method;
    }
    switch(s->options.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;
    }

    if(avctx->min_partition_order >= 0) {
        if(avctx->min_partition_order > MAX_PARTITION_ORDER) {
            av_log(avctx, AV_LOG_ERROR, "invalid min partition order: %d\n",
                   avctx->min_partition_order);
            return -1;
        }
        s->options.min_partition_order = avctx->min_partition_order;
    }
    if(avctx->max_partition_order >= 0) {
        if(avctx->max_partition_order > MAX_PARTITION_ORDER) {
            av_log(avctx, AV_LOG_ERROR, "invalid max partition order: %d\n",
                   avctx->max_partition_order);
            return -1;
        }
        s->options.max_partition_order = avctx->max_partition_order;
    }
    if(s->options.max_partition_order < s->options.min_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 -1;
    }
    av_log(avctx, AV_LOG_DEBUG, " partition order: %d, %d\n",
           s->options.min_partition_order, s->options.max_partition_order);

    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 -1;
        }
    } else {
        s->avctx->frame_size = select_blocksize(s->samplerate, s->options.block_time_ms);
    }
    av_log(avctx, AV_LOG_DEBUG, " block size: %d\n", s->avctx->frame_size);

    /* set LPC precision */
    if(avctx->lpc_coeff_precision > 0) {
        if(avctx->lpc_coeff_precision > MAX_LPC_PRECISION) {
            av_log(avctx, AV_LOG_ERROR, "invalid lpc coeff precision: %d\n",
                   avctx->lpc_coeff_precision);
            return -1;
        }
        s->options.lpc_coeff_precision = avctx->lpc_coeff_precision;
    } else {
        /* default LPC precision */
        s->options.lpc_coeff_precision = 15;
    }
    av_log(avctx, AV_LOG_DEBUG, " lpc precision: %d\n",
           s->options.lpc_coeff_precision);

    /* set maximum encoded frame size in verbatim mode */
    if(s->channels == 2) {
        s->max_framesize = 14 + ((s->avctx->frame_size * 33 + 7) >> 3);
    } else {
        s->max_framesize = 14 + (s->avctx->frame_size * s->channels * 2);
    }
    s->min_encoded_framesize = 0xFFFFFF;

    /* initialize MD5 context */
    s->md5ctx = av_malloc(av_md5_size);
    if(!s->md5ctx)
        return AVERROR_NOMEM;
    av_md5_init(s->md5ctx);

    streaminfo = av_malloc(FLAC_STREAMINFO_SIZE);
    write_streaminfo(s, streaminfo);
    avctx->extradata = streaminfo;
    avctx->extradata_size = FLAC_STREAMINFO_SIZE;

    s->frame_count = 0;

    avctx->coded_frame = avcodec_alloc_frame();
    avctx->coded_frame->key_frame = 1;

    return 0;
}

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

    frame = &s->frame;

    for(i=0; i<16; i++) {
        if(s->avctx->frame_size == flac_blocksizes[i]) {
            frame->blocksize = flac_blocksizes[i];
            frame->bs_code[0] = i;
            frame->bs_code[1] = 0;
            break;
        }
    }
    if(i == 16) {
        frame->blocksize = s->avctx->frame_size;
        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++) {
        frame->subframes[ch].obits = 16;
    }
}

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

    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] = samples[j];
        }
    }
}


#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(uint32_t sum, int n)
{
    int k;
    uint32_t sum2;

    if(sum <= n>>1)
        return 0;
    sum2 = sum-(n>>1);
    k = av_log2(n<256 ? FASTDIV(sum2,n) : sum2/n);
    return FFMIN(k, MAX_RICE_PARAM);
}

static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder,
                                         uint32_t *sums, int n, int pred_order)
{
    int i;
    int k, cnt, part;
    uint32_t all_bits;

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

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

    rc->porder = porder;

    return all_bits;
}

static void calc_sums(int pmin, int pmax, uint32_t *data, int n, int pred_order,
                      uint32_t sums[][MAX_PARTITIONS])
{
    int i, j;
    int parts;
    uint32_t *res, *res_end;

    /* sums for highest level */
    parts = (1 << pmax);
    res = &data[pred_order];
    res_end = &data[n >> pmax];
    for(i=0; i<parts; i++) {
        uint32_t sum = 0;
        while(res < res_end){
            sum += *(res++);
        }
        sums[pmax][i] = sum;
        res_end+= n >> pmax;
    }
    /* sums for lower levels */
    for(i=pmax-1; i>=pmin; i--) {
        parts = (1 << i);
        for(j=0; j<parts; j++) {
            sums[i][j] = sums[i+1][2*j] + sums[i+1][2*j+1];
        }
    }
}

static uint32_t calc_rice_params(RiceContext *rc, int pmin, int pmax,
                                 int32_t *data, int n, int pred_order)
{
    int i;
    uint32_t bits[MAX_PARTITION_ORDER+1];
    int opt_porder;
    RiceContext tmp_rc;
    uint32_t *udata;
    uint32_t sums[MAX_PARTITION_ORDER+1][MAX_PARTITIONS];

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

    udata = av_malloc(n * sizeof(uint32_t));
    for(i=0; i<n; i++) {
        udata[i] = (2*data[i]) ^ (data[i]>>31);
    }

    calc_sums(pmin, pmax, udata, n, pred_order, sums);

    opt_porder = pmin;
    bits[pmin] = UINT32_MAX;
    for(i=pmin; i<=pmax; i++) {
        bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums[i], n, pred_order);
        if(bits[i] <= bits[opt_porder]) {
            opt_porder = i;
            *rc= tmp_rc;
        }
    }

    av_freep(&udata);
    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 uint32_t calc_rice_params_fixed(RiceContext *rc, int pmin, int pmax,
                                       int32_t *data, int n, int pred_order,
                                       int bps)
{
    uint32_t bits;
    pmin = get_max_p_order(pmin, n, pred_order);
    pmax = get_max_p_order(pmax, n, pred_order);
    bits = pred_order*bps + 6;
    bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
    return bits;
}

static uint32_t calc_rice_params_lpc(RiceContext *rc, int pmin, int pmax,
                                     int32_t *data, int n, int pred_order,
                                     int bps, int precision)
{
    uint32_t bits;
    pmin = get_max_p_order(pmin, n, pred_order);
    pmax = get_max_p_order(pmax, n, pred_order);
    bits = pred_order*bps + 4 + 5 + pred_order*precision + 6;
    bits += calc_rice_params(rc, pmin, pmax, data, n, pred_order);
    return bits;
}

/**
 * Apply Welch window function to audio block
 */
static void apply_welch_window(const int32_t *data, int len, double *w_data)
{
    int i, n2;
    double w;
    double c;

    assert(!(len&1)); //the optimization in r11881 does not support odd len
                      //if someone wants odd len extend the change in r11881

    n2 = (len >> 1);
    c = 2.0 / (len - 1.0);

    w_data+=n2;
      data+=n2;
    for(i=0; i<n2; i++) {
        w = c - n2 + i;
        w = 1.0 - (w * w);
        w_data[-i-1] = data[-i-1] * w;
        w_data[+i  ] = data[+i  ] * w;
    }
}

/**
 * Calculates autocorrelation data from audio samples
 * A Welch window function is applied before calculation.
 */
void ff_flac_compute_autocorr(const int32_t *data, int len, int lag,
                              double *autoc)
{
    int i, j;
    double tmp[len + lag + 1];
    double *data1= tmp + lag;

    apply_welch_window(data, len, data1);

    for(j=0; j<lag; j++)
        data1[j-lag]= 0.0;
    data1[len] = 0.0;

    for(j=0; j<lag; j+=2){
        double sum0 = 1.0, sum1 = 1.0;
        for(i=0; i<len; i++){
            sum0 += data1[i] * data1[i-j];
            sum1 += data1[i] * data1[i-j-1];
        }
        autoc[j  ] = sum0;
        autoc[j+1] = sum1;
    }

    if(j==lag){
        double sum = 1.0;
        for(i=0; i<len; i+=2){
            sum += data1[i  ] * data1[i-j  ]
                 + data1[i+1] * data1[i-j+1];
        }
        autoc[j] = sum;
    }
}


static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n)
{
    assert(n > 0);
    memcpy(res, smp, n * sizeof(int32_t));
}

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;
        }
    }
}

#define LPC1(x) {\
    int c = coefs[(x)-1];\
    p0 += c*s;\
    s = smp[i-(x)+1];\
    p1 += c*s;\
}

static av_always_inline void encode_residual_lpc_unrolled(
    int32_t *res, const int32_t *smp, int n,
    int order, const int32_t *coefs, int shift, int big)
{
    int i;
    for(i=order; i<n; i+=2) {
        int s = smp[i-order];
        int p0 = 0, p1 = 0;
        if(big) {
            switch(order) {
                case 32: LPC1(32)
                case 31: LPC1(31)
                case 30: LPC1(30)
                case 29: LPC1(29)
                case 28: LPC1(28)
                case 27: LPC1(27)
                case 26: LPC1(26)
                case 25: LPC1(25)
                case 24: LPC1(24)
                case 23: LPC1(23)
                case 22: LPC1(22)
                case 21: LPC1(21)
                case 20: LPC1(20)
                case 19: LPC1(19)
                case 18: LPC1(18)
                case 17: LPC1(17)
                case 16: LPC1(16)
                case 15: LPC1(15)
                case 14: LPC1(14)
                case 13: LPC1(13)
                case 12: LPC1(12)
                case 11: LPC1(11)
                case 10: LPC1(10)
                case  9: LPC1( 9)
                         LPC1( 8)
                         LPC1( 7)
                         LPC1( 6)
                         LPC1( 5)
                         LPC1( 4)
                         LPC1( 3)
                         LPC1( 2)
                         LPC1( 1)
            }
        } else {
            switch(order) {
                case  8: LPC1( 8)
                case  7: LPC1( 7)
                case  6: LPC1( 6)
                case  5: LPC1( 5)
                case  4: LPC1( 4)
                case  3: LPC1( 3)
                case  2: LPC1( 2)
                case  1: LPC1( 1)
            }
        }
        res[i  ] = smp[i  ] - (p0 >> shift);
        res[i+1] = smp[i+1] - (p1 >> shift);
    }
}

static void encode_residual_lpc(int32_t *res, const int32_t *smp, int n,
                                int order, const int32_t *coefs, int shift)
{
    int i;
    for(i=0; i<order; i++) {
        res[i] = smp[i];
    }
#if CONFIG_SMALL
    for(i=order; i<n; i+=2) {
        int j;
        int s = smp[i];
        int p0 = 0, p1 = 0;
        for(j=0; j<order; j++) {
            int c = coefs[j];
            p1 += c*s;
            s = smp[i-j-1];
            p0 += c*s;
        }
        res[i  ] = smp[i  ] - (p0 >> shift);
        res[i+1] = smp[i+1] - (p1 >> shift);
    }
#else
    switch(order) {
        case  1: encode_residual_lpc_unrolled(res, smp, n, 1, coefs, shift, 0); break;
        case  2: encode_residual_lpc_unrolled(res, smp, n, 2, coefs, shift, 0); break;
        case  3: encode_residual_lpc_unrolled(res, smp, n, 3, coefs, shift, 0); break;
        case  4: encode_residual_lpc_unrolled(res, smp, n, 4, coefs, shift, 0); break;
        case  5: encode_residual_lpc_unrolled(res, smp, n, 5, coefs, shift, 0); break;
        case  6: encode_residual_lpc_unrolled(res, smp, n, 6, coefs, shift, 0); break;
        case  7: encode_residual_lpc_unrolled(res, smp, n, 7, coefs, shift, 0); break;
        case  8: encode_residual_lpc_unrolled(res, smp, n, 8, coefs, shift, 0); break;
        default: encode_residual_lpc_unrolled(res, smp, n, order, coefs, shift, 1); break;
    }
#endif
}

static int encode_residual(FlacEncodeContext *ctx, int ch)
{
    int i, n;
    int min_order, max_order, opt_order, precision, omethod;
    int min_porder, max_porder;
    FlacFrame *frame;
    FlacSubframe *sub;
    int32_t coefs[MAX_LPC_ORDER][MAX_LPC_ORDER];
    int shift[MAX_LPC_ORDER];
    int32_t *res, *smp;

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

    /* CONSTANT */
    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 sub->obits;
    }

    /* VERBATIM */
    if(n < 5) {
        sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
        encode_residual_verbatim(res, smp, n);
        return sub->obits * n;
    }

    min_order = ctx->options.min_prediction_order;
    max_order = ctx->options.max_prediction_order;
    min_porder = ctx->options.min_partition_order;
    max_porder = ctx->options.max_partition_order;
    precision = ctx->options.lpc_coeff_precision;
    omethod = ctx->options.prediction_order_method;

    /* FIXED */
    if(!ctx->options.use_lpc || max_order == 0 || (n <= max_order)) {
        uint32_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++) {
            encode_residual_fixed(res, smp, n, i);
            bits[i] = calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res,
                                             n, i, sub->obits);
            if(bits[i] < bits[opt_order]) {
                opt_order = i;
            }
        }
        sub->order = opt_order;
        sub->type = FLAC_SUBFRAME_FIXED;
        sub->type_code = sub->type | sub->order;
        if(sub->order != max_order) {
            encode_residual_fixed(res, smp, n, sub->order);
            return calc_rice_params_fixed(&sub->rc, min_porder, max_porder, res, n,
                                          sub->order, sub->obits);
        }
        return bits[sub->order];
    }

    /* LPC */
    opt_order = ff_lpc_calc_coefs(&ctx->dsp, smp, n, min_order, max_order,
                                  precision, coefs, shift, ctx->options.use_lpc,
                                  omethod, MAX_LPC_SHIFT, 0);

    if(omethod == ORDER_METHOD_2LEVEL ||
       omethod == ORDER_METHOD_4LEVEL ||
       omethod == ORDER_METHOD_8LEVEL) {
        int levels = 1 << omethod;
        uint32_t bits[levels];
        int order;
        int opt_index = levels-1;
        opt_order = max_order-1;
        bits[opt_index] = UINT32_MAX;
        for(i=levels-1; i>=0; i--) {
            order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1;
            if(order < 0) order = 0;
            encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]);
            bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
                                           res, n, order+1, sub->obits, precision);
            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
        uint32_t bits[MAX_LPC_ORDER];
        opt_order = 0;
        bits[0] = UINT32_MAX;
        for(i=min_order-1; i<max_order; i++) {
            encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
            bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
                                           res, n, i+1, sub->obits, precision);
            if(bits[i] < bits[opt_order]) {
                opt_order = i;
            }
        }
        opt_order++;
    } else if(omethod == ORDER_METHOD_LOG) {
        uint32_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;
                encode_residual_lpc(res, smp, n, i+1, coefs[i], shift[i]);
                bits[i] = calc_rice_params_lpc(&sub->rc, min_porder, max_porder,
                                            res, n, i+1, sub->obits, precision);
                if(bits[i] < bits[opt_order])
                    opt_order= i;
            }
        }
        opt_order++;
    }

    sub->order = opt_order;
    sub->type = FLAC_SUBFRAME_LPC;
    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];
    }
    encode_residual_lpc(res, smp, n, sub->order, sub->coefs, sub->shift);
    return calc_rice_params_lpc(&sub->rc, min_porder, max_porder, res, n, sub->order,
                                sub->obits, precision);
}

static int encode_residual_v(FlacEncodeContext *ctx, int ch)
{
    int i, n;
    FlacFrame *frame;
    FlacSubframe *sub;
    int32_t *res, *smp;

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

    /* CONSTANT */
    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 sub->obits;
    }

    /* VERBATIM */
    sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM;
    encode_residual_verbatim(res, smp, n);
    return sub->obits * n;
}

static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n)
{
    int i, best;
    int32_t lt, rt;
    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;
    for(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);
    }
    /* estimate bit counts */
    for(i=0; i<4; i++) {
        k = find_optimal_param(2*sum[i], n);
        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(i=1; i<4; i++) {
        if(score[i] < score[best]) {
            best = i;
        }
    }
    if(best == 0) {
        return FLAC_CHMODE_LEFT_RIGHT;
    } else if(best == 1) {
        return FLAC_CHMODE_LEFT_SIDE;
    } else if(best == 2) {
        return FLAC_CHMODE_RIGHT_SIDE;
    } else {
        return FLAC_CHMODE_MID_SIDE;
    }
}

/**
 * Perform stereo channel decorrelation
 */
static void channel_decorrelation(FlacEncodeContext *ctx)
{
    FlacFrame *frame;
    int32_t *left, *right;
    int i, n;

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

    if(ctx->channels != 2) {
        frame->ch_mode = FLAC_CHMODE_NOT_STEREO;
        return;
    }

    frame->ch_mode = estimate_stereo_mode(left, right, n);

    /* perform decorrelation and adjust bits-per-sample */
    if(frame->ch_mode == FLAC_CHMODE_LEFT_RIGHT) {
        return;
    }
    if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
        int32_t tmp;
        for(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(i=0; i<n; i++) {
            right[i] = left[i] - right[i];
        }
        frame->subframes[1].obits++;
    } else {
        for(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 output_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_NOT_STEREO) {
        put_bits(&s->pb, 4, s->ch_code);
    } else {
        put_bits(&s->pb, 4, frame->ch_mode);
    }
    put_bits(&s->pb, 3, 4); /* bits-per-sample 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_bits_count(&s->pb)>>3);
    put_bits(&s->pb, 8, crc);
}

static void output_subframe_constant(FlacEncodeContext *s, int ch)
{
    FlacSubframe *sub;
    int32_t res;

    sub = &s->frame.subframes[ch];
    res = sub->residual[0];
    put_sbits(&s->pb, sub->obits, res);
}

static void output_subframe_verbatim(FlacEncodeContext *s, int ch)
{
    int i;
    FlacFrame *frame;
    FlacSubframe *sub;
    int32_t res;

    frame = &s->frame;
    sub = &frame->subframes[ch];

    for(i=0; i<frame->blocksize; i++) {
        res = sub->residual[i];
        put_sbits(&s->pb, sub->obits, res);
    }
}

static void output_residual(FlacEncodeContext *ctx, int ch)
{
    int i, j, p, n, parts;
    int k, porder, psize, res_cnt;
    FlacFrame *frame;
    FlacSubframe *sub;
    int32_t *res;

    frame = &ctx->frame;
    sub = &frame->subframes[ch];
    res = sub->residual;
    n = frame->blocksize;

    /* rice-encoded block */
    put_bits(&ctx->pb, 2, 0);

    /* partition order */
    porder = sub->rc.porder;
    psize = n >> porder;
    parts = (1 << porder);
    put_bits(&ctx->pb, 4, porder);
    res_cnt = psize - sub->order;

    /* residual */
    j = sub->order;
    for(p=0; p<parts; p++) {
        k = sub->rc.params[p];
        put_bits(&ctx->pb, 4, k);
        if(p == 1) res_cnt = psize;
        for(i=0; i<res_cnt && j<n; i++, j++) {
            set_sr_golomb_flac(&ctx->pb, res[j], k, INT32_MAX, 0);
        }
    }
}

static void output_subframe_fixed(FlacEncodeContext *ctx, int ch)
{
    int i;
    FlacFrame *frame;
    FlacSubframe *sub;

    frame = &ctx->frame;
    sub = &frame->subframes[ch];

    /* warm-up samples */
    for(i=0; i<sub->order; i++) {
        put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
    }

    /* residual */
    output_residual(ctx, ch);
}

static void output_subframe_lpc(FlacEncodeContext *ctx, int ch)
{
    int i, cbits;
    FlacFrame *frame;
    FlacSubframe *sub;

    frame = &ctx->frame;
    sub = &frame->subframes[ch];

    /* warm-up samples */
    for(i=0; i<sub->order; i++) {
        put_sbits(&ctx->pb, sub->obits, sub->residual[i]);
    }

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

    /* residual */
    output_residual(ctx, ch);
}

static void output_subframes(FlacEncodeContext *s)
{
    FlacFrame *frame;
    FlacSubframe *sub;
    int ch;

    frame = &s->frame;

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

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

        /* subframe */
        if(sub->type == FLAC_SUBFRAME_CONSTANT) {
            output_subframe_constant(s, ch);
        } else if(sub->type == FLAC_SUBFRAME_VERBATIM) {
            output_subframe_verbatim(s, ch);
        } else if(sub->type == FLAC_SUBFRAME_FIXED) {
            output_subframe_fixed(s, ch);
        } else if(sub->type == FLAC_SUBFRAME_LPC) {
            output_subframe_lpc(s, ch);
        }
    }
}

static void output_frame_footer(FlacEncodeContext *s)
{
    int crc;
    flush_put_bits(&s->pb);
    crc = bswap_16(av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0,
                          s->pb.buf, put_bits_count(&s->pb)>>3));
    put_bits(&s->pb, 16, crc);
    flush_put_bits(&s->pb);
}

static void update_md5_sum(FlacEncodeContext *s, int16_t *samples)
{
#ifdef WORDS_BIGENDIAN
    int i;
    for(i = 0; i < s->frame.blocksize*s->channels; i++) {
        int16_t smp = le2me_16(samples[i]);
        av_md5_update(s->md5ctx, (uint8_t *)&smp, 2);
    }
#else
    av_md5_update(s->md5ctx, (uint8_t *)samples, s->frame.blocksize*s->channels*2);
#endif
}

static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
                             int buf_size, void *data)
{
    int ch;
    FlacEncodeContext *s;
    int16_t *samples = data;
    int out_bytes;
    int reencoded=0;

    s = avctx->priv_data;

    if(buf_size < s->max_framesize*2) {
        av_log(avctx, AV_LOG_ERROR, "output buffer too small\n");
        return 0;
    }

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

    init_frame(s);

    copy_samples(s, samples);

    channel_decorrelation(s);

    for(ch=0; ch<s->channels; ch++) {
        encode_residual(s, ch);
    }

write_frame:
    init_put_bits(&s->pb, frame, buf_size);
    output_frame_header(s);
    output_subframes(s);
    output_frame_footer(s);
    out_bytes = put_bits_count(&s->pb) >> 3;

    if(out_bytes > s->max_framesize) {
        if(reencoded) {
            /* still too large. must be an error. */
            av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
            return -1;
        }

        /* frame too large. use verbatim mode */
        for(ch=0; ch<s->channels; ch++) {
            encode_residual_v(s, ch);
        }
        reencoded = 1;
        goto write_frame;
    }

    s->frame_count++;
    s->sample_count += avctx->frame_size;
    update_md5_sum(s, samples);
    if (out_bytes > s->max_encoded_framesize)
        s->max_encoded_framesize = out_bytes;
    if (out_bytes < s->min_encoded_framesize)
        s->min_encoded_framesize = out_bytes;

    return out_bytes;
}

static av_cold int flac_encode_close(AVCodecContext *avctx)
{
    if (avctx->priv_data) {
        FlacEncodeContext *s = avctx->priv_data;
        av_freep(&s->md5ctx);
    }
    av_freep(&avctx->extradata);
    avctx->extradata_size = 0;
    av_freep(&avctx->coded_frame);
    return 0;
}

AVCodec flac_encoder = {
    "flac",
    CODEC_TYPE_AUDIO,
    CODEC_ID_FLAC,
    sizeof(FlacEncodeContext),
    flac_encode_init,
    flac_encode_frame,
    flac_encode_close,
    NULL,
    .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
    .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
    .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
};
