SampleTable.cpp revision a9660fe122ca382e1777e0c5d3c42ca67ffb0377
120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber/*
220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Copyright (C) 2009 The Android Open Source Project
320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * you may not use this file except in compliance with the License.
620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * You may obtain a copy of the License at
720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber *
1020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * Unless required by applicable law or agreed to in writing, software
1120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * See the License for the specific language governing permissions and
1420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber * limitations under the License.
1520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber */
1620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#define LOG_TAG "SampleTable"
18c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber//#define LOG_NDEBUG 0
1920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <utils/Log.h>
2020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2189e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber#include "include/SampleTable.h"
22c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber#include "include/SampleIterator.h"
2389e69da4d86348409994c9dafbbb2634ccd7c196Andreas Huber
2420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <arpa/inet.h>
2520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber#include <media/stagefright/foundation/ADebug.h>
2720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/DataSource.h>
2820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber#include <media/stagefright/Utils.h>
2920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3020111aa043c5f404472bc63b90bc5aad906b1101Andreas Hubernamespace android {
3120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
33c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType32 = FOURCC('s', 't', 'c', 'o');
34c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
35c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kChunkOffsetType64 = FOURCC('c', 'o', '6', '4');
36c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
37c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeType32 = FOURCC('s', 't', 's', 'z');
38c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber// static
39c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberconst uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');
40c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
41c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber////////////////////////////////////////////////////////////////////////////////
4220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kimconst off64_t kMaxOffset = INT64_MAX;
44f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim
4589aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup {
4689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    CompositionDeltaLookup();
4789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    void setEntries(
4989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            const uint32_t *deltaEntries, size_t numDeltaEntries);
5089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate:
5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex mLock;
5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    const uint32_t *mDeltaEntries;
5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mNumDeltaEntries;
5889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentDeltaEntry;
6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentEntrySampleIndex;
6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
6389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber};
6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6589aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    : mDeltaEntries(NULL),
6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mNumDeltaEntries(0),
6889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentDeltaEntry(0),
6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentEntrySampleIndex(0) {
7089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7289aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries(
7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        const uint32_t *deltaEntries, size_t numDeltaEntries) {
7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
7589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mDeltaEntries = deltaEntries;
7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mNumDeltaEntries = numDeltaEntries;
7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentDeltaEntry = 0;
7989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentEntrySampleIndex = 0;
8089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleIndex) {
8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (mDeltaEntries == NULL) {
8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        return 0;
8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
8989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (sampleIndex < mCurrentEntrySampleIndex) {
9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentDeltaEntry = 0;
9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex = 0;
9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    while (mCurrentDeltaEntry < mNumDeltaEntries) {
9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        }
10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex += sampleCount;
10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        ++mCurrentDeltaEntry;
10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return 0;
10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber////////////////////////////////////////////////////////////////////////////////
10989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
110693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
12170dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa      mHasTimeToSample(false),
12220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
123583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa      mTimeToSample(NULL),
1244678a6dc5f09008481524949a9667af5a6190374Andreas Huber      mSampleTimeEntries(NULL),
1254931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mCompositionTimeDeltaEntries(NULL),
1264931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mNumCompositionTimeDeltaEntries(0),
12789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCompositionDeltaLookup(new CompositionDeltaLookup),
12820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
1308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mSyncSamples(NULL),
1318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mLastSyncSampleIndex(0),
132583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa      mSampleToChunkEntries(NULL),
133583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa      mTotalSize(0) {
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
13520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13720111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
138c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
139c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
140c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
1418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    delete[] mSyncSamples;
1428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = NULL;
1438bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
144583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    delete[] mTimeToSample;
145583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTimeToSample = NULL;
146583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
14789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    delete mCompositionDeltaLookup;
14889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup = NULL;
14989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
1504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    delete[] mCompositionTimeDeltaEntries;
1514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = NULL;
1524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
1534678a6dc5f09008481524949a9667af5a6190374Andreas Huber    delete[] mSampleTimeEntries;
1544678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = NULL;
1554678a6dc5f09008481524949a9667af5a6190374Andreas Huber
156c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
157c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
15820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
160169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const {
161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    return mChunkOffsetOffset >= 0
162169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleToChunkOffset >= 0
163169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleSizeOffset >= 0
16470dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa        && mHasTimeToSample;
165169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber}
166169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
168c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
16920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1730c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
17920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
18334769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
209c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
21720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
22134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
233f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if ((data_size - 8) / sizeof(SampleToChunkEntry) < mNumSampleToChunkOffsets) {
23420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
23520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
237f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if ((uint64_t)kMaxTotalSize / sizeof(SampleToChunkEntry) <=
238583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            (uint64_t)mNumSampleToChunkOffsets) {
239583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Sample-to-chunk table size too large.");
2405c134e6b2047b10877f02a46f4bb293537269f00Joshua J. Drake        return ERROR_OUT_OF_RANGE;
241583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
242583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
243583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTotalSize += (uint64_t)mNumSampleToChunkOffsets *
244583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            sizeof(SampleToChunkEntry);
245583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mTotalSize > kMaxTotalSize) {
246583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Sample-to-chunk table size would make sample table too large.\n"
247583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Requested sample-to-chunk table size = %llu\n"
248583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Eventual sample table size >= %llu\n"
249583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Allowed sample table size = %llu\n",
250583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mNumSampleToChunkOffsets *
251583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa                      sizeof(SampleToChunkEntry),
252583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mTotalSize,
253583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)kMaxTotalSize);
254583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
255583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
2565c134e6b2047b10877f02a46f4bb293537269f00Joshua J. Drake
257c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
258583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        new (std::nothrow) SampleToChunkEntry[mNumSampleToChunkOffsets];
259583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (!mSampleToChunkEntries) {
260583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Cannot allocate sample-to-chunk table with %llu entries.",
261583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa                (unsigned long long)mNumSampleToChunkOffsets);
262583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
263583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
264583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
265583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mNumSampleToChunkOffsets == 0) {
266583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return OK;
267583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
268583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
269f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if ((off64_t)(kMaxOffset - 8 -
270583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            ((mNumSampleToChunkOffsets - 1) * sizeof(SampleToChunkEntry)))
271583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            < mSampleToChunkOffset) {
272583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_MALFORMED;
273583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
274c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
275c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
276f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim        uint8_t buffer[sizeof(SampleToChunkEntry)];
277f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim
278c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
279f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim                    mSampleToChunkOffset + 8 + i * sizeof(SampleToChunkEntry),
280f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim                    buffer,
281f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim                    sizeof(buffer))
282c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
283c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
284c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
285583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        // chunk index is 1 based in the spec.
286583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        if (U32_AT(buffer) < 1) {
287583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            ALOGE("b/23534160");
288583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            return ERROR_OUT_OF_RANGE;
289583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        }
290c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
291c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
292c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
293c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
294c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
295c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
296c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
29920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
301c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3060c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
31534769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
31620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
32220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
3275a132594b531f1f48098a790927f82080cc27f61Wei Jia    if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
328c27cee30d9359fa83e33b4f87f88e6bb9ef66341Wei Jia        ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
3295a132594b531f1f48098a790927f82080cc27f61Wei Jia        return ERROR_MALFORMED;
3305a132594b531f1f48098a790927f82080cc27f61Wei Jia    }
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
33620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3489f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
34920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
35020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
35220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
35320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
35420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
35520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
35620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
35720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
35820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
35920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
36220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
36320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
36420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
365c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
36670dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa    if (mHasTimeToSample || data_size < 8) {
36720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
36820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
36920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
37134769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
37220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
37320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
37420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
37520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
37620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
37720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
37820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
37920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
38020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
38120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
382f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if (mTimeToSampleCount > UINT32_MAX / (2 * sizeof(uint32_t))) {
383a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        // Choose this bound because
384a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        // 1) 2 * sizeof(uint32_t) is the amount of memory needed for one
385a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        //    time-to-sample entry in the time-to-sample table.
386a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        // 2) mTimeToSampleCount is the number of entries of the time-to-sample
387a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        //    table.
388a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa        // 3) We hope that the table size does not exceed UINT32_MAX.
389583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Time-to-sample table size too large.");
390edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
391edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
39220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
393a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa    // Note: At this point, we know that mTimeToSampleCount * 2 will not
394a3630a418b4f65277a42cd4018cd3b0b7e134d0cPawin Vongmasa    // overflow because of the above condition.
395583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
396583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    uint64_t allocSize = (uint64_t)mTimeToSampleCount * 2 * sizeof(uint32_t);
397583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTotalSize += allocSize;
398583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mTotalSize > kMaxTotalSize) {
399583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Time-to-sample table size would make sample table too large.\n"
400583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Requested time-to-sample table size = %llu\n"
401583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Eventual sample table size >= %llu\n"
402583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Allowed sample table size = %llu\n",
403583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)allocSize,
404583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mTotalSize,
405583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)kMaxTotalSize);
406583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
407583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
408583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
409583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTimeToSample = new (std::nothrow) uint32_t[mTimeToSampleCount * 2];
410583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (!mTimeToSample) {
411583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Cannot allocate time-to-sample table with %llu entries.",
412583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa                (unsigned long long)mTimeToSampleCount);
413583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
414583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
415583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
416583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mDataSource->readAt(data_offset + 8, mTimeToSample,
417583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            (size_t)allocSize) < (ssize_t)allocSize) {
418583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Incomplete data read for time-to-sample table.");
41920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
42020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
422583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    for (size_t i = 0; i < mTimeToSampleCount * 2; ++i) {
423583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        mTimeToSample[i] = ntohl(mTimeToSample[i]);
42420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
42570dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa
42670dec4dc7d1d813afaff58fb26b0fd7127e897bfPawin Vongmasa    mHasTimeToSample = true;
42720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
42820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
42920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4304931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
4314931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
432df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("There are reordered frames present.");
4334931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4344931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
4354931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
4364931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4374931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4384931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
4394931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
4404931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
4414931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
4424931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
4434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
4464931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
4474931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
4484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4504931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
4514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
4534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
4544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4554931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
457738a753a3ca7bf8f9f608ca941575626265294e4Wei Jia    uint64_t allocSize = (uint64_t)numEntries * 2 * sizeof(uint32_t);
458f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if (allocSize > kMaxTotalSize) {
459583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Composition-time-to-sample table size too large.");
460edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
461edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
462edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
463583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTotalSize += allocSize;
464583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mTotalSize > kMaxTotalSize) {
465583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Composition-time-to-sample table would make sample table too large.\n"
466583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Requested composition-time-to-sample table size = %llu\n"
467583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Eventual sample table size >= %llu\n"
468583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Allowed sample table size = %llu\n",
469583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)allocSize,
470583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mTotalSize,
471583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)kMaxTotalSize);
472583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
473583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
4744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
475583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries];
476583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (!mCompositionTimeDeltaEntries) {
477583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Cannot allocate composition-time-to-sample table with %llu "
478583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa                "entries.", (unsigned long long)numEntries);
479583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
480583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
481583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
482583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mDataSource->readAt(data_offset + 8, mCompositionTimeDeltaEntries,
483583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            (size_t)allocSize) < (ssize_t)allocSize) {
4844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
4854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
4864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
4884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4904931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
4914931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
4924931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
4934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
49489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup->setEntries(
49589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
49689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4974931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
4984931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
4994931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
500c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
50120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
50320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
50420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
50634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
50720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
50820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
50920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
51020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
51120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
51220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
51320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
51420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
51520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
516a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    uint32_t numSyncSamples = U32_AT(&header[4]);
51720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
518a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    if (numSyncSamples < 2) {
5193856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Table of sync samples is empty or has only a single entry!");
52020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
5218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
522a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    uint64_t allocSize = (uint64_t)numSyncSamples * sizeof(uint32_t);
523f4f36a0a313733b191349ac43d7f4d37038569b1Wonsik Kim    if (allocSize > kMaxTotalSize) {
524583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Sync sample table size too large.");
525edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih        return ERROR_OUT_OF_RANGE;
526edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih    }
527edd4a76eb4747bd19ed122df46fa46b452c12a0dRobert Shih
528583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTotalSize += allocSize;
529583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mTotalSize > kMaxTotalSize) {
530583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Sync sample table size would make sample table too large.\n"
531583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Requested sync sample table size = %llu\n"
532583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Eventual sample table size >= %llu\n"
533583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Allowed sample table size = %llu\n",
534583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)allocSize,
535583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mTotalSize,
536583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)kMaxTotalSize);
537583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
538583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
539583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
540a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    mSyncSamples = new (std::nothrow) uint32_t[numSyncSamples];
541583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (!mSyncSamples) {
542583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Cannot allocate sync sample table with %llu entries.",
543a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen                (unsigned long long)numSyncSamples);
544583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return ERROR_OUT_OF_RANGE;
545583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
546583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
547a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    if (mDataSource->readAt(data_offset + 8, mSyncSamples,
548583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa            (size_t)allocSize) != (ssize_t)allocSize) {
549a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen        delete mSyncSamples;
550a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen        mSyncSamples = NULL;
5518bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
5528bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
5538bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
554a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    for (size_t i = 0; i < numSyncSamples; ++i) {
5558bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
5568bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
5578bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
558a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    mSyncSampleOffset = data_offset;
559a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen    mNumSyncSamples = numSyncSamples;
560a9660fe122ca382e1777e0c5d3c42ca67ffb0377Marco Nelissen
56120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
56320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
56520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
56620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
56720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
56820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
56920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
57020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
57320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
57420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
57520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
57620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
57720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
57820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
579c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
580da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
58120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
58220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
58320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
58420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
58520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
58620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
58720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
58820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
58920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
59020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
59120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
59220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
593da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
594da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
595da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
596da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
5974678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
5984678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
5994678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
6004678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
6014931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
6024678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
6034678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
6044678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
6054678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
6064678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
607abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6084678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
6094678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
6104678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6114678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6145a132594b531f1f48098a790927f82080cc27f61Wei Jia    if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
615cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia        if (mNumSampleSizes == 0) {
616cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia            ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
617cccd2e5e3aa015d6ce96ba0245b7161c077cdba2Wei Jia        }
6184678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
6194678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
6204678a6dc5f09008481524949a9667af5a6190374Andreas Huber
621583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mTotalSize += (uint64_t)mNumSampleSizes * sizeof(SampleTimeEntry);
622583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (mTotalSize > kMaxTotalSize) {
623583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Sample entry table size would make sample table too large.\n"
624583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Requested sample entry table size = %llu\n"
625583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Eventual sample table size >= %llu\n"
626583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              "    Allowed sample table size = %llu\n",
627583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mNumSampleSizes * sizeof(SampleTimeEntry),
628583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)mTotalSize,
629583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa              (unsigned long long)kMaxTotalSize);
630583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return;
631583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
632583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa
633583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    mSampleTimeEntries = new (std::nothrow) SampleTimeEntry[mNumSampleSizes];
634583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    if (!mSampleTimeEntries) {
635583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        ALOGE("Cannot allocate sample entry table with %llu entries.",
636583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa                (unsigned long long)mNumSampleSizes);
637583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa        return;
638583a012a9fce81162b163d3533e2644d4abad88aPawin Vongmasa    }
6394678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6404678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
6414678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
6424678a6dc5f09008481524949a9667af5a6190374Andreas Huber
64320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
64420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
64520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
64620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6474678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
64865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            if (sampleIndex < mNumSampleSizes) {
64965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // Technically this should always be the case if the file
65065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // is well-formed, but you know... there's (gasp) malformed
65165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // content out there.
65220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
65365a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
654abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
65589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                uint32_t compTimeDelta =
65689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    mCompositionDeltaLookup->getCompositionTimeOffset(
65789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                            sampleIndex);
65889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
65965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mCompositionTime =
66089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    sampleTime + compTimeDelta;
66165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            }
6624678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6634678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
6644678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
6654678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
6664678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
6674678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6684678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
6694678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
6704678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
6714678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6724678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
673599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
674599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint32_t *sample_index, uint32_t flags) {
6754678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
6764678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6775a132594b531f1f48098a790927f82080cc27f61Wei Jia    if (mSampleTimeEntries == NULL) {
6785a132594b531f1f48098a790927f82080cc27f61Wei Jia        return ERROR_OUT_OF_RANGE;
6795a132594b531f1f48098a790927f82080cc27f61Wei Jia    }
6805a132594b531f1f48098a790927f82080cc27f61Wei Jia
6814678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
682225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSampleSizes;
683225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
684225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
685599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        uint64_t centerTime =
686599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            getSampleTime(center, scale_num, scale_den);
6874678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6884678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
689225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
6904678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
6914678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
6924678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
693599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = mSampleTimeEntries[center].mSampleIndex;
694599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
6954678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
6964678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
6974678a6dc5f09008481524949a9667af5a6190374Andreas Huber
698599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    uint32_t closestIndex = left;
699599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
700599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    if (closestIndex == mNumSampleSizes) {
701a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
702a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
703a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
704599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
705599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    } else if (closestIndex == 0) {
706599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
707599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
708599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead return first sample
709599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
710599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
711599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
712599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
7134678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
7144678a6dc5f09008481524949a9667af5a6190374Andreas Huber
7154678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
7164678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
7174678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
718599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --closestIndex;
7194678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
7204678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7224678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
7234678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
724599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
7254678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
72720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7284678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
7294678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
7304678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
731599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // pick closest based on timestamp. use abs_difference for safety
732599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(
733599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    getSampleTime(closestIndex, scale_num, scale_den), req_time) >
734599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(
735599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                    req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) {
736599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --closestIndex;
7374678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
7384678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
7394678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
74020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
74120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7424678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
7434678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
74420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
74520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
746abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
747abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
748abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
749abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
75020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
75120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
75220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
75320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
75420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
75520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
75620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
75720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
758abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
759abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
760abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
761abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
762da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
763abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
764225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    uint32_t right_plus_one = mNumSyncSamples;
765225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar    while (left < right_plus_one) {
766225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar        uint32_t center = left + (right_plus_one - left) / 2;
7678f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t x = mSyncSamples[center];
76820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7698f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        if (start_sample_index < x) {
770225d5b20409fd400bfa4ed5e9bc1d5babb498471Lajos Molnar            right_plus_one = center;
7718f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else if (start_sample_index > x) {
7728f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center + 1;
7738f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else {
774599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            *sample_index = x;
775599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            return OK;
77620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
777f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
778599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
7798d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    if (left == mNumSyncSamples) {
7808d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        if (flags == kFlagAfter) {
78129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("tried to find a sync frame after the last one: %d", left);
7828d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng            return ERROR_OUT_OF_RANGE;
7838d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        }
784599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagBefore;
7858d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    }
786599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    else if (left == 0) {
787599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        if (flags == kFlagBefore) {
788599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            ALOGE("tried to find a sync frame before the first one: %d", left);
789abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
790599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // normally we should return out of range, but that is
791599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // treated as end-of-stream.  instead seek to first sync
792599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            //
793599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // return ERROR_OUT_OF_RANGE;
794abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
795599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        flags = kFlagAfter;
796abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
797abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
798599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    // Now ssi[left - 1] <(=) start_sample_index <= ssi[left]
799abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
800abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
801abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
802599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            --left;
803abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
804abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
805abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
806abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
807599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // nothing to do
808abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
809abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
810abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
811599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        {
812599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // this route is not used, but implement it nonetheless
813599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            CHECK(flags == kFlagClosest);
814599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
815599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            status_t err = mSampleIterator->seekTo(start_sample_index);
816599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
817599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
818599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
819599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t sample_time = mSampleIterator->getSampleTime();
820599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
821599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left]);
822599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
823599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
824599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
825599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t upper_time = mSampleIterator->getSampleTime();
826599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
827599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
828599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (err != OK) {
829599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                return err;
830599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
831599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            uint32_t lower_time = mSampleIterator->getSampleTime();
832599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar
833599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            // use abs_difference for safety
834599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            if (abs_difference(upper_time, sample_time) >
835599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                abs_difference(sample_time, lower_time)) {
836599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar                --left;
837599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar            }
838abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
839599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar        }
84020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
84120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
842599950efbb03b1672561d4cf2272504b879525e8Lajos Molnar    *sample_index = mSyncSamples[left];
84320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
84420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
84520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
8467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
847c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
848c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
8507e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
8517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
8527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
8537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
8547e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
8567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
8577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
8597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
8617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
8627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
8647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
8657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
8667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
8677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
8698bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
8707e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8717e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
8727e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
873c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
8747e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
8757e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
8767e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
8777e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8787e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
8797e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
8807e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
8817e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
8827e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
8837e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8847e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
8857e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
8867e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
8877e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
8887e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
889c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
890c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
891c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
892c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
893c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
894c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
895c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
896c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
897c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
898c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
8994678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
900170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        bool *isSyncSample,
901170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        uint32_t *sampleDuration) {
902c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
903c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
904c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
905c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
906c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
907c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
908c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
909c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
910c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
911c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
912c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
913c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
914c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
915c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
916c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
9174678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
9184678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
919c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
920c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
9218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
9228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
9238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
9248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
9258bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
9268bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
9278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
9288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
9298bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
9308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
9318bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
9328bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
9338bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
9348bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
9358bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
9368bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
9378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
9388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
9398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
9408bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
9418bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
9428bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
943170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    if (sampleDuration) {
944170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih        *sampleDuration = mSampleIterator->getSampleDuration();
945170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih    }
946170056540e9ce65261b45efd15f67e72e2df1bedRobert Shih
947c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
948c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
949c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
95089aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
95189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
9524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
9534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
95420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
95520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
956