/*
 * 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 <stdint.h>

#include "libavutil/error.h"
#include "libavutil/ffmath.h"

#include "opus.h"
#include "vorbis.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 > 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 > 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 > 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 > 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 > 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 > 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,
                                    OpusContext *s)
{
    static const uint8_t default_channel_map[2] = { 0, 1 };

    int (*channel_reorder)(int, int) = channel_reorder_unknown;

    const uint8_t *extradata, *channel_map;
    int extradata_size;
    int version, channels, map_type, streams, stereo_streams, i, j;
    uint64_t layout;

    if (!avctx->extradata) {
        if (avctx->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);

    channels = avctx->extradata ? extradata[9] : (avctx->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);
    if (s->gain_i)
        s->gain = ff_exp10(s->gain_i / (20.0 * 256));

    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");
            return AVERROR_INVALIDDATA;
        }
        layout         = (channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_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);
            return AVERROR_INVALIDDATA;
        }

        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);
            return AVERROR_INVALIDDATA;
        }

        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");
                return AVERROR_INVALIDDATA;
            }
            layout = ff_vorbis_channel_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)) {
                av_log(avctx, AV_LOG_ERROR,
                       "Channel mapping 2 is only specified for channel counts"
                       " which can be written as (n + 1)^2 for nonnegative integer n\n");
                return AVERROR_INVALIDDATA;
            }
            layout = 0;
        } else
            layout = 0;

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

    s->channel_maps = av_mallocz_array(channels, sizeof(*s->channel_maps));
    if (!s->channel_maps)
        return AVERROR(ENOMEM);

    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);
            return AVERROR_INVALIDDATA;
        }

        /* 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;
        }
    }

    avctx->channels       = channels;
    avctx->channel_layout = layout;
    s->nb_streams         = streams;
    s->nb_stereo_streams  = stereo_streams;

    return 0;
}
