/*
 * Opus encoder using libopus
 * Copyright (c) 2012 Nathan Caldwell
 *
 * 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 <opus.h>
#include <opus_multistream.h>

#include "libavutil/opt.h"
#include "avcodec.h"
#include "bytestream.h"
#include "internal.h"
#include "libopus.h"
#include "vorbis.h"
#include "audio_frame_queue.h"

typedef struct LibopusEncOpts {
    int vbr;
    int application;
    int packet_loss;
    int complexity;
    float frame_duration;
    int packet_size;
    int max_bandwidth;
    int mapping_family;
} LibopusEncOpts;

typedef struct LibopusEncContext {
    AVClass *class;
    OpusMSEncoder *enc;
    int stream_count;
    uint8_t *samples;
    LibopusEncOpts opts;
    AudioFrameQueue afq;
    const uint8_t *encoder_channel_map;
} LibopusEncContext;

static const uint8_t opus_coupled_streams[8] = {
    0, 1, 1, 2, 2, 2, 2, 3
};

/* Opus internal to Vorbis channel order mapping written in the header */
static const uint8_t opus_vorbis_channel_map[8][8] = {
    { 0 },
    { 0, 1 },
    { 0, 2, 1 },
    { 0, 1, 2, 3 },
    { 0, 4, 1, 2, 3 },
    { 0, 4, 1, 2, 3, 5 },
    { 0, 4, 1, 2, 3, 5, 6 },
    { 0, 6, 1, 2, 3, 4, 5, 7 },
};

/* libavcodec to libopus channel order mapping, passed to libopus */
static const uint8_t libavcodec_libopus_channel_map[8][8] = {
    { 0 },
    { 0, 1 },
    { 0, 1, 2 },
    { 0, 1, 2, 3 },
    { 0, 1, 3, 4, 2 },
    { 0, 1, 4, 5, 2, 3 },
    { 0, 1, 5, 6, 2, 4, 3 },
    { 0, 1, 6, 7, 4, 5, 2, 3 },
};

static void libopus_write_header(AVCodecContext *avctx, int stream_count,
                                 int coupled_stream_count,
                                 int mapping_family,
                                 const uint8_t *channel_mapping)
{
    uint8_t *p   = avctx->extradata;
    int channels = avctx->channels;

    bytestream_put_buffer(&p, "OpusHead", 8);
    bytestream_put_byte(&p, 1); /* Version */
    bytestream_put_byte(&p, channels);
    bytestream_put_le16(&p, avctx->initial_padding); /* Lookahead samples at 48kHz */
    bytestream_put_le32(&p, avctx->sample_rate); /* Original sample rate */
    bytestream_put_le16(&p, 0); /* Gain of 0dB is recommended. */

    /* Channel mapping */
    bytestream_put_byte(&p, mapping_family);
    if (mapping_family != 0) {
        bytestream_put_byte(&p, stream_count);
        bytestream_put_byte(&p, coupled_stream_count);
        bytestream_put_buffer(&p, channel_mapping, channels);
    }
}

static int libopus_configure_encoder(AVCodecContext *avctx, OpusMSEncoder *enc,
                                     LibopusEncOpts *opts)
{
    int ret;

    if (avctx->global_quality) {
        av_log(avctx, AV_LOG_ERROR,
               "Quality-based encoding not supported, "
               "please specify a bitrate and VBR setting.\n");
        return AVERROR(EINVAL);
    }

    ret = opus_multistream_encoder_ctl(enc, OPUS_SET_BITRATE(avctx->bit_rate));
    if (ret != OPUS_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to set bitrate: %s\n", opus_strerror(ret));
        return ret;
    }

    ret = opus_multistream_encoder_ctl(enc,
                                       OPUS_SET_COMPLEXITY(opts->complexity));
    if (ret != OPUS_OK)
        av_log(avctx, AV_LOG_WARNING,
               "Unable to set complexity: %s\n", opus_strerror(ret));

    ret = opus_multistream_encoder_ctl(enc, OPUS_SET_VBR(!!opts->vbr));
    if (ret != OPUS_OK)
        av_log(avctx, AV_LOG_WARNING,
               "Unable to set VBR: %s\n", opus_strerror(ret));

    ret = opus_multistream_encoder_ctl(enc,
                                       OPUS_SET_VBR_CONSTRAINT(opts->vbr == 2));
    if (ret != OPUS_OK)
        av_log(avctx, AV_LOG_WARNING,
               "Unable to set constrained VBR: %s\n", opus_strerror(ret));

    ret = opus_multistream_encoder_ctl(enc,
                                       OPUS_SET_PACKET_LOSS_PERC(opts->packet_loss));
    if (ret != OPUS_OK)
        av_log(avctx, AV_LOG_WARNING,
               "Unable to set expected packet loss percentage: %s\n",
               opus_strerror(ret));

    if (avctx->cutoff) {
        ret = opus_multistream_encoder_ctl(enc,
                                           OPUS_SET_MAX_BANDWIDTH(opts->max_bandwidth));
        if (ret != OPUS_OK)
            av_log(avctx, AV_LOG_WARNING,
                   "Unable to set maximum bandwidth: %s\n", opus_strerror(ret));
    }

    return OPUS_OK;
}

static int libopus_check_max_channels(AVCodecContext *avctx,
                                      int max_channels) {
    if (avctx->channels > max_channels) {
        av_log(avctx, AV_LOG_ERROR, "Opus mapping family undefined for %d channels.\n",
               avctx->channels);
        return AVERROR(EINVAL);
    }

    return 0;
}

static int libopus_check_vorbis_layout(AVCodecContext *avctx, int mapping_family) {
    av_assert2(avctx->channels < FF_ARRAY_ELEMS(ff_vorbis_channel_layouts));

    if (!avctx->channel_layout) {
        av_log(avctx, AV_LOG_WARNING,
               "No channel layout specified. Opus encoder will use Vorbis "
               "channel layout for %d channels.\n", avctx->channels);
    } else if (avctx->channel_layout != ff_vorbis_channel_layouts[avctx->channels - 1]) {
        char name[32];
        av_get_channel_layout_string(name, sizeof(name), avctx->channels,
                                     avctx->channel_layout);
        av_log(avctx, AV_LOG_ERROR,
               "Invalid channel layout %s for specified mapping family %d.\n",
               name, mapping_family);

        return AVERROR(EINVAL);
    }

    return 0;
}

static int libopus_validate_layout_and_get_channel_map(
        AVCodecContext *avctx,
        int mapping_family,
        const uint8_t ** channel_map_result)
{
    const uint8_t * channel_map = NULL;
    int ret;

    switch (mapping_family) {
    case -1:
        ret = libopus_check_max_channels(avctx, 8);
        if (ret == 0) {
            ret = libopus_check_vorbis_layout(avctx, mapping_family);
            /* Channels do not need to be reordered. */
        }

        break;
    case 0:
        ret = libopus_check_max_channels(avctx, 2);
        if (ret == 0) {
            ret = libopus_check_vorbis_layout(avctx, mapping_family);
        }
        break;
    case 1:
        /* Opus expects channels to be in Vorbis order. */
        ret = libopus_check_max_channels(avctx, 8);
        if (ret == 0) {
            ret = libopus_check_vorbis_layout(avctx, mapping_family);
            channel_map = ff_vorbis_channel_layout_offsets[avctx->channels - 1];
        }
        break;
    case 255:
        ret = libopus_check_max_channels(avctx, 254);
        break;
    default:
        av_log(avctx, AV_LOG_WARNING,
               "Unknown channel mapping family %d. Output channel layout may be invalid.\n",
               mapping_family);
        ret = 0;
    }

    *channel_map_result = channel_map;
    return ret;
}

static av_cold int libopus_encode_init(AVCodecContext *avctx)
{
    LibopusEncContext *opus = avctx->priv_data;
    OpusMSEncoder *enc;
    uint8_t libopus_channel_mapping[255];
    int ret = OPUS_OK;
    int av_ret;
    int coupled_stream_count, header_size, frame_size;
    int mapping_family;

    frame_size = opus->opts.frame_duration * 48000 / 1000;
    switch (frame_size) {
    case 120:
    case 240:
        if (opus->opts.application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
            av_log(avctx, AV_LOG_WARNING,
                   "LPC mode cannot be used with a frame duration of less "
                   "than 10ms. Enabling restricted low-delay mode.\n"
                   "Use a longer frame duration if this is not what you want.\n");
        /* Frame sizes less than 10 ms can only use MDCT mode, so switching to
         * RESTRICTED_LOWDELAY avoids an unnecessary extra 2.5ms lookahead. */
        opus->opts.application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
    case 480:
    case 960:
    case 1920:
    case 2880:
        opus->opts.packet_size =
        avctx->frame_size      = frame_size * avctx->sample_rate / 48000;
        break;
    default:
        av_log(avctx, AV_LOG_ERROR, "Invalid frame duration: %g.\n"
               "Frame duration must be exactly one of: 2.5, 5, 10, 20, 40 or 60.\n",
               opus->opts.frame_duration);
        return AVERROR(EINVAL);
    }

    if (avctx->compression_level < 0 || avctx->compression_level > 10) {
        av_log(avctx, AV_LOG_WARNING,
               "Compression level must be in the range 0 to 10. "
               "Defaulting to 10.\n");
        opus->opts.complexity = 10;
    } else {
        opus->opts.complexity = avctx->compression_level;
    }

    if (avctx->cutoff) {
        switch (avctx->cutoff) {
        case  4000:
            opus->opts.max_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
            break;
        case  6000:
            opus->opts.max_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
            break;
        case  8000:
            opus->opts.max_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
            break;
        case 12000:
            opus->opts.max_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
            break;
        case 20000:
            opus->opts.max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
            break;
        default:
            av_log(avctx, AV_LOG_WARNING,
                   "Invalid frequency cutoff: %d. Using default maximum bandwidth.\n"
                   "Cutoff frequency must be exactly one of: 4000, 6000, 8000, 12000 or 20000.\n",
                   avctx->cutoff);
            avctx->cutoff = 0;
        }
    }

    /* Channels may need to be reordered to match opus mapping. */
    av_ret = libopus_validate_layout_and_get_channel_map(avctx, opus->opts.mapping_family,
                                                         &opus->encoder_channel_map);
    if (av_ret) {
        return av_ret;
    }

    if (opus->opts.mapping_family == -1) {
        /* By default, use mapping family 1 for the header but use the older
         * libopus multistream API to avoid surround masking. */

        /* Set the mapping family so that the value is correct in the header */
        mapping_family = avctx->channels > 2 ? 1 : 0;
        coupled_stream_count = opus_coupled_streams[avctx->channels - 1];
        opus->stream_count   = avctx->channels - coupled_stream_count;
        memcpy(libopus_channel_mapping,
               opus_vorbis_channel_map[avctx->channels - 1],
               avctx->channels * sizeof(*libopus_channel_mapping));

        enc = opus_multistream_encoder_create(
            avctx->sample_rate, avctx->channels, opus->stream_count,
            coupled_stream_count,
            libavcodec_libopus_channel_map[avctx->channels - 1],
            opus->opts.application, &ret);
    } else {
        /* Use the newer multistream API. The encoder will set the channel
         * mapping and coupled stream counts to its internal defaults and will
         * use surround masking analysis to save bits. */
        mapping_family = opus->opts.mapping_family;
        enc = opus_multistream_surround_encoder_create(
            avctx->sample_rate, avctx->channels, mapping_family,
            &opus->stream_count, &coupled_stream_count, libopus_channel_mapping,
            opus->opts.application, &ret);
    }

    if (ret != OPUS_OK) {
        av_log(avctx, AV_LOG_ERROR,
               "Failed to create encoder: %s\n", opus_strerror(ret));
        return ff_opus_error_to_averror(ret);
    }

    if (!avctx->bit_rate) {
        /* Sane default copied from opusenc */
        avctx->bit_rate = 64000 * opus->stream_count +
                          32000 * coupled_stream_count;
        av_log(avctx, AV_LOG_WARNING,
               "No bit rate set. Defaulting to %"PRId64" bps.\n", (int64_t)avctx->bit_rate);
    }

    if (avctx->bit_rate < 500 || avctx->bit_rate > 256000 * avctx->channels) {
        av_log(avctx, AV_LOG_ERROR, "The bit rate %"PRId64" bps is unsupported. "
               "Please choose a value between 500 and %d.\n", (int64_t)avctx->bit_rate,
               256000 * avctx->channels);
        ret = AVERROR(EINVAL);
        goto fail;
    }

    ret = libopus_configure_encoder(avctx, enc, &opus->opts);
    if (ret != OPUS_OK) {
        ret = ff_opus_error_to_averror(ret);
        goto fail;
    }

    /* Header includes channel mapping table if and only if mapping family is 0 */
    header_size = 19 + (mapping_family == 0 ? 0 : 2 + avctx->channels);
    avctx->extradata = av_malloc(header_size + AV_INPUT_BUFFER_PADDING_SIZE);
    if (!avctx->extradata) {
        av_log(avctx, AV_LOG_ERROR, "Failed to allocate extradata.\n");
        ret = AVERROR(ENOMEM);
        goto fail;
    }
    avctx->extradata_size = header_size;

    opus->samples = av_mallocz_array(frame_size, avctx->channels *
                               av_get_bytes_per_sample(avctx->sample_fmt));
    if (!opus->samples) {
        av_log(avctx, AV_LOG_ERROR, "Failed to allocate samples buffer.\n");
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    ret = opus_multistream_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&avctx->initial_padding));
    if (ret != OPUS_OK)
        av_log(avctx, AV_LOG_WARNING,
               "Unable to get number of lookahead samples: %s\n",
               opus_strerror(ret));

    libopus_write_header(avctx, opus->stream_count, coupled_stream_count,
                         mapping_family, libopus_channel_mapping);

    ff_af_queue_init(avctx, &opus->afq);

    opus->enc = enc;

    return 0;

fail:
    opus_multistream_encoder_destroy(enc);
    av_freep(&avctx->extradata);
    return ret;
}

static void libopus_copy_samples_with_channel_map(
    uint8_t *dst, const uint8_t *src, const uint8_t *channel_map,
    int nb_channels, int nb_samples, int bytes_per_sample) {
    int sample, channel;
    for (sample = 0; sample < nb_samples; ++sample) {
        for (channel = 0; channel < nb_channels; ++channel) {
            const size_t src_pos = bytes_per_sample * (nb_channels * sample + channel);
            const size_t dst_pos = bytes_per_sample * (nb_channels * sample + channel_map[channel]);

            memcpy(&dst[dst_pos], &src[src_pos], bytes_per_sample);
        }
    }
}

static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt,
                          const AVFrame *frame, int *got_packet_ptr)
{
    LibopusEncContext *opus = avctx->priv_data;
    const int bytes_per_sample = av_get_bytes_per_sample(avctx->sample_fmt);
    const int sample_size      = avctx->channels * bytes_per_sample;
    uint8_t *audio;
    int ret;
    int discard_padding;

    if (frame) {
        ret = ff_af_queue_add(&opus->afq, frame);
        if (ret < 0)
            return ret;
        if (opus->encoder_channel_map != NULL) {
            audio = opus->samples;
            libopus_copy_samples_with_channel_map(
                audio, frame->data[0], opus->encoder_channel_map,
                avctx->channels, frame->nb_samples, bytes_per_sample);
        } else if (frame->nb_samples < opus->opts.packet_size) {
            audio = opus->samples;
            memcpy(audio, frame->data[0], frame->nb_samples * sample_size);
        } else
            audio = frame->data[0];
    } else {
        if (!opus->afq.remaining_samples || (!opus->afq.frame_alloc && !opus->afq.frame_count))
            return 0;
        audio = opus->samples;
        memset(audio, 0, opus->opts.packet_size * sample_size);
    }

    /* Maximum packet size taken from opusenc in opus-tools. 60ms packets
     * consist of 3 frames in one packet. The maximum frame size is 1275
     * bytes along with the largest possible packet header of 7 bytes. */
    if ((ret = ff_alloc_packet2(avctx, avpkt, (1275 * 3 + 7) * opus->stream_count, 0)) < 0)
        return ret;

    if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT)
        ret = opus_multistream_encode_float(opus->enc, (float *)audio,
                                            opus->opts.packet_size,
                                            avpkt->data, avpkt->size);
    else
        ret = opus_multistream_encode(opus->enc, (opus_int16 *)audio,
                                      opus->opts.packet_size,
                                      avpkt->data, avpkt->size);

    if (ret < 0) {
        av_log(avctx, AV_LOG_ERROR,
               "Error encoding frame: %s\n", opus_strerror(ret));
        return ff_opus_error_to_averror(ret);
    }

    av_shrink_packet(avpkt, ret);

    ff_af_queue_remove(&opus->afq, opus->opts.packet_size,
                       &avpkt->pts, &avpkt->duration);

    discard_padding = opus->opts.packet_size - avpkt->duration;
    // Check if subtraction resulted in an overflow
    if ((discard_padding < opus->opts.packet_size) != (avpkt->duration > 0)) {
        av_packet_unref(avpkt);
        av_free(avpkt);
        return AVERROR(EINVAL);
    }
    if (discard_padding > 0) {
        uint8_t* side_data = av_packet_new_side_data(avpkt,
                                                     AV_PKT_DATA_SKIP_SAMPLES,
                                                     10);
        if(!side_data) {
            av_packet_unref(avpkt);
            av_free(avpkt);
            return AVERROR(ENOMEM);
        }
        AV_WL32(side_data + 4, discard_padding);
    }

    *got_packet_ptr = 1;

    return 0;
}

static av_cold int libopus_encode_close(AVCodecContext *avctx)
{
    LibopusEncContext *opus = avctx->priv_data;

    opus_multistream_encoder_destroy(opus->enc);

    ff_af_queue_close(&opus->afq);

    av_freep(&opus->samples);
    av_freep(&avctx->extradata);

    return 0;
}

#define OFFSET(x) offsetof(LibopusEncContext, opts.x)
#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
static const AVOption libopus_options[] = {
    { "application",    "Intended application type",           OFFSET(application),    AV_OPT_TYPE_INT,   { .i64 = OPUS_APPLICATION_AUDIO }, OPUS_APPLICATION_VOIP, OPUS_APPLICATION_RESTRICTED_LOWDELAY, FLAGS, "application" },
        { "voip",           "Favor improved speech intelligibility",   0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP },                0, 0, FLAGS, "application" },
        { "audio",          "Favor faithfulness to the input",         0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO },               0, 0, FLAGS, "application" },
        { "lowdelay",       "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" },
    { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 60.0, FLAGS },
    { "packet_loss",    "Expected packet loss percentage",     OFFSET(packet_loss),    AV_OPT_TYPE_INT,   { .i64 = 0 },    0,   100,  FLAGS },
    { "vbr",            "Variable bit rate mode",              OFFSET(vbr),            AV_OPT_TYPE_INT,   { .i64 = 1 },    0,   2,    FLAGS, "vbr" },
        { "off",            "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" },
        { "on",             "Use variable bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, 0, 0, FLAGS, "vbr" },
        { "constrained",    "Use constrained VBR",   0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, FLAGS, "vbr" },
    { "mapping_family", "Channel Mapping Family",              OFFSET(mapping_family), AV_OPT_TYPE_INT,   { .i64 = -1 },   -1,  255,  FLAGS, "mapping_family" },
    { NULL },
};

static const AVClass libopus_class = {
    .class_name = "libopus",
    .item_name  = av_default_item_name,
    .option     = libopus_options,
    .version    = LIBAVUTIL_VERSION_INT,
};

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

static const int libopus_sample_rates[] = {
    48000, 24000, 16000, 12000, 8000, 0,
};

AVCodec ff_libopus_encoder = {
    .name            = "libopus",
    .long_name       = NULL_IF_CONFIG_SMALL("libopus Opus"),
    .type            = AVMEDIA_TYPE_AUDIO,
    .id              = AV_CODEC_ID_OPUS,
    .priv_data_size  = sizeof(LibopusEncContext),
    .init            = libopus_encode_init,
    .encode2         = libopus_encode,
    .close           = libopus_encode_close,
    .capabilities    = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SMALL_LAST_FRAME,
    .sample_fmts     = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
                                                      AV_SAMPLE_FMT_FLT,
                                                      AV_SAMPLE_FMT_NONE },
    .supported_samplerates = libopus_sample_rates,
    .priv_class      = &libopus_class,
    .defaults        = libopus_defaults,
};
