/*
 * SMPTE 302M decoder
 * Copyright (c) 2008 Laurent Aimar <fenrir@videolan.org>
 * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier@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 "libavutil/intreadwrite.h"
#include "avcodec.h"
#include "internal.h"

#define AES3_HEADER_LEN 4

typedef struct S302MDecodeContext {
    AVFrame frame;
} S302MDecodeContext;

static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
                                    int buf_size)
{
    uint32_t h;
    int frame_size, channels, bits;

    if (buf_size <= AES3_HEADER_LEN) {
        av_log(avctx, AV_LOG_ERROR, "frame is too short\n");
        return AVERROR_INVALIDDATA;
    }

    /*
     * AES3 header :
     * size:            16
     * number channels   2
     * channel_id        8
     * bits per samples  2
     * alignments        4
     */

    h = AV_RB32(buf);
    frame_size =  (h >> 16) & 0xffff;
    channels   = ((h >> 14) & 0x0003) * 2 +  2;
    bits       = ((h >>  4) & 0x0003) * 4 + 16;

    if (AES3_HEADER_LEN + frame_size != buf_size || bits > 24) {
        av_log(avctx, AV_LOG_ERROR, "frame has invalid header\n");
        return AVERROR_INVALIDDATA;
    }

    /* Set output properties */
    avctx->bits_per_coded_sample = bits;
    if (bits > 16)
        avctx->sample_fmt = AV_SAMPLE_FMT_S32;
    else
        avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    avctx->channels    = channels;
    switch(channels) {
        case 2:
            avctx->channel_layout = AV_CH_LAYOUT_STEREO;
            break;
        case 4:
            avctx->channel_layout = AV_CH_LAYOUT_QUAD;
            break;
        case 8:
            avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX;
    }
    avctx->sample_rate = 48000;
    avctx->bit_rate    = 48000 * avctx->channels * (avctx->bits_per_coded_sample + 4) +
                         32 * (48000 / (buf_size * 8 /
                                        (avctx->channels *
                                         (avctx->bits_per_coded_sample + 4))));

    return frame_size;
}

static int s302m_decode_frame(AVCodecContext *avctx, void *data,
                              int *got_frame_ptr, AVPacket *avpkt)
{
    S302MDecodeContext *s = avctx->priv_data;
    const uint8_t *buf = avpkt->data;
    int buf_size       = avpkt->size;
    int block_size, ret;

    int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
    if (frame_size < 0)
        return frame_size;

    buf_size -= AES3_HEADER_LEN;
    buf      += AES3_HEADER_LEN;

    /* get output buffer */
    block_size = (avctx->bits_per_coded_sample + 4) / 4;
    s->frame.nb_samples = 2 * (buf_size / block_size) / avctx->channels;
    if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }

    buf_size = (s->frame.nb_samples * avctx->channels / 2) * block_size;

    if (avctx->bits_per_coded_sample == 24) {
        uint32_t *o = (uint32_t *)s->frame.data[0];
        for (; buf_size > 6; buf_size -= 7) {
            *o++ = (av_reverse[buf[2]]        << 24) |
                   (av_reverse[buf[1]]        << 16) |
                   (av_reverse[buf[0]]        <<  8);
            *o++ = (av_reverse[buf[6] & 0xf0] << 28) |
                   (av_reverse[buf[5]]        << 20) |
                   (av_reverse[buf[4]]        << 12) |
                   (av_reverse[buf[3] & 0x0f] <<  4);
            buf += 7;
        }
    } else if (avctx->bits_per_coded_sample == 20) {
        uint32_t *o = (uint32_t *)s->frame.data[0];
        for (; buf_size > 5; buf_size -= 6) {
            *o++ = (av_reverse[buf[2] & 0xf0] << 28) |
                   (av_reverse[buf[1]]        << 20) |
                   (av_reverse[buf[0]]        << 12);
            *o++ = (av_reverse[buf[5] & 0xf0] << 28) |
                   (av_reverse[buf[4]]        << 20) |
                   (av_reverse[buf[3]]        << 12);
            buf += 6;
        }
    } else {
        uint16_t *o = (uint16_t *)s->frame.data[0];
        for (; buf_size > 4; buf_size -= 5) {
            *o++ = (av_reverse[buf[1]]        <<  8) |
                    av_reverse[buf[0]];
            *o++ = (av_reverse[buf[4] & 0xf0] << 12) |
                   (av_reverse[buf[3]]        <<  4) |
                   (av_reverse[buf[2]]        >>  4);
            buf += 5;
        }
    }

    *got_frame_ptr   = 1;
    *(AVFrame *)data = s->frame;

    return avpkt->size;
}

static int s302m_decode_init(AVCodecContext *avctx)
{
    S302MDecodeContext *s = avctx->priv_data;

    avcodec_get_frame_defaults(&s->frame);
    avctx->coded_frame = &s->frame;

    return 0;
}


AVCodec ff_s302m_decoder = {
    .name           = "s302m",
    .type           = AVMEDIA_TYPE_AUDIO,
    .id             = CODEC_ID_S302M,
    .priv_data_size = sizeof(S302MDecodeContext),
    .init           = s302m_decode_init,
    .decode         = s302m_decode_frame,
    .capabilities   = CODEC_CAP_DR1,
    .long_name      = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
};
