/*
 * Opus encoder
 * Copyright (c) 2017 Rostislav Pehlivanov <atomnuker@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 "opusenc.h"
#include "opus_pvq.h"
#include "opusenc_psy.h"
#include "opustab.h"

#include "libavutil/float_dsp.h"
#include "libavutil/opt.h"
#include "internal.h"
#include "bytestream.h"
#include "audio_frame_queue.h"

typedef struct OpusEncContext {
    AVClass *av_class;
    OpusEncOptions options;
    OpusPsyContext psyctx;
    AVCodecContext *avctx;
    AudioFrameQueue afq;
    AVFloatDSPContext *dsp;
    MDCT15Context *mdct[CELT_BLOCK_NB];
    CeltPVQ *pvq;
    struct FFBufQueue bufqueue;

    uint8_t enc_id[64];
    int enc_id_bits;

    OpusPacketInfo packet;

    int channels;

    CeltFrame *frame;
    OpusRangeCoder *rc;

    /* Actual energy the decoder will have */
    float last_quantized_energy[OPUS_MAX_CHANNELS][CELT_MAX_BANDS];

    DECLARE_ALIGNED(32, float, scratch)[2048];
} OpusEncContext;

static void opus_write_extradata(AVCodecContext *avctx)
{
    uint8_t *bs = avctx->extradata;

    bytestream_put_buffer(&bs, "OpusHead", 8);
    bytestream_put_byte  (&bs, 0x1);
    bytestream_put_byte  (&bs, avctx->channels);
    bytestream_put_le16  (&bs, avctx->initial_padding);
    bytestream_put_le32  (&bs, avctx->sample_rate);
    bytestream_put_le16  (&bs, 0x0);
    bytestream_put_byte  (&bs, 0x0); /* Default layout */
}

static int opus_gen_toc(OpusEncContext *s, uint8_t *toc, int *size, int *fsize_needed)
{
    int i, tmp = 0x0, extended_toc = 0;
    static const int toc_cfg[][OPUS_MODE_NB][OPUS_BANDWITH_NB] = {
        /*  Silk                    Hybrid                  Celt                    Layer     */
        /*  NB  MB  WB SWB  FB      NB  MB  WB SWB  FB      NB  MB  WB SWB  FB      Bandwidth */
        { {  0,  0,  0,  0,  0 }, {  0,  0,  0,  0,  0 }, { 17,  0, 21, 25, 29 } }, /* 2.5 ms */
        { {  0,  0,  0,  0,  0 }, {  0,  0,  0,  0,  0 }, { 18,  0, 22, 26, 30 } }, /*   5 ms */
        { {  1,  5,  9,  0,  0 }, {  0,  0,  0, 13, 15 }, { 19,  0, 23, 27, 31 } }, /*  10 ms */
        { {  2,  6, 10,  0,  0 }, {  0,  0,  0, 14, 16 }, { 20,  0, 24, 28, 32 } }, /*  20 ms */
        { {  3,  7, 11,  0,  0 }, {  0,  0,  0,  0,  0 }, {  0,  0,  0,  0,  0 } }, /*  40 ms */
        { {  4,  8, 12,  0,  0 }, {  0,  0,  0,  0,  0 }, {  0,  0,  0,  0,  0 } }, /*  60 ms */
    };
    int cfg = toc_cfg[s->packet.framesize][s->packet.mode][s->packet.bandwidth];
    *fsize_needed = 0;
    if (!cfg)
        return 1;
    if (s->packet.frames == 2) {                                       /* 2 packets */
        if (s->frame[0].framebits == s->frame[1].framebits) {          /* same size */
            tmp = 0x1;
        } else {                                                  /* different size */
            tmp = 0x2;
            *fsize_needed = 1;                     /* put frame sizes in the packet */
        }
    } else if (s->packet.frames > 2) {
        tmp = 0x3;
        extended_toc = 1;
    }
    tmp |= (s->channels > 1) << 2;                                /* Stereo or mono */
    tmp |= (cfg - 1)         << 3;                           /* codec configuration */
    *toc++ = tmp;
    if (extended_toc) {
        for (i = 0; i < (s->packet.frames - 1); i++)
            *fsize_needed |= (s->frame[i].framebits != s->frame[i + 1].framebits);
        tmp = (*fsize_needed) << 7;                                /* vbr flag */
        tmp |= (0) << 6;                                       /* padding flag */
        tmp |= s->packet.frames;
        *toc++ = tmp;
    }
    *size = 1 + extended_toc;
    return 0;
}

static void celt_frame_setup_input(OpusEncContext *s, CeltFrame *f)
{
    int sf, ch;
    AVFrame *cur = NULL;
    const int subframesize = s->avctx->frame_size;
    int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;

    cur = ff_bufqueue_get(&s->bufqueue);

    for (ch = 0; ch < f->channels; ch++) {
        CeltBlock *b = &f->block[ch];
        const void *input = cur->extended_data[ch];
        size_t bps = av_get_bytes_per_sample(cur->format);
        memcpy(b->overlap, input, bps*cur->nb_samples);
    }

    av_frame_free(&cur);

    for (sf = 0; sf < subframes; sf++) {
        if (sf != (subframes - 1))
            cur = ff_bufqueue_get(&s->bufqueue);
        else
            cur = ff_bufqueue_peek(&s->bufqueue, 0);

        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *b = &f->block[ch];
            const void *input = cur->extended_data[ch];
            const size_t bps  = av_get_bytes_per_sample(cur->format);
            const size_t left = (subframesize - cur->nb_samples)*bps;
            const size_t len  = FFMIN(subframesize, cur->nb_samples)*bps;
            memcpy(&b->samples[sf*subframesize], input, len);
            memset(&b->samples[cur->nb_samples], 0, left);
        }

        /* Last frame isn't popped off and freed yet - we need it for overlap */
        if (sf != (subframes - 1))
            av_frame_free(&cur);
    }
}

/* Apply the pre emphasis filter */
static void celt_apply_preemph_filter(OpusEncContext *s, CeltFrame *f)
{
    int i, sf, ch;
    const int subframesize = s->avctx->frame_size;
    const int subframes = OPUS_BLOCK_SIZE(s->packet.framesize) / subframesize;

    /* Filter overlap */
    for (ch = 0; ch < f->channels; ch++) {
        CeltBlock *b = &f->block[ch];
        float m = b->emph_coeff;
        for (i = 0; i < CELT_OVERLAP; i++) {
            float sample = b->overlap[i];
            b->overlap[i] = sample - m;
            m = sample * CELT_EMPH_COEFF;
        }
        b->emph_coeff = m;
    }

    /* Filter the samples but do not update the last subframe's coeff - overlap ^^^ */
    for (sf = 0; sf < subframes; sf++) {
        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *b = &f->block[ch];
            float m = b->emph_coeff;
            for (i = 0; i < subframesize; i++) {
                float sample = b->samples[sf*subframesize + i];
                b->samples[sf*subframesize + i] = sample - m;
                m = sample * CELT_EMPH_COEFF;
            }
            if (sf != (subframes - 1))
                b->emph_coeff = m;
        }
    }
}

/* Create the window and do the mdct */
static void celt_frame_mdct(OpusEncContext *s, CeltFrame *f)
{
    int i, j, t, ch;
    float *win = s->scratch, *temp = s->scratch + 1920;

    if (f->transient) {
        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *b = &f->block[ch];
            float *src1 = b->overlap;
            for (t = 0; t < f->blocks; t++) {
                float *src2 = &b->samples[CELT_OVERLAP*t];
                s->dsp->vector_fmul(win, src1, ff_celt_window, 128);
                s->dsp->vector_fmul_reverse(&win[CELT_OVERLAP], src2,
                                            ff_celt_window - 8, 128);
                src1 = src2;
                s->mdct[0]->mdct(s->mdct[0], b->coeffs + t, win, f->blocks);
            }
        }
    } else {
        int blk_len = OPUS_BLOCK_SIZE(f->size), wlen = OPUS_BLOCK_SIZE(f->size + 1);
        int rwin = blk_len - CELT_OVERLAP, lap_dst = (wlen - blk_len - CELT_OVERLAP) >> 1;
        memset(win, 0, wlen*sizeof(float));
        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *b = &f->block[ch];

            /* Overlap */
            s->dsp->vector_fmul(temp, b->overlap, ff_celt_window, 128);
            memcpy(win + lap_dst, temp, CELT_OVERLAP*sizeof(float));

            /* Samples, flat top window */
            memcpy(&win[lap_dst + CELT_OVERLAP], b->samples, rwin*sizeof(float));

            /* Samples, windowed */
            s->dsp->vector_fmul_reverse(temp, b->samples + rwin,
                                        ff_celt_window - 8, 128);
            memcpy(win + lap_dst + blk_len, temp, CELT_OVERLAP*sizeof(float));

            s->mdct[f->size]->mdct(s->mdct[f->size], b->coeffs, win, 1);
        }
    }

    for (ch = 0; ch < f->channels; ch++) {
        CeltBlock *block = &f->block[ch];
        for (i = 0; i < CELT_MAX_BANDS; i++) {
            float ener = 0.0f;
            int band_offset = ff_celt_freq_bands[i] << f->size;
            int band_size   = ff_celt_freq_range[i] << f->size;
            float *coeffs   = &block->coeffs[band_offset];

            for (j = 0; j < band_size; j++)
                ener += coeffs[j]*coeffs[j];

            block->lin_energy[i] = sqrtf(ener) + FLT_EPSILON;
            ener = 1.0f/block->lin_energy[i];

            for (j = 0; j < band_size; j++)
                coeffs[j] *= ener;

            block->energy[i] = log2f(block->lin_energy[i]) - ff_celt_mean_energy[i];

            /* CELT_ENERGY_SILENCE is what the decoder uses and its not -infinity */
            block->energy[i] = FFMAX(block->energy[i], CELT_ENERGY_SILENCE);
        }
    }
}

static void celt_enc_tf(CeltFrame *f, OpusRangeCoder *rc)
{
    int i, tf_select = 0, diff = 0, tf_changed = 0, tf_select_needed;
    int bits = f->transient ? 2 : 4;

    tf_select_needed = ((f->size && (opus_rc_tell(rc) + bits + 1) <= f->framebits));

    for (i = f->start_band; i < f->end_band; i++) {
        if ((opus_rc_tell(rc) + bits + tf_select_needed) <= f->framebits) {
            const int tbit = (diff ^ 1) == f->tf_change[i];
            ff_opus_rc_enc_log(rc, tbit, bits);
            diff ^= tbit;
            tf_changed |= diff;
        }
        bits = f->transient ? 4 : 5;
    }

    if (tf_select_needed && ff_celt_tf_select[f->size][f->transient][0][tf_changed] !=
                            ff_celt_tf_select[f->size][f->transient][1][tf_changed]) {
        ff_opus_rc_enc_log(rc, f->tf_select, 1);
        tf_select = f->tf_select;
    }

    for (i = f->start_band; i < f->end_band; i++)
        f->tf_change[i] = ff_celt_tf_select[f->size][f->transient][tf_select][f->tf_change[i]];
}

static void celt_enc_quant_pfilter(OpusRangeCoder *rc, CeltFrame *f)
{
    float gain = f->pf_gain;
    int i, txval, octave = f->pf_octave, period = f->pf_period, tapset = f->pf_tapset;

    ff_opus_rc_enc_log(rc, f->pfilter, 1);
    if (!f->pfilter)
        return;

    /* Octave */
    txval = FFMIN(octave, 6);
    ff_opus_rc_enc_uint(rc, txval, 6);
    octave = txval;
    /* Period */
    txval = av_clip(period - (16 << octave) + 1, 0, (1 << (4 + octave)) - 1);
    ff_opus_rc_put_raw(rc, period, 4 + octave);
    period = txval + (16 << octave) - 1;
    /* Gain */
    txval = FFMIN(((int)(gain / 0.09375f)) - 1, 7);
    ff_opus_rc_put_raw(rc, txval, 3);
    gain   = 0.09375f * (txval + 1);
    /* Tapset */
    if ((opus_rc_tell(rc) + 2) <= f->framebits)
        ff_opus_rc_enc_cdf(rc, tapset, ff_celt_model_tapset);
    else
        tapset = 0;
    /* Finally create the coeffs */
    for (i = 0; i < 2; i++) {
        CeltBlock *block = &f->block[i];

        block->pf_period_new = FFMAX(period, CELT_POSTFILTER_MINPERIOD);
        block->pf_gains_new[0] = gain * ff_celt_postfilter_taps[tapset][0];
        block->pf_gains_new[1] = gain * ff_celt_postfilter_taps[tapset][1];
        block->pf_gains_new[2] = gain * ff_celt_postfilter_taps[tapset][2];
    }
}

static void exp_quant_coarse(OpusRangeCoder *rc, CeltFrame *f,
                             float last_energy[][CELT_MAX_BANDS], int intra)
{
    int i, ch;
    float alpha, beta, prev[2] = { 0, 0 };
    const uint8_t *pmod = ff_celt_coarse_energy_dist[f->size][intra];

    /* Inter is really just differential coding */
    if (opus_rc_tell(rc) + 3 <= f->framebits)
        ff_opus_rc_enc_log(rc, intra, 3);
    else
        intra = 0;

    if (intra) {
        alpha = 0.0f;
        beta  = 1.0f - (4915.0f/32768.0f);
    } else {
        alpha = ff_celt_alpha_coef[f->size];
        beta  = ff_celt_beta_coef[f->size];
    }

    for (i = f->start_band; i < f->end_band; i++) {
        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *block = &f->block[ch];
            const int left = f->framebits - opus_rc_tell(rc);
            const float last = FFMAX(-9.0f, last_energy[ch][i]);
            float diff = block->energy[i] - prev[ch] - last*alpha;
            int q_en = lrintf(diff);
            if (left >= 15) {
                ff_opus_rc_enc_laplace(rc, &q_en, pmod[i << 1] << 7, pmod[(i << 1) + 1] << 6);
            } else if (left >= 2) {
                q_en = av_clip(q_en, -1, 1);
                ff_opus_rc_enc_cdf(rc, 2*q_en + 3*(q_en < 0), ff_celt_model_energy_small);
            } else if (left >= 1) {
                q_en = av_clip(q_en, -1, 0);
                ff_opus_rc_enc_log(rc, (q_en & 1), 1);
            } else q_en = -1;

            block->error_energy[i] = q_en - diff;
            prev[ch] += beta * q_en;
        }
    }
}

static void celt_quant_coarse(CeltFrame *f, OpusRangeCoder *rc,
                              float last_energy[][CELT_MAX_BANDS])
{
    uint32_t inter, intra;
    OPUS_RC_CHECKPOINT_SPAWN(rc);

    exp_quant_coarse(rc, f, last_energy, 1);
    intra = OPUS_RC_CHECKPOINT_BITS(rc);

    OPUS_RC_CHECKPOINT_ROLLBACK(rc);

    exp_quant_coarse(rc, f, last_energy, 0);
    inter = OPUS_RC_CHECKPOINT_BITS(rc);

    if (inter > intra) { /* Unlikely */
        OPUS_RC_CHECKPOINT_ROLLBACK(rc);
        exp_quant_coarse(rc, f, last_energy, 1);
    }
}

static void celt_quant_fine(CeltFrame *f, OpusRangeCoder *rc)
{
    int i, ch;
    for (i = f->start_band; i < f->end_band; i++) {
        if (!f->fine_bits[i])
            continue;
        for (ch = 0; ch < f->channels; ch++) {
            CeltBlock *block = &f->block[ch];
            int quant, lim = (1 << f->fine_bits[i]);
            float offset, diff = 0.5f - block->error_energy[i];
            quant = av_clip(floor(diff*lim), 0, lim - 1);
            ff_opus_rc_put_raw(rc, quant, f->fine_bits[i]);
            offset = 0.5f - ((quant + 0.5f) * (1 << (14 - f->fine_bits[i])) / 16384.0f);
            block->error_energy[i] -= offset;
        }
    }
}

static void celt_quant_final(OpusEncContext *s, OpusRangeCoder *rc, CeltFrame *f)
{
    int i, ch, priority;
    for (priority = 0; priority < 2; priority++) {
        for (i = f->start_band; i < f->end_band && (f->framebits - opus_rc_tell(rc)) >= f->channels; i++) {
            if (f->fine_priority[i] != priority || f->fine_bits[i] >= CELT_MAX_FINE_BITS)
                continue;
            for (ch = 0; ch < f->channels; ch++) {
                CeltBlock *block = &f->block[ch];
                const float err = block->error_energy[i];
                const float offset = 0.5f * (1 << (14 - f->fine_bits[i] - 1)) / 16384.0f;
                const int sign = FFABS(err + offset) < FFABS(err - offset);
                ff_opus_rc_put_raw(rc, sign, 1);
                block->error_energy[i] -= offset*(1 - 2*sign);
            }
        }
    }
}

static void celt_encode_frame(OpusEncContext *s, OpusRangeCoder *rc,
                              CeltFrame *f, int index)
{
    int i, ch;

    ff_opus_rc_enc_init(rc);

    ff_opus_psy_celt_frame_init(&s->psyctx, f, index);

    celt_frame_setup_input(s, f);

    if (f->silence) {
        if (f->framebits >= 16)
            ff_opus_rc_enc_log(rc, 1, 15); /* Silence (if using explicit singalling) */
        for (ch = 0; ch < s->channels; ch++)
            memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS);
        return;
    }

    /* Filters */
    celt_apply_preemph_filter(s, f);
    if (f->pfilter) {
        ff_opus_rc_enc_log(rc, 0, 15);
        celt_enc_quant_pfilter(rc, f);
    }

    /* Transform */
    celt_frame_mdct(s, f);

    /* Need to handle transient/non-transient switches at any point during analysis */
    while (ff_opus_psy_celt_frame_process(&s->psyctx, f, index))
        celt_frame_mdct(s, f);

    ff_opus_rc_enc_init(rc);

    /* Silence */
    ff_opus_rc_enc_log(rc, 0, 15);

    /* Pitch filter */
    if (!f->start_band && opus_rc_tell(rc) + 16 <= f->framebits)
        celt_enc_quant_pfilter(rc, f);

    /* Transient flag */
    if (f->size && opus_rc_tell(rc) + 3 <= f->framebits)
        ff_opus_rc_enc_log(rc, f->transient, 3);

    /* Main encoding */
    celt_quant_coarse  (f, rc, s->last_quantized_energy);
    celt_enc_tf        (f, rc);
    ff_celt_bitalloc   (f, rc, 1);
    celt_quant_fine    (f, rc);
    ff_celt_quant_bands(f, rc);

    /* Anticollapse bit */
    if (f->anticollapse_needed)
        ff_opus_rc_put_raw(rc, f->anticollapse, 1);

    /* Final per-band energy adjustments from leftover bits */
    celt_quant_final(s, rc, f);

    for (ch = 0; ch < f->channels; ch++) {
        CeltBlock *block = &f->block[ch];
        for (i = 0; i < CELT_MAX_BANDS; i++)
            s->last_quantized_energy[ch][i] = block->energy[i] + block->error_energy[i];
    }
}

static inline int write_opuslacing(uint8_t *dst, int v)
{
    dst[0] = FFMIN(v - FFALIGN(v - 255, 4), v);
    dst[1] = v - dst[0] >> 2;
    return 1 + (v >= 252);
}

static void opus_packet_assembler(OpusEncContext *s, AVPacket *avpkt)
{
    int i, offset, fsize_needed;

    /* Write toc */
    opus_gen_toc(s, avpkt->data, &offset, &fsize_needed);

    /* Frame sizes if needed */
    if (fsize_needed) {
        for (i = 0; i < s->packet.frames - 1; i++) {
            offset += write_opuslacing(avpkt->data + offset,
                                       s->frame[i].framebits >> 3);
        }
    }

    /* Packets */
    for (i = 0; i < s->packet.frames; i++) {
        ff_opus_rc_enc_end(&s->rc[i], avpkt->data + offset,
                           s->frame[i].framebits >> 3);
        offset += s->frame[i].framebits >> 3;
    }

    avpkt->size = offset;
}

/* Used as overlap for the first frame and padding for the last encoded packet */
static AVFrame *spawn_empty_frame(OpusEncContext *s)
{
    int i;
    AVFrame *f = av_frame_alloc();
    if (!f)
        return NULL;
    f->format         = s->avctx->sample_fmt;
    f->nb_samples     = s->avctx->frame_size;
    f->channel_layout = s->avctx->channel_layout;
    if (av_frame_get_buffer(f, 4)) {
        av_frame_free(&f);
        return NULL;
    }
    for (i = 0; i < s->channels; i++) {
        size_t bps = av_get_bytes_per_sample(f->format);
        memset(f->extended_data[i], 0, bps*f->nb_samples);
    }
    return f;
}

static int opus_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                             const AVFrame *frame, int *got_packet_ptr)
{
    OpusEncContext *s = avctx->priv_data;
    int i, ret, frame_size, alloc_size = 0;

    if (frame) { /* Add new frame to queue */
        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
            return ret;
        ff_bufqueue_add(avctx, &s->bufqueue, av_frame_clone(frame));
    } else {
        ff_opus_psy_signal_eof(&s->psyctx);
        if (!s->afq.remaining_samples)
            return 0; /* We've been flushed and there's nothing left to encode */
    }

    /* Run the psychoacoustic system */
    if (ff_opus_psy_process(&s->psyctx, &s->packet))
        return 0;

    frame_size = OPUS_BLOCK_SIZE(s->packet.framesize);

    if (!frame) {
        /* This can go negative, that's not a problem, we only pad if positive */
        int pad_empty = s->packet.frames*(frame_size/s->avctx->frame_size) - s->bufqueue.available + 1;
        /* Pad with empty 2.5 ms frames to whatever framesize was decided,
         * this should only happen at the very last flush frame. The frames
         * allocated here will be freed (because they have no other references)
         * after they get used by celt_frame_setup_input() */
        for (i = 0; i < pad_empty; i++) {
            AVFrame *empty = spawn_empty_frame(s);
            if (!empty)
                return AVERROR(ENOMEM);
            ff_bufqueue_add(avctx, &s->bufqueue, empty);
        }
    }

    for (i = 0; i < s->packet.frames; i++) {
        celt_encode_frame(s, &s->rc[i], &s->frame[i], i);
        alloc_size += s->frame[i].framebits >> 3;
    }

    /* Worst case toc + the frame lengths if needed */
    alloc_size += 2 + s->packet.frames*2;

    if ((ret = ff_alloc_packet2(avctx, avpkt, alloc_size, 0)) < 0)
        return ret;

    /* Assemble packet */
    opus_packet_assembler(s, avpkt);

    /* Update the psychoacoustic system */
    ff_opus_psy_postencode_update(&s->psyctx, s->frame, s->rc);

    /* Remove samples from queue and skip if needed */
    ff_af_queue_remove(&s->afq, s->packet.frames*frame_size, &avpkt->pts, &avpkt->duration);
    if (s->packet.frames*frame_size > avpkt->duration) {
        uint8_t *side = av_packet_new_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, 10);
        if (!side)
            return AVERROR(ENOMEM);
        AV_WL32(&side[4], s->packet.frames*frame_size - avpkt->duration + 120);
    }

    *got_packet_ptr = 1;

    return 0;
}

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

    for (i = 0; i < CELT_BLOCK_NB; i++)
        ff_mdct15_uninit(&s->mdct[i]);

    ff_celt_pvq_uninit(&s->pvq);
    av_freep(&s->dsp);
    av_freep(&s->frame);
    av_freep(&s->rc);
    ff_af_queue_close(&s->afq);
    ff_opus_psy_end(&s->psyctx);
    ff_bufqueue_discard_all(&s->bufqueue);
    av_freep(&avctx->extradata);

    return 0;
}

static av_cold int opus_encode_init(AVCodecContext *avctx)
{
    int i, ch, ret, max_frames;
    OpusEncContext *s = avctx->priv_data;

    s->avctx = avctx;
    s->channels = avctx->channels;

    /* Opus allows us to change the framesize on each packet (and each packet may
     * have multiple frames in it) but we can't change the codec's frame size on
     * runtime, so fix it to the lowest possible number of samples and use a queue
     * to accumulate AVFrames until we have enough to encode whatever the encoder
     * decides is the best */
    avctx->frame_size = 120;
    /* Initial padding will change if SILK is ever supported */
    avctx->initial_padding = 120;

    if (!avctx->bit_rate) {
        int coupled = ff_opus_default_coupled_streams[s->channels - 1];
        avctx->bit_rate = coupled*(96000) + (s->channels - coupled*2)*(48000);
    } else if (avctx->bit_rate < 6000 || avctx->bit_rate > 255000 * s->channels) {
        int64_t clipped_rate = av_clip(avctx->bit_rate, 6000, 255000 * s->channels);
        av_log(avctx, AV_LOG_ERROR, "Unsupported bitrate %"PRId64" kbps, clipping to %"PRId64" kbps\n",
               avctx->bit_rate/1000, clipped_rate/1000);
        avctx->bit_rate = clipped_rate;
    }

    /* Extradata */
    avctx->extradata_size = 19;
    avctx->extradata = av_malloc(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!avctx->extradata)
        return AVERROR(ENOMEM);
    opus_write_extradata(avctx);

    ff_af_queue_init(avctx, &s->afq);

    if ((ret = ff_celt_pvq_init(&s->pvq, 1)) < 0)
        return ret;

    if (!(s->dsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT)))
        return AVERROR(ENOMEM);

    /* I have no idea why a base scaling factor of 68 works, could be the twiddles */
    for (i = 0; i < CELT_BLOCK_NB; i++)
        if ((ret = ff_mdct15_init(&s->mdct[i], 0, i + 3, 68 << (CELT_BLOCK_NB - 1 - i))))
            return AVERROR(ENOMEM);

    /* Zero out previous energy (matters for inter first frame) */
    for (ch = 0; ch < s->channels; ch++)
        memset(s->last_quantized_energy[ch], 0.0f, sizeof(float)*CELT_MAX_BANDS);

    /* Allocate an empty frame to use as overlap for the first frame of audio */
    ff_bufqueue_add(avctx, &s->bufqueue, spawn_empty_frame(s));
    if (!ff_bufqueue_peek(&s->bufqueue, 0))
        return AVERROR(ENOMEM);

    if ((ret = ff_opus_psy_init(&s->psyctx, s->avctx, &s->bufqueue, &s->options)))
        return ret;

    /* Frame structs and range coder buffers */
    max_frames = ceilf(FFMIN(s->options.max_delay_ms, 120.0f)/2.5f);
    s->frame = av_malloc(max_frames*sizeof(CeltFrame));
    if (!s->frame)
        return AVERROR(ENOMEM);
    s->rc = av_malloc(max_frames*sizeof(OpusRangeCoder));
    if (!s->rc)
        return AVERROR(ENOMEM);

    for (i = 0; i < max_frames; i++) {
        s->frame[i].dsp = s->dsp;
        s->frame[i].avctx = s->avctx;
        s->frame[i].seed = 0;
        s->frame[i].pvq = s->pvq;
        s->frame[i].apply_phase_inv = 1;
        s->frame[i].block[0].emph_coeff = s->frame[i].block[1].emph_coeff = 0.0f;
    }

    return 0;
}

#define OPUSENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption opusenc_options[] = {
    { "opus_delay", "Maximum delay in milliseconds", offsetof(OpusEncContext, options.max_delay_ms), AV_OPT_TYPE_FLOAT, { .dbl = OPUS_MAX_LOOKAHEAD }, 2.5f, OPUS_MAX_LOOKAHEAD, OPUSENC_FLAGS, "max_delay_ms" },
    { NULL },
};

static const AVClass opusenc_class = {
    .class_name = "Opus encoder",
    .item_name  = av_default_item_name,
    .option     = opusenc_options,
    .version    = LIBAVUTIL_VERSION_INT,
};

static const AVCodecDefault opusenc_defaults[] = {
    { "b", "0" },
    { "compression_level", "10" },
    { NULL },
};

AVCodec ff_opus_encoder = {
    .name           = "opus",
    .long_name      = NULL_IF_CONFIG_SMALL("Opus"),
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_OPUS,
    .defaults       = opusenc_defaults,
    .priv_class     = &opusenc_class,
    .priv_data_size = sizeof(OpusEncContext),
    .init           = opus_encode_init,
    .encode2        = opus_encode_frame,
    .close          = opus_encode_end,
    .caps_internal  = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
    .capabilities   = AV_CODEC_CAP_EXPERIMENTAL | AV_CODEC_CAP_SMALL_LAST_FRAME | AV_CODEC_CAP_DELAY,
    .supported_samplerates = (const int []){ 48000, 0 },
    .channel_layouts = (const uint64_t []){ AV_CH_LAYOUT_MONO,
                                            AV_CH_LAYOUT_STEREO, 0 },
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLTP,
                                                     AV_SAMPLE_FMT_NONE },
};
