/*
 * Copyright (C) 2010 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 "VBRISeeker"

#include <inttypes.h>

#include <utils/Log.h>

#include "VBRISeeker.h"

#include <media/stagefright/foundation/avc_utils.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/DataSourceBase.h>

namespace android {

static uint32_t U24_AT(const uint8_t *ptr) {
    return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
}

// static
VBRISeeker *VBRISeeker::CreateFromSource(
        DataSourceBase *source, off64_t post_id3_pos) {
    off64_t pos = post_id3_pos;

    uint8_t header[4];
    ssize_t n = source->readAt(pos, header, sizeof(header));
    if (n < (ssize_t)sizeof(header)) {
        return NULL;
    }

    uint32_t tmp = U32_AT(&header[0]);
    size_t frameSize;
    int sampleRate;
    if (!GetMPEGAudioFrameSize(tmp, &frameSize, &sampleRate)) {
        return NULL;
    }

    // VBRI header follows 32 bytes after the header _ends_.
    pos += sizeof(header) + 32;

    uint8_t vbriHeader[26];
    n = source->readAt(pos, vbriHeader, sizeof(vbriHeader));
    if (n < (ssize_t)sizeof(vbriHeader)) {
        return NULL;
    }

    if (memcmp(vbriHeader, "VBRI", 4)) {
        return NULL;
    }

    size_t numFrames = U32_AT(&vbriHeader[14]);

    int64_t durationUs =
        numFrames * 1000000LL * (sampleRate >= 32000 ? 1152 : 576) / sampleRate;

    ALOGV("duration = %.2f secs", durationUs / 1E6);

    size_t numEntries = U16_AT(&vbriHeader[18]);
    size_t entrySize = U16_AT(&vbriHeader[22]);
    size_t scale = U16_AT(&vbriHeader[20]);

    ALOGV("%zu entries, scale=%zu, size_per_entry=%zu",
         numEntries,
         scale,
         entrySize);

    if (entrySize > 4) {
        ALOGE("invalid VBRI entry size: %zu", entrySize);
        return NULL;
    }

    VBRISeeker *seeker = new (std::nothrow) VBRISeeker;
    if (seeker == NULL) {
        ALOGW("Couldn't allocate VBRISeeker");
        return NULL;
    }

    size_t totalEntrySize = numEntries * entrySize;
    uint8_t *buffer = new (std::nothrow) uint8_t[totalEntrySize];
    if (!buffer) {
        ALOGW("Couldn't allocate %zu bytes", totalEntrySize);
        delete seeker;
        return NULL;
    }

    n = source->readAt(pos + sizeof(vbriHeader), buffer, totalEntrySize);
    if (n < (ssize_t)totalEntrySize) {
        delete[] buffer;
        buffer = NULL;
        delete seeker;
        return NULL;
    }

    seeker->mBasePos = post_id3_pos + frameSize;
    // only update mDurationUs if the calculated duration is valid (non zero)
    // otherwise, leave duration at -1 so that getDuration() and getOffsetForTime()
    // return false when called, to indicate that this vbri tag does not have the
    // requested information
    if (durationUs) {
        seeker->mDurationUs = durationUs;
    }

    off64_t offset = post_id3_pos;
    for (size_t i = 0; i < numEntries; ++i) {
        uint32_t numBytes;
        switch (entrySize) {
            case 1: numBytes = buffer[i]; break;
            case 2: numBytes = U16_AT(buffer + 2 * i); break;
            case 3: numBytes = U24_AT(buffer + 3 * i); break;
            default:
            {
                CHECK_EQ(entrySize, 4u);
                numBytes = U32_AT(buffer + 4 * i); break;
            }
        }

        numBytes *= scale;

        seeker->mSegments.push(numBytes);

        ALOGV("entry #%zu: %u offset %#016llx", i, numBytes, (long long)offset);
        offset += numBytes;
    }

    delete[] buffer;
    buffer = NULL;

    ALOGI("Found VBRI header.");

    return seeker;
}

VBRISeeker::VBRISeeker()
    : mDurationUs(-1) {
}

bool VBRISeeker::getDuration(int64_t *durationUs) {
    if (mDurationUs < 0) {
        return false;
    }

    *durationUs = mDurationUs;

    return true;
}

bool VBRISeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
    if (mDurationUs < 0 || mSegments.size() == 0) {
        return false;
    }

    int64_t segmentDurationUs = mDurationUs / mSegments.size();

    int64_t nowUs = 0;
    *pos = mBasePos;
    size_t segmentIndex = 0;
    while (segmentIndex < mSegments.size() && nowUs < *timeUs) {
        nowUs += segmentDurationUs;
        *pos += mSegments.itemAt(segmentIndex++);
    }

    ALOGV("getOffsetForTime %lld us => 0x%016llx", (long long)*timeUs, (long long)*pos);

    *timeUs = nowUs;

    return true;
}

}  // namespace android

