/*
 * Core Audio Format demuxer
 * Copyright (c) 2007 Justin Ruggles
 * Copyright (c) 2009 Peter Ross
 *
 * 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
 * Core Audio Format demuxer
 */

#include <inttypes.h>

#include "avformat.h"
#include "internal.h"
#include "isom.h"
#include "mov_chan.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/intfloat.h"
#include "libavutil/dict.h"
#include "caf.h"

typedef struct CafContext {
    int bytes_per_packet;           ///< bytes in a packet, or 0 if variable
    int frames_per_packet;          ///< frames in a packet, or 0 if variable
    int64_t num_bytes;              ///< total number of bytes in stream

    int64_t packet_cnt;             ///< packet counter
    int64_t frame_cnt;              ///< frame counter

    int64_t data_start;             ///< data start position, in bytes
    int64_t data_size;              ///< raw data size, in bytes
} CafContext;

static int probe(const AVProbeData *p)
{
    if (AV_RB32(p->buf) == MKBETAG('c','a','f','f') && AV_RB16(&p->buf[4]) == 1)
        return AVPROBE_SCORE_MAX;
    return 0;
}

/** Read audio description chunk */
static int read_desc_chunk(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    CafContext *caf = s->priv_data;
    AVStream *st;
    int flags;

    /* new audio stream */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    /* parse format description */
    st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codecpar->sample_rate = av_int2double(avio_rb64(pb));
    st->codecpar->codec_tag   = avio_rl32(pb);
    flags = avio_rb32(pb);
    caf->bytes_per_packet  = avio_rb32(pb);
    st->codecpar->block_align = caf->bytes_per_packet;
    caf->frames_per_packet = avio_rb32(pb);
    st->codecpar->channels    = avio_rb32(pb);
    st->codecpar->bits_per_coded_sample = avio_rb32(pb);

    /* calculate bit rate for constant size packets */
    if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
        st->codecpar->bit_rate = (uint64_t)st->codecpar->sample_rate * (uint64_t)caf->bytes_per_packet * 8
                                 / (uint64_t)caf->frames_per_packet;
    } else {
        st->codecpar->bit_rate = 0;
    }

    /* determine codec */
    if (st->codecpar->codec_tag == MKTAG('l','p','c','m'))
        st->codecpar->codec_id = ff_mov_get_lpcm_codec_id(st->codecpar->bits_per_coded_sample, (flags ^ 0x2) | 0x4);
    else
        st->codecpar->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codecpar->codec_tag);
    return 0;
}

/** Read magic cookie chunk */
static int read_kuki_chunk(AVFormatContext *s, int64_t size)
{
    AVIOContext *pb = s->pb;
    AVStream *st      = s->streams[0];
    int ret;

    if (size < 0 || size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
        return -1;

    if (st->codecpar->codec_id == AV_CODEC_ID_AAC) {
        /* The magic cookie format for AAC is an mp4 esds atom.
           The lavc AAC decoder requires the data from the codec specific
           description as extradata input. */
        int strt, skip;

        strt = avio_tell(pb);
        ff_mov_read_esds(s, pb);
        skip = size - (avio_tell(pb) - strt);
        if (skip < 0 || !st->codecpar->extradata ||
            st->codecpar->codec_id != AV_CODEC_ID_AAC) {
            av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n");
            return AVERROR_INVALIDDATA;
        }
        avio_skip(pb, skip);
    } else if (st->codecpar->codec_id == AV_CODEC_ID_ALAC) {
#define ALAC_PREAMBLE 12
#define ALAC_HEADER   36
#define ALAC_NEW_KUKI 24
        uint8_t preamble[12];
        if (size < ALAC_NEW_KUKI) {
            av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
            avio_skip(pb, size);
            return AVERROR_INVALIDDATA;
        }
        if (avio_read(pb, preamble, ALAC_PREAMBLE) != ALAC_PREAMBLE) {
            av_log(s, AV_LOG_ERROR, "failed to read preamble\n");
            return AVERROR_INVALIDDATA;
        }

        if ((ret = ff_alloc_extradata(st->codecpar, ALAC_HEADER)) < 0)
            return ret;

        /* For the old style cookie, we skip 12 bytes, then read 36 bytes.
         * The new style cookie only contains the last 24 bytes of what was
         * 36 bytes in the old style cookie, so we fabricate the first 12 bytes
         * in that case to maintain compatibility. */
        if (!memcmp(&preamble[4], "frmaalac", 8)) {
            if (size < ALAC_PREAMBLE + ALAC_HEADER) {
                av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n");
                av_freep(&st->codecpar->extradata);
                return AVERROR_INVALIDDATA;
            }
            if (avio_read(pb, st->codecpar->extradata, ALAC_HEADER) != ALAC_HEADER) {
                av_log(s, AV_LOG_ERROR, "failed to read kuki header\n");
                av_freep(&st->codecpar->extradata);
                return AVERROR_INVALIDDATA;
            }
            avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER);
        } else {
            AV_WB32(st->codecpar->extradata, 36);
            memcpy(&st->codecpar->extradata[4], "alac", 4);
            AV_WB32(&st->codecpar->extradata[8], 0);
            memcpy(&st->codecpar->extradata[12], preamble, 12);
            if (avio_read(pb, &st->codecpar->extradata[24], ALAC_NEW_KUKI - 12) != ALAC_NEW_KUKI - 12) {
                av_log(s, AV_LOG_ERROR, "failed to read new kuki header\n");
                av_freep(&st->codecpar->extradata);
                return AVERROR_INVALIDDATA;
            }
            avio_skip(pb, size - ALAC_NEW_KUKI);
        }
    } else if (st->codecpar->codec_id == AV_CODEC_ID_OPUS) {
        // The data layout for Opus is currently unknown, so we do not export
        // extradata at all. Multichannel streams are not supported.
        if (st->codecpar->channels > 2) {
            avpriv_request_sample(s, "multichannel Opus in CAF");
            return AVERROR_PATCHWELCOME;
        }
        avio_skip(pb, size);
    } else if ((ret = ff_get_extradata(s, st->codecpar, pb, size)) < 0) {
        return ret;
    }

    return 0;
}

/** Read packet table chunk */
static int read_pakt_chunk(AVFormatContext *s, int64_t size)
{
    AVIOContext *pb = s->pb;
    AVStream *st      = s->streams[0];
    CafContext *caf   = s->priv_data;
    int64_t pos = 0, ccount, num_packets;
    int i;

    ccount = avio_tell(pb);

    num_packets = avio_rb64(pb);
    if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets)
        return AVERROR_INVALIDDATA;

    st->nb_frames  = avio_rb64(pb); /* valid frames */
    st->nb_frames += avio_rb32(pb); /* priming frames */
    st->nb_frames += avio_rb32(pb); /* remainder frames */

    st->duration = 0;
    for (i = 0; i < num_packets; i++) {
        av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME);
        pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb);
        st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb);
    }

    if (avio_tell(pb) - ccount > size) {
        av_log(s, AV_LOG_ERROR, "error reading packet table\n");
        return AVERROR_INVALIDDATA;
    }
    avio_skip(pb, ccount + size - avio_tell(pb));

    caf->num_bytes = pos;
    return 0;
}

/** Read information chunk */
static void read_info_chunk(AVFormatContext *s, int64_t size)
{
    AVIOContext *pb = s->pb;
    unsigned int i;
    unsigned int nb_entries = avio_rb32(pb);
    for (i = 0; i < nb_entries && !avio_feof(pb); i++) {
        char key[32];
        char value[1024];
        avio_get_str(pb, INT_MAX, key, sizeof(key));
        avio_get_str(pb, INT_MAX, value, sizeof(value));
        av_dict_set(&s->metadata, key, value, 0);
    }
}

static int read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    CafContext *caf = s->priv_data;
    AVStream *st;
    uint32_t tag = 0;
    int found_data, ret;
    int64_t size, pos;

    avio_skip(pb, 8); /* magic, version, file flags */

    /* audio description chunk */
    if (avio_rb32(pb) != MKBETAG('d','e','s','c')) {
        av_log(s, AV_LOG_ERROR, "desc chunk not present\n");
        return AVERROR_INVALIDDATA;
    }
    size = avio_rb64(pb);
    if (size != 32)
        return AVERROR_INVALIDDATA;

    ret = read_desc_chunk(s);
    if (ret)
        return ret;
    st = s->streams[0];

    /* parse each chunk */
    found_data = 0;
    while (!avio_feof(pb)) {

        /* stop at data chunk if seeking is not supported or
           data chunk size is unknown */
        if (found_data && (caf->data_size < 0 || !(pb->seekable & AVIO_SEEKABLE_NORMAL)))
            break;

        tag  = avio_rb32(pb);
        size = avio_rb64(pb);
        pos  = avio_tell(pb);
        if (avio_feof(pb))
            break;

        switch (tag) {
        case MKBETAG('d','a','t','a'):
            avio_skip(pb, 4); /* edit count */
            caf->data_start = avio_tell(pb);
            caf->data_size  = size < 0 ? -1 : size - 4;
            if (caf->data_size > 0 && (pb->seekable & AVIO_SEEKABLE_NORMAL))
                avio_skip(pb, caf->data_size);
            found_data = 1;
            break;

        case MKBETAG('c','h','a','n'):
            if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
                return ret;
            break;

        /* magic cookie chunk */
        case MKBETAG('k','u','k','i'):
            if (read_kuki_chunk(s, size))
                return AVERROR_INVALIDDATA;
            break;

        /* packet table chunk */
        case MKBETAG('p','a','k','t'):
            if (read_pakt_chunk(s, size))
                return AVERROR_INVALIDDATA;
            break;

        case MKBETAG('i','n','f','o'):
            read_info_chunk(s, size);
            break;

        default:
            av_log(s, AV_LOG_WARNING,
                   "skipping CAF chunk: %08"PRIX32" (%s), size %"PRId64"\n",
                   tag, av_fourcc2str(av_bswap32(tag)), size);
        case MKBETAG('f','r','e','e'):
            if (size < 0 && found_data)
                goto found_data;
            if (size < 0)
                return AVERROR_INVALIDDATA;
            break;
        }

        if (size > 0) {
            if (pos > INT64_MAX - size)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, FFMAX(0, pos + size - avio_tell(pb)));
        }
    }

    if (!found_data)
        return AVERROR_INVALIDDATA;

found_data:
    if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
        if (caf->data_size > 0)
            st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
    } else if (st->nb_index_entries && st->duration > 0) {
        if (st->codecpar->sample_rate && caf->data_size / st->duration > INT64_MAX / st->codecpar->sample_rate / 8) {
            av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %d * 8 * %"PRId64"\n",
                   st->codecpar->sample_rate, caf->data_size / st->duration);
            return AVERROR_INVALIDDATA;
        }
        st->codecpar->bit_rate = st->codecpar->sample_rate * 8LL *
                                 (caf->data_size / st->duration);
    } else {
        av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when "
                                "block size or frame size are variable.\n");
        return AVERROR_INVALIDDATA;
    }

    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
    st->start_time = 0;

    /* position the stream at the start of data */
    if (caf->data_size >= 0)
        avio_seek(pb, caf->data_start, SEEK_SET);

    return 0;
}

#define CAF_MAX_PKT_SIZE 4096

static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    AVStream *st      = s->streams[0];
    CafContext *caf   = s->priv_data;
    int res, pkt_size = 0, pkt_frames = 0;
    int64_t left      = CAF_MAX_PKT_SIZE;

    if (avio_feof(pb))
        return AVERROR_EOF;

    /* don't read past end of data chunk */
    if (caf->data_size > 0) {
        left = (caf->data_start + caf->data_size) - avio_tell(pb);
        if (!left)
            return AVERROR_EOF;
        if (left < 0)
            return AVERROR(EIO);
    }

    pkt_frames = caf->frames_per_packet;
    pkt_size   = caf->bytes_per_packet;

    if (pkt_size > 0 && pkt_frames == 1) {
        pkt_size   = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size;
        pkt_size   = FFMIN(pkt_size, left);
        pkt_frames = pkt_size / caf->bytes_per_packet;
    } else if (st->nb_index_entries) {
        if (caf->packet_cnt < st->nb_index_entries - 1) {
            pkt_size   = st->index_entries[caf->packet_cnt + 1].pos       - st->index_entries[caf->packet_cnt].pos;
            pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp;
        } else if (caf->packet_cnt == st->nb_index_entries - 1) {
            pkt_size   = caf->num_bytes - st->index_entries[caf->packet_cnt].pos;
            pkt_frames = st->duration   - st->index_entries[caf->packet_cnt].timestamp;
        } else {
            return AVERROR(EIO);
        }
    }

    if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left)
        return AVERROR(EIO);

    res = av_get_packet(pb, pkt, pkt_size);
    if (res < 0)
        return res;

    pkt->size           = res;
    pkt->stream_index   = 0;
    pkt->dts = pkt->pts = caf->frame_cnt;

    caf->packet_cnt++;
    caf->frame_cnt += pkt_frames;

    return 0;
}

static int read_seek(AVFormatContext *s, int stream_index,
                     int64_t timestamp, int flags)
{
    AVStream *st = s->streams[0];
    CafContext *caf = s->priv_data;
    int64_t pos, packet_cnt, frame_cnt;

    timestamp = FFMAX(timestamp, 0);

    if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) {
        /* calculate new byte position based on target frame position */
        pos = caf->bytes_per_packet * (timestamp / caf->frames_per_packet);
        if (caf->data_size > 0)
            pos = FFMIN(pos, caf->data_size);
        packet_cnt = pos / caf->bytes_per_packet;
        frame_cnt  = caf->frames_per_packet * packet_cnt;
    } else if (st->nb_index_entries) {
        packet_cnt = av_index_search_timestamp(st, timestamp, flags);
        frame_cnt  = st->index_entries[packet_cnt].timestamp;
        pos        = st->index_entries[packet_cnt].pos;
    } else {
        return -1;
    }

    if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0)
        return -1;

    caf->packet_cnt = packet_cnt;
    caf->frame_cnt  = frame_cnt;

    return 0;
}

AVInputFormat ff_caf_demuxer = {
    .name           = "caf",
    .long_name      = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"),
    .priv_data_size = sizeof(CafContext),
    .read_probe     = probe,
    .read_header    = read_header,
    .read_packet    = read_packet,
    .read_seek      = read_seek,
    .codec_tag      = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 },
};
