/*
 * Copyright 2012, 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 "NuMediaExtractor"
#include <utils/Log.h>

#include <media/stagefright/NuMediaExtractor.h>

#include <media/esds/ESDS.h>

#include <datasource/DataSourceFactory.h>
#include <datasource/FileSource.h>
#include <media/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaExtractor.h>
#include <media/stagefright/MediaExtractorFactory.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
#include <media/stagefright/FoundationUtils.h>

namespace android {

NuMediaExtractor::Sample::Sample()
    : mBuffer(NULL),
      mSampleTimeUs(-1LL) {
}

NuMediaExtractor::Sample::Sample(MediaBufferBase *buffer, int64_t timeUs)
    : mBuffer(buffer),
      mSampleTimeUs(timeUs) {
}

NuMediaExtractor::NuMediaExtractor(EntryPoint entryPoint)
    : mEntryPoint(entryPoint),
      mTotalBitrate(-1LL),
      mDurationUs(-1LL) {
}

NuMediaExtractor::~NuMediaExtractor() {
    releaseAllTrackSamples();

    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
        TrackInfo *info = &mSelectedTracks.editItemAt(i);

        status_t err = info->mSource->stop();
        ALOGE_IF(err != OK, "error %d stopping track %zu", err, i);
    }

    mSelectedTracks.clear();
    if (mDataSource != NULL) {
        mDataSource->close();
    }
}

status_t NuMediaExtractor::initMediaExtractor(const sp<DataSource>& dataSource) {
    status_t err = OK;

    mImpl = MediaExtractorFactory::Create(dataSource);
    if (mImpl == NULL) {
        ALOGE("%s: failed to create MediaExtractor", __FUNCTION__);
        return ERROR_UNSUPPORTED;
    }

    setEntryPointToRemoteMediaExtractor();

    if (!mCasToken.empty()) {
        err = mImpl->setMediaCas(mCasToken);
        if (err != OK) {
            ALOGE("%s: failed to setMediaCas (%d)", __FUNCTION__, err);
            return err;
        }
    }

    // Get the name of the implementation.
    mName = mImpl->name();

    // Update the duration and bitrate
    err = updateDurationAndBitrate();
    if (err == OK) {
        mDataSource = dataSource;
    }

    return OK;
}

status_t NuMediaExtractor::setDataSource(
        const sp<MediaHTTPService> &httpService,
        const char *path,
        const KeyedVector<String8, String8> *headers) {
    Mutex::Autolock autoLock(mLock);

    if (mImpl != NULL || path == NULL) {
        return -EINVAL;
    }

    sp<DataSource> dataSource =
        DataSourceFactory::getInstance()->CreateFromURI(httpService, path, headers);

    if (dataSource == NULL) {
        return -ENOENT;
    }

    // Initialize MediaExtractor using the data source
    return initMediaExtractor(dataSource);
}

status_t NuMediaExtractor::setDataSource(int fd, off64_t offset, off64_t size) {

    ALOGV("setDataSource fd=%d (%s), offset=%lld, length=%lld",
            fd, nameForFd(fd).c_str(), (long long) offset, (long long) size);

    Mutex::Autolock autoLock(mLock);

    if (mImpl != NULL) {
        return -EINVAL;
    }

    sp<FileSource> fileSource = new FileSource(dup(fd), offset, size);

    status_t err = fileSource->initCheck();
    if (err != OK) {
        return err;
    }

    // Initialize MediaExtractor using the file source
    return initMediaExtractor(fileSource);
}

status_t NuMediaExtractor::setDataSource(const sp<DataSource> &source) {
    Mutex::Autolock autoLock(mLock);

    if (mImpl != NULL) {
        return -EINVAL;
    }

    status_t err = source->initCheck();
    if (err != OK) {
        return err;
    }

    // Initialize MediaExtractor using the given data source
    return initMediaExtractor(source);
}

const char* NuMediaExtractor::getName() const {
    Mutex::Autolock autoLock(mLock);
    return mImpl == nullptr ? nullptr : mName.c_str();
}

static String8 arrayToString(const std::vector<uint8_t> &array) {
    String8 result;
    for (size_t i = 0; i < array.size(); i++) {
        result.appendFormat("%02x ", array[i]);
    }
    if (result.empty()) {
        result.append("(null)");
    }
    return result;
}

status_t NuMediaExtractor::setMediaCas(const HInterfaceToken &casToken) {
    ALOGV("setMediaCas: casToken={%s}", arrayToString(casToken).c_str());

    Mutex::Autolock autoLock(mLock);

    if (casToken.empty()) {
        return BAD_VALUE;
    }

    mCasToken = casToken;

    if (mImpl != NULL) {
        status_t err = mImpl->setMediaCas(casToken);
        if (err != OK) {
            ALOGE("%s: failed to setMediaCas (%d)", __FUNCTION__, err);
            return err;
        }
        err = updateDurationAndBitrate();
        if (err != OK) {
            return err;
        }
    }

    return OK;
}

status_t NuMediaExtractor::updateDurationAndBitrate() {
    if (mImpl->countTracks() > kMaxTrackCount) {
        return ERROR_UNSUPPORTED;
    }

    mTotalBitrate = 0LL;
    mDurationUs = -1LL;

    for (size_t i = 0; i < mImpl->countTracks(); ++i) {
        sp<MetaData> meta = mImpl->getTrackMetaData(i);
        if (meta == NULL) {
            ALOGW("no metadata for track %zu", i);
            continue;
        }

        int32_t bitrate;
        if (!meta->findInt32(kKeyBitRate, &bitrate)) {
            const char *mime;
            CHECK(meta->findCString(kKeyMIMEType, &mime));
            ALOGV("track of type '%s' does not publish bitrate", mime);

            mTotalBitrate = -1LL;
        } else if (mTotalBitrate >= 0LL) {
            mTotalBitrate += bitrate;
        }

        int64_t durationUs;
        if (meta->findInt64(kKeyDuration, &durationUs)
                && durationUs > mDurationUs) {
            mDurationUs = durationUs;
        }
    }
    return OK;
}

size_t NuMediaExtractor::countTracks() const {
    Mutex::Autolock autoLock(mLock);

    return mImpl == NULL ? 0 : mImpl->countTracks();
}

status_t NuMediaExtractor::getTrackFormat(
        size_t index, sp<AMessage> *format, uint32_t flags) const {
    Mutex::Autolock autoLock(mLock);

    *format = NULL;

    if (mImpl == NULL) {
        return -EINVAL;
    }

    if (index >= mImpl->countTracks()) {
        return -ERANGE;
    }

    sp<MetaData> meta = mImpl->getTrackMetaData(index, flags);
    // Extractors either support trackID-s or not, so either all tracks have trackIDs or none.
    // Generate trackID if missing.
    int32_t trackID;
    if (meta != NULL && !meta->findInt32(kKeyTrackID, &trackID)) {
        meta->setInt32(kKeyTrackID, (int32_t)index + 1);
    }
    return convertMetaDataToMessage(meta, format);
}

status_t NuMediaExtractor::getFileFormat(sp<AMessage> *format) const {
    Mutex::Autolock autoLock(mLock);

    *format = NULL;

    if (mImpl == NULL) {
        return -EINVAL;
    }

    sp<MetaData> meta = mImpl->getMetaData();

    if (meta == nullptr) {
        //extractor did not publish file metadata
        return -EINVAL;
    }

    const char *mime;
    if (!meta->findCString(kKeyMIMEType, &mime)) {
        // no mime type maps to invalid
        return -EINVAL;
    }
    *format = new AMessage();
    (*format)->setString("mime", mime);

    uint32_t type;
    const void *pssh;
    size_t psshsize;
    if (meta->findData(kKeyPssh, &type, &pssh, &psshsize)) {
        sp<ABuffer> buf = new ABuffer(psshsize);
        if (buf->data() == nullptr) {
            return -ENOMEM;
        }
        memcpy(buf->data(), pssh, psshsize);
        (*format)->setBuffer("pssh", buf);
    }

    // Copy over the slow-motion related metadata
    const void *slomoMarkers;
    size_t slomoMarkersSize;
    if (meta->findData(kKeySlowMotionMarkers, &type, &slomoMarkers, &slomoMarkersSize)
            && slomoMarkersSize > 0) {
        sp<ABuffer> buf = new ABuffer(slomoMarkersSize);
        if (buf->data() == nullptr) {
            return -ENOMEM;
        }
        memcpy(buf->data(), slomoMarkers, slomoMarkersSize);
        (*format)->setBuffer("slow-motion-markers", buf);
    }

    int32_t temporalLayerCount;
    if (meta->findInt32(kKeyTemporalLayerCount, &temporalLayerCount)
            && temporalLayerCount > 0) {
        (*format)->setInt32("temporal-layer-count", temporalLayerCount);
    }

    float captureFps;
    if (meta->findFloat(kKeyCaptureFramerate, &captureFps) && captureFps > 0.0f) {
        (*format)->setFloat("capture-rate", captureFps);
    }

    return OK;
}

status_t NuMediaExtractor::getExifOffsetSize(off64_t *offset, size_t *size) const {
    Mutex::Autolock autoLock(mLock);

    if (mImpl == NULL) {
        return -EINVAL;
    }

    sp<MetaData> meta = mImpl->getMetaData();

    if (meta == nullptr) {
        //extractor did not publish file metadata
        return -EINVAL;
    }

    int64_t exifOffset, exifSize;
    if (meta->findInt64(kKeyExifOffset, &exifOffset)
     && meta->findInt64(kKeyExifSize, &exifSize)) {
        *offset = (off64_t) exifOffset;
        *size = (size_t) exifSize;

        return OK;
    }
    return ERROR_UNSUPPORTED;
}

status_t NuMediaExtractor::selectTrack(size_t index,
        int64_t startTimeUs, MediaSource::ReadOptions::SeekMode mode) {
    Mutex::Autolock autoLock(mLock);

    if (mImpl == NULL) {
        return -EINVAL;
    }

    if (index >= mImpl->countTracks()) {
        return -ERANGE;
    }

    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
        TrackInfo *info = &mSelectedTracks.editItemAt(i);

        if (info->mTrackIndex == index) {
            // This track has already been selected.
            return OK;
        }
    }

    sp<IMediaSource> source = mImpl->getTrack(index);

    if (source == nullptr) {
        ALOGE("track %zu is empty", index);
        return ERROR_MALFORMED;
    }

    status_t ret = source->start();
    if (ret != OK) {
        ALOGE("track %zu failed to start", index);
        return ret;
    }

    sp<MetaData> meta = source->getFormat();
    if (meta == NULL) {
        ALOGE("track %zu has no meta data", index);
        return ERROR_MALFORMED;
    }

    const char *mime;
    if (!meta->findCString(kKeyMIMEType, &mime)) {
        ALOGE("track %zu has no mime type in meta data", index);
        return ERROR_MALFORMED;
    }
    ALOGV("selectTrack, track[%zu]: %s", index, mime);

    mSelectedTracks.push();
    TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1);

    info->mSource = source;
    info->mTrackIndex = index;
    if (!strncasecmp(mime, "audio/", 6)) {
        info->mTrackType = MEDIA_TRACK_TYPE_AUDIO;
        info->mMaxFetchCount = 64;
    } else if (!strncasecmp(mime, "video/", 6)) {
        info->mTrackType = MEDIA_TRACK_TYPE_VIDEO;
        info->mMaxFetchCount = 8;
    } else {
        info->mTrackType = MEDIA_TRACK_TYPE_UNKNOWN;
        info->mMaxFetchCount = 1;
    }
    info->mFinalResult = OK;
    releaseTrackSamples(info);
    info->mTrackFlags = 0;

    if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) {
        info->mTrackFlags |= kIsVorbis;
    }

    if (startTimeUs >= 0) {
        fetchTrackSamples(info, startTimeUs, mode);
    }

    return OK;
}

status_t NuMediaExtractor::unselectTrack(size_t index) {
    Mutex::Autolock autoLock(mLock);

    if (mImpl == NULL) {
        return -EINVAL;
    }

    if (index >= mImpl->countTracks()) {
        return -ERANGE;
    }

    size_t i;
    for (i = 0; i < mSelectedTracks.size(); ++i) {
        TrackInfo *info = &mSelectedTracks.editItemAt(i);

        if (info->mTrackIndex == index) {
            break;
        }
    }

    if (i == mSelectedTracks.size()) {
        // Not selected.
        return OK;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(i);

    releaseTrackSamples(info);

    CHECK_EQ((status_t)OK, info->mSource->stop());

    mSelectedTracks.removeAt(i);

    return OK;
}

void NuMediaExtractor::releaseTrackSamples(TrackInfo *info) {
    if (info == NULL) {
        return;
    }

    auto it = info->mSamples.begin();
    while (it != info->mSamples.end()) {
        if (it->mBuffer != NULL) {
            it->mBuffer->release();
        }
        it = info->mSamples.erase(it);
    }
}

void NuMediaExtractor::releaseAllTrackSamples() {
    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
        releaseTrackSamples(&mSelectedTracks.editItemAt(i));
    }
}

void NuMediaExtractor::setEntryPointToRemoteMediaExtractor() {
    if (mImpl == NULL) {
        return;
    }
    status_t err = mImpl->setEntryPoint(mEntryPoint);
    if (err != OK) {
        ALOGW("Failed to set entry point with error %d.", err);
    }
}

ssize_t NuMediaExtractor::fetchAllTrackSamples(
        int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
    TrackInfo *minInfo = NULL;
    ssize_t minIndex = ERROR_END_OF_STREAM;

    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
        TrackInfo *info = &mSelectedTracks.editItemAt(i);
        fetchTrackSamples(info, seekTimeUs, mode);

        status_t err = info->mFinalResult;
        if (err != OK && err != ERROR_END_OF_STREAM && info->mSamples.empty()) {
            return err;
        }

        if (info->mSamples.empty()) {
            continue;
        }

        if (minInfo == NULL) {
            minInfo = info;
            minIndex = i;
        } else {
            auto it = info->mSamples.begin();
            auto itMin = minInfo->mSamples.begin();
            if (it->mSampleTimeUs < itMin->mSampleTimeUs) {
                minInfo = info;
                minIndex = i;
            }
        }
    }

    return minIndex;
}

void NuMediaExtractor::fetchTrackSamples(TrackInfo *info,
        int64_t seekTimeUs, MediaSource::ReadOptions::SeekMode mode) {
    if (info == NULL) {
        return;
    }

    MediaSource::ReadOptions options;
    if (seekTimeUs >= 0LL) {
        options.setSeekTo(seekTimeUs, mode);
        info->mFinalResult = OK;
        releaseTrackSamples(info);
    } else if (info->mFinalResult != OK || !info->mSamples.empty()) {
        return;
    }

    status_t err = OK;
    Vector<MediaBufferBase *> mediaBuffers;
    if (info->mSource->supportReadMultiple()) {
        options.setNonBlocking();
        err = info->mSource->readMultiple(&mediaBuffers, info->mMaxFetchCount, &options);
    } else {
        MediaBufferBase *mbuf = NULL;
        err = info->mSource->read(&mbuf, &options);
        if (err == OK && mbuf != NULL) {
            mediaBuffers.push_back(mbuf);
        }
    }

    info->mFinalResult = err;
    if (err != OK && err != ERROR_END_OF_STREAM) {
        ALOGW("read on track %zu failed with error %d", info->mTrackIndex, err);
    }

    size_t count = mediaBuffers.size();
    bool releaseRemaining = false;
    for (size_t id = 0; id < count; ++id) {
        int64_t timeUs;
        MediaBufferBase *mbuf = mediaBuffers[id];
        if (mbuf == NULL) {
            continue;
        }
        if (releaseRemaining) {
            mbuf->release();
            continue;
        }
        if (mbuf->meta_data().findInt64(kKeyTime, &timeUs)) {
            info->mSamples.emplace_back(mbuf, timeUs);
        } else {
            mbuf->meta_data().dumpToLog();
            info->mFinalResult = ERROR_MALFORMED;
            mbuf->release();
            releaseRemaining = true;
        }
    }
}

status_t NuMediaExtractor::seekTo(
        int64_t timeUs, MediaSource::ReadOptions::SeekMode mode) {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples(timeUs, mode);

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    return OK;
}

status_t NuMediaExtractor::advance() {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples();

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);

    if (info == NULL || info->mSamples.empty()) {
        return ERROR_END_OF_STREAM;
    }

    auto it = info->mSamples.begin();
    if (it->mBuffer != NULL) {
        it->mBuffer->release();
    }
    info->mSamples.erase(it);

    if (info->mSamples.empty()) {
        minIndex = fetchAllTrackSamples();
        if (minIndex < 0) {
            return ERROR_END_OF_STREAM;
        }
        info = &mSelectedTracks.editItemAt(minIndex);
        if (info == NULL || info->mSamples.empty()) {
            return ERROR_END_OF_STREAM;
        }
    }
    return OK;
}

status_t NuMediaExtractor::appendVorbisNumPageSamples(
        MediaBufferBase *mbuf, const sp<ABuffer> &buffer) {
    int32_t numPageSamples;
    if (!mbuf->meta_data().findInt32(
            kKeyValidSamples, &numPageSamples)) {
        numPageSamples = -1;
    }

    // caller has verified there is sufficient space
    // insert, including accounting for the space used.
    memcpy((uint8_t *)buffer->data() + mbuf->range_length(),
           &numPageSamples,
           sizeof(numPageSamples));
    buffer->setRange(buffer->offset(), buffer->size() + sizeof(numPageSamples));

    uint32_t type;
    const void *data;
    size_t size, size2;
    if (mbuf->meta_data().findData(kKeyEncryptedSizes, &type, &data, &size)) {
        // Signal numPageSamples (a plain int32_t) is appended at the end,
        // i.e. sizeof(numPageSamples) plain bytes + 0 encrypted bytes
        if (SIZE_MAX - size < sizeof(int32_t)) {
            return -ENOMEM;
        }

        size_t newSize = size + sizeof(int32_t);
        sp<ABuffer> abuf = new ABuffer(newSize);
        uint8_t *adata = static_cast<uint8_t *>(abuf->data());
        if (adata == NULL) {
            return -ENOMEM;
        }

        // append 0 to encrypted sizes
        int32_t zero = 0;
        memcpy(adata, data, size);
        memcpy(adata + size, &zero, sizeof(zero));
        mbuf->meta_data().setData(kKeyEncryptedSizes, type, adata, newSize);

        if (mbuf->meta_data().findData(kKeyPlainSizes, &type, &data, &size2)) {
            if (size2 != size) {
                return ERROR_MALFORMED;
            }
            memcpy(adata, data, size);
        } else {
            // if sample meta data does not include plain size array, assume filled with zeros,
            // i.e. entire buffer is encrypted
            memset(adata, 0, size);
        }
        // append sizeof(numPageSamples) to plain sizes.
        int32_t int32Size = sizeof(numPageSamples);
        memcpy(adata + size, &int32Size, sizeof(int32Size));
        mbuf->meta_data().setData(kKeyPlainSizes, type, adata, newSize);
    }

    return OK;
}

status_t NuMediaExtractor::readSampleData(const sp<ABuffer> &buffer) {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples();

    buffer->setRange(0, 0);     // start with an empty buffer

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);

    auto it = info->mSamples.begin();
    size_t sampleSize = it->mBuffer->range_length();

    if (info->mTrackFlags & kIsVorbis) {
        // Each sample's data is suffixed by the number of page samples
        // or -1 if not available.
        sampleSize += sizeof(int32_t);
    }

    // capacity() is ok since we cleared out the buffer
    if (buffer->capacity() < sampleSize) {
        return -ENOMEM;
    }

    const size_t srclen = it->mBuffer->range_length();
    const uint8_t *src =
        (const uint8_t *)it->mBuffer->data()
            + it->mBuffer->range_offset();

    memcpy((uint8_t *)buffer->data(), src, srclen);
    buffer->setRange(0, srclen);

    status_t err = OK;
    if (info->mTrackFlags & kIsVorbis) {
        // adjusts range when it inserts the extra bits
        err = appendVorbisNumPageSamples(it->mBuffer, buffer);
    }

    return err;
}

status_t NuMediaExtractor::getSampleSize(size_t *sampleSize) {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples();

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
    auto it = info->mSamples.begin();
    *sampleSize = it->mBuffer->range_length();

    if (info->mTrackFlags & kIsVorbis) {
        // Each sample's data is suffixed by the number of page samples
        // or -1 if not available.
        *sampleSize += sizeof(int32_t);
    }

    return OK;
}

status_t NuMediaExtractor::getSampleTrackIndex(size_t *trackIndex) {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples();

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
    *trackIndex = info->mTrackIndex;

    return OK;
}

status_t NuMediaExtractor::getSampleTime(int64_t *sampleTimeUs) {
    Mutex::Autolock autoLock(mLock);

    ssize_t minIndex = fetchAllTrackSamples();

    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
    *sampleTimeUs = info->mSamples.begin()->mSampleTimeUs;

    return OK;
}

status_t NuMediaExtractor::getSampleMeta(sp<MetaData> *sampleMeta) {
    Mutex::Autolock autoLock(mLock);

    *sampleMeta = NULL;

    ssize_t minIndex = fetchAllTrackSamples();

    if (minIndex < 0) {
        status_t err = minIndex;
        return err;
    }

    TrackInfo *info = &mSelectedTracks.editItemAt(minIndex);
    *sampleMeta = new MetaData(info->mSamples.begin()->mBuffer->meta_data());

    return OK;
}

status_t NuMediaExtractor::getMetrics(Parcel *reply) {
    if (mImpl == NULL) {
        return -EINVAL;
    }
    status_t status = mImpl->getMetrics(reply);
    return status;
}

bool NuMediaExtractor::getTotalBitrate(int64_t *bitrate) const {
    if (mTotalBitrate > 0) {
        *bitrate = mTotalBitrate;
        return true;
    }

    off64_t size;
    if (mDurationUs > 0 && mDataSource->getSize(&size) == OK) {
        *bitrate = size * 8000000LL / mDurationUs;  // in bits/sec
        return true;
    }

    return false;
}

// Returns true iff cached duration is available/applicable.
bool NuMediaExtractor::getCachedDuration(
        int64_t *durationUs, bool *eos) const {
    Mutex::Autolock autoLock(mLock);

    off64_t cachedDataRemaining = -1;
    status_t finalStatus = mDataSource->getAvailableSize(-1, &cachedDataRemaining);

    int64_t bitrate;
    if (cachedDataRemaining >= 0
            && getTotalBitrate(&bitrate)) {
        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
        *eos = (finalStatus != OK);
        return true;
    }

    return false;
}

// Return OK if we have received an audio presentation info.
// Return ERROR_END_OF_STREAM if no tracks are available.
// Return ERROR_UNSUPPORTED if the track has no audio presentation.
// Return INVALID_OPERATION if audio presentation metadata version does not match.
status_t NuMediaExtractor::getAudioPresentations(
        size_t trackIndex, AudioPresentationCollection *presentations) {
    Mutex::Autolock autoLock(mLock);
    ssize_t minIndex = fetchAllTrackSamples();
    if (minIndex < 0) {
        return ERROR_END_OF_STREAM;
    }
    for (size_t i = 0; i < mSelectedTracks.size(); ++i) {
        TrackInfo *info = &mSelectedTracks.editItemAt(i);

        if (info->mTrackIndex == trackIndex) {
            sp<MetaData> meta = new MetaData(info->mSamples.begin()->mBuffer->meta_data());

            uint32_t type;
            const void *data;
            size_t size;
            if (meta != NULL && meta->findData(kKeyAudioPresentationInfo, &type, &data, &size)) {
                std::istringstream inStream(std::string(static_cast<const char*>(data), size));
                return deserializeAudioPresentations(&inStream, presentations);
            }
            ALOGV("Track %zu does not contain any audio presentation", trackIndex);
            return ERROR_UNSUPPORTED;
        }
    }
    ALOGV("Source does not contain any audio presentation");
    return ERROR_UNSUPPORTED;
}

status_t NuMediaExtractor::setLogSessionId(const String8& logSessionId) {
    if (mImpl == nullptr) {
        return ERROR_UNSUPPORTED;
    }
    status_t status = mImpl->setLogSessionId(logSessionId);
    if (status != OK) {
        ALOGW("Failed to set log session id: %d.", status);
    }
    return status;
}

}  // namespace android
