/*
 * MD STUDIO audio demuxer
 *
 * Copyright (c) 2009 Benjamin Larsson
 *
 * 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/channel_layout.h"
#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "pcm.h"

#define AT1_SU_SIZE     212

static int aea_read_probe(AVProbeData *p)
{
    if (p->buf_size <= 2048+212)
        return 0;

    /* Magic is '00 08 00 00' in Little Endian*/
    if (AV_RL32(p->buf)==0x800) {
        int ch, i;
        ch = p->buf[264];

        if (ch != 1 && ch != 2)
            return 0;

        /* Check so that the redundant bsm bytes and info bytes are valid
         * the block size mode bytes have to be the same
         * the info bytes have to be the same
         */
        for (i = 2048; i + 211 < p->buf_size; i+= 212) {
            int bsm_s, bsm_e, inb_s, inb_e;
            bsm_s = p->buf[0];
            inb_s = p->buf[1];
            inb_e = p->buf[210];
            bsm_e = p->buf[211];

            if (bsm_s != bsm_e || inb_s != inb_e)
                return 0;
        }
        return AVPROBE_SCORE_MAX / 4 + 1;
    }
    return 0;
}

static int aea_read_header(AVFormatContext *s)
{
    AVStream *st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    /* Parse the amount of channels and skip to pos 2048(0x800) */
    avio_skip(s->pb, 264);
    st->codec->channels = avio_r8(s->pb);
    avio_skip(s->pb, 1783);


    st->codec->codec_type     = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id       = AV_CODEC_ID_ATRAC1;
    st->codec->sample_rate    = 44100;
    st->codec->bit_rate       = 292000;

    if (st->codec->channels != 1 && st->codec->channels != 2) {
        av_log(s,AV_LOG_ERROR,"Channels %d not supported!\n",st->codec->channels);
        return AVERROR_INVALIDDATA;
    }

    st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;

    st->codec->block_align = AT1_SU_SIZE * st->codec->channels;
    return 0;
}

static int aea_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align);

    pkt->stream_index = 0;
    if (ret <= 0)
        return AVERROR(EIO);

    return ret;
}

AVInputFormat ff_aea_demuxer = {
    .name           = "aea",
    .long_name      = NULL_IF_CONFIG_SMALL("MD STUDIO audio"),
    .read_probe     = aea_read_probe,
    .read_header    = aea_read_header,
    .read_packet    = aea_read_packet,
    .read_seek      = ff_pcm_read_seek,
    .flags          = AVFMT_GENERIC_INDEX,
    .extensions     = "aea",
};
