/*
 * On2 VP8 parser for Ogg
 * Copyright (C) 2013 James Almer
 *
 * 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 "avformat.h"
#include "internal.h"
#include "oggdec.h"

#define VP8_HEADER_SIZE 26

static int vp8_header(AVFormatContext *s, int idx)
{
    struct ogg *ogg = s->priv_data;
    struct ogg_stream *os = ogg->streams + idx;
    uint8_t *p = os->buf + os->pstart;
    AVStream *st = s->streams[idx];
    AVRational framerate;

    if (os->psize < 7 || p[0] != 0x4f)
        return 0;

    switch (p[5]){
    case 0x01:
        if (os->psize < VP8_HEADER_SIZE) {
            av_log(s, AV_LOG_ERROR, "Invalid OggVP8 header packet");
            return AVERROR_INVALIDDATA;
        }

        if (p[6] != 1) {
            av_log(s, AV_LOG_WARNING, "Unknown OggVP8 version %d.%d\n", p[6], p[7]);
            return AVERROR_INVALIDDATA;
        }

        st->codec->width            = AV_RB16(p +  8);
        st->codec->height           = AV_RB16(p + 10);
        st->sample_aspect_ratio.num = AV_RB24(p + 12);
        st->sample_aspect_ratio.den = AV_RB24(p + 15);
        framerate.den               = AV_RB32(p + 18);
        framerate.num               = AV_RB32(p + 22);

        avpriv_set_pts_info(st, 64, framerate.num, framerate.den);
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->codec->codec_id   = AV_CODEC_ID_VP8;
        st->need_parsing      = AVSTREAM_PARSE_HEADERS;
        break;
    case 0x02:
        if (p[6] != 0x20)
            return AVERROR_INVALIDDATA;
        ff_vorbis_comment(s, &st->metadata, p + 7, os->psize - 7);
        break;
    default:
        av_log(s, AV_LOG_ERROR, "Unknown VP8 header type 0x%02X\n", p[5]);
        return AVERROR_INVALIDDATA;
    }

    return 1;
}

static uint64_t vp8_gptopts(AVFormatContext *s, int idx, uint64_t granule, int64_t *dts)
{
    struct ogg *ogg = s->priv_data;
    struct ogg_stream *os = ogg->streams + idx;

    uint64_t pts  = (granule >> 32);
    uint32_t dist = (granule >>  3) & 0x07ffffff;

    if (!dist)
        os->pflags |= AV_PKT_FLAG_KEY;

    if (dts)
        *dts = pts;

    return pts;
}

static int vp8_packet(AVFormatContext *s, int idx)
{
    struct ogg *ogg = s->priv_data;
    struct ogg_stream *os = ogg->streams + idx;
    uint8_t *p = os->buf + os->pstart;

    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
        int seg;
        int duration;
        uint8_t *last_pkt = p;
        uint8_t *next_pkt;

        seg = os->segp;
        duration = (last_pkt[0] >> 4) & 1;
        next_pkt = last_pkt += os->psize;
        for (; seg < os->nsegs; seg++) {
            if (os->segments[seg] < 255) {
                duration += (last_pkt[0] >> 4) & 1;
                last_pkt  = next_pkt + os->segments[seg];
            }
            next_pkt += os->segments[seg];
        }
        os->lastpts = os->lastdts = vp8_gptopts(s, idx, os->granule, NULL) - duration;
        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
            s->streams[idx]->start_time = os->lastpts;
            if (s->streams[idx]->duration)
                s->streams[idx]->duration -= s->streams[idx]->start_time;
        }
    }

    if (os->psize > 0)
        os->pduration = (p[0] >> 4) & 1;

    return 0;
}

const struct ogg_codec ff_vp8_codec = {
    .magic     = "OVP80",
    .magicsize = 5,
    .header    = vp8_header,
    .packet    = vp8_packet,
    .gptopts   = vp8_gptopts,
    .nb_header = 1,
};
