/*
 * DHAV demuxer
 *
 * Copyright (c) 2018 Paul B Mahol
 *
 * 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/parseutils.h"
#include "avio_internal.h"
#include "avformat.h"
#include "internal.h"

typedef struct DHAVContext {
    unsigned type;
    unsigned subtype;
    unsigned channel;
    unsigned frame_subnumber;
    unsigned frame_number;
    unsigned date;
    unsigned timestamp;
    int width, height;
    int video_codec;
    int frame_rate;
    int audio_channels;
    int audio_codec;
    int sample_rate;
    int64_t last_good_pos;
    int64_t duration;

    int video_stream_index;
    int audio_stream_index;
} DHAVContext;

typedef struct DHAVStream {
    int64_t last_timestamp;
    int64_t last_time;
    int64_t pts;
} DHAVStream;

static int dhav_probe(const AVProbeData *p)
{
    if (!memcmp(p->buf, "DAHUA", 5))
        return AVPROBE_SCORE_MAX;

    if (memcmp(p->buf, "DHAV", 4))
        return 0;

    if (p->buf[4] == 0xf0 ||
        p->buf[4] == 0xf1 ||
        p->buf[4] == 0xfc ||
        p->buf[4] == 0xfd)
        return AVPROBE_SCORE_MAX;
    return 0;
}

static const uint32_t sample_rates[] = {
    8000, 4000, 8000, 11025, 16000,
    20000, 22050, 32000, 44100, 48000,
    96000, 192000, 64000,
};

static int parse_ext(AVFormatContext *s, int length)
{
    DHAVContext *dhav = s->priv_data;
    int index, ret = 0;

    while (length > 0) {
        int type = avio_r8(s->pb);

        switch (type) {
        case 0x80:
            ret = avio_skip(s->pb, 1);
            dhav->width  = 8 * avio_r8(s->pb);
            dhav->height = 8 * avio_r8(s->pb);
            length -= 4;
            break;
        case 0x81:
            ret = avio_skip(s->pb, 1);
            dhav->video_codec = avio_r8(s->pb);
            dhav->frame_rate = avio_r8(s->pb);
            length -= 4;
            break;
        case 0x82:
            ret = avio_skip(s->pb, 3);
            dhav->width  = avio_rl16(s->pb);
            dhav->height = avio_rl16(s->pb);
            length -= 8;
            break;
        case 0x83:
            dhav->audio_channels = avio_r8(s->pb);
            dhav->audio_codec = avio_r8(s->pb);
            index = avio_r8(s->pb);
            if (index < FF_ARRAY_ELEMS(sample_rates)) {
                dhav->sample_rate = sample_rates[index];
            } else {
                dhav->sample_rate = 8000;
            }
            length -= 4;
            break;
        case 0x88:
            ret = avio_skip(s->pb, 7);
            length -= 8;
            break;
        case 0x8c:
            ret = avio_skip(s->pb, 1);
            dhav->audio_channels = avio_r8(s->pb);
            dhav->audio_codec = avio_r8(s->pb);
            index = avio_r8(s->pb);
            if (index < FF_ARRAY_ELEMS(sample_rates)) {
                dhav->sample_rate = sample_rates[index];
            } else {
                dhav->sample_rate = 8000;
            }
            ret = avio_skip(s->pb, 3);
            length -= 8;
            break;
        case 0x91:
        case 0x92:
        case 0x93:
        case 0x95:
        case 0x9a:
        case 0x9b: // sample aspect ratio
        case 0xb3:
            ret = avio_skip(s->pb, 7);
            length -= 8;
            break;
        case 0x84:
        case 0x85:
        case 0x8b:
        case 0x94:
        case 0x96:
        case 0xa0:
        case 0xb2:
        case 0xb4:
            ret = avio_skip(s->pb, 3);
            length -= 4;
            break;
        default:
            av_log(s, AV_LOG_INFO, "Unknown type: %X, skipping rest of header.\n", type);
            ret = avio_skip(s->pb, length - 1);
            length = 0;
        }

        if (ret < 0)
            return ret;
    }

    return 0;
}

static int read_chunk(AVFormatContext *s)
{
    DHAVContext *dhav = s->priv_data;
    int frame_length, ext_length;
    int64_t start, end;
    int ret;

    if (avio_feof(s->pb))
        return AVERROR_EOF;

    if (avio_rl32(s->pb) != MKTAG('D','H','A','V')) {
        dhav->last_good_pos += 0x8000;
        avio_seek(s->pb, dhav->last_good_pos, SEEK_SET);

        while (avio_rl32(s->pb) != MKTAG('D','H','A','V')) {
            if (avio_feof(s->pb))
                return AVERROR_EOF;
            dhav->last_good_pos += 0x8000;
            ret = avio_skip(s->pb, 0x8000 - 4);
            if (ret < 0)
                return ret;
        }
    }

    start = avio_tell(s->pb) - 4;
    dhav->last_good_pos = start;
    dhav->type = avio_r8(s->pb);
    dhav->subtype = avio_r8(s->pb);
    dhav->channel = avio_r8(s->pb);
    dhav->frame_subnumber = avio_r8(s->pb);
    dhav->frame_number = avio_rl32(s->pb);
    frame_length = avio_rl32(s->pb);
    dhav->date = avio_rl32(s->pb);

    if (frame_length < 24)
        return AVERROR_INVALIDDATA;
    if (dhav->type == 0xf1) {
        ret = avio_skip(s->pb, frame_length - 20);
        return ret < 0 ? ret : 0;
    }

    dhav->timestamp = avio_rl16(s->pb);
    ext_length = avio_r8(s->pb);
    avio_skip(s->pb, 1); // checksum

    ret = parse_ext(s, ext_length);
    if (ret < 0)
        return ret;

    end = avio_tell(s->pb);

    return frame_length - 8 - (end - start);
}

static void get_timeinfo(unsigned date, struct tm *timeinfo)
{
    int year, month, day, hour, min, sec;

    sec   =   date        & 0x3F;
    min   =  (date >>  6) & 0x3F;
    hour  =  (date >> 12) & 0x1F;
    day   =  (date >> 17) & 0x1F;
    month =  (date >> 22) & 0x0F;
    year  = ((date >> 26) & 0x3F) + 2000;

    timeinfo->tm_year = year - 1900;
    timeinfo->tm_mon  = month - 1;
    timeinfo->tm_mday = day;
    timeinfo->tm_hour = hour;
    timeinfo->tm_min  = min;
    timeinfo->tm_sec  = sec;
}

static int64_t get_duration(AVFormatContext *s)
{
    DHAVContext *dhav = s->priv_data;
    int64_t start_pos = avio_tell(s->pb);
    int64_t start = 0, end = 0;
    struct tm timeinfo;

    if (!s->pb->seekable)
        return 0;

    avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET);
    if (avio_rl32(s->pb) == MKTAG('d','h','a','v')) {
        int seek_back = avio_rl32(s->pb);

        avio_seek(s->pb, -seek_back, SEEK_CUR);
        read_chunk(s);
        get_timeinfo(dhav->date, &timeinfo);
        end = av_timegm(&timeinfo) * 1000LL;
    } else {
        avio_seek(s->pb, start_pos, SEEK_SET);
        return 0;
    }

    avio_seek(s->pb, start_pos, SEEK_SET);

    read_chunk(s);
    get_timeinfo(dhav->date, &timeinfo);
    start = av_timegm(&timeinfo) * 1000LL;

    avio_seek(s->pb, start_pos, SEEK_SET);

    return end - start;
}

static int dhav_read_header(AVFormatContext *s)
{
    DHAVContext *dhav = s->priv_data;
    uint8_t signature[5];

    ffio_ensure_seekback(s->pb, 5);
    avio_read(s->pb, signature, sizeof(signature));
    if (!memcmp(signature, "DAHUA", 5)) {
        avio_skip(s->pb, 0x400 - 5);
        dhav->last_good_pos = avio_tell(s->pb);
    } else {
        if (!memcmp(signature, "DHAV", 4)) {
            avio_seek(s->pb, -5, SEEK_CUR);
            dhav->last_good_pos = avio_tell(s->pb);
        } else if (s->pb->seekable) {
            avio_seek(s->pb, avio_size(s->pb) - 8, SEEK_SET);
            while (avio_rl32(s->pb) == MKTAG('d','h','a','v')) {
                int seek_back;

                seek_back = avio_rl32(s->pb) + 8;
                dhav->last_good_pos = avio_tell(s->pb);
                avio_seek(s->pb, -seek_back, SEEK_CUR);
            }
            avio_seek(s->pb, dhav->last_good_pos, SEEK_SET);
        }
    }

    dhav->duration = get_duration(s);
    dhav->last_good_pos = avio_tell(s->pb);
    s->ctx_flags |= AVFMTCTX_NOHEADER;
    dhav->video_stream_index = -1;
    dhav->audio_stream_index = -1;

    return 0;
}

static int64_t get_pts(AVFormatContext *s, int stream_index)
{
    DHAVStream *dst = s->streams[stream_index]->priv_data;
    DHAVContext *dhav = s->priv_data;
    struct tm timeinfo;
    time_t t;

    get_timeinfo(dhav->date, &timeinfo);

    t = av_timegm(&timeinfo);
    if (dst->last_time == t) {
        int64_t diff = dhav->timestamp - dst->last_timestamp;

        if (diff < 0)
            diff += 65535;
        dst->pts += diff;
    } else {
        dst->pts = t * 1000LL;
    }

    dst->last_time = t;
    dst->last_timestamp = dhav->timestamp;

    return dst->pts;
}

static int dhav_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    DHAVContext *dhav = s->priv_data;
    int size, ret, stream_index;

retry:
    while ((ret = read_chunk(s)) == 0)
        ;

    if (ret < 0)
        return ret;

    if (dhav->type == 0xfd && dhav->video_stream_index == -1) {
        AVStream *st = avformat_new_stream(s, NULL);
        DHAVStream *dst;

        if (!st)
            return AVERROR(ENOMEM);

        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
        switch (dhav->video_codec) {
        case 0x1: st->codecpar->codec_id = AV_CODEC_ID_MPEG4; break;
        case 0x3: st->codecpar->codec_id = AV_CODEC_ID_MJPEG; break;
        case 0x2:
        case 0x4:
        case 0x8: st->codecpar->codec_id = AV_CODEC_ID_H264;  break;
        case 0xc: st->codecpar->codec_id = AV_CODEC_ID_HEVC;  break;
        default: avpriv_request_sample(s, "Unknown video codec %X", dhav->video_codec);
        }
        st->duration             = dhav->duration;
        st->codecpar->width      = dhav->width;
        st->codecpar->height     = dhav->height;
        st->avg_frame_rate.num   = dhav->frame_rate;
        st->avg_frame_rate.den   = 1;
        st->priv_data = dst = av_mallocz(sizeof(DHAVStream));
        if (!st->priv_data)
            return AVERROR(ENOMEM);
        dst->last_time = AV_NOPTS_VALUE;
        dhav->video_stream_index = st->index;

        avpriv_set_pts_info(st, 64, 1, 1000);
    } else if (dhav->type == 0xf0 && dhav->audio_stream_index == -1) {
        AVStream *st = avformat_new_stream(s, NULL);
        DHAVStream *dst;

        if (!st)
            return AVERROR(ENOMEM);

        st->codecpar->codec_type  = AVMEDIA_TYPE_AUDIO;
        switch (dhav->audio_codec) {
        case 0x07: st->codecpar->codec_id = AV_CODEC_ID_PCM_S8;    break;
        case 0x0c: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; break;
        case 0x10: st->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; break;
        case 0x0a: st->codecpar->codec_id = AV_CODEC_ID_PCM_MULAW; break;
        case 0x16: st->codecpar->codec_id = AV_CODEC_ID_PCM_MULAW; break;
        case 0x0e: st->codecpar->codec_id = AV_CODEC_ID_PCM_ALAW;  break;
        case 0x1a: st->codecpar->codec_id = AV_CODEC_ID_AAC;       break;
        case 0x1f: st->codecpar->codec_id = AV_CODEC_ID_MP2;       break;
        case 0x21: st->codecpar->codec_id = AV_CODEC_ID_MP3;       break;
        case 0x0d: st->codecpar->codec_id = AV_CODEC_ID_ADPCM_MS;  break;
        default: avpriv_request_sample(s, "Unknown audio codec %X", dhav->audio_codec);
        }
        st->duration              = dhav->duration;
        st->codecpar->channels    = dhav->audio_channels;
        st->codecpar->sample_rate = dhav->sample_rate;
        st->priv_data = dst = av_mallocz(sizeof(DHAVStream));
        if (!st->priv_data)
            return AVERROR(ENOMEM);
        dst->last_time = AV_NOPTS_VALUE;
        dhav->audio_stream_index  = st->index;

        avpriv_set_pts_info(st, 64, 1, 1000);
    }

    stream_index = dhav->type == 0xf0 ? dhav->audio_stream_index : dhav->video_stream_index;
    if (stream_index < 0) {
        avio_skip(s->pb, ret);
        if (avio_rl32(s->pb) == MKTAG('d','h','a','v'))
            avio_skip(s->pb, 4);
        goto retry;
    }

    size = ret;
    ret = av_get_packet(s->pb, pkt, size);
    if (ret < 0)
        return ret;
    pkt->stream_index = stream_index;
    if (dhav->type != 0xfc)
        pkt->flags   |= AV_PKT_FLAG_KEY;
    pkt->duration = 1;
    if (pkt->stream_index >= 0)
        pkt->pts = get_pts(s, pkt->stream_index);
    pkt->pos = dhav->last_good_pos;
    if (avio_rl32(s->pb) == MKTAG('d','h','a','v'))
        avio_skip(s->pb, 4);

    return ret;
}

static int dhav_read_seek(AVFormatContext *s, int stream_index,
                          int64_t timestamp, int flags)
{
    DHAVContext *dhav = s->priv_data;
    AVStream *st = s->streams[stream_index];
    int index = av_index_search_timestamp(st, timestamp, flags);
    int64_t pts;

    if (index < 0)
        return -1;
    if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0)
        return -1;

    pts = st->internal->index_entries[index].timestamp;

    for (int n = 0; n < s->nb_streams; n++) {
        AVStream *st = s->streams[n];
        DHAVStream *dst = st->priv_data;

        dst->pts = pts;
        dst->last_time = AV_NOPTS_VALUE;
    }
    dhav->last_good_pos = avio_tell(s->pb);

    return 0;
}

AVInputFormat ff_dhav_demuxer = {
    .name           = "dhav",
    .long_name      = NULL_IF_CONFIG_SMALL("Video DAV"),
    .priv_data_size = sizeof(DHAVContext),
    .read_probe     = dhav_probe,
    .read_header    = dhav_read_header,
    .read_packet    = dhav_read_packet,
    .read_seek      = dhav_read_seek,
    .extensions     = "dav",
    .flags          = AVFMT_GENERIC_INDEX | AVFMT_NO_BYTE_SEEK | AVFMT_TS_DISCONT | AVFMT_TS_NONSTRICT,
};
