/*
 * 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 "include/VBRISeeker.h"

#include "include/avc_utils.h"
#include "include/MP3Extractor.h"

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/Utils.h>

namespace android {

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

// static
sp<VBRISeeker> VBRISeeker::CreateFromSource(
        const sp<DataSource> &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;
    }

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

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

        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

