/*
 * AAC encoder wrapper
 * Copyright (c) 2010 Martin Storsjo
 *
 * 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 <vo-aacenc/voAAC.h>
#include <vo-aacenc/cmnMemory.h>

#include "avcodec.h"
#include "audio_frame_queue.h"
#include "internal.h"
#include "mpeg4audio.h"

#define FRAME_SIZE 1024
#define ENC_DELAY  1600

typedef struct AACContext {
    VO_AUDIO_CODECAPI codec_api;
    VO_HANDLE handle;
    VO_MEM_OPERATOR mem_operator;
    VO_CODEC_INIT_USERDATA user_data;
    VO_PBYTE end_buffer;
    AudioFrameQueue afq;
    int last_frame;
    int last_samples;
} AACContext;


static int aac_encode_close(AVCodecContext *avctx)
{
    AACContext *s = avctx->priv_data;

    s->codec_api.Uninit(s->handle);
    av_freep(&avctx->extradata);
    ff_af_queue_close(&s->afq);
    av_freep(&s->end_buffer);

    return 0;
}

static av_cold int aac_encode_init(AVCodecContext *avctx)
{
    AACContext *s = avctx->priv_data;
    AACENC_PARAM params = { 0 };
    int index, ret;

    avctx->frame_size = FRAME_SIZE;
    avctx->delay      = ENC_DELAY;
    s->last_frame     = 2;
    ff_af_queue_init(avctx, &s->afq);

    s->end_buffer = av_mallocz(avctx->frame_size * avctx->channels * 2);
    if (!s->end_buffer) {
        ret = AVERROR(ENOMEM);
        goto error;
    }

    voGetAACEncAPI(&s->codec_api);

    s->mem_operator.Alloc = cmnMemAlloc;
    s->mem_operator.Copy = cmnMemCopy;
    s->mem_operator.Free = cmnMemFree;
    s->mem_operator.Set = cmnMemSet;
    s->mem_operator.Check = cmnMemCheck;
    s->user_data.memflag = VO_IMF_USERMEMOPERATOR;
    s->user_data.memData = &s->mem_operator;
    s->codec_api.Init(&s->handle, VO_AUDIO_CodingAAC, &s->user_data);

    params.sampleRate = avctx->sample_rate;
    params.bitRate    = avctx->bit_rate;
    params.nChannels  = avctx->channels;
    params.adtsUsed   = !(avctx->flags & CODEC_FLAG_GLOBAL_HEADER);
    if (s->codec_api.SetParam(s->handle, VO_PID_AAC_ENCPARAM, &params)
        != VO_ERR_NONE) {
        av_log(avctx, AV_LOG_ERROR, "Unable to set encoding parameters\n");
        ret = AVERROR(EINVAL);
        goto error;
    }

    for (index = 0; index < 16; index++)
        if (avctx->sample_rate == avpriv_mpeg4audio_sample_rates[index])
            break;
    if (index == 16) {
        av_log(avctx, AV_LOG_ERROR, "Unsupported sample rate %d\n",
                                    avctx->sample_rate);
        ret = AVERROR(ENOSYS);
        goto error;
    }
    if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
        avctx->extradata_size = 2;
        avctx->extradata      = av_mallocz(avctx->extradata_size +
                                           FF_INPUT_BUFFER_PADDING_SIZE);
        if (!avctx->extradata) {
            ret = AVERROR(ENOMEM);
            goto error;
        }

        avctx->extradata[0] = 0x02 << 3 | index >> 1;
        avctx->extradata[1] = (index & 0x01) << 7 | avctx->channels << 3;
    }
    return 0;
error:
    aac_encode_close(avctx);
    return ret;
}

static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
                            const AVFrame *frame, int *got_packet_ptr)
{
    AACContext *s = avctx->priv_data;
    VO_CODECBUFFER input = { 0 }, output = { 0 };
    VO_AUDIO_OUTPUTINFO output_info = { { 0 } };
    VO_PBYTE samples;
    int ret;

    /* handle end-of-stream small frame and flushing */
    if (!frame) {
        if (s->last_frame <= 0)
            return 0;
        if (s->last_samples > 0 && s->last_samples < ENC_DELAY - FRAME_SIZE) {
            s->last_samples = 0;
            s->last_frame--;
        }
        s->last_frame--;
        memset(s->end_buffer, 0, 2 * avctx->channels * avctx->frame_size);
        samples = s->end_buffer;
    } else {
        if (frame->nb_samples < avctx->frame_size) {
            s->last_samples = frame->nb_samples;
            memcpy(s->end_buffer, frame->data[0], 2 * avctx->channels * frame->nb_samples);
            samples = s->end_buffer;
        } else {
            samples = (VO_PBYTE)frame->data[0];
        }
        /* add current frame to the queue */
        if ((ret = ff_af_queue_add(&s->afq, frame)) < 0)
            return ret;
    }

    if ((ret = ff_alloc_packet2(avctx, avpkt, FFMAX(8192, 768 * avctx->channels))) < 0)
        return ret;

    input.Buffer  = samples;
    input.Length  = 2 * avctx->channels * avctx->frame_size;
    output.Buffer = avpkt->data;
    output.Length = avpkt->size;

    s->codec_api.SetInputData(s->handle, &input);
    if (s->codec_api.GetOutputData(s->handle, &output, &output_info)
        != VO_ERR_NONE) {
        av_log(avctx, AV_LOG_ERROR, "Unable to encode frame\n");
        return AVERROR(EINVAL);
    }

    /* Get the next frame pts/duration */
    ff_af_queue_remove(&s->afq, avctx->frame_size, &avpkt->pts,
                       &avpkt->duration);

    avpkt->size = output.Length;
    *got_packet_ptr = 1;
    return 0;
}

/* duplicated from avpriv_mpeg4audio_sample_rates to avoid shared build
 * failures */
static const int mpeg4audio_sample_rates[16] = {
    96000, 88200, 64000, 48000, 44100, 32000,
    24000, 22050, 16000, 12000, 11025, 8000, 7350
};

AVCodec ff_libvo_aacenc_encoder = {
    .name           = "libvo_aacenc",
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = AV_CODEC_ID_AAC,
    .priv_data_size = sizeof(AACContext),
    .init           = aac_encode_init,
    .encode2        = aac_encode_frame,
    .close          = aac_encode_close,
    .supported_samplerates = mpeg4audio_sample_rates,
    .capabilities   = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
    .sample_fmts    = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                     AV_SAMPLE_FMT_NONE },
    .long_name      = NULL_IF_CONFIG_SMALL("Android VisualOn AAC (Advanced Audio Coding)"),
};
