/*
 * Ogg bitstream support
 * Luca Barbato <lu_zero@gentoo.org>
 * Based on tcvp implementation
 *
 */

/**
    Copyright (C) 2005  Michael Ahlberg, Måns Rullgård

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use, copy,
    modify, merge, publish, distribute, sublicense, and/or sell copies
    of the Software, and to permit persons to whom the Software is
    furnished to do so, subject to the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
    DEALINGS IN THE SOFTWARE.
**/


#include <stdio.h>
#include "oggdec.h"
#include "avformat.h"

#define MAX_PAGE_SIZE 65307
#define DECODER_BUFFER_SIZE MAX_PAGE_SIZE

static const struct ogg_codec * const ogg_codecs[] = {
    &ff_speex_codec,
    &ff_vorbis_codec,
    &ff_theora_codec,
    &ff_flac_codec,
    &ff_old_flac_codec,
    &ff_ogm_video_codec,
    &ff_ogm_audio_codec,
    &ff_ogm_text_codec,
    &ff_ogm_old_codec,
    NULL
};

//FIXME We could avoid some structure duplication
static int
ogg_save (AVFormatContext * s)
{
    struct ogg *ogg = s->priv_data;
    struct ogg_state *ost =
        av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
    int i;
    ost->pos = url_ftell (s->pb);
    ost->curidx = ogg->curidx;
    ost->next = ogg->state;
    ost->nstreams = ogg->nstreams;
    memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));

    for (i = 0; i < ogg->nstreams; i++){
        struct ogg_stream *os = ogg->streams + i;
        os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
        memcpy (os->buf, ost->streams[i].buf, os->bufpos);
    }

    ogg->state = ost;

    return 0;
}

static int
ogg_restore (AVFormatContext * s, int discard)
{
    struct ogg *ogg = s->priv_data;
    ByteIOContext *bc = s->pb;
    struct ogg_state *ost = ogg->state;
    int i;

    if (!ost)
        return 0;

    ogg->state = ost->next;

    if (!discard){
        struct ogg_stream *old_streams = ogg->streams;

        for (i = 0; i < ogg->nstreams; i++)
            av_free (ogg->streams[i].buf);

        url_fseek (bc, ost->pos, SEEK_SET);
        ogg->curidx = ost->curidx;
        ogg->nstreams = ost->nstreams;
        ogg->streams = av_realloc (ogg->streams,
                                   ogg->nstreams * sizeof (*ogg->streams));

        if (ogg->streams) {
        memcpy(ogg->streams, ost->streams,
               ost->nstreams * sizeof(*ogg->streams));
        } else {
            av_free(old_streams);
            ogg->nstreams = 0;
        }
    }

    av_free (ost);

    return 0;
}

static int
ogg_reset (struct ogg * ogg)
{
    int i;

    for (i = 0; i < ogg->nstreams; i++){
        struct ogg_stream *os = ogg->streams + i;
        os->bufpos = 0;
        os->pstart = 0;
        os->psize = 0;
        os->granule = -1;
        os->lastgp = -1;
        os->nsegs = 0;
        os->segp = 0;
    }

    ogg->curidx = -1;

    return 0;
}

static const struct ogg_codec *
ogg_find_codec (uint8_t * buf, int size)
{
    int i;

    for (i = 0; ogg_codecs[i]; i++)
        if (size >= ogg_codecs[i]->magicsize &&
            !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
            return ogg_codecs[i];

    return NULL;
}

static int
ogg_find_stream (struct ogg * ogg, int serial)
{
    int i;

    for (i = 0; i < ogg->nstreams; i++)
        if (ogg->streams[i].serial == serial)
            return i;

    return -1;
}

static int
ogg_new_stream (AVFormatContext * s, uint32_t serial)
{

    struct ogg *ogg = s->priv_data;
    int idx = ogg->nstreams++;
    AVStream *st;
    struct ogg_stream *os;

    os = av_realloc (ogg->streams, ogg->nstreams * sizeof (*ogg->streams));

    if (!os)
        return AVERROR(ENOMEM);

    ogg->streams = os;

    memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
    os = ogg->streams + idx;
    os->serial = serial;
    os->bufsize = DECODER_BUFFER_SIZE;
    os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
    os->header = -1;

    st = av_new_stream (s, idx);
    if (!st)
        return AVERROR(ENOMEM);

    av_set_pts_info(st, 64, 1, 1000000);

    return idx;
}

static int
ogg_new_buf(struct ogg *ogg, int idx)
{
    struct ogg_stream *os = ogg->streams + idx;
    uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
    int size = os->bufpos - os->pstart;
    if(os->buf){
        memcpy(nb, os->buf + os->pstart, size);
        av_free(os->buf);
    }
    os->buf = nb;
    os->bufpos = size;
    os->pstart = 0;

    return 0;
}

static int
ogg_read_page (AVFormatContext * s, int *str)
{
    ByteIOContext *bc = s->pb;
    struct ogg *ogg = s->priv_data;
    struct ogg_stream *os;
    int i = 0;
    int flags, nsegs;
    uint64_t gp;
    uint32_t serial;
    uint32_t seq;
    uint32_t crc;
    int size, idx;
    uint8_t sync[4];
    int sp = 0;

    if (get_buffer (bc, sync, 4) < 4)
        return -1;

    do{
        int c;

        if (sync[sp & 3] == 'O' &&
            sync[(sp + 1) & 3] == 'g' &&
            sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
            break;

        c = url_fgetc (bc);
        if (c < 0)
            return -1;
        sync[sp++ & 3] = c;
    }while (i++ < MAX_PAGE_SIZE);

    if (i >= MAX_PAGE_SIZE){
        av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
        return -1;
    }

    if (url_fgetc (bc) != 0)      /* version */
        return -1;

    flags = url_fgetc (bc);
    gp = get_le64 (bc);
    serial = get_le32 (bc);
    seq = get_le32 (bc);
    crc = get_le32 (bc);
    nsegs = url_fgetc (bc);

    idx = ogg_find_stream (ogg, serial);
    if (idx < 0){
        idx = ogg_new_stream (s, serial);
        if (idx < 0)
            return -1;
    }

    os = ogg->streams + idx;

    if(os->psize > 0)
        ogg_new_buf(ogg, idx);

    if (get_buffer (bc, os->segments, nsegs) < nsegs)
        return -1;

    os->nsegs = nsegs;
    os->segp = 0;

    size = 0;
    for (i = 0; i < nsegs; i++)
        size += os->segments[i];

    if (flags & OGG_FLAG_CONT){
        if (!os->psize){
            while (os->segp < os->nsegs){
                int seg = os->segments[os->segp++];
                os->pstart += seg;
                if (seg < 255)
                    break;
            }
        }
    }else{
        os->psize = 0;
        os->pstart = 0;
        os->bufpos = 0;
    }

    if (os->bufsize - os->bufpos < size){
        uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!nb)
            return AVERROR(ENOMEM);
        memcpy (nb, os->buf, os->bufpos);
        av_free (os->buf);
        os->buf = nb;
    }

    if (get_buffer (bc, os->buf + os->bufpos, size) < size)
        return -1;

    os->lastgp = os->granule;
    os->bufpos += size;
    os->granule = gp;
    os->flags = flags;

    memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
    if (str)
        *str = idx;

    return 0;
}

static int
ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
{
    struct ogg *ogg = s->priv_data;
    int idx;
    struct ogg_stream *os;
    int complete = 0;
    int segp = 0, psize = 0;

#if 0
    av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
#endif

    do{
        idx = ogg->curidx;

        while (idx < 0){
            if (ogg_read_page (s, &idx) < 0)
                return -1;
        }

        os = ogg->streams + idx;

#if 0
        av_log (s, AV_LOG_DEBUG,
                "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
                idx, os->pstart, os->psize, os->segp, os->nsegs);
#endif

        if (!os->codec){
            if (os->header < 0){
                os->codec = ogg_find_codec (os->buf, os->bufpos);
                if (!os->codec){
                    os->header = 0;
                    return 0;
                }
            }else{
                return 0;
            }
        }

        segp = os->segp;
        psize = os->psize;

        while (os->segp < os->nsegs){
            int ss = os->segments[os->segp++];
            os->psize += ss;
            if (ss < 255){
                complete = 1;
                break;
            }
        }

        if (!complete && os->segp == os->nsegs){
            ogg->curidx = -1;
        }
    }while (!complete);

#if 0
    av_log (s, AV_LOG_DEBUG,
            "ogg_packet: idx %i, frame size %i, start %i\n",
            idx, os->psize, os->pstart);
#endif

    ogg->curidx = idx;

    if (os->header < 0){
        int hdr = os->codec->header (s, idx);
        if (!hdr){
            os->header = os->seq;
            os->segp = segp;
            os->psize = psize;
            ogg->headers = 1;
        }else{
            os->pstart += os->psize;
            os->psize = 0;
        }
    }

    if (os->header > -1 && os->seq > os->header){
        os->pflags = 0;
        if (os->codec && os->codec->packet)
            os->codec->packet (s, idx);
        if (str)
            *str = idx;
        if (dstart)
            *dstart = os->pstart;
        if (dsize)
            *dsize = os->psize;
        os->pstart += os->psize;
        os->psize = 0;
    }

    os->seq++;
    if (os->segp == os->nsegs)
        ogg->curidx = -1;

    return 0;
}

static int
ogg_get_headers (AVFormatContext * s)
{
    struct ogg *ogg = s->priv_data;

    do{
        if (ogg_packet (s, NULL, NULL, NULL) < 0)
            return -1;
    }while (!ogg->headers);

#if 0
    av_log (s, AV_LOG_DEBUG, "found headers\n");
#endif

    return 0;
}

static uint64_t
ogg_gptopts (AVFormatContext * s, int i, uint64_t gp)
{
    struct ogg *ogg = s->priv_data;
    struct ogg_stream *os = ogg->streams + i;
    uint64_t pts = AV_NOPTS_VALUE;

    if(os->codec->gptopts){
        pts = os->codec->gptopts(s, i, gp);
    } else {
        pts = gp;
    }

    return pts;
}


static int
ogg_get_length (AVFormatContext * s)
{
    struct ogg *ogg = s->priv_data;
    int idx = -1, i;
    int64_t size, end;

    if(url_is_streamed(s->pb))
        return 0;

// already set
    if (s->duration != AV_NOPTS_VALUE)
        return 0;

    size = url_fsize(s->pb);
    if(size < 0)
        return 0;
    end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size;

    ogg_save (s);
    url_fseek (s->pb, end, SEEK_SET);

    while (!ogg_read_page (s, &i)){
		// NARFLEX: SageTV, I added the '&& !i' to this conditional so it took the first stream.
		// I had test files that this fixed a duration detection problem on.
        if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
            ogg->streams[i].codec && !i)
            idx = i;
    }

    if (idx != -1){
        s->streams[idx]->duration =
            ogg_gptopts (s, idx, ogg->streams[idx].granule);
    }

    ogg->size = size;
    ogg_restore (s, 0);

    return 0;
}


static int
ogg_read_header (AVFormatContext * s, AVFormatParameters * ap)
{
    struct ogg *ogg = s->priv_data;
    ogg->curidx = -1;
    //linear headers seek from start
    if (ogg_get_headers (s) < 0){
        return -1;
    }

    //linear granulepos seek from end
    ogg_get_length (s);

    //fill the extradata in the per codec callbacks
    return 0;
}


static int
ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
{
    struct ogg *ogg;
    struct ogg_stream *os;
    int idx = -1;
    int pstart, psize;

    //Get an ogg packet
    do{
        if (ogg_packet (s, &idx, &pstart, &psize) < 0)
            return AVERROR(EIO);
    }while (idx < 0 || !s->streams[idx]);

    ogg = s->priv_data;
    os = ogg->streams + idx;

    //Alloc a pkt
    if (av_new_packet (pkt, psize) < 0)
        return AVERROR(EIO);
    pkt->stream_index = idx;
    memcpy (pkt->data, os->buf + pstart, psize);
    if (os->lastgp != -1LL){
        pkt->pts = ogg_gptopts (s, idx, os->lastgp);
        os->lastgp = -1;
    }

    pkt->flags = os->pflags;

    return psize;
}


static int
ogg_read_close (AVFormatContext * s)
{
    struct ogg *ogg = s->priv_data;
    int i;

    for (i = 0; i < ogg->nstreams; i++){
        av_free (ogg->streams[i].buf);
        av_free (ogg->streams[i].private);
    }
    av_free (ogg->streams);
    return 0;
}


static int64_t
ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg,
                    int64_t pos_limit)
{
    struct ogg *ogg = s->priv_data;
    ByteIOContext *bc = s->pb;
    int64_t pts = AV_NOPTS_VALUE;
    int i;
    url_fseek(bc, *pos_arg, SEEK_SET);
    while (url_ftell(bc) < pos_limit && !ogg_read_page (s, &i)) {
        if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
            ogg->streams[i].codec && i == stream_index) {
            pts = ogg_gptopts(s, i, ogg->streams[i].granule);
            // FIXME: this is the position of the packet after the one with above
            // pts.
            *pos_arg = url_ftell(bc);
            break;
        }
    }
    ogg_reset(ogg);
    return pts;
}

static int ogg_probe(AVProbeData *p)
{
    if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
        p->buf[2] == 'g' && p->buf[3] == 'S' &&
        p->buf[4] == 0x0 && p->buf[5] <= 0x7 )
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}

AVInputFormat ogg_demuxer = {
    "ogg",
    NULL_IF_CONFIG_SMALL("Ogg"),
    sizeof (struct ogg),
    ogg_probe,
    ogg_read_header,
    ogg_read_packet,
    ogg_read_close,
    NULL,
    ogg_read_timestamp,
    .extensions = "ogg",
};
