/*
 * LXF demuxer
 * Copyright (c) 2010 Tomas Härdin
 *
 * 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 "libavcodec/bytestream.h"
#include "avformat.h"
#include "internal.h"

#define LXF_MAX_PACKET_HEADER_SIZE 256
#define LXF_HEADER_DATA_SIZE    120
#define LXF_IDENT               "LEITCH\0"
#define LXF_IDENT_LENGTH        8
#define LXF_SAMPLERATE          48000

static const AVCodecTag lxf_tags[] = {
    { AV_CODEC_ID_MJPEG,       0 },
    { AV_CODEC_ID_MPEG1VIDEO,  1 },
    { AV_CODEC_ID_MPEG2VIDEO,  2 },    //MpMl, 4:2:0
    { AV_CODEC_ID_MPEG2VIDEO,  3 },    //MpPl, 4:2:2
    { AV_CODEC_ID_DVVIDEO,     4 },    //DV25
    { AV_CODEC_ID_DVVIDEO,     5 },    //DVCPRO
    { AV_CODEC_ID_DVVIDEO,     6 },    //DVCPRO50
    { AV_CODEC_ID_RAWVIDEO,    7 },    //AV_PIX_FMT_ARGB, where alpha is used for chroma keying
    { AV_CODEC_ID_RAWVIDEO,    8 },    //16-bit chroma key
    { AV_CODEC_ID_MPEG2VIDEO,  9 },    //4:2:2 CBP ("Constrained Bytes per Gop")
    { AV_CODEC_ID_NONE,        0 },
};

typedef struct {
    int channels;                       ///< number of audio channels. zero means no audio
    int frame_number;                   ///< current video frame
    uint32_t video_format, packet_type, extended_size;
} LXFDemuxContext;

static int lxf_probe(AVProbeData *p)
{
    if (!memcmp(p->buf, LXF_IDENT, LXF_IDENT_LENGTH))
        return AVPROBE_SCORE_MAX;

    return 0;
}

/**
 * Verify the checksum of an LXF packet header
 *
 * @param[in] header the packet header to check
 * @return zero if the checksum is OK, non-zero otherwise
 */
static int check_checksum(const uint8_t *header, int size)
{
    int x;
    uint32_t sum = 0;

    for (x = 0; x < size; x += 4)
        sum += AV_RL32(&header[x]);

    return sum;
}

/**
 * Read input until we find the next ident. If found, copy it to the header buffer
 *
 * @param[out] header where to copy the ident to
 * @return 0 if an ident was found, < 0 on I/O error
 */
static int sync(AVFormatContext *s, uint8_t *header)
{
    uint8_t buf[LXF_IDENT_LENGTH];
    int ret;

    if ((ret = avio_read(s->pb, buf, LXF_IDENT_LENGTH)) != LXF_IDENT_LENGTH)
        return ret < 0 ? ret : AVERROR_EOF;

    while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) {
        if (url_feof(s->pb))
            return AVERROR_EOF;

        memmove(buf, &buf[1], LXF_IDENT_LENGTH-1);
        buf[LXF_IDENT_LENGTH-1] = avio_r8(s->pb);
    }

    memcpy(header, LXF_IDENT, LXF_IDENT_LENGTH);

    return 0;
}

/**
 * Read and checksum the next packet header
 *
 * @return the size of the payload following the header or < 0 on failure
 */
static int get_packet_header(AVFormatContext *s)
{
    LXFDemuxContext *lxf = s->priv_data;
    AVIOContext   *pb  = s->pb;
    int track_size, samples, ret;
    uint32_t version, audio_format, header_size, channels, tmp;
    AVStream *st;
    uint8_t header[LXF_MAX_PACKET_HEADER_SIZE];
    const uint8_t *p = header + LXF_IDENT_LENGTH;

    //find and read the ident
    if ((ret = sync(s, header)) < 0)
        return ret;

    ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8);
    if (ret != 8)
        return ret < 0 ? ret : AVERROR_EOF;

    version     = bytestream_get_le32(&p);
    header_size = bytestream_get_le32(&p);
    if (version > 1)
        avpriv_request_sample(s, "Unknown format version %i\n", version);

    if (header_size < (version ? 72 : 60) ||
        header_size > LXF_MAX_PACKET_HEADER_SIZE ||
        (header_size & 3)) {
        av_log(s, AV_LOG_ERROR, "Invalid header size 0x%x\n", header_size);
        return AVERROR_INVALIDDATA;
    }

    //read the rest of the packet header
    if ((ret = avio_read(pb, header + (p - header),
                          header_size - (p - header))) !=
                          header_size - (p - header))
        return ret < 0 ? ret : AVERROR_EOF;

    if (check_checksum(header, header_size))
        av_log(s, AV_LOG_ERROR, "checksum error\n");

    lxf->packet_type = bytestream_get_le32(&p);
    p += version ? 20 : 12;

    lxf->extended_size = 0;
    switch (lxf->packet_type) {
    case 0:
        //video
        lxf->video_format = bytestream_get_le32(&p);
        ret               = bytestream_get_le32(&p);
        //skip VBI data and metadata
        avio_skip(pb, (int64_t)(uint32_t)AV_RL32(p + 4) +
                      (int64_t)(uint32_t)AV_RL32(p + 12));
        break;
    case 1:
        //audio
        if (s->nb_streams < 2) {
            av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n");
            break;
        }

        if (version == 0)
            p += 8;
        audio_format = bytestream_get_le32(&p);
        channels     = bytestream_get_le32(&p);
        track_size   = bytestream_get_le32(&p);

        st = s->streams[1];

        //set codec based on specified audio bitdepth
        //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment
        st->codec->bits_per_coded_sample = (audio_format >> 6) & 0x3F;

        if (st->codec->bits_per_coded_sample != (audio_format & 0x3F)) {
            av_log(s, AV_LOG_WARNING, "only tightly packed PCM currently supported\n");
            return AVERROR_PATCHWELCOME;
        }

        switch (st->codec->bits_per_coded_sample) {
        case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break;
        case 20: st->codec->codec_id = AV_CODEC_ID_PCM_LXF;   break;
        case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break;
        case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break;
        default:
            av_log(s, AV_LOG_WARNING,
                   "only 16-, 20-, 24- and 32-bit PCM currently supported\n");
            return AVERROR_PATCHWELCOME;
        }

        samples = track_size * 8 / st->codec->bits_per_coded_sample;

        //use audio packet size to determine video standard
        //for NTSC we have one 8008-sample audio frame per five video frames
        if (samples == LXF_SAMPLERATE * 5005 / 30000) {
            avpriv_set_pts_info(s->streams[0], 64, 1001, 30000);
        } else {
            //assume PAL, but warn if we don't have 1920 samples
            if (samples != LXF_SAMPLERATE / 25)
                av_log(s, AV_LOG_WARNING,
                       "video doesn't seem to be PAL or NTSC. guessing PAL\n");

            avpriv_set_pts_info(s->streams[0], 64, 1, 25);
        }

        //TODO: warning if track mask != (1 << channels) - 1?
        ret = av_popcount(channels) * track_size;

        break;
    default:
        tmp = bytestream_get_le32(&p);
        ret = bytestream_get_le32(&p);
        if (tmp == 1)
            lxf->extended_size = bytestream_get_le32(&p);
        break;
    }

    return ret;
}

static int lxf_read_header(AVFormatContext *s)
{
    LXFDemuxContext *lxf = s->priv_data;
    AVIOContext   *pb  = s->pb;
    uint8_t header_data[LXF_HEADER_DATA_SIZE];
    int ret;
    AVStream *st;
    uint32_t video_params, disk_params;
    uint16_t record_date, expiration_date;

    if ((ret = get_packet_header(s)) < 0)
        return ret;

    if (ret != LXF_HEADER_DATA_SIZE) {
        av_log(s, AV_LOG_ERROR, "expected %d B size header, got %d\n",
               LXF_HEADER_DATA_SIZE, ret);
        return AVERROR_INVALIDDATA;
    }

    if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE)
        return ret < 0 ? ret : AVERROR_EOF;

    if (!(st = avformat_new_stream(s, NULL)))
        return AVERROR(ENOMEM);

    st->duration          = AV_RL32(&header_data[32]);
    video_params          = AV_RL32(&header_data[40]);
    record_date           = AV_RL16(&header_data[56]);
    expiration_date       = AV_RL16(&header_data[58]);
    disk_params           = AV_RL32(&header_data[116]);

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->bit_rate   = 1000000 * ((video_params >> 14) & 0xFF);
    st->codec->codec_tag  = video_params & 0xF;
    st->codec->codec_id   = ff_codec_get_id(lxf_tags, st->codec->codec_tag);
    st->need_parsing      = AVSTREAM_PARSE_HEADERS;

    av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n",
           record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF,
           (record_date >> 11) & 0x1F);

    av_log(s, AV_LOG_DEBUG, "expire: %x = %i-%02i-%02i\n",
           expiration_date, 1900 + (expiration_date & 0x7F), (expiration_date >> 7) & 0xF,
           (expiration_date >> 11) & 0x1F);

    if ((video_params >> 22) & 1)
        av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n");

    if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) {
        if (!(st = avformat_new_stream(s, NULL)))
            return AVERROR(ENOMEM);

        st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
        st->codec->sample_rate = LXF_SAMPLERATE;
        st->codec->channels    = lxf->channels;

        avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
    }

    avio_skip(s->pb, lxf->extended_size);

    return 0;
}

static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    LXFDemuxContext *lxf = s->priv_data;
    AVIOContext   *pb  = s->pb;
    uint32_t stream;
    int ret, ret2;

    if ((ret = get_packet_header(s)) < 0)
        return ret;

    stream = lxf->packet_type;

    if (stream > 1) {
        av_log(s, AV_LOG_WARNING, "got packet with illegal stream index %u\n", stream);
        return AVERROR(EAGAIN);
    }

    if (stream == 1 && s->nb_streams < 2) {
        av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n");
        return AVERROR_INVALIDDATA;
    }

    if ((ret2 = av_new_packet(pkt, ret)) < 0)
        return ret2;

    if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) {
        av_free_packet(pkt);
        return ret2 < 0 ? ret2 : AVERROR_EOF;
    }

    pkt->stream_index = stream;

    if (!stream) {
        //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B)
        if (((lxf->video_format >> 22) & 0x3) < 2)
            pkt->flags |= AV_PKT_FLAG_KEY;

        pkt->dts = lxf->frame_number++;
    }

    return ret;
}

AVInputFormat ff_lxf_demuxer = {
    .name           = "lxf",
    .long_name      = NULL_IF_CONFIG_SMALL("VR native stream (LXF)"),
    .priv_data_size = sizeof(LXFDemuxContext),
    .read_probe     = lxf_probe,
    .read_header    = lxf_read_header,
    .read_packet    = lxf_read_packet,
    .codec_tag      = (const AVCodecTag* const []){lxf_tags, 0},
};
