/*
 * R3D REDCODE demuxer
 * Copyright (c) 2008 Baptiste Coudurier <baptiste dot coudurier at gmail dot 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/intreadwrite.h"
#include "libavutil/dict.h"
#include "libavutil/mathematics.h"
#include "avformat.h"
#include "internal.h"

typedef struct R3DContext {
    unsigned video_offsets_count;
    unsigned rdvo_offset;

    int audio_channels;
} R3DContext;

typedef struct Atom {
    unsigned size;
    uint32_t tag;
    uint64_t offset;
} Atom;

static int read_atom(AVFormatContext *s, Atom *atom)
{
    atom->offset = avio_tell(s->pb);
    atom->size = avio_rb32(s->pb);
    if (atom->size < 8)
        return -1;
    atom->tag = avio_rl32(s->pb);
    av_log(s, AV_LOG_TRACE, "atom %u %.4s offset %#"PRIx64"\n",
            atom->size, (char*)&atom->tag, atom->offset);
    return atom->size;
}

static int r3d_read_red1(AVFormatContext *s)
{
    AVStream *st = avformat_new_stream(s, NULL);
    R3DContext *r3d = s->priv_data;
    char filename[258];
    int tmp;
    int av_unused tmp2;
    AVRational framerate;

    if (!st)
        return AVERROR(ENOMEM);
    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codecpar->codec_id = AV_CODEC_ID_JPEG2000;

    tmp  = avio_r8(s->pb); // major version
    tmp2 = avio_r8(s->pb); // minor version
    av_log(s, AV_LOG_TRACE, "version %d.%d\n", tmp, tmp2);

    tmp = avio_rb16(s->pb); // unknown
    av_log(s, AV_LOG_TRACE, "unknown1 %d\n", tmp);

    tmp = avio_rb32(s->pb);
    avpriv_set_pts_info(st, 32, 1, tmp);

    tmp = avio_rb32(s->pb); // filenum
    av_log(s, AV_LOG_TRACE, "filenum %d\n", tmp);

    avio_skip(s->pb, 32); // unknown

    st->codecpar->width  = avio_rb32(s->pb);
    st->codecpar->height = avio_rb32(s->pb);

    tmp = avio_rb16(s->pb); // unknown
    av_log(s, AV_LOG_TRACE, "unknown2 %d\n", tmp);

    framerate.num = avio_rb16(s->pb);
    framerate.den = avio_rb16(s->pb);
    if (framerate.num > 0 && framerate.den > 0) {
#if FF_API_R_FRAME_RATE
        st->r_frame_rate =
#endif
        st->avg_frame_rate = framerate;
    }

    r3d->audio_channels = avio_r8(s->pb); // audio channels
    av_log(s, AV_LOG_TRACE, "audio channels %d\n", tmp);

    avio_read(s->pb, filename, 257);
    filename[sizeof(filename)-1] = 0;
    av_dict_set(&st->metadata, "filename", filename, 0);

    av_log(s, AV_LOG_TRACE, "filename %s\n", filename);
    av_log(s, AV_LOG_TRACE, "resolution %dx%d\n", st->codecpar->width, st->codecpar->height);
    av_log(s, AV_LOG_TRACE, "timescale %d\n", st->time_base.den);
    av_log(s, AV_LOG_TRACE, "frame rate %d/%d\n",
            framerate.num, framerate.den);

    return 0;
}

static int r3d_read_rdvo(AVFormatContext *s, Atom *atom)
{
    R3DContext *r3d = s->priv_data;
    AVStream *st = s->streams[0];
    int i;

    r3d->video_offsets_count = (atom->size - 8) / 4;

    for (i = 0; i < r3d->video_offsets_count; i++) {
        unsigned video_offset = avio_rb32(s->pb);
        if (!video_offset) {
            r3d->video_offsets_count = i;
            break;
        }
        av_log(s, AV_LOG_TRACE, "video offset %d: %#x\n", i, video_offset);
    }

    if (st->avg_frame_rate.num)
        st->duration = av_rescale_q(r3d->video_offsets_count,
                                    av_inv_q(st->avg_frame_rate),
                                    st->time_base);
    av_log(s, AV_LOG_TRACE, "duration %"PRId64"\n", st->duration);

    return 0;
}

static void r3d_read_reos(AVFormatContext *s)
{
    R3DContext *r3d = s->priv_data;
    int av_unused tmp;

    r3d->rdvo_offset = avio_rb32(s->pb);
    avio_rb32(s->pb); // rdvs offset
    avio_rb32(s->pb); // rdao offset
    avio_rb32(s->pb); // rdas offset

    tmp = avio_rb32(s->pb);
    av_log(s, AV_LOG_TRACE, "num video chunks %d\n", tmp);

    tmp = avio_rb32(s->pb);
    av_log(s, AV_LOG_TRACE, "num audio chunks %d\n", tmp);

    avio_skip(s->pb, 6*4);
}

static int r3d_read_header(AVFormatContext *s)
{
    R3DContext *r3d = s->priv_data;
    Atom atom;
    int ret;

    if (read_atom(s, &atom) < 0) {
        av_log(s, AV_LOG_ERROR, "error reading atom\n");
        return -1;
    }
    if (atom.tag == MKTAG('R','E','D','1')) {
        if ((ret = r3d_read_red1(s)) < 0) {
            av_log(s, AV_LOG_ERROR, "error parsing 'red1' atom\n");
            return ret;
        }
    } else {
        av_log(s, AV_LOG_ERROR, "could not find 'red1' atom\n");
        return -1;
    }

    /* we cannot create the audio stream now because we do not know the
     * sample rate */
    if (r3d->audio_channels)
        s->ctx_flags |= AVFMTCTX_NOHEADER;

    s->internal->data_offset = avio_tell(s->pb);
    av_log(s, AV_LOG_TRACE, "data offset %#"PRIx64"\n", s->internal->data_offset);
    if (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL))
        return 0;
    // find REOB/REOF/REOS to load index
    avio_seek(s->pb, avio_size(s->pb)-48-8, SEEK_SET);
    if (read_atom(s, &atom) < 0)
        av_log(s, AV_LOG_ERROR, "error reading end atom\n");

    if (atom.tag != MKTAG('R','E','O','B') &&
        atom.tag != MKTAG('R','E','O','F') &&
        atom.tag != MKTAG('R','E','O','S'))
        goto out;

    r3d_read_reos(s);

    if (r3d->rdvo_offset) {
        avio_seek(s->pb, r3d->rdvo_offset, SEEK_SET);
        if (read_atom(s, &atom) < 0)
            av_log(s, AV_LOG_ERROR, "error reading 'rdvo' atom\n");
        if (atom.tag == MKTAG('R','D','V','O')) {
            if (r3d_read_rdvo(s, &atom) < 0)
                av_log(s, AV_LOG_ERROR, "error parsing 'rdvo' atom\n");
        }
    }

 out:
    avio_seek(s->pb, s->internal->data_offset, SEEK_SET);
    return 0;
}

static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom)
{
    AVStream *st = s->streams[0];
    int tmp;
    int av_unused tmp2;
    int64_t pos = avio_tell(s->pb);
    unsigned dts;
    int ret;

    dts = avio_rb32(s->pb);

    tmp = avio_rb32(s->pb);
    av_log(s, AV_LOG_TRACE, "frame num %d\n", tmp);

    tmp  = avio_r8(s->pb); // major version
    tmp2 = avio_r8(s->pb); // minor version
    av_log(s, AV_LOG_TRACE, "version %d.%d\n", tmp, tmp2);

    tmp = avio_rb16(s->pb); // unknown
    av_log(s, AV_LOG_TRACE, "unknown %d\n", tmp);

    if (tmp > 4) {
        tmp = avio_rb16(s->pb); // unknown
        av_log(s, AV_LOG_TRACE, "unknown %d\n", tmp);

        tmp = avio_rb16(s->pb); // unknown
        av_log(s, AV_LOG_TRACE, "unknown %d\n", tmp);

        tmp = avio_rb32(s->pb);
        av_log(s, AV_LOG_TRACE, "width %d\n", tmp);
        tmp = avio_rb32(s->pb);
        av_log(s, AV_LOG_TRACE, "height %d\n", tmp);

        tmp = avio_rb32(s->pb);
        av_log(s, AV_LOG_TRACE, "metadata len %d\n", tmp);
    }
    tmp = atom->size - 8 - (avio_tell(s->pb) - pos);
    if (tmp < 0)
        return -1;
    ret = av_get_packet(s->pb, pkt, tmp);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "error reading video packet\n");
        return -1;
    }

    pkt->stream_index = 0;
    pkt->dts = dts;
    if (st->avg_frame_rate.num)
        pkt->duration = (uint64_t)st->time_base.den*
            st->avg_frame_rate.den/st->avg_frame_rate.num;
    av_log(s, AV_LOG_TRACE, "pkt dts %"PRId64" duration %"PRId64"\n", pkt->dts, pkt->duration);

    return 0;
}

static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom)
{
    R3DContext *r3d = s->priv_data;
    AVStream *st;
    int av_unused tmp, tmp2;
    int samples, size;
    int64_t pos = avio_tell(s->pb);
    unsigned dts;
    int ret;

    if (s->nb_streams < 2) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;
        st->codecpar->channels = r3d->audio_channels;
        avpriv_set_pts_info(st, 32, 1, s->streams[0]->time_base.den);
    } else {
        st = s->streams[1];
    }

    dts = avio_rb32(s->pb);

    st->codecpar->sample_rate = avio_rb32(s->pb);
    if (st->codecpar->sample_rate <= 0) {
        av_log(s, AV_LOG_ERROR, "Bad sample rate\n");
        return AVERROR_INVALIDDATA;
    }

    samples = avio_rb32(s->pb);

    tmp = avio_rb32(s->pb);
    av_log(s, AV_LOG_TRACE, "packet num %d\n", tmp);

    tmp = avio_rb16(s->pb); // unknown
    av_log(s, AV_LOG_TRACE, "unknown %d\n", tmp);

    tmp  = avio_r8(s->pb); // major version
    tmp2 = avio_r8(s->pb); // minor version
    av_log(s, AV_LOG_TRACE, "version %d.%d\n", tmp, tmp2);

    tmp = avio_rb32(s->pb); // unknown
    av_log(s, AV_LOG_TRACE, "unknown %d\n", tmp);

    size = atom->size - 8 - (avio_tell(s->pb) - pos);
    if (size < 0)
        return -1;
    ret = av_get_packet(s->pb, pkt, size);
    if (ret < 0) {
        av_log(s, AV_LOG_ERROR, "error reading audio packet\n");
        return ret;
    }

    pkt->stream_index = 1;
    pkt->dts = dts;
    if (st->codecpar->sample_rate)
        pkt->duration = av_rescale(samples, st->time_base.den, st->codecpar->sample_rate);
    av_log(s, AV_LOG_TRACE, "pkt dts %"PRId64" duration %"PRId64" samples %d sample rate %d\n",
            pkt->dts, pkt->duration, samples, st->codecpar->sample_rate);

    return 0;
}

static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    R3DContext *r3d = s->priv_data;
    Atom atom;
    int err = 0;

    while (!err) {
        if (read_atom(s, &atom) < 0) {
            err = -1;
            break;
        }
        switch (atom.tag) {
        case MKTAG('R','E','D','V'):
            if (s->streams[0]->discard == AVDISCARD_ALL)
                goto skip;
            if (!(err = r3d_read_redv(s, pkt, &atom)))
                return 0;
            break;
        case MKTAG('R','E','D','A'):
            if (!r3d->audio_channels)
                return -1;
            if (s->nb_streams >= 2 && s->streams[1]->discard == AVDISCARD_ALL)
                goto skip;
            if (!(err = r3d_read_reda(s, pkt, &atom)))
                return 0;
            break;
        default:
        skip:
            avio_skip(s->pb, atom.size-8);
        }
    }
    return err;
}

static int r3d_probe(const AVProbeData *p)
{
    if (AV_RL32(p->buf + 4) == MKTAG('R','E','D','1'))
        return AVPROBE_SCORE_MAX;
    return 0;
}

static int r3d_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
{
    AVStream *st = s->streams[0]; // video stream
    R3DContext *r3d = s->priv_data;
    int frame_num;

    if (!st->avg_frame_rate.num)
        return -1;

    frame_num = av_rescale_q(sample_time, st->time_base,
                             av_inv_q(st->avg_frame_rate));
    av_log(s, AV_LOG_TRACE, "seek frame num %d timestamp %"PRId64"\n",
            frame_num, sample_time);

    if (frame_num < r3d->video_offsets_count) {
        if (avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET) < 0)
            return -1;
    } else {
        av_log(s, AV_LOG_ERROR, "could not seek to frame %d\n", frame_num);
        return -1;
    }

    return 0;
}

AVInputFormat ff_r3d_demuxer = {
    .name           = "r3d",
    .long_name      = NULL_IF_CONFIG_SMALL("REDCODE R3D"),
    .priv_data_size = sizeof(R3DContext),
    .read_probe     = r3d_probe,
    .read_header    = r3d_read_header,
    .read_packet    = r3d_read_packet,
    .read_seek      = r3d_seek,
};
