/*
 * Copyright (c) 2012 Andrew D'Addesio
 * Copyright (c) 2013-2014 Mozilla Corporation
 *
 * 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
 */

/**
 * @file
 * Opus decoder/parser shared code
 */

#include "libavutil/attributes.h"
#include "libavutil/channel_layout.h"
#include "libavutil/error.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"

#include "avcodec.h"
#include "internal.h"
#include "mathops.h"
#include "opus.h"
#include "opus_parse.h"
#include "vorbis_data.h"

static const uint16_t opus_frame_duration[32] = {
    480, 960, 1920, 2880,
    480, 960, 1920, 2880,
    480, 960, 1920, 2880,
    480, 960,
    480, 960,
    120, 240,  480,  960,
    120, 240,  480,  960,
    120, 240,  480,  960,
    120, 240,  480,  960,
};

/**
 * Read a 1- or 2-byte frame length
 */
static inline int xiph_lacing_16bit(const uint8_t **ptr, const uint8_t *end)
{
    int val;

    if (*ptr >= end)
        return AVERROR_INVALIDDATA;
    val = *(*ptr)++;
    if (val >= 252) {
        if (*ptr >= end)
            return AVERROR_INVALIDDATA;
        val += 4 * *(*ptr)++;
    }
    return val;
}

/**
 * Read a multi-byte length (used for code 3 packet padding size)
 */
static inline int xiph_lacing_full(const uint8_t **ptr, const uint8_t *end)
{
    int val = 0;
    int next;

    while (1) {
        if (*ptr >= end || val > INT_MAX - 254)
            return AVERROR_INVALIDDATA;
        next = *(*ptr)++;
        val += next;
        if (next < 255)
            break;
        else
            val--;
    }
    return val;
}

/**
 * Parse Opus packet info from raw packet data
 */
int ff_opus_parse_packet(OpusPacket *pkt, const uint8_t *buf, int buf_size,
                         int self_delimiting)
{
    const uint8_t *ptr = buf;
    const uint8_t *end = buf + buf_size;
    int padding = 0;
    int frame_bytes, i;

    if (buf_size < 1)
        goto fail;

    /* TOC byte */
    i = *ptr++;
    pkt->code   = (i     ) & 0x3;
    pkt->stereo = (i >> 2) & 0x1;
    pkt->config = (i >> 3) & 0x1F;

    /* code 2 and code 3 packets have at least 1 byte after the TOC */
    if (pkt->code >= 2 && buf_size < 2)
        goto fail;

    switch (pkt->code) {
    case 0:
        /* 1 frame */
        pkt->frame_count = 1;
        pkt->vbr         = 0;

        if (self_delimiting) {
            int len = xiph_lacing_16bit(&ptr, end);
            if (len < 0 || len > end - ptr)
                goto fail;
            end      = ptr + len;
            buf_size = end - buf;
        }

        frame_bytes = end - ptr;
        if (frame_bytes > OPUS_MAX_FRAME_SIZE)
            goto fail;
        pkt->frame_offset[0] = ptr - buf;
        pkt->frame_size[0]   = frame_bytes;
        break;
    case 1:
        /* 2 frames, equal size */
        pkt->frame_count = 2;
        pkt->vbr         = 0;

        if (self_delimiting) {
            int len = xiph_lacing_16bit(&ptr, end);
            if (len < 0 || 2 * len > end - ptr)
                goto fail;
            end      = ptr + 2 * len;
            buf_size = end - buf;
        }

        frame_bytes = end - ptr;
        if (frame_bytes & 1 || frame_bytes >> 1 > OPUS_MAX_FRAME_SIZE)
            goto fail;
        pkt->frame_offset[0] = ptr - buf;
        pkt->frame_size[0]   = frame_bytes >> 1;
        pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0];
        pkt->frame_size[1]   = frame_bytes >> 1;
        break;
    case 2:
        /* 2 frames, different sizes */
        pkt->frame_count = 2;
        pkt->vbr         = 1;

        /* read 1st frame size */
        frame_bytes = xiph_lacing_16bit(&ptr, end);
        if (frame_bytes < 0)
            goto fail;

        if (self_delimiting) {
            int len = xiph_lacing_16bit(&ptr, end);
            if (len < 0 || len + frame_bytes > end - ptr)
                goto fail;
            end      = ptr + frame_bytes + len;
            buf_size = end - buf;
        }

        pkt->frame_offset[0] = ptr - buf;
        pkt->frame_size[0]   = frame_bytes;

        /* calculate 2nd frame size */
        frame_bytes = end - ptr - pkt->frame_size[0];
        if (frame_bytes < 0 || frame_bytes > OPUS_MAX_FRAME_SIZE)
            goto fail;
        pkt->frame_offset[1] = pkt->frame_offset[0] + pkt->frame_size[0];
        pkt->frame_size[1]   = frame_bytes;
        break;
    case 3:
        /* 1 to 48 frames, can be different sizes */
        i = *ptr++;
        pkt->frame_count = (i     ) & 0x3F;
        padding          = (i >> 6) & 0x01;
        pkt->vbr         = (i >> 7) & 0x01;

        if (pkt->frame_count == 0 || pkt->frame_count > OPUS_MAX_FRAMES)
            goto fail;

        /* read padding size */
        if (padding) {
            padding = xiph_lacing_full(&ptr, end);
            if (padding < 0)
                goto fail;
        }

        /* read frame sizes */
        if (pkt->vbr) {
            /* for VBR, all frames except the final one have their size coded
               in the bitstream. the last frame size is implicit. */
            int total_bytes = 0;
            for (i = 0; i < pkt->frame_count - 1; i++) {
                frame_bytes = xiph_lacing_16bit(&ptr, end);
                if (frame_bytes < 0)
                    goto fail;
                pkt->frame_size[i] = frame_bytes;
                total_bytes += frame_bytes;
            }

            if (self_delimiting) {
                int len = xiph_lacing_16bit(&ptr, end);
                if (len < 0 || len + total_bytes + padding > end - ptr)
                    goto fail;
                end      = ptr + total_bytes + len + padding;
                buf_size = end - buf;
            }

            frame_bytes = end - ptr - padding;
            if (total_bytes > frame_bytes)
                goto fail;
            pkt->frame_offset[0] = ptr - buf;
            for (i = 1; i < pkt->frame_count; i++)
                pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1];
            pkt->frame_size[pkt->frame_count-1] = frame_bytes - total_bytes;
        } else {
            /* for CBR, the remaining packet bytes are divided evenly between
               the frames */
            if (self_delimiting) {
                frame_bytes = xiph_lacing_16bit(&ptr, end);
                if (frame_bytes < 0 || pkt->frame_count * frame_bytes + padding > end - ptr)
                    goto fail;
                end      = ptr + pkt->frame_count * frame_bytes + padding;
                buf_size = end - buf;
            } else {
                frame_bytes = end - ptr - padding;
                if (frame_bytes % pkt->frame_count ||
                    frame_bytes / pkt->frame_count > OPUS_MAX_FRAME_SIZE)
                    goto fail;
                frame_bytes /= pkt->frame_count;
            }

            pkt->frame_offset[0] = ptr - buf;
            pkt->frame_size[0]   = frame_bytes;
            for (i = 1; i < pkt->frame_count; i++) {
                pkt->frame_offset[i] = pkt->frame_offset[i-1] + pkt->frame_size[i-1];
                pkt->frame_size[i]   = frame_bytes;
            }
        }
    }

    pkt->packet_size = buf_size;
    pkt->data_size   = pkt->packet_size - padding;

    /* total packet duration cannot be larger than 120ms */
    pkt->frame_duration = opus_frame_duration[pkt->config];
    if (pkt->frame_duration * pkt->frame_count > OPUS_MAX_PACKET_DUR)
        goto fail;

    /* set mode and bandwidth */
    if (pkt->config < 12) {
        pkt->mode = OPUS_MODE_SILK;
        pkt->bandwidth = pkt->config >> 2;
    } else if (pkt->config < 16) {
        pkt->mode = OPUS_MODE_HYBRID;
        pkt->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND + (pkt->config >= 14);
    } else {
        pkt->mode = OPUS_MODE_CELT;
        pkt->bandwidth = (pkt->config - 16) >> 2;
        /* skip medium band */
        if (pkt->bandwidth)
            pkt->bandwidth++;
    }

    return 0;

fail:
    memset(pkt, 0, sizeof(*pkt));
    return AVERROR_INVALIDDATA;
}

static int channel_reorder_vorbis(int nb_channels, int channel_idx)
{
    return ff_vorbis_channel_layout_offsets[nb_channels - 1][channel_idx];
}

static int channel_reorder_unknown(int nb_channels, int channel_idx)
{
    return channel_idx;
}

av_cold int ff_opus_parse_extradata(AVCodecContext *avctx,
                                    OpusParseContext *s)
{
    static const uint8_t default_channel_map[2] = { 0, 1 };

    int (*channel_reorder)(int, int) = channel_reorder_unknown;
    int channels = avctx->ch_layout.nb_channels;

    const uint8_t *extradata, *channel_map;
    int extradata_size;
    int version, map_type, streams, stereo_streams, i, j, ret;
    AVChannelLayout layout = { 0 };

    if (!avctx->extradata) {
        if (channels > 2) {
            av_log(avctx, AV_LOG_ERROR,
                   "Multichannel configuration without extradata.\n");
            return AVERROR(EINVAL);
        }
        extradata      = opus_default_extradata;
        extradata_size = sizeof(opus_default_extradata);
    } else {
        extradata = avctx->extradata;
        extradata_size = avctx->extradata_size;
    }

    if (extradata_size < 19) {
        av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
               extradata_size);
        return AVERROR_INVALIDDATA;
    }

    version = extradata[8];
    if (version > 15) {
        avpriv_request_sample(avctx, "Extradata version %d", version);
        return AVERROR_PATCHWELCOME;
    }

    avctx->delay = AV_RL16(extradata + 10);
    if (avctx->internal)
        avctx->internal->skip_samples = avctx->delay;

    channels = avctx->extradata ? extradata[9] : (channels == 1) ? 1 : 2;
    if (!channels) {
        av_log(avctx, AV_LOG_ERROR, "Zero channel count specified in the extradata\n");
        return AVERROR_INVALIDDATA;
    }

    s->gain_i = AV_RL16(extradata + 16);

    map_type = extradata[18];
    if (!map_type) {
        if (channels > 2) {
            av_log(avctx, AV_LOG_ERROR,
                   "Channel mapping 0 is only specified for up to 2 channels\n");
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
        layout         = (channels == 1) ? (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO :
                                           (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
        streams        = 1;
        stereo_streams = channels - 1;
        channel_map    = default_channel_map;
    } else if (map_type == 1 || map_type == 2 || map_type == 255) {
        if (extradata_size < 21 + channels) {
            av_log(avctx, AV_LOG_ERROR, "Invalid extradata size: %d\n",
                   extradata_size);
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }

        streams        = extradata[19];
        stereo_streams = extradata[20];
        if (!streams || stereo_streams > streams ||
            streams + stereo_streams > 255) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid stream/stereo stream count: %d/%d\n", streams, stereo_streams);
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }

        if (map_type == 1) {
            if (channels > 8) {
                av_log(avctx, AV_LOG_ERROR,
                       "Channel mapping 1 is only specified for up to 8 channels\n");
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            av_channel_layout_copy(&layout, &ff_vorbis_ch_layouts[channels - 1]);
            channel_reorder = channel_reorder_vorbis;
        } else if (map_type == 2) {
            int ambisonic_order = ff_sqrt(channels) - 1;
            if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)) &&
                channels != ((ambisonic_order + 1) * (ambisonic_order + 1) + 2)) {
                av_log(avctx, AV_LOG_ERROR,
                       "Channel mapping 2 is only specified for channel counts"
                       " which can be written as (n + 1)^2 or (n + 1)^2 + 2"
                       " for nonnegative integer n\n");
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            if (channels > 227) {
                av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }

            layout.order = AV_CHANNEL_ORDER_AMBISONIC;
            layout.nb_channels = channels;
            if (channels != ((ambisonic_order + 1) * (ambisonic_order + 1)))
                layout.u.mask = AV_CH_LAYOUT_STEREO;
        } else {
            layout.order       = AV_CHANNEL_ORDER_UNSPEC;
            layout.nb_channels = channels;
        }

        channel_map = extradata + 21;
    } else {
        avpriv_request_sample(avctx, "Mapping type %d", map_type);
        return AVERROR_PATCHWELCOME;
    }

    s->channel_maps = av_calloc(channels, sizeof(*s->channel_maps));
    if (!s->channel_maps) {
        ret = AVERROR(ENOMEM);
        goto fail;
    }

    for (i = 0; i < channels; i++) {
        ChannelMap *map = &s->channel_maps[i];
        uint8_t     idx = channel_map[channel_reorder(channels, i)];

        if (idx == 255) {
            map->silence = 1;
            continue;
        } else if (idx >= streams + stereo_streams) {
            av_log(avctx, AV_LOG_ERROR,
                   "Invalid channel map for output channel %d: %d\n", i, idx);
            av_freep(&s->channel_maps);
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }

        /* check that we did not see this index yet */
        map->copy = 0;
        for (j = 0; j < i; j++)
            if (channel_map[channel_reorder(channels, j)] == idx) {
                map->copy     = 1;
                map->copy_idx = j;
                break;
            }

        if (idx < 2 * stereo_streams) {
            map->stream_idx  = idx / 2;
            map->channel_idx = idx & 1;
        } else {
            map->stream_idx  = idx - stereo_streams;
            map->channel_idx = 0;
        }
    }

    ret = av_channel_layout_copy(&avctx->ch_layout, &layout);
    if (ret < 0)
        goto fail;

    s->nb_streams         = streams;
    s->nb_stereo_streams  = stereo_streams;

    return 0;
fail:
    av_channel_layout_uninit(&layout);
    return ret;
}

