/*
 * Opus parser for Ogg
 * Copyright (c) 2012 Nicolas George
 *
 * 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 <string.h>

#include "libavutil/intreadwrite.h"
#include "avformat.h"
#include "internal.h"
#include "oggdec.h"

struct oggopus_private {
    int need_comments;
    unsigned pre_skip;
    int64_t cur_dts;
};

#define OPUS_HEAD_SIZE 19

static int opus_header(AVFormatContext *avf, int idx)
{
    struct ogg *ogg              = avf->priv_data;
    struct ogg_stream *os        = &ogg->streams[idx];
    AVStream *st                 = avf->streams[idx];
    struct oggopus_private *priv = os->private;
    uint8_t *packet              = os->buf + os->pstart;

    if (!priv) {
        priv = os->private = av_mallocz(sizeof(*priv));
        if (!priv)
            return AVERROR(ENOMEM);
    }

    if (os->flags & OGG_FLAG_BOS) {
        if (os->psize < OPUS_HEAD_SIZE || (AV_RL8(packet + 8) & 0xF0) != 0)
            return AVERROR_INVALIDDATA;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id   = AV_CODEC_ID_OPUS;
        st->codec->channels   = AV_RL8 (packet + 9);
        priv->pre_skip        = AV_RL16(packet + 10);
        /*orig_sample_rate    = AV_RL32(packet + 12);*/
        /*gain                = AV_RL16(packet + 16);*/
        /*channel_map         = AV_RL8 (packet + 18);*/

        if (ff_alloc_extradata(st->codec, os->psize))
            return AVERROR(ENOMEM);

        memcpy(st->codec->extradata, packet, os->psize);

        st->codec->sample_rate = 48000;
        avpriv_set_pts_info(st, 64, 1, 48000);
        priv->need_comments = 1;
        return 1;
    }

    if (priv->need_comments) {
        if (os->psize < 8 || memcmp(packet, "OpusTags", 8))
            return AVERROR_INVALIDDATA;
        ff_vorbis_comment(avf, &st->metadata, packet + 8, os->psize - 8);
        priv->need_comments--;
        return 1;
    }

    return 0;
}

static int opus_duration(uint8_t *src, int size)
{
    unsigned nb_frames  = 1;
    unsigned toc        = src[0];
    unsigned toc_config = toc >> 3;
    unsigned toc_count  = toc & 3;
    unsigned frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) :
                          toc_config < 16 ? 480 << (toc_config & 1) :
                                            120 << (toc_config & 3);
    if (toc_count == 3) {
        if (size<2)
            return AVERROR_INVALIDDATA;
        nb_frames = src[1] & 0x3F;
    } else if (toc_count) {
        nb_frames = 2;
    }

    return frame_size * nb_frames;
}

static int opus_packet(AVFormatContext *avf, int idx)
{
    struct ogg *ogg              = avf->priv_data;
    struct ogg_stream *os        = &ogg->streams[idx];
    AVStream *st                 = avf->streams[idx];
    struct oggopus_private *priv = os->private;
    uint8_t *packet              = os->buf + os->pstart;
    int ret;

    if (!os->psize)
        return AVERROR_INVALIDDATA;

    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
        int seg, d;
        int duration;
        uint8_t *last_pkt  = os->buf + os->pstart;
        uint8_t *next_pkt  = last_pkt;

        duration = 0;
        seg = os->segp;
        d = opus_duration(last_pkt, os->psize);
        if (d < 0) {
            os->pflags |= AV_PKT_FLAG_CORRUPT;
            return 0;
        }
        duration += d;
        last_pkt = next_pkt =  next_pkt + os->psize;
        for (; seg < os->nsegs; seg++) {
            if (os->segments[seg] < 255) {
                int d = opus_duration(last_pkt, os->segments[seg]);
                if (d < 0) {
                    duration = os->granule;
                    break;
                }
                duration += d;
                last_pkt  = next_pkt + os->segments[seg];
            }
            next_pkt += os->segments[seg];
        }
        os->lastpts                 =
        os->lastdts                 = os->granule - duration;
    }

    if ((ret = opus_duration(packet, os->psize)) < 0)
        return ret;

    os->pduration = ret;
    if (os->lastpts != AV_NOPTS_VALUE) {
        if (st->start_time == AV_NOPTS_VALUE)
            st->start_time = os->lastpts;
        priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip;
    }

    priv->cur_dts += os->pduration;
    if ((os->flags & OGG_FLAG_EOS)) {
        int64_t skip = priv->cur_dts - os->granule + priv->pre_skip;
        skip = FFMIN(skip, os->pduration);
        if (skip > 0) {
            os->pduration = skip < os->pduration ? os->pduration - skip : 1;
            os->end_trimming = skip;
            av_log(avf, AV_LOG_DEBUG,
                   "Last packet was truncated to %d due to end trimming.\n",
                   os->pduration);
        }
    }

    return 0;
}

const struct ogg_codec ff_opus_codec = {
    .name             = "Opus",
    .magic            = "OpusHead",
    .magicsize        = 8,
    .header           = opus_header,
    .packet           = opus_packet,
    .nb_header        = 1,
};
