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
4389aa8fe4cb00d2f24260005b008602232d678684Andreas Huberstruct SampleTable::CompositionDeltaLookup {
4489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    CompositionDeltaLookup();
4589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    void setEntries(
4789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            const uint32_t *deltaEntries, size_t numDeltaEntries);
4889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
4989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
5089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5189aa8fe4cb00d2f24260005b008602232d678684Andreas Huberprivate:
5289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex mLock;
5389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    const uint32_t *mDeltaEntries;
5589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mNumDeltaEntries;
5689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
5789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentDeltaEntry;
5889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    size_t mCurrentEntrySampleIndex;
5989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
6189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber};
6289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
6389aa8fe4cb00d2f24260005b008602232d678684Andreas HuberSampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
6489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    : mDeltaEntries(NULL),
6589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mNumDeltaEntries(0),
6689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentDeltaEntry(0),
6789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCurrentEntrySampleIndex(0) {
6889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
6989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7089aa8fe4cb00d2f24260005b008602232d678684Andreas Hubervoid SampleTable::CompositionDeltaLookup::setEntries(
7189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        const uint32_t *deltaEntries, size_t numDeltaEntries) {
7289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
7389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
7489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mDeltaEntries = deltaEntries;
7589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mNumDeltaEntries = numDeltaEntries;
7689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentDeltaEntry = 0;
7789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCurrentEntrySampleIndex = 0;
7889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
7989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8089aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
8189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleIndex) {
8289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    Mutex::Autolock autolock(mLock);
8389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (mDeltaEntries == NULL) {
8589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        return 0;
8689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
8789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
8889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    if (sampleIndex < mCurrentEntrySampleIndex) {
8989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentDeltaEntry = 0;
9089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex = 0;
9189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
9289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    while (mCurrentDeltaEntry < mNumDeltaEntries) {
9489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
9589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
9689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
9789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        }
9889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
9989aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        mCurrentEntrySampleIndex += sampleCount;
10089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber        ++mCurrentDeltaEntry;
10189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    }
10289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10389aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return 0;
10489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber}
10589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
10689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber////////////////////////////////////////////////////////////////////////////////
10789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
108693d271e62a3726689ff68f4505ba49228eb94b2Andreas HuberSampleTable::SampleTable(const sp<DataSource> &source)
10920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    : mDataSource(source),
11020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetOffset(-1),
11120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mChunkOffsetType(0),
11220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumChunkOffsets(0),
11320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleToChunkOffset(-1),
11420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleToChunkOffsets(0),
11520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeOffset(-1),
11620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSampleSizeFieldSize(0),
11720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mDefaultSampleSize(0),
11820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mNumSampleSizes(0),
11920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSampleCount(0),
12020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mTimeToSample(NULL),
1214678a6dc5f09008481524949a9667af5a6190374Andreas Huber      mSampleTimeEntries(NULL),
1224931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mCompositionTimeDeltaEntries(NULL),
1234931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber      mNumCompositionTimeDeltaEntries(0),
12489aa8fe4cb00d2f24260005b008602232d678684Andreas Huber      mCompositionDeltaLookup(new CompositionDeltaLookup),
12520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber      mSyncSampleOffset(-1),
126c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mNumSyncSamples(0),
1278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mSyncSamples(NULL),
1288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber      mLastSyncSampleIndex(0),
129c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber      mSampleToChunkEntries(NULL) {
130c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = new SampleIterator(this);
13120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
13220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
13320111aa043c5f404472bc63b90bc5aad906b1101Andreas HuberSampleTable::~SampleTable() {
134c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete[] mSampleToChunkEntries;
135c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries = NULL;
136c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
1378bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    delete[] mSyncSamples;
1388bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = NULL;
1398bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
14089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    delete mCompositionDeltaLookup;
14189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup = NULL;
14289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
1434931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    delete[] mCompositionTimeDeltaEntries;
1444931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = NULL;
1454931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
1464678a6dc5f09008481524949a9667af5a6190374Andreas Huber    delete[] mSampleTimeEntries;
1474678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = NULL;
1484678a6dc5f09008481524949a9667af5a6190374Andreas Huber
14920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    delete[] mTimeToSample;
15020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = NULL;
151c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
152c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    delete mSampleIterator;
153c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleIterator = NULL;
15420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
15520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
156169c286ed166499c5099d2b336967e0bf3d25551Andreas Huberbool SampleTable::isValid() const {
157169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber    return mChunkOffsetOffset >= 0
158169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleToChunkOffset >= 0
159169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mSampleSizeOffset >= 0
160169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber        && mTimeToSample != NULL;
161169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber}
162169c286ed166499c5099d2b336967e0bf3d25551Andreas Huber
16320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setChunkOffsetParams(
164c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
16520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetOffset >= 0) {
16620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
16720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
16820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
1690c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kChunkOffsetType32 || type == kChunkOffsetType64);
17020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetOffset = data_offset;
17220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mChunkOffsetType = type;
17320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
17520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
17620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
17720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
17820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
17934769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
18020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
18120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
18220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
18520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
18620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
18720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
18820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
18920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumChunkOffsets = U32_AT(&header[4]);
19020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
19120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mChunkOffsetType == kChunkOffsetType32) {
19220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 4) {
19320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
19620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 8 + mNumChunkOffsets * 8) {
19720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
19820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
19920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
20220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
20320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
20420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleToChunkParams(
205c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
20620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleToChunkOffset >= 0) {
20720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
20820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
20920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleToChunkOffset = data_offset;
21120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8) {
21320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
21420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
21520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
21620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
21734769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
21820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
21920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
22020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
22320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
22420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
22520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
22620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleToChunkOffsets = U32_AT(&header[4]);
22820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
22920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 8 + mNumSampleToChunkOffsets * 12) {
23020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
23120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
23220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
233c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    mSampleToChunkEntries =
234c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        new SampleToChunkEntry[mNumSampleToChunkOffsets];
235c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
236c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    for (uint32_t i = 0; i < mNumSampleToChunkOffsets; ++i) {
237c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint8_t buffer[12];
238c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        if (mDataSource->readAt(
239c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                    mSampleToChunkOffset + 8 + i * 12, buffer, sizeof(buffer))
240c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber                != (ssize_t)sizeof(buffer)) {
241c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            return ERROR_IO;
242c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        }
243c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
244c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        CHECK(U32_AT(buffer) >= 1);  // chunk index is 1 based in the spec.
245c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
246c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        // We want the chunk index to be 0-based.
247c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].startChunk = U32_AT(buffer) - 1;
248c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].samplesPerChunk = U32_AT(&buffer[4]);
249c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        mSampleToChunkEntries[i].chunkDesc = U32_AT(&buffer[8]);
250c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
251c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
25220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
25320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
25420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
25520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setSampleSizeParams(
256c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        uint32_t type, off64_t data_offset, size_t data_size) {
25720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSampleSizeOffset >= 0) {
25820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
25920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2610c89199745bc1bf05b997fc7c342017807676b6fAndreas Huber    CHECK(type == kSampleSizeType32 || type == kSampleSizeTypeCompact);
26220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSampleSizeOffset = data_offset;
26420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (data_size < 12) {
26620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
26720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
26820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
26920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[12];
27034769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
27120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
27220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
27320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
27520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
27620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
27720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
27820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
27920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mDefaultSampleSize = U32_AT(&header[4]);
28120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSampleSizes = U32_AT(&header[8]);
28220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (type == kSampleSizeType32) {
28420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mSampleSizeFieldSize = 32;
28520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
28620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mDefaultSampleSize != 0) {
28720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return OK;
28820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
28920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
29020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + mNumSampleSizes * 4) {
29120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
29220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    } else {
29420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if ((mDefaultSampleSize & 0xffffff00) != 0) {
29520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            // The high 24 bits are reserved and must be 0.
29620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
29720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
29820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
2999f753df58a70f20db220af31cb202bbd21b30f36Andreas Huber        mSampleSizeFieldSize = mDefaultSampleSize & 0xff;
30020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mDefaultSampleSize = 0;
30120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (mSampleSizeFieldSize != 4 && mSampleSizeFieldSize != 8
30320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            && mSampleSizeFieldSize != 16) {
30420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
30620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
30720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (data_size < 12 + (mNumSampleSizes * mSampleSizeFieldSize + 4) / 8) {
30820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return ERROR_MALFORMED;
30920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
31020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
31120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
31320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
31420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
31520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::setTimeToSampleParams(
316c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t data_offset, size_t data_size) {
31720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mTimeToSample != NULL || data_size < 8) {
31820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
31920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
32234769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
32320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
32420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
32520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
32620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
32720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
32820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
32920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
33020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
33120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSampleCount = U32_AT(&header[4]);
33320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
33420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
33520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
33634769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
33720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset + 8, mTimeToSample, size) < (ssize_t)size) {
33820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
33920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount * 2; ++i) {
34220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        mTimeToSample[i] = ntohl(mTimeToSample[i]);
34320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
34420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
34520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
34620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
34720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
3484931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huberstatus_t SampleTable::setCompositionTimeToSampleParams(
3494931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        off64_t data_offset, size_t data_size) {
350df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("There are reordered frames present.");
3514931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3524931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
3534931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3544931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3554931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3564931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    uint8_t header[8];
3574931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3584931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset, header, sizeof(header))
3594931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)sizeof(header)) {
3604931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3614931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3624931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3634931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (U32_AT(header) != 0) {
3644931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        // Expected version = 0, flags = 0.
3654931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3664931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3674931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3684931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    size_t numEntries = U32_AT(&header[4]);
3694931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3704931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (data_size != (numEntries + 1) * 8) {
3714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_MALFORMED;
3724931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3734931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3744931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mNumCompositionTimeDeltaEntries = numEntries;
3754931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
3764931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3774931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    if (mDataSource->readAt(
3784931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
3794931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber            < (ssize_t)numEntries * 8) {
3804931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        delete[] mCompositionTimeDeltaEntries;
3814931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries = NULL;
3824931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3834931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        return ERROR_IO;
3844931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3854931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
3864931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    for (size_t i = 0; i < 2 * numEntries; ++i) {
3874931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
3884931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    }
3894931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
39089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    mCompositionDeltaLookup->setEntries(
39189aa8fe4cb00d2f24260005b008602232d678684Andreas Huber            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);
39289aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
3934931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber    return OK;
3944931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
3954931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
396c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dongstatus_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
39720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset >= 0 || data_size < 8) {
39820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
39920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
40020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mSyncSampleOffset = data_offset;
40220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    uint8_t header[8];
40434769bc913e9f6bb138e666d94a9d685bf3da217Andreas Huber    if (mDataSource->readAt(
40520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber                data_offset, header, sizeof(header)) < (ssize_t)sizeof(header)) {
40620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_IO;
40720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
40820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
40920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (U32_AT(header) != 0) {
41020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // Expected version = 0, flags = 0.
41120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return ERROR_MALFORMED;
41220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
41320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    mNumSyncSamples = U32_AT(&header[4]);
41520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
41620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mNumSyncSamples < 2) {
4173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("Table of sync samples is empty or has only a single entry!");
41820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
4198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    mSyncSamples = new uint32_t[mNumSyncSamples];
4218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    size_t size = mNumSyncSamples * sizeof(uint32_t);
4228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
4238bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            != (ssize_t)size) {
4248bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        return ERROR_IO;
4258bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4268bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
4278bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    for (size_t i = 0; i < mNumSyncSamples; ++i) {
4288bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        mSyncSamples[i] = ntohl(mSyncSamples[i]) - 1;
4298bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
4308bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
43120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
43220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
43320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countChunkOffsets() const {
43520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumChunkOffsets;
43620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
43720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
43820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberuint32_t SampleTable::countSamples() const {
43920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return mNumSampleSizes;
44020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
44120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huberstatus_t SampleTable::getMaxSampleSize(size_t *max_size) {
44320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
44420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *max_size = 0;
44620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
44720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mNumSampleSizes; ++i) {
44820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        size_t sample_size;
449c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(i, &sample_size);
450da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
45120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (err != OK) {
45220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            return err;
45320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
45420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
45520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        if (sample_size > *max_size) {
45620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            *max_size = sample_size;
45720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
45820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
45920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
46020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
46120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
46220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
463da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huberuint32_t abs_difference(uint32_t time1, uint32_t time2) {
464da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber    return time1 > time2 ? time1 - time2 : time2 - time1;
465da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber}
466da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
4674678a6dc5f09008481524949a9667af5a6190374Andreas Huber// static
4684678a6dc5f09008481524949a9667af5a6190374Andreas Huberint SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
4694678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
4704678a6dc5f09008481524949a9667af5a6190374Andreas Huber    const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
4714931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
4724678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (a->mCompositionTime < b->mCompositionTime) {
4734678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return -1;
4744678a6dc5f09008481524949a9667af5a6190374Andreas Huber    } else if (a->mCompositionTime > b->mCompositionTime) {
4754678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return 1;
4764678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
477abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
4784678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return 0;
4794678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
4804678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4814678a6dc5f09008481524949a9667af5a6190374Andreas Hubervoid SampleTable::buildSampleEntriesTable() {
48220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    Mutex::Autolock autoLock(mLock);
48320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4844678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (mSampleTimeEntries != NULL) {
4854678a6dc5f09008481524949a9667af5a6190374Andreas Huber        return;
4864678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
4874678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4884678a6dc5f09008481524949a9667af5a6190374Andreas Huber    mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];
4894678a6dc5f09008481524949a9667af5a6190374Andreas Huber
4904678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleIndex = 0;
4914678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t sampleTime = 0;
4924678a6dc5f09008481524949a9667af5a6190374Andreas Huber
49320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
49420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t n = mTimeToSample[2 * i];
49520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        uint32_t delta = mTimeToSample[2 * i + 1];
49620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
4974678a6dc5f09008481524949a9667af5a6190374Andreas Huber        for (uint32_t j = 0; j < n; ++j) {
49865a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            if (sampleIndex < mNumSampleSizes) {
49965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // Technically this should always be the case if the file
50065a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // is well-formed, but you know... there's (gasp) malformed
50165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                // content out there.
50220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
50365a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
504abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
50589aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                uint32_t compTimeDelta =
50689aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    mCompositionDeltaLookup->getCompositionTimeOffset(
50789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                            sampleIndex);
50889aa8fe4cb00d2f24260005b008602232d678684Andreas Huber
50965a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber                mSampleTimeEntries[sampleIndex].mCompositionTime =
51089aa8fe4cb00d2f24260005b008602232d678684Andreas Huber                    sampleTime + compTimeDelta;
51165a2670e84f44f6cdd80d625a7248fc65319ab8cAndreas Huber            }
5124678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5134678a6dc5f09008481524949a9667af5a6190374Andreas Huber            ++sampleIndex;
5144678a6dc5f09008481524949a9667af5a6190374Andreas Huber            sampleTime += delta;
5154678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5164678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5174678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5184678a6dc5f09008481524949a9667af5a6190374Andreas Huber    qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
5194678a6dc5f09008481524949a9667af5a6190374Andreas Huber          CompareIncreasingTime);
5204678a6dc5f09008481524949a9667af5a6190374Andreas Huber}
5214678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5224678a6dc5f09008481524949a9667af5a6190374Andreas Huberstatus_t SampleTable::findSampleAtTime(
5234678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
5244678a6dc5f09008481524949a9667af5a6190374Andreas Huber    buildSampleEntriesTable();
5254678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5264678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t left = 0;
5274678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t right = mNumSampleSizes;
5284678a6dc5f09008481524949a9667af5a6190374Andreas Huber    while (left < right) {
5294678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t center = (left + right) / 2;
5304678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
5314678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5324678a6dc5f09008481524949a9667af5a6190374Andreas Huber        if (req_time < centerTime) {
5334678a6dc5f09008481524949a9667af5a6190374Andreas Huber            right = center;
5344678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else if (req_time > centerTime) {
5354678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center + 1;
5364678a6dc5f09008481524949a9667af5a6190374Andreas Huber        } else {
5374678a6dc5f09008481524949a9667af5a6190374Andreas Huber            left = center;
5384678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5394678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
5404678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5414678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5424678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (left == mNumSampleSizes) {
543a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        if (flags == kFlagAfter) {
544a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber            return ERROR_OUT_OF_RANGE;
545a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber        }
546a488c7daf91357611fcdbff7a32e5a73ec630070Andreas Huber
5474678a6dc5f09008481524949a9667af5a6190374Andreas Huber        --left;
5484678a6dc5f09008481524949a9667af5a6190374Andreas Huber    }
5494678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5504678a6dc5f09008481524949a9667af5a6190374Andreas Huber    uint32_t closestIndex = left;
551abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
5524678a6dc5f09008481524949a9667af5a6190374Andreas Huber    switch (flags) {
5534678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagBefore:
5544678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
5554678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex > 0
5564678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
5574678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            > req_time) {
5584678a6dc5f09008481524949a9667af5a6190374Andreas Huber                --closestIndex;
55920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            }
5604678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5614678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
56220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5634678a6dc5f09008481524949a9667af5a6190374Andreas Huber        case kFlagAfter:
5644678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
5654678a6dc5f09008481524949a9667af5a6190374Andreas Huber            while (closestIndex + 1 < mNumSampleSizes
5664678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    && mSampleTimeEntries[closestIndex].mCompositionTime
5674678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            < req_time) {
5684678a6dc5f09008481524949a9667af5a6190374Andreas Huber                ++closestIndex;
5694678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
5704678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
57120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
57220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5734678a6dc5f09008481524949a9667af5a6190374Andreas Huber        default:
5744678a6dc5f09008481524949a9667af5a6190374Andreas Huber        {
5754678a6dc5f09008481524949a9667af5a6190374Andreas Huber            CHECK(flags == kFlagClosest);
5764678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5774678a6dc5f09008481524949a9667af5a6190374Andreas Huber            if (closestIndex > 0) {
5784678a6dc5f09008481524949a9667af5a6190374Andreas Huber                // Check left neighbour and pick closest.
5794678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff1 =
5804678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
5814678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex].mCompositionTime,
5824678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
5834678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5844678a6dc5f09008481524949a9667af5a6190374Andreas Huber                uint32_t absdiff2 =
5854678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    abs_difference(
5864678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            mSampleTimeEntries[closestIndex - 1].mCompositionTime,
5874678a6dc5f09008481524949a9667af5a6190374Andreas Huber                            req_time);
5884678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5894678a6dc5f09008481524949a9667af5a6190374Andreas Huber                if (absdiff1 > absdiff2) {
5904678a6dc5f09008481524949a9667af5a6190374Andreas Huber                    closestIndex = closestIndex - 1;
5914678a6dc5f09008481524949a9667af5a6190374Andreas Huber                }
5924678a6dc5f09008481524949a9667af5a6190374Andreas Huber            }
5934678a6dc5f09008481524949a9667af5a6190374Andreas Huber
5944678a6dc5f09008481524949a9667af5a6190374Andreas Huber            break;
5954678a6dc5f09008481524949a9667af5a6190374Andreas Huber        }
59620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
59720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
5984678a6dc5f09008481524949a9667af5a6190374Andreas Huber    *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
5994678a6dc5f09008481524949a9667af5a6190374Andreas Huber
6004678a6dc5f09008481524949a9667af5a6190374Andreas Huber    return OK;
60120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
60220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
603abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huberstatus_t SampleTable::findSyncSampleNear(
604abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t start_sample_index, uint32_t *sample_index, uint32_t flags) {
605abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    Mutex::Autolock autoLock(mLock);
606abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
60720111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    *sample_index = 0;
60820111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
60920111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    if (mSyncSampleOffset < 0) {
61020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        // All samples are sync-samples.
61120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        *sample_index = start_sample_index;
61220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        return OK;
61320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
61420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
615abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (mNumSyncSamples == 0) {
616abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        *sample_index = 0;
617abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        return OK;
618abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
619da76c64dee7d95c967e2841302300cfb081e67b2Andreas Huber
620abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    uint32_t left = 0;
6218f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    uint32_t right = mNumSyncSamples;
6228f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    while (left < right) {
6238f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t center = left + (right - left) / 2;
6248f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        uint32_t x = mSyncSamples[center];
62520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
6268f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        if (start_sample_index < x) {
6278f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            right = center;
6288f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else if (start_sample_index > x) {
6298f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center + 1;
6308f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber        } else {
6318f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber            left = center;
63220111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber            break;
63320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber        }
634f53263a7d580fb550dbc6c8d4f104119beb82ad7James Dong    }
6358d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    if (left == mNumSyncSamples) {
6368d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        if (flags == kFlagAfter) {
63729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("tried to find a sync frame after the last one: %d", left);
6388d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng            return ERROR_OUT_OF_RANGE;
6398d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        }
6408d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng        left = left - 1;
6418d0dd8b46163ec7b42e2051c441ae2bf96dd9aecHong Teng    }
642abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6438f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // Now ssi[left] is the sync sample index just before (or at)
6448f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // start_sample_index.
6458f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples.
646abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6478f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber    uint32_t x = mSyncSamples[left];
648abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
649abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    if (left + 1 < mNumSyncSamples) {
6508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t y = mSyncSamples[left + 1];
651abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
652abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        // our sample lies between sync samples x and y.
653abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
654abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        status_t err = mSampleIterator->seekTo(start_sample_index);
655abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
656abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
657abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
658abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
659abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t sample_time = mSampleIterator->getSampleTime();
660abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
661abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(x);
662abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
663abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
664abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
665abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t x_time = mSampleIterator->getSampleTime();
666abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
667abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        err = mSampleIterator->seekTo(y);
668abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (err != OK) {
669abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            return err;
670abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
671abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
672abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        uint32_t y_time = mSampleIterator->getSampleTime();
673abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
674abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        if (abs_difference(x_time, sample_time)
675abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                > abs_difference(y_time, sample_time)) {
676abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            // Pick the sync sample closest (timewise) to the start-sample.
677abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            x = y;
678abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            ++left;
679abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
680abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    }
681abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
682abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    switch (flags) {
683abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagBefore:
684abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
685abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x > start_sample_index) {
686abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                CHECK(left > 0);
687abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6888f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                x = mSyncSamples[left - 1];
689abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
6908f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                if (x > start_sample_index) {
6918f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // The table of sync sample indices was not sorted
6928f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // properly.
6938f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    return ERROR_MALFORMED;
6948f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                }
695abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
696abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
697abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
698abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
699abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        case kFlagAfter:
700abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        {
701abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            if (x < start_sample_index) {
702abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                if (left + 1 >= mNumSyncSamples) {
703abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                    return ERROR_OUT_OF_RANGE;
704abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber                }
705abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                x = mSyncSamples[left + 1];
707abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
7088f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                if (x < start_sample_index) {
7098f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // The table of sync sample indices was not sorted
7108f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    // properly.
7118f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                    return ERROR_MALFORMED;
7128f76ebf90d0391a4baa8a921ed6e291dfc7891daAndreas Huber                }
713abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            }
714abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
715abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
716abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        }
717abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber
718abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber        default:
719abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber            break;
72020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    }
72120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
722abd1f4f870925d6776dbe4b930b759a1ab6595caAndreas Huber    *sample_index = x;
72320111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
72420111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber    return OK;
72520111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}
72620111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
7277e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huberstatus_t SampleTable::findThumbnailSample(uint32_t *sample_index) {
728c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
729c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7307e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (mSyncSampleOffset < 0) {
7317e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // All samples are sync-samples.
7327e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        *sample_index = 0;
7337e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        return OK;
7347e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7357e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7367e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    uint32_t bestSampleIndex = 0;
7377e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t maxSampleSize = 0;
7387e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7397e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    static const size_t kMaxNumSyncSamplesToScan = 20;
7407e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7417e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // Consider the first kMaxNumSyncSamplesToScan sync samples and
7427e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    // pick the one with the largest (compressed) size as the thumbnail.
7437e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7447e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    size_t numSamplesToScan = mNumSyncSamples;
7457e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    if (numSamplesToScan > kMaxNumSyncSamplesToScan) {
7467e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        numSamplesToScan = kMaxNumSyncSamplesToScan;
7477e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7487e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7497e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    for (size_t i = 0; i < numSamplesToScan; ++i) {
7508bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        uint32_t x = mSyncSamples[i];
7517e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7527e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        // Now x is a sample index.
7537e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        size_t sampleSize;
754c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        status_t err = getSampleSize_l(x, &sampleSize);
7557e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (err != OK) {
7567e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            return err;
7577e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7587e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7597e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        if (i == 0 || sampleSize > maxSampleSize) {
7607e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            bestSampleIndex = x;
7617e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber            maxSampleSize = sampleSize;
7627e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber        }
7637e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    }
7647e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7657e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    *sample_index = bestSampleIndex;
7667e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
7677e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber    return OK;
7687e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber}
7697e04dcf8d6784dd56f53aa90bf34431ab4f0710cAndreas Huber
770c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getSampleSize_l(
771c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex, size_t *sampleSize) {
772c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return mSampleIterator->getSampleSizeDirect(
773c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber            sampleIndex, sampleSize);
774c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
775c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
776c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huberstatus_t SampleTable::getMetaDataForSample(
777c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        uint32_t sampleIndex,
778c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong        off64_t *offset,
779c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        size_t *size,
7804678a6dc5f09008481524949a9667af5a6190374Andreas Huber        uint32_t *compositionTime,
7818bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        bool *isSyncSample) {
782c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    Mutex::Autolock autoLock(mLock);
783c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
784c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    status_t err;
785c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if ((err = mSampleIterator->seekTo(sampleIndex)) != OK) {
786c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        return err;
787c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
788c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
789c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (offset) {
790c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *offset = mSampleIterator->getSampleOffset();
791c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
792c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
793c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    if (size) {
794c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber        *size = mSampleIterator->getSampleSize();
795c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
796c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
7974678a6dc5f09008481524949a9667af5a6190374Andreas Huber    if (compositionTime) {
7984678a6dc5f09008481524949a9667af5a6190374Andreas Huber        *compositionTime = mSampleIterator->getSampleTime();
799c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    }
800c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
8018bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    if (isSyncSample) {
8028bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        *isSyncSample = false;
8038bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        if (mSyncSampleOffset < 0) {
8048bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            // Every sample is a sync sample.
8058bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            *isSyncSample = true;
8068bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        } else {
8078bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            size_t i = (mLastSyncSampleIndex < mNumSyncSamples)
8088bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                    && (mSyncSamples[mLastSyncSampleIndex] <= sampleIndex)
8098bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ? mLastSyncSampleIndex : 0;
8108bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8118bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            while (i < mNumSyncSamples && mSyncSamples[i] < sampleIndex) {
8128bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                ++i;
8138bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8148bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8158bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            if (i < mNumSyncSamples && mSyncSamples[i] == sampleIndex) {
8168bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber                *isSyncSample = true;
8178bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            }
8188bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
8198bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber            mLastSyncSampleIndex = i;
8208bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber        }
8218bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber    }
8228bf59e735760af0b6a85747fd90bf8cf1e5388d7Andreas Huber
823c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber    return OK;
824c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber}
825c57b67905c2128ddadfeca96785ee1f593b6605aAndreas Huber
82689aa8fe4cb00d2f24260005b008602232d678684Andreas Huberuint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
82789aa8fe4cb00d2f24260005b008602232d678684Andreas Huber    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
8284931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber}
8294931bb5259d10c1fa01e7405fb7aaef58a8ffb22Andreas Huber
83020111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber}  // namespace android
83120111aa043c5f404472bc63b90bc5aad906b1101Andreas Huber
832