/*
 * 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/common.h"
#include "libavutil/intreadwrite.h"
#include "avcodec.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 6:
            avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
            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 = avctx->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             = AV_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"),
};
