/*
 * 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 (buf_size - AES3_HEADER_LEN > UINT16_MAX) {
        av_log(avctx, AV_LOG_ERROR, "number of samples in frame too big\n");
        return AVERROR(EINVAL);
    }

    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 },
 /* .channel_layouts       = (const uint64_t[]) { AV_CH_LAYOUT_STEREO,
                                                  AV_CH_LAYOUT_QUAD,
                                                  AV_CH_LAYOUT_5POINT1_BACK,
                                                  AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX,
                                                  0 }, */
};
