/*
 * Musepack SV7 decoder
 * Copyright (c) 2006 Konstantin Shishkov
 *
 * 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
 */

/**
 * @file
 * MPEG Audio Layer 1/2 -like codec with frames of 1152 samples
 * divided into 32 subbands.
 */

#include "libavutil/channel_layout.h"
#include "libavutil/internal.h"
#include "libavutil/lfg.h"
#include "libavutil/mem.h"
#include "libavutil/mem_internal.h"
#include "libavutil/thread.h"

#include "avcodec.h"
#include "codec_internal.h"
#include "decode.h"
#include "get_bits.h"
#include "mpegaudiodsp.h"

#include "mpc.h"
#include "mpc7data.h"

static VLCElem scfi_vlc[1 << MPC7_SCFI_BITS];
static VLCElem dscf_vlc[1 << MPC7_DSCF_BITS];
static VLCElem hdr_vlc [1 << MPC7_HDR_BITS];
static const VLCElem *quant_vlc[MPC7_QUANT_VLC_TABLES][2];

static av_cold void mpc7_init_static(void)
{
    static VLCElem quant_tables[7224];
    VLCInitState state = VLC_INIT_STATE(quant_tables);
    const uint8_t *raw_quant_table = mpc7_quant_vlcs;

    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(scfi_vlc, MPC7_SCFI_BITS, MPC7_SCFI_SIZE,
                                       &mpc7_scfi[1], 2,
                                       &mpc7_scfi[0], 2, 1, 0, 0);
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(dscf_vlc, MPC7_DSCF_BITS, MPC7_DSCF_SIZE,
                                       &mpc7_dscf[1], 2,
                                       &mpc7_dscf[0], 2, 1, -7, 0);
    VLC_INIT_STATIC_TABLE_FROM_LENGTHS(hdr_vlc, MPC7_HDR_BITS, MPC7_HDR_SIZE,
                                       &mpc7_hdr[1], 2,
                                       &mpc7_hdr[0], 2, 1, -5, 0);
    for (int i = 0; i < MPC7_QUANT_VLC_TABLES; i++) {
        for (int j = 0; j < 2; j++) {
            quant_vlc[i][j] =
                ff_vlc_init_tables_from_lengths(&state, 9, mpc7_quant_vlc_sizes[i],
                                                &raw_quant_table[1], 2,
                                                &raw_quant_table[0], 2, 1,
                                                mpc7_quant_vlc_off[i], 0);
            raw_quant_table += 2 * mpc7_quant_vlc_sizes[i];
        }
    }
    ff_mpa_synth_init_fixed();
}

static av_cold int mpc7_decode_init(AVCodecContext * avctx)
{
    static AVOnce init_static_once = AV_ONCE_INIT;
    MPCContext *c = avctx->priv_data;
    GetBitContext gb;
    LOCAL_ALIGNED_16(uint8_t, buf, [16]);

    /* Musepack SV7 is always stereo */
    if (avctx->ch_layout.nb_channels != 2) {
        avpriv_request_sample(avctx, "%d channels", avctx->ch_layout.nb_channels);
        return AVERROR_PATCHWELCOME;
    }

    if(avctx->extradata_size < 16){
        av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);
        return AVERROR_INVALIDDATA;
    }
    memset(c->oldDSCF, 0, sizeof(c->oldDSCF));
    av_lfg_init(&c->rnd, 0xDEADBEEF);
    ff_bswapdsp_init(&c->bdsp);
    ff_mpadsp_init(&c->mpadsp);
    c->bdsp.bswap_buf((uint32_t *) buf, (const uint32_t *) avctx->extradata, 4);
    init_get_bits(&gb, buf, 128);

    c->IS = get_bits1(&gb);
    c->MSS = get_bits1(&gb);
    c->maxbands = get_bits(&gb, 6);
    if(c->maxbands >= BANDS){
        av_log(avctx, AV_LOG_ERROR, "Too many bands: %i\n", c->maxbands);
        return AVERROR_INVALIDDATA;
    }
    skip_bits_long(&gb, 88);
    c->gapless = get_bits1(&gb);
    c->lastframelen = get_bits(&gb, 11);
    av_log(avctx, AV_LOG_DEBUG, "IS: %d, MSS: %d, TG: %d, LFL: %d, bands: %d\n",
            c->IS, c->MSS, c->gapless, c->lastframelen, c->maxbands);
    c->frames_to_skip = 0;

    avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
    av_channel_layout_uninit(&avctx->ch_layout);
    avctx->ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;

    ff_thread_once(&init_static_once, mpc7_init_static);

    return 0;
}

/**
 * Fill samples for given subband
 */
static inline void idx_to_quant(MPCContext *c, GetBitContext *gb, int idx, int *dst)
{
    int i, i1, t;
    switch(idx){
    case -1:
        for(i = 0; i < SAMPLES_PER_BAND; i++){
            *dst++ = (av_lfg_get(&c->rnd) & 0x3FC) - 510;
        }
        break;
    case 1:
        i1 = get_bits1(gb);
        for(i = 0; i < SAMPLES_PER_BAND/3; i++){
            t = get_vlc2(gb, quant_vlc[0][i1], 9, 2);
            *dst++ = mpc7_idx30[t];
            *dst++ = mpc7_idx31[t];
            *dst++ = mpc7_idx32[t];
        }
        break;
    case 2:
        i1 = get_bits1(gb);
        for(i = 0; i < SAMPLES_PER_BAND/2; i++){
            t = get_vlc2(gb, quant_vlc[1][i1], 9, 2);
            *dst++ = mpc7_idx50[t];
            *dst++ = mpc7_idx51[t];
        }
        break;
    case  3: case  4: case  5: case  6: case  7:
        i1 = get_bits1(gb);
        for(i = 0; i < SAMPLES_PER_BAND; i++)
            *dst++ = get_vlc2(gb, quant_vlc[idx-1][i1], 9, 2);
        break;
    case  8: case  9: case 10: case 11: case 12:
    case 13: case 14: case 15: case 16: case 17:
        t = (1 << (idx - 2)) - 1;
        for(i = 0; i < SAMPLES_PER_BAND; i++)
            *dst++ = get_bits(gb, idx - 1) - t;
        break;
    default: // case 0 and -2..-17
        return;
    }
}

static int get_scale_idx(GetBitContext *gb, int ref)
{
    int t = get_vlc2(gb, dscf_vlc, MPC7_DSCF_BITS, 1);
    if (t == 8)
        return get_bits(gb, 6);
    return ref + t;
}

static int mpc7_decode_frame(AVCodecContext *avctx, AVFrame *frame,
                             int *got_frame_ptr, AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size;
    MPCContext *c = avctx->priv_data;
    GetBitContext gb;
    int i, ch;
    int mb = -1;
    Band *bands = c->bands;
    int off, ret, last_frame, skip;
    int bits_used, bits_avail;

    memset(bands, 0, sizeof(*bands) * (c->maxbands + 1));

    buf_size = avpkt->size & ~3;
    if (buf_size <= 0) {
        av_log(avctx, AV_LOG_ERROR, "packet size is too small (%i bytes)\n",
               avpkt->size);
        return AVERROR_INVALIDDATA;
    }
    if (buf_size != avpkt->size) {
        av_log(avctx, AV_LOG_WARNING, "packet size is not a multiple of 4. "
               "extra bytes at the end will be skipped.\n");
    }

    skip       = buf[0];
    last_frame = buf[1];
    buf       += 4;
    buf_size  -= 4;

    /* get output buffer */
    frame->nb_samples = MPC_FRAME_SIZE;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;

    av_fast_padded_malloc(&c->bits, &c->buf_size, buf_size);
    if (!c->bits)
        return AVERROR(ENOMEM);
    c->bdsp.bswap_buf((uint32_t *) c->bits, (const uint32_t *) buf,
                      buf_size >> 2);
    if ((ret = init_get_bits8(&gb, c->bits, buf_size)) < 0)
        return ret;
    skip_bits_long(&gb, skip);

    /* read subband indexes */
    for(i = 0; i <= c->maxbands; i++){
        for(ch = 0; ch < 2; ch++){
            int t = i ? get_vlc2(&gb, hdr_vlc, MPC7_HDR_BITS, 1) : 4;
            if(t == 4) bands[i].res[ch] = get_bits(&gb, 4);
            else bands[i].res[ch] = bands[i-1].res[ch] + t;
            if (bands[i].res[ch] < -1 || bands[i].res[ch] > 17) {
                av_log(avctx, AV_LOG_ERROR, "subband index invalid\n");
                return AVERROR_INVALIDDATA;
            }
        }

        if(bands[i].res[0] || bands[i].res[1]){
            mb = i;
            if(c->MSS) bands[i].msf = get_bits1(&gb);
        }
    }
    /* get scale indexes coding method */
    for(i = 0; i <= mb; i++)
        for(ch = 0; ch < 2; ch++)
            if (bands[i].res[ch])
                bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc, MPC7_SCFI_BITS, 1);
    /* get scale indexes */
    for(i = 0; i <= mb; i++){
        for(ch = 0; ch < 2; ch++){
            if(bands[i].res[ch]){
                bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i];
                bands[i].scf_idx[ch][0] = get_scale_idx(&gb, bands[i].scf_idx[ch][2]);
                switch(bands[i].scfi[ch]){
                case 0:
                    bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]);
                    bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]);
                    break;
                case 1:
                    bands[i].scf_idx[ch][1] = get_scale_idx(&gb, bands[i].scf_idx[ch][0]);
                    bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1];
                    break;
                case 2:
                    bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0];
                    bands[i].scf_idx[ch][2] = get_scale_idx(&gb, bands[i].scf_idx[ch][1]);
                    break;
                case 3:
                    bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0];
                    break;
                }
                c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2];
            }
        }
    }
    /* get quantizers */
    memset(c->Q, 0, sizeof(c->Q));
    off = 0;
    for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND)
        for(ch = 0; ch < 2; ch++)
            idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);

    ff_mpc_dequantize_and_synth(c, mb, (int16_t **)frame->extended_data, 2);
    if(last_frame)
        frame->nb_samples = c->lastframelen;

    bits_used = get_bits_count(&gb);
    bits_avail = buf_size * 8;
    if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) {
        av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
        return AVERROR_INVALIDDATA;
    }
    if(c->frames_to_skip){
        c->frames_to_skip--;
        *got_frame_ptr = 0;
        return avpkt->size;
    }

    *got_frame_ptr = 1;

    return avpkt->size;
}

static void mpc7_decode_flush(AVCodecContext *avctx)
{
    MPCContext *c = avctx->priv_data;

    memset(c->oldDSCF, 0, sizeof(c->oldDSCF));
    c->frames_to_skip = 32;
}

static av_cold int mpc7_decode_close(AVCodecContext *avctx)
{
    MPCContext *c = avctx->priv_data;
    av_freep(&c->bits);
    c->buf_size = 0;
    return 0;
}

const FFCodec ff_mpc7_decoder = {
    .p.name         = "mpc7",
    CODEC_LONG_NAME("Musepack SV7"),
    .p.type         = AVMEDIA_TYPE_AUDIO,
    .p.id           = AV_CODEC_ID_MUSEPACK7,
    .priv_data_size = sizeof(MPCContext),
    .init           = mpc7_decode_init,
    .close          = mpc7_decode_close,
    FF_CODEC_DECODE_CB(mpc7_decode_frame),
    .flush          = mpc7_decode_flush,
    .p.capabilities = AV_CODEC_CAP_DR1,
    .p.sample_fmts  = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
                                                      AV_SAMPLE_FMT_NONE },
};
