/*
 * Sony OpenMG (OMA) demuxer
 *
 * Copyright (c) 2008 Maxim Poliakovski
 *               2008 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
 */

/**
 * @file
 * This is a demuxer for Sony OpenMG Music files
 *
 * Known file extensions: ".oma", "aa3"
 * The format of such files consists of three parts:
 * - "ea3" header carrying overall info and metadata. Except for starting with
 *   "ea" instead of "ID", it's an ID3v2 header.
 * - "EA3" header is a Sony-specific header containing information about
 *   the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA),
 *   codec specific info (packet size, sample rate, channels and so on)
 *   and DRM related info (file encryption, content id).
 * - Sound data organized in packets follow the EA3 header
 *   (can be encrypted using the Sony DRM!).
 *
 * LIMITATIONS: This version supports only plain (unencrypted) OMA files.
 * If any DRM-protected (encrypted) file is encountered you will get the
 * corresponding error message. Try to remove the encryption using any
 * Sony software (for example SonicStage).
 * CODEC SUPPORT: Only ATRAC3 codec is currently supported!
 */

#include "avformat.h"
#include "libavutil/intreadwrite.h"
#include "pcm.h"
#include "riff.h"
#include "id3v2.h"

#define EA3_HEADER_SIZE 96

enum {
    OMA_CODECID_ATRAC3  = 0,
    OMA_CODECID_ATRAC3P = 1,
    OMA_CODECID_MP3     = 3,
    OMA_CODECID_LPCM    = 4,
    OMA_CODECID_WMA     = 5,
};

static const AVCodecTag codec_oma_tags[] = {
    { CODEC_ID_ATRAC3,  OMA_CODECID_ATRAC3 },
    { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P },
    { CODEC_ID_MP3,     OMA_CODECID_MP3 },
};

#define ID3v2_EA3_MAGIC "ea3"

static int oma_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    static const uint16_t srate_tab[6] = {320,441,480,882,960,0};
    int     ret, framesize, jsflag, samplerate;
    uint32_t codec_params;
    int16_t eid;
    uint8_t buf[EA3_HEADER_SIZE];
    uint8_t *edata;
    AVStream *st;

    ff_id3v2_read(s, ID3v2_EA3_MAGIC);
    ret = avio_read(s->pb, buf, EA3_HEADER_SIZE);
    if (ret < EA3_HEADER_SIZE)
        return -1;

    if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) {
        av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n");
        return -1;
    }

    eid = AV_RB16(&buf[6]);
    if (eid != -1 && eid != -128) {
        av_log(s, AV_LOG_ERROR, "Encrypted file! Eid: %d\n", eid);
        return -1;
    }

    codec_params = AV_RB24(&buf[33]);

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);

    st->start_time = 0;
    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_tag   = buf[32];
    st->codec->codec_id    = ff_codec_get_id(codec_oma_tags, st->codec->codec_tag);

    switch (buf[32]) {
        case OMA_CODECID_ATRAC3:
            samplerate = srate_tab[(codec_params >> 13) & 7]*100;
            if (samplerate != 44100)
                av_log_ask_for_sample(s, "Unsupported sample rate: %d\n",
                                      samplerate);

            framesize = (codec_params & 0x3FF) * 8;
            jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */
            st->codec->channels    = 2;
            st->codec->sample_rate = samplerate;
            st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;

            /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */
            st->codec->extradata_size = 14;
            edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!edata)
                return AVERROR(ENOMEM);

            st->codec->extradata = edata;
            AV_WL16(&edata[0],  1);             // always 1
            AV_WL32(&edata[2],  samplerate);    // samples rate
            AV_WL16(&edata[6],  jsflag);        // coding mode
            AV_WL16(&edata[8],  jsflag);        // coding mode
            AV_WL16(&edata[10], 1);             // always 1
            // AV_WL16(&edata[12], 0);          // always 0

            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
            break;
        case OMA_CODECID_ATRAC3P:
            st->codec->channels = (codec_params >> 10) & 7;
            framesize = ((codec_params & 0x3FF) * 8) + 8;
            st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100;
            st->codec->bit_rate    = st->codec->sample_rate * framesize * 8 / 1024;
            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
            av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n");
            break;
        case OMA_CODECID_MP3:
            st->need_parsing = AVSTREAM_PARSE_FULL;
            framesize = 1024;
            break;
        default:
            av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]);
            return -1;
            break;
    }

    st->codec->block_align = framesize;

    return 0;
}


static int oma_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;
}

static int oma_read_probe(AVProbeData *p)
{
    const uint8_t *buf;
    unsigned tag_len = 0;

    buf = p->buf;
    /* version must be 3 and flags byte zero */
    if (ff_id3v2_match(buf, ID3v2_EA3_MAGIC) && buf[3] == 3 && !buf[4])
        tag_len = ff_id3v2_tag_len(buf);

    // This check cannot overflow as tag_len has at most 28 bits
    if (p->buf_size < tag_len + 5)
        return 0;

    buf += tag_len;

    if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE)
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}


AVInputFormat ff_oma_demuxer = {
    "oma",
    NULL_IF_CONFIG_SMALL("Sony OpenMG audio"),
    0,
    oma_read_probe,
    oma_read_header,
    oma_read_packet,
    0,
    pcm_read_seek,
    .flags= AVFMT_GENERIC_INDEX,
    .extensions = "oma,aa3",
    .codec_tag= (const AVCodecTag* const []){codec_oma_tags, 0},
};

