/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//#define LOG_NDEBUG 0
#define LOG_TAG "OpusHeader"
#include <cstring>
#include <inttypes.h>
#include <stdint.h>

#include <log/log.h>

#include "OpusHeader.h"

namespace android {

// Opus uses Vorbis channel mapping, and Vorbis channel mapping specifies
// mappings for up to 8 channels. This information is part of the Vorbis I
// Specification:
// http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html
constexpr int kMaxChannels = 8;

constexpr uint8_t kOpusChannelMap[kMaxChannels][kMaxChannels] = {
        {0},
        {0, 1},
        {0, 2, 1},
        {0, 1, 2, 3},
        {0, 4, 1, 2, 3},
        {0, 4, 1, 2, 3, 5},
        {0, 4, 1, 2, 3, 5, 6},
        {0, 6, 1, 2, 3, 4, 5, 7},
};

// Size of the Opus header excluding optional mapping information.
constexpr size_t kOpusHeaderSize = 19;
// Offset to magic string that starts Opus header.
constexpr size_t kOpusHeaderLabelOffset = 0;
// Offset to Opus version in the Opus header.
constexpr size_t kOpusHeaderVersionOffset = 8;
// Offset to the channel count byte in the Opus header.
constexpr size_t kOpusHeaderChannelsOffset = 9;
// Offset to the pre-skip value in the Opus header.
constexpr size_t kOpusHeaderSkipSamplesOffset = 10;
// Offset to sample rate in the Opus header.
constexpr size_t kOpusHeaderSampleRateOffset = 12;
// Offset to the gain value in the Opus header.
constexpr size_t kOpusHeaderGainOffset = 16;
// Offset to the channel mapping byte in the Opus header.
constexpr size_t kOpusHeaderChannelMappingOffset = 18;
// Opus Header contains a stream map. The mapping values are in the header
// beyond the always present |kOpusHeaderSize| bytes of data. The mapping
// data contains stream count, coupling information, and per channel mapping
// values:
//   - Byte 0: Number of streams.
//   - Byte 1: Number coupled.
//   - Byte 2: Starting at byte 2 are |header->channels| uint8 mapping
//             values.
// Offset to the number of streams in the Opus header.
constexpr size_t kOpusHeaderNumStreamsOffset = 19;
// Offset to the number of streams that are coupled in the Opus header.
constexpr size_t kOpusHeaderNumCoupledStreamsOffset = 20;
// Offset to the stream to channel mapping in the Opus header.
constexpr size_t kOpusHeaderStreamMapOffset = 21;

// Default audio output channel layout. Used to initialize |stream_map| in
// OpusHeader, and passed to opus_multistream_decoder_create() when the header
// does not contain mapping information. The values are valid only for mono and
// stereo output: Opus streams with more than 2 channels require a stream map.
constexpr int kMaxChannelsWithDefaultLayout = 2;

static uint16_t ReadLE16(const uint8_t* data, size_t data_size, uint32_t read_offset) {
    // check whether the 2nd byte is within the buffer
    if (read_offset + 1 >= data_size) return 0;
    uint16_t val;
    val = data[read_offset];
    val |= data[read_offset + 1] << 8;
    return val;
}

// Parses Opus Header. Header spec: http://wiki.xiph.org/OggOpus#ID_Header
bool ParseOpusHeader(const uint8_t* data, size_t data_size, OpusHeader* header) {
    if (data == NULL) {
        return false;
    }
    if (data_size < kOpusHeaderSize) {
        ALOGV("Header size is too small.");
        return false;
    }
    header->channels = data[kOpusHeaderChannelsOffset];

    if (header->channels < 1 || header->channels > kMaxChannels) {
        ALOGV("Invalid Header, bad channel count: %d", header->channels);
        return false;
    }
    header->skip_samples = ReadLE16(data, data_size, kOpusHeaderSkipSamplesOffset);
    header->gain_db = static_cast<int16_t>(ReadLE16(data, data_size, kOpusHeaderGainOffset));
    header->channel_mapping = data[kOpusHeaderChannelMappingOffset];
    if (!header->channel_mapping) {
        if (header->channels > kMaxChannelsWithDefaultLayout) {
            ALOGV("Invalid Header, missing stream map.");
            return false;
        }
        header->num_streams = 1;
        header->num_coupled = header->channels > 1;
        header->stream_map[0] = 0;
        header->stream_map[1] = 1;
        return true;
    }
    if (data_size < kOpusHeaderStreamMapOffset + header->channels) {
        ALOGV("Invalid stream map; insufficient data for current channel "
              "count: %d",
              header->channels);
        return false;
    }
    header->num_streams = data[kOpusHeaderNumStreamsOffset];
    header->num_coupled = data[kOpusHeaderNumCoupledStreamsOffset];
    if (header->num_coupled > header->num_streams ||
        header->num_streams + header->num_coupled != header->channels) {
        ALOGV("Inconsistent channel mapping, streams: %d coupled: %d channels: %d",
        header->num_streams, header->num_coupled, header->channels);
        return false;
    }
    for (int i = 0; i < header->channels; ++i) {
        uint8_t value = data[kOpusHeaderStreamMapOffset + i];
        if (value != 255 && value >= header->channels) {
            ALOGV("Invalid channel mapping for index %i : %d", i, value);
            return false;
        }
        header->stream_map[i] = value;
    }
    return true;
}

int WriteOpusHeader(const OpusHeader &header, int input_sample_rate,
                    uint8_t* output, size_t output_size) {
    // See https://wiki.xiph.org/OggOpus#ID_Header.
    if (header.channels < 1 || header.channels > kMaxChannels) {
        ALOGE("Invalid channel count: %d", header.channels);
        return -1;
    }
    const size_t total_size = kOpusHeaderStreamMapOffset + header.channels;
    if (output_size < total_size) {
        ALOGE("Output buffer too small for header.");
        return -1;
    }

    // ensure entire header is cleared, even though we overwrite much of it below
    memset(output, 0, output_size);

    // Set magic signature.
    memcpy(output + kOpusHeaderLabelOffset, "OpusHead", 8);
    // Set Opus version.
    output[kOpusHeaderVersionOffset] = 1;
    // Set channel count.
    output[kOpusHeaderChannelsOffset] = (uint8_t)header.channels;
    // Set pre-skip
    memcpy(output + kOpusHeaderSkipSamplesOffset, &header.skip_samples, sizeof(uint16_t));
    // Set original input sample rate in Hz.
    memcpy(output + kOpusHeaderSampleRateOffset, &input_sample_rate, sizeof(uint32_t));
    // Set output gain in dB.
    memcpy(output + kOpusHeaderGainOffset, &header.gain_db, sizeof(uint16_t));

    if (header.channels > 2) {
        // Set channel mapping
        output[kOpusHeaderChannelMappingOffset] = 1;
        // Assuming no coupled streams. This should actually be
        // channels() - |coupled_streams|.
        output[kOpusHeaderNumStreamsOffset] = header.channels;
        output[kOpusHeaderNumCoupledStreamsOffset] = 0;

        // Set the actual stream map.
        for (int i = 0; i < header.channels; ++i) {
            output[kOpusHeaderStreamMapOffset + i] = kOpusChannelMap[header.channels - 1][i];
        }
        return kOpusHeaderStreamMapOffset + header.channels + 1;
    } else {
        output[kOpusHeaderChannelMappingOffset] = 0;
        return kOpusHeaderChannelMappingOffset + 1;
    }
}

int WriteOpusHeaders(const OpusHeader &header, int inputSampleRate,
                     uint8_t* output, size_t outputSize, uint64_t codecDelay,
                     uint64_t seekPreRoll) {
    if (outputSize < AOPUS_UNIFIED_CSD_MINSIZE) {
        ALOGD("Buffer not large enough to hold unified OPUS CSD");
        return -1;
    }
    int headerLen = 0;

    // Add opus header
    /*
      Following is the CSD syntax for signalling OpusHeader
      (http://wiki.xiph.org/OggOpus#ID_Header)

      Marker (8 bytes) | Length (8 bytes) | OpusHeader

      Markers supported:
      AOPUS_CSD_OPUS_HEADER_MARKER - Signals Opus Header

      Length should be a value within AOPUS_OPUSHEAD_MINSIZE and AOPUS_OPUSHEAD_MAXSIZE.
    */

    memcpy(output + headerLen, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE);
    headerLen += AOPUS_MARKER_SIZE;

    // Place holder for opusHeader Size
    headerLen += AOPUS_LENGTH_SIZE;

    int headerSize = WriteOpusHeader(header, inputSampleRate, output + headerLen,
        outputSize - headerLen);
    if (headerSize < 0) {
        ALOGD("%s: WriteOpusHeader failed", __func__);
        return -1;
    }
    headerLen += headerSize;

    // Update opus headerSize after AOPUS_CSD_OPUS_HEADER_MARKER
    uint64_t length = headerSize;
    memcpy(output + AOPUS_MARKER_SIZE, &length, AOPUS_LENGTH_SIZE);

    /*
      Following is the CSD syntax for signalling codec delay and
      seek pre-roll which is to be appended after OpusHeader

      Marker (8 bytes) | Length (8 bytes) | Samples in ns (8 bytes)

      Markers supported:
      AOPUS_CSD_CODEC_DELAY_MARKER - codec delay as samples in ns, represented in 8 bytes
      AOPUS_CSD_SEEK_PREROLL_MARKER - preroll adjustment as samples in ns, represented in 8 bytes

    */
    length = sizeof(codecDelay);
    if (headerLen > (outputSize - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE - length)) {
        ALOGD("Buffer not large enough to hold codec delay");
        return -1;
    }
    // Add codec delay
    memcpy(output + headerLen, AOPUS_CSD_CODEC_DELAY_MARKER, AOPUS_MARKER_SIZE);
    headerLen += AOPUS_MARKER_SIZE;
    memcpy(output + headerLen, &length, AOPUS_LENGTH_SIZE);
    headerLen += AOPUS_LENGTH_SIZE;
    memcpy(output + headerLen, &codecDelay, length);
    headerLen += length;

    length = sizeof(seekPreRoll);
    if (headerLen > (outputSize - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE - length)) {
        ALOGD("Buffer not large enough to hold seek pre roll");
        return -1;
    }
    // Add skip pre roll
    memcpy(output + headerLen, AOPUS_CSD_SEEK_PREROLL_MARKER, AOPUS_MARKER_SIZE);
    headerLen += AOPUS_MARKER_SIZE;
    memcpy(output + headerLen, &length, AOPUS_LENGTH_SIZE);
    headerLen += AOPUS_LENGTH_SIZE;
    memcpy(output + headerLen, &seekPreRoll, length);
    headerLen += length;

    return headerLen;
}

bool IsOpusHeader(const uint8_t *data, size_t data_size) {
    if (data_size < AOPUS_MARKER_SIZE) {
        return false;
    }

    return !memcmp(data, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE);
}

bool GetOpusHeaderBuffers(const uint8_t *data, size_t data_size,
                          void **opusHeadBuf, size_t *opusHeadSize,
                          void **codecDelayBuf, size_t *codecDelaySize,
                          void **seekPreRollBuf, size_t *seekPreRollSize) {
    *codecDelayBuf = NULL;
    *codecDelaySize = 0;
    *seekPreRollBuf = NULL;
    *seekPreRollSize = 0;
    *opusHeadBuf = NULL;
    *opusHeadSize = 0;

    // AOPUS_MARKER_SIZE is 8 "OpusHead" is of size 8
    if (data_size < 8)
        return false;

    // Check if the CSD is in legacy format
    if (!memcmp("OpusHead", data, 8)) {
        if (data_size < AOPUS_OPUSHEAD_MINSIZE || data_size > AOPUS_OPUSHEAD_MAXSIZE) {
            ALOGD("Unexpected size for opusHeadSize %zu", data_size);
            return false;
        }
        *opusHeadBuf = (void *)data;
        *opusHeadSize = data_size;
        return true;
    } else if (memcmp(AOPUS_CSD_MARKER_PREFIX, data, AOPUS_CSD_MARKER_PREFIX_SIZE) == 0) {
        if (data_size < AOPUS_UNIFIED_CSD_MINSIZE || data_size > AOPUS_UNIFIED_CSD_MAXSIZE) {
            ALOGD("Unexpected size for unified opus csd %zu", data_size);
            return false;
        }
        size_t i = 0;
        bool found = false;
        while (i <= data_size - AOPUS_MARKER_SIZE - AOPUS_LENGTH_SIZE) {
            uint8_t *csdBuf = (uint8_t *)data + i;
            if (!memcmp(csdBuf, AOPUS_CSD_OPUS_HEADER_MARKER, AOPUS_MARKER_SIZE)) {
                uint64_t value;
                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
                if (value < AOPUS_OPUSHEAD_MINSIZE || value > AOPUS_OPUSHEAD_MAXSIZE) {
                    ALOGD("Unexpected size for opusHeadSize %" PRIu64, value);
                    return false;
                }
                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
                if (i > data_size) {
                    ALOGD("Marker signals a header that is larger than input");
                    return false;
                }
                *opusHeadBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
                *opusHeadSize = value;
                found = true;
            } else if (!memcmp(csdBuf, AOPUS_CSD_CODEC_DELAY_MARKER, AOPUS_MARKER_SIZE)) {
                uint64_t value;
                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
                if (value != sizeof(uint64_t)) {
                    ALOGD("Unexpected size for codecDelay %" PRIu64, value);
                    return false;
                }
                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
                if (i > data_size) {
                    ALOGD("Marker signals a header that is larger than input");
                    return false;
                }
                *codecDelayBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
                *codecDelaySize = value;
            } else if (!memcmp(csdBuf, AOPUS_CSD_SEEK_PREROLL_MARKER, AOPUS_MARKER_SIZE)) {
                uint64_t value;
                memcpy(&value, csdBuf + AOPUS_MARKER_SIZE, sizeof(value));
                if (value != sizeof(uint64_t)) {
                    ALOGD("Unexpected size for seekPreRollSize %" PRIu64, value);
                    return false;
                }
                i += AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE + value;
                if (i > data_size) {
                    ALOGD("Marker signals a header that is larger than input");
                    return false;
                }
                *seekPreRollBuf = csdBuf + AOPUS_MARKER_SIZE + AOPUS_LENGTH_SIZE;
                *seekPreRollSize = value;
            } else {
                i++;
            }
        }
        return found;
    } else {
        return false;  // it isn't in either format
    }
}

}  // namespace android
