/*
 * SMPTE 302M encoder
 * Copyright (c) 2010 Google, Inc.
 * Copyright (c) 2013 Darryl Wallace <wallacdj@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 "avcodec.h"
#include "internal.h"
#include "mathops.h"
#include "put_bits.h"

#define AES3_HEADER_LEN 4

typedef struct S302MEncContext {
    uint8_t framing_index; /* Set for even channels on multiple of 192 samples */
} S302MEncContext;

static av_cold int s302m_encode_init(AVCodecContext *avctx)
{
    S302MEncContext *s = avctx->priv_data;

    if (avctx->channels & 1 || avctx->channels > 8) {
        av_log(avctx, AV_LOG_ERROR,
               "Encoding %d channel(s) is not allowed. Only 2, 4, 6 and 8 channels are supported.\n",
               avctx->channels);
        return AVERROR(EINVAL);
    }

    switch (avctx->sample_fmt) {
    case AV_SAMPLE_FMT_S16:
        avctx->bits_per_raw_sample = 16;
        break;
    case AV_SAMPLE_FMT_S32:
        if (avctx->bits_per_raw_sample > 20) {
            if (avctx->bits_per_raw_sample > 24)
                av_log(avctx, AV_LOG_WARNING, "encoding as 24 bits-per-sample\n");
            avctx->bits_per_raw_sample = 24;
        } else if (!avctx->bits_per_raw_sample) {
            avctx->bits_per_raw_sample = 24;
        } else if (avctx->bits_per_raw_sample <= 20) {
            avctx->bits_per_raw_sample = 20;
        }
    }

    avctx->frame_size = 0;
    avctx->bit_rate   = 48000 * avctx->channels *
                       (avctx->bits_per_raw_sample + 4);
    s->framing_index  = 0;

    return 0;
}

static int s302m_encode2_frame(AVCodecContext *avctx, AVPacket *avpkt,
                               const AVFrame *frame, int *got_packet_ptr)
{
    S302MEncContext *s = avctx->priv_data;
    const int buf_size = AES3_HEADER_LEN +
                        (frame->nb_samples *
                         avctx->channels *
                        (avctx->bits_per_raw_sample + 4)) / 8;
    int ret, c, channels;
    uint8_t *o;
    PutBitContext pb;

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

    o = avpkt->data;
    init_put_bits(&pb, o, buf_size);
    put_bits(&pb, 16, buf_size - AES3_HEADER_LEN);
    put_bits(&pb, 2, (avctx->channels - 2) >> 1);   // number of channels
    put_bits(&pb, 8, 0);                            // channel ID
    put_bits(&pb, 2, (avctx->bits_per_raw_sample - 16) / 4); // bits per samples (0 = 16bit, 1 = 20bit, 2 = 24bit)
    put_bits(&pb, 4, 0);                            // alignments
    flush_put_bits(&pb);
    o += AES3_HEADER_LEN;

    if (avctx->bits_per_raw_sample == 24) {
        const uint32_t *samples = (uint32_t *)frame->data[0];

        for (c = 0; c < frame->nb_samples; c++) {
            uint8_t vucf = s->framing_index == 0 ? 0x10: 0;

            for (channels = 0; channels < avctx->channels; channels += 2) {
                o[0] = ff_reverse[(samples[0] & 0x0000FF00) >> 8];
                o[1] = ff_reverse[(samples[0] & 0x00FF0000) >> 16];
                o[2] = ff_reverse[(samples[0] & 0xFF000000) >> 24];
                o[3] = ff_reverse[(samples[1] & 0x00000F00) >> 4] | vucf;
                o[4] = ff_reverse[(samples[1] & 0x000FF000) >> 12];
                o[5] = ff_reverse[(samples[1] & 0x0FF00000) >> 20];
                o[6] = ff_reverse[(samples[1] & 0xF0000000) >> 28];
                o += 7;
                samples += 2;
            }

            s->framing_index++;
            if (s->framing_index >= 192)
                s->framing_index = 0;
        }
    } else if (avctx->bits_per_raw_sample == 20) {
        const uint32_t *samples = (uint32_t *)frame->data[0];

        for (c = 0; c < frame->nb_samples; c++) {
            uint8_t vucf = s->framing_index == 0 ? 0x80: 0;

            for (channels = 0; channels < avctx->channels; channels += 2) {
                o[0] = ff_reverse[ (samples[0] & 0x000FF000) >> 12];
                o[1] = ff_reverse[ (samples[0] & 0x0FF00000) >> 20];
                o[2] = ff_reverse[((samples[0] & 0xF0000000) >> 28) | vucf];
                o[3] = ff_reverse[ (samples[1] & 0x000FF000) >> 12];
                o[4] = ff_reverse[ (samples[1] & 0x0FF00000) >> 20];
                o[5] = ff_reverse[ (samples[1] & 0xF0000000) >> 28];
                o += 6;
                samples += 2;
            }

            s->framing_index++;
            if (s->framing_index >= 192)
                s->framing_index = 0;
        }
    } else if (avctx->bits_per_raw_sample == 16) {
        const uint16_t *samples = (uint16_t *)frame->data[0];

        for (c = 0; c < frame->nb_samples; c++) {
            uint8_t vucf = s->framing_index == 0 ? 0x10 : 0;

            for (channels = 0; channels < avctx->channels; channels += 2) {
                o[0] = ff_reverse[ samples[0] & 0xFF];
                o[1] = ff_reverse[(samples[0] & 0xFF00) >>  8];
                o[2] = ff_reverse[(samples[1] & 0x0F)   <<  4] | vucf;
                o[3] = ff_reverse[(samples[1] & 0x0FF0) >>  4];
                o[4] = ff_reverse[(samples[1] & 0xF000) >> 12];
                o += 5;
                samples += 2;

            }

            s->framing_index++;
            if (s->framing_index >= 192)
                s->framing_index = 0;
        }
    }

    *got_packet_ptr = 1;

    return 0;
}

AVCodec ff_s302m_encoder = {
    .name                  = "s302m",
    .long_name             = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
    .type                  = AVMEDIA_TYPE_AUDIO,
    .id                    = AV_CODEC_ID_S302M,
    .priv_data_size        = sizeof(S302MEncContext),
    .init                  = s302m_encode_init,
    .encode2               = s302m_encode2_frame,
    .sample_fmts           = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32,
                                                            AV_SAMPLE_FMT_S16,
                                                            AV_SAMPLE_FMT_NONE },
    .capabilities          = AV_CODEC_CAP_VARIABLE_FRAME_SIZE | AV_CODEC_CAP_EXPERIMENTAL,
    .supported_samplerates = (const int[]) { 48000, 0 },
};
